commit 6acc2de3141a2c1eefd2e7dccf70855a13d9b123 Author: janeptrv Date: Mon Oct 5 01:41:50 2020 -0400 Initial Commit - beginnings of base systems. no complete features diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ed36e39 --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# gradle + +.gradle/ +build/ +out/ +classes/ + +# eclipse + +*.launch + +# idea + +.idea/ +*.iml +*.ipr +*.iws + +# vscode + +.settings/ +.vscode/ +bin/ +.classpath +.project + +# fabric + +run/ +logs/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d4df2a8 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# Petroleum +### A Minecraft "mod" + + +#### Features + +- none, yet. + +# +[by janeptrv](https://j4.pm) diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..a5b3e60 --- /dev/null +++ b/build.gradle @@ -0,0 +1,80 @@ +plugins { + id 'java' + id 'idea' + id 'fabric-loom' version '0.4-SNAPSHOT' + id 'maven-publish' +} + +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 + +archivesBaseName = project.archives_base_name +version = project.mod_version +group = project.maven_group + +dependencies { + //to change the versions see the gradle.properties file + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + + // Fabric API. This is technically optional, but you probably want it anyway. + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + + // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. + // You may need to force-disable transitiveness on them. + compileOnly "com.google.code.findbugs:jsr305:3.0.2" +} + +processResources { + inputs.property "version", project.version + + from(sourceSets.main.resources.srcDirs) { + include "fabric.mod.json" + expand "version": project.version + } + + from(sourceSets.main.resources.srcDirs) { + exclude "fabric.mod.json" + } +} + +// ensure that the encoding is set to UTF-8, no matter what the system default is +// this fixes some edge cases with special characters not displaying correctly +// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html +tasks.withType(JavaCompile) { + options.encoding = "UTF-8" +} + +// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task +// if it is present. +// If you remove this task, sources will not be generated. +task sourcesJar(type: Jar, dependsOn: classes) { + classifier = "sources" + from sourceSets.main.allSource +} + +jar { + from "LICENSE" +} + +// configure the maven publication +publishing { + publications { + mavenJava(MavenPublication) { + // add all the jars that should be included when publishing to maven + artifact(remapJar) { + builtBy remapJar + } + artifact(sourcesJar) { + builtBy remapSourcesJar + } + } + } + + // select the repositories you want to publish to + repositories { + // uncomment to publish to the local maven + // mavenLocal() + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..8d94d1d --- /dev/null +++ b/gradle.properties @@ -0,0 +1,17 @@ +# Done to increase the memory available to gradle. +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 + +# Mod Properties + mod_version = 0.1.3 + 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 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..490fda8 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..622ab64 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..2fe81a7 --- /dev/null +++ b/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..62bd9b9 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,103 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/logs/latest.log b/logs/latest.log new file mode 100644 index 0000000..e69de29 diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..5b60df3 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,10 @@ +pluginManagement { + repositories { + jcenter() + maven { + name = 'Fabric' + url = 'https://maven.fabricmc.net/' + } + gradlePluginPortal() + } +} diff --git a/src/main/java/pm/j4/petroleum/PetroleumMod.java b/src/main/java/pm/j4/petroleum/PetroleumMod.java new file mode 100644 index 0000000..d5744d2 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/PetroleumMod.java @@ -0,0 +1,159 @@ +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.base.ModuleBase; +import pm.j4.petroleum.modules.bindings.BindingManager; +import pm.j4.petroleum.util.config.ConfigHolder; +import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.modules.list.ModList; +import pm.j4.petroleum.modules.menu.ModMenu; +import pm.j4.petroleum.modules.splash.SplashText; + + +//TODO: +// petroleum module checklist +// [ ] xray (lol) +// [ ] combat stuff. killaura, anti knockback, etc +// [ ] render stuff. tracers, nametags +// [ ] wurst taco. but a fish +// [ ] elytra fly +// [ ] movement stuff. nofall, jesus, speed +// [ ] elytra bhop +// [ ] boatfly +// [ ] anti anti cheat +/** + * The type Petroleum mod. + */ +public class PetroleumMod implements ModInitializer { + /** + * The Mod data. + */ + public static ModMetadata modData = null; + /** + * The constant client. + */ + private static MinecraftClient client; + /** + * The constant activeMods. + */ + private static final List activeMods = Arrays.asList( + new SplashText(), + new ModMenu(), + new ModList(), + new BindingManager(), + new ExampleModule() + ); + + /** + * Is active boolean. + * + * @param modName the mod name + * @return the boolean + */ + public static boolean isActive(String modName) { + return activeMods.stream().anyMatch(mod -> mod.getModuleName().equals(modName)); + } + + /** + * Gets mod. + * + * @param modName the mod name + * @return the mod + */ + public static Optional getMod(String modName) { + return activeMods.stream().filter(mod -> mod.getModuleName().equals(modName)).findFirst(); + } + + /** + * Gets active mods. + * + * @return the active mods + */ + public static List getActiveMods() { + return activeMods; + } + + /** + * The constant registeredBinds. + */ + private static final List registeredBinds = new ArrayList<>(); + + /** + * Add bind. + * + * @param b the b + */ + public static void addBind(KeyBinding b) { + registeredBinds.add(b); + } + + /** + * Remove bind. + * + * @param b the b + */ + public static void removeBind(KeyBinding b) { + registeredBinds.remove(b); + } + + /** + * Gets active keybinds. + * + * @return the active keybinds + */ + public static List getActiveKeybinds() { + return registeredBinds; + } + + /** + * Gets server address. + * + * @return the server address + */ + public static String getServerAddress() { + if (client != null && client.getServer() != null) { + IntegratedServer server = client.getServer(); + if (server.isRemote() && !server.getServerIp().isEmpty()) { + return server.getServerIp(); + } + } + return null; + } + + @Override + public void onInitialize() { + ConfigManager.initConfig(); + // always update mod data + Optional modContainer = FabricLoader.getInstance().getModContainer("petroleum"); + modContainer.ifPresent(container -> modData = container.getMetadata()); + + //initialize any keybinds, data, etc. + activeMods.forEach(ModuleBase::init); + + Optional conf = ConfigManager.getConfig(); + //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); + } + } + //System.out.println(getServerAddress()); + })); + } +} diff --git a/src/main/java/pm/j4/petroleum/gui/PModMenuScreen.java b/src/main/java/pm/j4/petroleum/gui/PModMenuScreen.java new file mode 100644 index 0000000..c2b399c --- /dev/null +++ b/src/main/java/pm/j4/petroleum/gui/PModMenuScreen.java @@ -0,0 +1,50 @@ +package pm.j4.petroleum.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +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.PetroleumMod; +import pm.j4.petroleum.util.config.ConfigManager; + +public class PModMenuScreen extends Screen { + public PModMenuScreen() { + super(new TranslatableText("petroleum.modlist")); + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + System.out.println("MENU ACTIVATED"); + this.client.textRenderer.drawWithShadow(matrices, new LiteralText("Menu Open"), 10, 50, -1); + this.renderBackground(matrices); + super.render(matrices, mouseX, mouseY, delta); + } + + @Override + protected void init() { + this.addButton(new PMovableButton(10, 10, 40, 10, PetroleumMod.getActiveMods().get(0))); + } + + @Override + public void onClose() { + ConfigManager.getConfig().get().disableModule("petroleum.modmenu"); + super.onClose(); + } + + @Override + public void renderBackground(MatrixStack matrices) { + Tessellator t_1 = Tessellator.getInstance(); + BufferBuilder buffer = t_1.getBuffer(); + RenderSystem.color4f(0.0F, 0.0F, 0.0F, 0.1F); + buffer.begin(7, VertexFormats.POSITION_COLOR); + buffer.vertex(0,this.height, 0.0D).color(0.0F, 0.0F, 0.0F, 0.1F).next(); + buffer.vertex(this.width, this.height, 0.0D).color(0.0F, 0.0F, 0.0F, 0.1F).next(); + buffer.vertex(this.width, 0, 0.0D).color(0.0F, 0.0F, 0.0F, 0.1F).next(); + buffer.vertex(0,0,0.0D).color(0.0F, 0.0F, 0.0F, 0.1F).next(); + t_1.draw(); + } +} diff --git a/src/main/java/pm/j4/petroleum/gui/PModuleConfigEntry.java b/src/main/java/pm/j4/petroleum/gui/PModuleConfigEntry.java new file mode 100644 index 0000000..cbbd0a3 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/gui/PModuleConfigEntry.java @@ -0,0 +1,47 @@ +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.modules.base.ConfigurationOption; + +/** + * The type P module config entry. + */ +public class PModuleConfigEntry extends EntryListWidget.Entry { + /** + * The Option. + */ + protected final ConfigurationOption option; + /** + * The Display text. + */ + protected final Text displayText; + + /** + * Instantiates a new P module config entry. + * + * @param option the option + * @param text the text + */ + public PModuleConfigEntry(ConfigurationOption option, Text text) { + this.option = option; + this.displayText = text; + } + + @Override + public 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.toStringValue()), x, y + fontHeight + 4, 0xFFFFFF); + } + } +} \ No newline at end of file diff --git a/src/main/java/pm/j4/petroleum/gui/PModuleConfigPane.java b/src/main/java/pm/j4/petroleum/gui/PModuleConfigPane.java new file mode 100644 index 0000000..72273ba --- /dev/null +++ b/src/main/java/pm/j4/petroleum/gui/PModuleConfigPane.java @@ -0,0 +1,115 @@ +package pm.j4.petroleum.gui; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.widget.EntryListWidget; +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.util.math.MatrixStack; + +/** + * The type P module config pane. + */ +public class PModuleConfigPane extends EntryListWidget { + /** + * The Parent. + */ + private final POptionsScreen parent; + /** + * The Last selected. + */ + private POptionEntry lastSelected; + + /** + * Instantiates a new P module config pane. + * + * @param client the client + * @param width the width + * @param height the height + * @param top the top + * @param bottom the bottom + * @param entryHeight the entry height + * @param screen the screen + */ + public PModuleConfigPane(MinecraftClient client, int width, int height, int top, int bottom, int entryHeight, POptionsScreen screen) { + super(client, width, height, top, bottom, entryHeight); + this.parent = screen; + /** + * The Text renderer. + */ + TextRenderer textRenderer = client.textRenderer; + } + + @Override + public PModuleConfigEntry getSelected() { + return null; + } + + @Override + public int getRowWidth() { + return this.width - 10; + } + + @Override + protected int getScrollbarPositionX() { + return this.width - 6 + left; + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + POptionEntry selectedEntry = parent.getSelected(); + if (selectedEntry != lastSelected) { + lastSelected = selectedEntry; + clearEntries(); + setScrollAmount(-Double.MAX_VALUE); + String id = lastSelected.getModId(); + if (lastSelected != null && id != null && !id.isEmpty()) { + children().addAll(lastSelected.module.getConfigEntries()); + } + } + + Tessellator t_1 = Tessellator.getInstance(); + BufferBuilder buffer = t_1.getBuffer(); + + RenderSystem.depthFunc(515); + RenderSystem.disableDepthTest(); + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(GlStateManager.SrcFactor.SRC_ALPHA, + GlStateManager.DstFactor.ONE_MINUS_DST_ALPHA, + GlStateManager.SrcFactor.ZERO, + GlStateManager.DstFactor.ONE); + RenderSystem.disableAlphaTest(); + RenderSystem.shadeModel(7425); + RenderSystem.disableTexture(); + + buffer.begin(7, VertexFormats.POSITION_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(); + t_1.draw(); + + buffer.begin(7, VertexFormats.POSITION_COLOR); + buffer.vertex(this.left, this.bottom, 0.0D).color(0, 0, 0, 128).next(); + buffer.vertex(this.right, this.bottom, 0.0D).color(0, 0, 0, 128).next(); + buffer.vertex(this.right, this.top, 0.0D).color(0, 0, 0, 128).next(); + buffer.vertex(this.left, this.top, 0.0D).color(0, 0, 0, 128).next(); + t_1.draw(); + + int rl = this.getRowLeft(); + int sc = this.top + 4 - (int) this.getScrollAmount(); + this.renderList(matrices, rl, sc, mouseX, mouseY, delta); + + RenderSystem.enableTexture(); + RenderSystem.shadeModel(7424); + RenderSystem.enableAlphaTest(); + RenderSystem.disableBlend(); + } +} diff --git a/src/main/java/pm/j4/petroleum/gui/PModuleConfigurationWidget.java b/src/main/java/pm/j4/petroleum/gui/PModuleConfigurationWidget.java new file mode 100644 index 0000000..cd24a72 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/gui/PModuleConfigurationWidget.java @@ -0,0 +1,281 @@ +package pm.j4.petroleum.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget; +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Matrix4f; +import pm.j4.petroleum.mixin.EntryListWidgetAccessor; +import pm.j4.petroleum.modules.base.ModuleBase; + +/** + * The type P module configuration widget. + */ +public class PModuleConfigurationWidget extends AlwaysSelectedEntryListWidget { + /** + * The Parent. + */ + private final POptionsScreen parent; + /** + * The Module id. + */ + private String moduleId = null; + /** + * The Mods. + */ + private List mods; + /** + * The Extra mods. + */ + private final Set extraMods = new HashSet<>(); + /** + * The Scrolling. + */ + private boolean scrolling = false; + + /** + * Instantiates a new P module configuration widget. + * + * @param client the client + * @param width the width + * @param height the height + * @param y1 the y 1 + * @param y2 the y 2 + * @param entryHeight the entry height + * @param list the list + * @param parent the parent + */ + public PModuleConfigurationWidget(MinecraftClient client, int width, int height, int y1, int y2, int entryHeight, PModuleConfigurationWidget list, POptionsScreen parent) { + super(client, width, height, y1, y2, entryHeight); + this.parent = parent; + if (list != null) { + mods = list.mods; + } + setScrollAmount(parent.getScrollPercent() * Math.max(0, this.getMaxPosition() - (this.bottom - this.top - 4))); + } + + @Override + public void setScrollAmount(double amount) { + super.setScrollAmount(amount); + int denominator = Math.max(0, this.getMaxPosition() - (this.bottom - this.top - 4)); + if (denominator <= 0) { + parent.updateScrollPercent(0); + } else { + parent.updateScrollPercent(getScrollAmount() / Math.max(0, this.getMaxPosition() - (this.bottom - this.top - 4))); + } + } + + @Override + protected boolean isFocused() { + return parent.getFocused() == this; + } + + /** + * Select. + * + * @param entry the entry + */ + public void select(POptionEntry entry) { + this.setSelected(entry); + } + + @Override + public void setSelected(POptionEntry entry) { + super.setSelected(entry); + moduleId = entry.getModId(); + parent.updateSelected(entry); + } + + @Override + protected boolean isSelectedItem(int index) { + return super.isSelectedItem(index); + } + + @Override + public int addEntry(POptionEntry entry) { + if (extraMods.contains(entry.module)) { + return 0; + } + extraMods.add(entry.module); + int i = super.addEntry(entry); + if (entry.getModId().equals(moduleId)) { + setSelected(entry); + } + return i; + } + + @Override + protected boolean removeEntry(POptionEntry entry) { + extraMods.remove(entry.module); + return super.removeEntry(entry); + } + + @Override + protected POptionEntry remove(int index) { + extraMods.remove(getEntry(index).module); + return super.remove(index); + } + + @Override + protected void renderList(MatrixStack matrices, int x, int y, int mouseX, int mouseY, float delta) { + int itemCount = this.getItemCount(); + Tessellator t_1 = Tessellator.getInstance(); + BufferBuilder buffer = t_1.getBuffer(); + + for (int index = 0; index < itemCount; ++index) { + int entryTop = this.getRowTop(index); + int entryBottom = this.getRowTop(index) + this.itemHeight; + if (entryBottom >= this.top && entryTop <= this.bottom) { + int entryHeight = this.itemHeight - 4; + POptionEntry entry = this.getEntry(index); + int rowWidth = this.getRowWidth(); + int entryLeft; + if (((EntryListWidgetAccessor) this).isRenderSelection() && this.isSelectedItem(index)) { + entryLeft = getRowLeft() - 2 + entry.getXOffset(); + int selectionRight = x + rowWidth + 2; + RenderSystem.disableTexture(); + float brightness = this.isFocused() ? 1.0F : 0.5F; + RenderSystem.color4f(brightness, brightness, brightness, 1.0F); + Matrix4f matrix = matrices.peek().getModel(); + buffer.begin(7, VertexFormats.POSITION); + buffer.vertex(matrix, entryLeft, entryTop + entryHeight + 2, 0.0F).next(); + buffer.vertex(matrix, selectionRight, entryTop + entryHeight + 2, 0.0F).next(); + buffer.vertex(matrix, selectionRight, entryTop - 2, 0.0F).next(); + buffer.vertex(matrix, entryLeft, entryTop - 2, 0.0F).next(); + t_1.draw(); + RenderSystem.color4f(0.0F, 0.0F, 0.0F, 1.0F); + buffer.begin(7, VertexFormats.POSITION); + buffer.vertex(matrix, entryLeft + 1, entryTop + entryHeight + 1, 0.0F).next(); + buffer.vertex(matrix, selectionRight, entryTop + entryHeight + 1, 0.0F).next(); + buffer.vertex(matrix, selectionRight, entryTop - 1, 0.0F).next(); + buffer.vertex(matrix, entryLeft + 1, entryTop - 1, 0.0F).next(); + t_1.draw(); + RenderSystem.enableTexture(); + } + + entryLeft = this.getRowLeft(); + entry.render(matrices, + index, + entryTop, + entryLeft, + rowWidth, + entryHeight, + mouseX, + mouseY, + this.isMouseOver(mouseX, mouseY) && Objects.equals(this.getEntryAtPos(mouseX, mouseY), entry), + delta); + } + } + } + + @Override + protected void updateScrollingState(double mouseX, double mouseY, int button) { + super.updateScrollingState(mouseX, mouseY, button); + this.scrolling = button == 0 && + mouseX >= (double) this.getScrollbarPositionX() && + mouseX < (double) (this.getScrollbarPositionX() + 6); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + this.updateScrollingState(mouseX, mouseY, button); + if (!this.isMouseOver(mouseX, mouseY)) { + return false; + } else { + POptionEntry entry = this.getEntryAtPos(mouseX, mouseY); + if (entry != null) { + if (entry.mouseClicked(mouseX, mouseY, button)) { + this.setFocused(entry); + this.setDragging(true); + return true; + } else if (button == 0) { + this.clickedHeader((int) (mouseX - (double) (this.left + this.width / 2 - this.getRowWidth() / 2)), + (int) (mouseY - (double) this.top) + (int) this.getScrollAmount() - 4); + } + } + } + + return this.scrolling; + } + + /** + * Gets entry at pos. + * + * @param x the x + * @param y the y + * @return the entry at pos + */ + public final POptionEntry getEntryAtPos(double x, double y) { + int i = MathHelper.floor(y - (double) this.top) - this.headerHeight + (int) this.getScrollAmount() - 4; + int index = i / this.itemHeight; + return x < (double) this.getScrollbarPositionX() && + x >= (double) getRowLeft() && + x <= (double) (getRowLeft() + getRowWidth()) && + index >= 0 && i >= 0 && + index < this.getItemCount() ? this.children().get(index) : null; + } + + @Override + protected int getScrollbarPositionX() { + return this.width - 6; + } + + @Override + public int getRowWidth() { + return this.width - (Math.max(0, this.getMaxPosition() - (this.bottom - this.top - 4)) > 0 ? 18 : 12); + } + + @Override + public int getRowLeft() { + return left + 6; + } + + /** + * Gets width. + * + * @return the width + */ + public int getWidth() { + return width; + } + + /** + * Gets top. + * + * @return the top + */ + public int getTop() { + return this.top; + } + + /** + * Gets parent. + * + * @return the parent + */ + public POptionsScreen getParent() { + return parent; + } + + @Override + protected int getMaxPosition() { + return super.getMaxPosition() + 4; + } + + /** + * Gets displayed count. + * + * @return the displayed count + */ + public int getDisplayedCount() { + return children().size(); + } +} diff --git a/src/main/java/pm/j4/petroleum/gui/PMovableButton.java b/src/main/java/pm/j4/petroleum/gui/PMovableButton.java new file mode 100644 index 0000000..6965b19 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/gui/PMovableButton.java @@ -0,0 +1,42 @@ +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.AbstractButtonWidget; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.Text; +import net.minecraft.util.math.MathHelper; +import pm.j4.petroleum.modules.base.ModuleBase; + +public class PMovableButton extends AbstractButtonWidget { + public PMovableButton(int x, int y, int width, int height, ModuleBase module) { + super(x, y, width, height, module.getReadableName()); + } + + @Override + protected void onDrag(double mouseX, double mouseY, double deltaX, double deltaY) { + System.out.println(mouseX + "/" + mouseY + "/" + deltaX + "/" + deltaY); + this.x += (int)deltaX; + this.y += (int)deltaY; + } + + @Override + public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) { + // CURRENT BUTTON RENDERING + //TODO just do some shit with Tessellator and BufferBuilder to draw the lines around the button + MinecraftClient minecraftClient = MinecraftClient.getInstance(); + TextRenderer textRenderer = minecraftClient.textRenderer; + minecraftClient.getTextureManager().bindTexture(WIDGETS_LOCATION); + RenderSystem.color4f(1.0F, 1.0F, 1.0F, this.alpha); + int i = this.getYImage(this.isHovered()); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + RenderSystem.enableDepthTest(); + this.drawTexture(matrices, this.x, this.y, 0, 46 + i * 20, this.width / 2, this.height); + this.drawTexture(matrices, this.x + this.width / 2, this.y, 200 - this.width / 2, 46 + i * 20, this.width / 2, this.height); + this.renderBg(matrices, minecraftClient, mouseX, mouseY); + int j = this.active ? 16777215 : 10526880; + drawCenteredText(matrices, textRenderer, this.getMessage(), this.x + this.width / 2, this.y + (this.height - 8) / 2, j | MathHelper.ceil(this.alpha * 255.0F) << 24); + } +} diff --git a/src/main/java/pm/j4/petroleum/gui/POptionEntry.java b/src/main/java/pm/j4/petroleum/gui/POptionEntry.java new file mode 100644 index 0000000..ad5fdb7 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/gui/POptionEntry.java @@ -0,0 +1,94 @@ +package pm.j4.petroleum.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.StringVisitable; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.Language; +import pm.j4.petroleum.modules.base.ModuleBase; + +/** + * The type P option entry. + */ +public class POptionEntry extends AlwaysSelectedEntryListWidget.Entry { + + /** + * The Module. + */ + protected final ModuleBase module; + /** + * The Client. + */ + protected final MinecraftClient client; + /** + * The List. + */ + private final PModuleConfigurationWidget list; + + /** + * Instantiates a new P option entry. + * + * @param mod the mod + * @param list the list + */ + public POptionEntry(ModuleBase mod, PModuleConfigurationWidget list) { + this.module = mod; + this.client = MinecraftClient.getInstance(); + this.list = list; + } + + //TODO TEST move text to be centered + @Override + public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + x += getXOffset(); + entryWidth -= getXOffset(); + RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); + Text name = this.getModName(); + StringVisitable nameString = name; + int maxNameWidth = entryWidth - 32 - 3; + TextRenderer font = this.client.textRenderer; + if (font.getWidth(name) > maxNameWidth) { + StringVisitable ellipse = StringVisitable.plain("..."); + nameString = StringVisitable.concat(font.trimToWidth(nameString, maxNameWidth - font.getWidth(ellipse)), ellipse); + } + + font.draw(matrices, Language.getInstance().reorder(nameString), x + 32 + 3, y + (entryHeight / 2), 0xFFFFFF); + } + + @Override + public boolean mouseClicked(double x, double y, int b) { + this.list.select(this); + return true; + } + + /** + * Gets mod id. + * + * @return the mod id + */ + public String getModId() { + return module.getModuleName(); + } + + /** + * Gets mod name. + * + * @return the mod name + */ + public TranslatableText getModName() { + return module.getReadableName(); + } + + /** + * Gets x offset. + * + * @return the x offset + */ + public int getXOffset() { + return 0; + } +} diff --git a/src/main/java/pm/j4/petroleum/gui/POptionsScreen.java b/src/main/java/pm/j4/petroleum/gui/POptionsScreen.java new file mode 100644 index 0000000..1f3ee35 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/gui/POptionsScreen.java @@ -0,0 +1,224 @@ +package pm.j4.petroleum.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ScreenTexts; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.LiteralText; +import net.minecraft.text.StringVisitable; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import pm.j4.petroleum.PetroleumMod; +import pm.j4.petroleum.modules.base.ModuleBase; +import pm.j4.petroleum.util.config.ConfigManager; + +/** + * The type P options screen. + */ +@SuppressWarnings("deprecation") +public class POptionsScreen extends Screen { + /** + * The Previous screen. + */ + private final Screen previousScreen; + /** + * The Scroll percent. + */ + private double scrollPercent = 0; + /** + * The Modules. + */ + private PModuleConfigurationWidget modules; + /** + * The Config pane. + */ + private PModuleConfigPane configPane; + /** + * The Selected. + */ + private POptionEntry selected; + /** + * The Tooltip. + */ + private Text tooltip; + + /** + * The Pane y. + */ + private int paneY; + /** + * The Right pane x. + */ + private int rightPaneX; + + /** + * Instantiates a new P options screen. + * + * @param previousScreen the previous screen + */ + public POptionsScreen(Screen previousScreen) { + super(new TranslatableText("petroleum.options")); + this.previousScreen = previousScreen; + } + + @Override + public void onClose() { + super.onClose(); + assert this.client != null; + this.client.openScreen(previousScreen); + } + + protected void init() { + paneY = 48; + int paneWidth = this.width / 2 - 8; + rightPaneX = width - paneWidth; + this.modules = new PModuleConfigurationWidget(this.client, + this.width - paneWidth, + this.height, + paneY + 19, + this.height - 36, + 36, + this.modules, + this); + this.modules.setLeftPos(0); + this.children.add(this.modules); + this.configPane = new PModuleConfigPane(this.client, + paneWidth, + this.height, + paneY + 19, + this.height - 36, + 48, + this); + this.configPane.setLeftPos(paneWidth); + this.children.add(this.configPane); + List configurableModules = new ArrayList<>(); + if (ConfigManager.getConfig().isPresent()) { + configurableModules.addAll(PetroleumMod.getActiveMods() + .stream().filter(ModuleBase::configurable) + .collect(Collectors.toList())); + } + configurableModules.forEach(module -> this.modules.addEntry(new POptionEntry(module, this.modules))); + this.addButton(new ButtonWidget(this.width / 2 - 75, this.height - 30, 150, 20, ScreenTexts.DONE, (buttonWidget) -> { + ConfigManager.save(); + assert this.client != null; + this.client.openScreen(this.previousScreen); + })); + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + this.renderBackground(matrices); + + this.modules.render(matrices, mouseX, mouseY, delta); + if (selected != null) { + this.configPane.render(matrices, mouseX, mouseY, delta); + } + RenderSystem.disableBlend(); + drawTextWithShadow(matrices, this.textRenderer, this.title, this.modules.getWidth() / 2, 8, 16777215); + super.render(matrices, mouseX, mouseY, delta); + + if (selected != null) { + int offset = 36; + int x = rightPaneX; + int maxNameWidth = this.width - (x + offset); + int lineSpacing = textRenderer.fontHeight + 1; + Text name = selected.getModName(); + + StringVisitable trimmedName = name; + + if (textRenderer.getWidth(name) > maxNameWidth) { + StringVisitable ellipsis = StringVisitable.plain("..."); + trimmedName = StringVisitable.concat(textRenderer.trimToWidth(name, maxNameWidth - textRenderer.getWidth(ellipsis)), ellipsis); + } + if (mouseX > x + offset && mouseY > paneY + 1 && mouseY < paneY + 1 + textRenderer.fontHeight && mouseX < x + offset + textRenderer.getWidth(trimmedName)) { + setTooltip(new LiteralText("Configure " + selected.getModName())); + } + textRenderer.draw(matrices, selected.getModName(), x + offset, paneY + 2 + lineSpacing, 0x808080); + + if (this.tooltip != null) { + this.renderOrderedTooltip(matrices, textRenderer.wrapLines(this.tooltip, Integer.MAX_VALUE), mouseX, mouseY); + } + } + } + + /** + * Sets tooltip. + * + * @param tooltip the tooltip + */ + private void setTooltip(Text tooltip) { + this.tooltip = tooltip; + } + + @Override + public void renderBackground(MatrixStack matrices) { + POptionsScreen.overlayBackground(this.width, this.height); + } + + /** + * Overlay background. + * + * @param x2 the x 2 + * @param y2 the y 2 + */ + static void overlayBackground(int x2, int y2) { + Tessellator t_1 = Tessellator.getInstance(); + BufferBuilder buffer = t_1.getBuffer(); + Objects.requireNonNull(MinecraftClient.getInstance()).getTextureManager().bindTexture(DrawableHelper.OPTIONS_BACKGROUND_TEXTURE); + RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); + buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR); + buffer.vertex(0, y2, 0.0D).texture(0 / 32.0F, y2 / 32.0F).color(64, 64, 64, 255).next(); + buffer.vertex(x2, y2, 0.0D).texture(x2 / 32.0F, y2 / 32.0F).color(64, 64, 64, 255).next(); + buffer.vertex(x2, 0, 0.0D).texture(x2 / 32.0F, 0 / 32.0F).color(64, 64, 64, 255).next(); + buffer.vertex(0, 0, 0.0D).texture(0 / 32.0F, 0 / 32.0F).color(64, 64, 64, 255).next(); + t_1.draw(); + } + + /** + * Gets scroll percent. + * + * @return the scroll percent + */ + double getScrollPercent() { + return scrollPercent; + } + + /** + * Update scroll percent. + * + * @param scrollPercent the scroll percent + */ + void updateScrollPercent(double scrollPercent) { + this.scrollPercent = scrollPercent; + } + + /** + * Gets selected. + * + * @return the selected + */ + POptionEntry getSelected() { + return selected; + } + + /** + * Update selected. + * + * @param entry the entry + */ + void updateSelected(POptionEntry entry) { + if (entry != null) { + this.selected = entry; + } + } +} diff --git a/src/main/java/pm/j4/petroleum/mixin/DebugHudMixin.java b/src/main/java/pm/j4/petroleum/mixin/DebugHudMixin.java new file mode 100644 index 0000000..6e29426 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/mixin/DebugHudMixin.java @@ -0,0 +1,38 @@ +package pm.j4.petroleum.mixin; + +import java.util.List; +import java.util.Optional; +import net.minecraft.client.gui.hud.DebugHud; +import net.minecraft.client.util.math.MatrixStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import pm.j4.petroleum.util.config.ConfigHolder; +import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.modules.splash.SplashText; + +/** + * The type Debug hud mixin. + */ +@Mixin(DebugHud.class) +public class DebugHudMixin { + /** + * Render text right. + * + * @param matrices the matrices + * @param ci the ci + * @param list the list + */ + @Inject(method = "renderLeftText", + at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/client/gui/hud/DebugHud;getLeftText()Ljava/util/List;"), + locals = LocalCapture.CAPTURE_FAILSOFT) + protected void renderTextRight(MatrixStack matrices, CallbackInfo ci, List list) { + Optional config = ConfigManager.getConfig(); + if (config.isPresent() && config.get().isModuleEnabled("petroleum.splashtext")) { + list.add("[Petroleum] " + SplashText.get() + " loaded"); + } + + } +} diff --git a/src/main/java/pm/j4/petroleum/mixin/EntryListWidgetAccessor.java b/src/main/java/pm/j4/petroleum/mixin/EntryListWidgetAccessor.java new file mode 100644 index 0000000..eea68ab --- /dev/null +++ b/src/main/java/pm/j4/petroleum/mixin/EntryListWidgetAccessor.java @@ -0,0 +1,19 @@ +package pm.j4.petroleum.mixin; + +import net.minecraft.client.gui.widget.EntryListWidget; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +/** + * The interface Entry list widget accessor. + */ +@Mixin(EntryListWidget.class) +public interface EntryListWidgetAccessor { + /** + * Is render selection boolean. + * + * @return the boolean + */ + @Accessor("renderSelection") + boolean isRenderSelection(); +} diff --git a/src/main/java/pm/j4/petroleum/mixin/ModListMixin.java b/src/main/java/pm/j4/petroleum/mixin/ModListMixin.java new file mode 100644 index 0000000..968fe2c --- /dev/null +++ b/src/main/java/pm/j4/petroleum/mixin/ModListMixin.java @@ -0,0 +1,89 @@ +package pm.j4.petroleum.mixin; + + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.gui.hud.InGameHud; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.TranslatableText; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import pm.j4.petroleum.modules.base.ModuleBase; +import pm.j4.petroleum.util.config.ConfigHolder; +import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.modules.list.ModList; + +/** + * The type Mod list mixin. + */ +@Mixin(InGameHud.class) +public abstract class ModListMixin extends DrawableHelper { + /** + * The Scaled height. + */ + @Shadow + private int scaledHeight; + /** + * The Client. + */ + private final MinecraftClient client; + + /** + * Gets font renderer. + * + * @return the font renderer + */ + @Shadow + public abstract TextRenderer getFontRenderer(); + + + /** + * Instantiates a new Mod list mixin. + * + * @param client the client + */ + public ModListMixin(MinecraftClient client) { + this.client = client; + } + + /** + * Render. + * + * @param matrices the matrices + * @param tickDelta the tick delta + * @param ci the ci + */ + @Inject(method = "render(Lnet/minecraft/client/util/math/MatrixStack;F)V", + at = @At("HEAD")) + public void render(MatrixStack matrices, float tickDelta, CallbackInfo ci) { + Optional config = ConfigManager.getConfig(); + if (config.isPresent() && + config.get().isModuleEnabled("petroleum.modlist") && + !this.client.options.hudHidden && + !this.client.options.debugEnabled) { + renderModuleList(matrices); + } + } + + /** + * Render module list. + * + * @param matrices the matrices + */ + private void renderModuleList(MatrixStack matrices) { + List modules = ModList.getActive(); + List activeModuleList = modules.stream().map(module -> module.getReadableName()).collect(Collectors.toList()); + int fontHeight = this.getFontRenderer().fontHeight; + int startHeight = this.scaledHeight - (activeModuleList.size() * (fontHeight + 4)); + for (int i = 0; i < activeModuleList.size(); i++) { + this.getFontRenderer().drawWithShadow(matrices, activeModuleList.get(i), 10, 10 + (i * (fontHeight + 4)), -1); + } + } +} diff --git a/src/main/java/pm/j4/petroleum/mixin/ModMenuMixin.java b/src/main/java/pm/j4/petroleum/mixin/ModMenuMixin.java new file mode 100644 index 0000000..36b9851 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/mixin/ModMenuMixin.java @@ -0,0 +1,11 @@ +package pm.j4.petroleum.mixin; + +/** + * Mixin for in-game module management menu. + * Includes module activation/deactivation, as well as some configuration options. + * A separate menu for advanced configurations should also be added eventually. + * This module should handle the rendering of the menu and all of its buttons, + * while delegating button presses to @link pm.j4.petroleum.modules.menu.ModMenu + */ +public class ModMenuMixin { +} diff --git a/src/main/java/pm/j4/petroleum/mixin/OptionsMenuMixin.java b/src/main/java/pm/j4/petroleum/mixin/OptionsMenuMixin.java new file mode 100644 index 0000000..be27f25 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/mixin/OptionsMenuMixin.java @@ -0,0 +1,42 @@ +package pm.j4.petroleum.mixin; + +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.options.OptionsScreen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import pm.j4.petroleum.gui.POptionsScreen; + +/** + * The type Options menu mixin. + */ +@Mixin(OptionsScreen.class) +public class OptionsMenuMixin extends Screen { + + /** + * Instantiates a new Options menu mixin. + * + * @param title the title + */ + protected OptionsMenuMixin(Text title) { + super(title); + } + + /** + * Init. + * + * @param ci the ci + */ + @Inject(at = @At(value = "TAIL"), + method = "init()V") + protected void init(CallbackInfo ci) { + this.addButton(new ButtonWidget(this.width / 2 - 75, this.height / 6 + 140, 150, 20, new TranslatableText("petroleum.options"), (buttonWidget) -> { + assert this.client != null; + this.client.openScreen(new POptionsScreen(this)); + })); + } +} diff --git a/src/main/java/pm/j4/petroleum/mixin/TitleScreenMixin.java b/src/main/java/pm/j4/petroleum/mixin/TitleScreenMixin.java new file mode 100644 index 0000000..9be245b --- /dev/null +++ b/src/main/java/pm/j4/petroleum/mixin/TitleScreenMixin.java @@ -0,0 +1,132 @@ +package pm.j4.petroleum.mixin; + +import java.util.Optional; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.TitleScreen; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.Text; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import pm.j4.petroleum.util.config.ConfigHolder; +import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.modules.splash.SplashText; + + +/** + * Mixin attached to the TitleScreen. + * Currently, it is only used to display a string of text with the mod's version. + * Any other modules will likely extend the options screen or pause screen, + * so the module is unlikely to be used elsewhere. + */ +@Mixin(TitleScreen.class) +public class TitleScreenMixin extends Screen { + /** + * The Opacity. + */ + private double opacity = 0; + /** + * The Ascending. + */ + private boolean ascending = false; + + /** + * Stub method. + * Since the mixin injects itself into the *actual* TitleScreen used by the game, + * this should never run. + * + * @param title the title + */ + protected TitleScreenMixin(Text title) { + super(title); + } + + /** + * Mixin injection into the render method. + * It captures locals so that the text can be rendered alongside the + * screen fade-in. + * It injects before the call to @link com.mojang.bridge.game.GameVersion#getName() using INVOKE_ASSIGN, + * because attempting to use a regular invoke statement on @link net.minecraft.client.gui.DrawHelper#drawStringWithShadow() + * repeatedly failed. + *

+ * + * @param matrices the matrices + * @param mouseX the mouse x + * @param mouseY the mouse y + * @param delta the delta + * @param ci the ci + * @param f the f + * @param i the + * @param j the j + * @param g the g + * @param l the l + */ + @Inject(method = "render", + at = @At( + value = "INVOKE_ASSIGN", + target = "Lcom/mojang/bridge/game/GameVersion;getName()Ljava/lang/String;", + ordinal = 0), + locals = LocalCapture.CAPTURE_FAILSOFT) + private void render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci, float f, int i, int j, float g, int l) { + Optional config = ConfigManager.getConfig(); + if (config.isPresent() && config.get().isModuleEnabled("petroleum.splashtext")) { + drawStringWithShadow(matrices, this.textRenderer, SplashText.get(), 2, this.height - 20, blink(13108374) | l); + } + } + + /** + * fades an integer color based on the values declared at the top of the class. + * + * @param color the integer representation of the color to fade. this should generally remain constant. + * @return the color, adjusted for "opacity". It's RGB and not RGBA, so it just lowers all color values. + */ + @SuppressWarnings("SameParameterValue") + private int blink(int color) { + /* + The Speed. + */ + int speed = 3; + /* + The Opacity max. + */ + double opacity_max = 1000; + if (ascending) { + opacity += speed; + if (opacity > opacity_max) { + opacity = opacity_max; + ascending = false; + } + } else { + opacity -= speed; + /* + The Opacity min. + */ + double opacity_min = 500; + if (opacity < opacity_min) { + opacity = opacity_min; + ascending = true; + } + } + double opacityD = (opacity / opacity_max); + /* + The R mask. + */ + int r_mask = 16711680; + int r = ((color & r_mask) / Integer.parseInt("010000", 16)); + /* + The G mask. + */ + int g_mask = 65280; + int g = ((color & g_mask) / Integer.parseInt("000100", 16)); + /* + The B mask. + */ + int b_mask = 255; + int b = ((color & b_mask)); + return ((int) (r * opacityD) * Integer.parseInt("010000", 16)) | + ((int) (g * opacityD) * Integer.parseInt("000100", 16)) | + ((int) (b * opacityD)); + } +} diff --git a/src/main/java/pm/j4/petroleum/modules/ExampleModule.java b/src/main/java/pm/j4/petroleum/modules/ExampleModule.java new file mode 100644 index 0000000..e3ace8e --- /dev/null +++ b/src/main/java/pm/j4/petroleum/modules/ExampleModule.java @@ -0,0 +1,34 @@ +package pm.j4.petroleum.modules; + +import java.util.HashMap; +import java.util.Map; +import net.minecraft.client.MinecraftClient; +import pm.j4.petroleum.modules.base.ConfigurationOption; +import pm.j4.petroleum.modules.base.ModuleBase; +import pm.j4.petroleum.modules.base.option.BooleanValue; + +/** + * The type Example module. + */ +public class ExampleModule extends ModuleBase { + /** + * example mod + */ + public ExampleModule() { + super("petroleum.example", true, false, true); + } + + @Override + protected Map getDefaultConfig() { + Map options = new HashMap<>(); + ConfigurationOption option = new ConfigurationOption<>(new BooleanValue(false)); + options.put("petroleum.example_b_one", option); + options.put("petroleum.example_b_two", option); + return options; + } + + @Override + public void activate(MinecraftClient client) { + System.out.println("Example Mod Keybind Activate"); + } +} diff --git a/src/main/java/pm/j4/petroleum/modules/base/ConfigurationOption.java b/src/main/java/pm/j4/petroleum/modules/base/ConfigurationOption.java new file mode 100644 index 0000000..8216dfe --- /dev/null +++ b/src/main/java/pm/j4/petroleum/modules/base/ConfigurationOption.java @@ -0,0 +1,68 @@ +package pm.j4.petroleum.modules.base; + +/** + * The type Configuration option. + * + * @param the type parameter + */ +public class ConfigurationOption { + + /** + * The Value. + */ + private T value; + + /** + * Instantiates a new Configuration option. + * + * @param initialValue the initial value + */ + public ConfigurationOption(T initialValue) { + this.value = initialValue; + } + + /** + * Sets value. + * + * @param value the value + */ + public void setValue(T value) { + this.value = value; + } + + /** + * Gets value. + * + * @return the value + */ + public T getValue() { + return this.value; + } + + /** + * To string value string. + * + * @return the string + */ + public String toStringValue() { + return this.value.getStringValue(); + } + + /** + * Sets from string value. + * + * @param value the value + */ + public void setFromStringValue(String value) { + this.value.toStringValue(value); + } + + /** + * Gets value type. + * + * @return the value type + */ + public String getValueType() { + return this.value.getType(); + } +} diff --git a/src/main/java/pm/j4/petroleum/modules/base/ModuleBase.java b/src/main/java/pm/j4/petroleum/modules/base/ModuleBase.java new file mode 100644 index 0000000..8f37768 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/modules/base/ModuleBase.java @@ -0,0 +1,210 @@ +package pm.j4.petroleum.modules.base; + +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; + +/** + * 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 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, boolean activatable, boolean hidden, boolean hasConfigMenu) { + this.moduleName = name; + 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. + */ + public void activate(MinecraftClient client) { + this.toggle(); + } + + /** + * Toggle mod. + */ + public void toggle() { + Optional config = ConfigManager.getConfig(); + config.ifPresent(configHolder -> configHolder.toggleModule(this.moduleName)); + } + + /** + * The Module's name. + */ + private final String moduleName; + + /** + * Gets module name. + * + * @return the module name + */ + public String getModuleName() { + return this.moduleName; + } + + /** + * The Readable name. + */ + private final TranslatableText readableName; + + /** + * Gets readable name. + * + * @return the readable name + */ + public TranslatableText getReadableName() { + return this.readableName; + } + + /** + * The Activatable. + */ + private final boolean activatable; + + /** + * Is activatable boolean. + * + * @return the boolean + */ + public boolean isActivatable() { + return activatable; + } + + /** + * The Hidden. + */ + private final boolean hidden; + + /** + * Is hidden boolean. + * + * @return the boolean + */ + public boolean isHidden() { + return hidden; + } + + + /** + * The Has config menu. + */ + private final boolean hasConfigMenu; + + /** + * Configurable boolean. + * + * @return the boolean + */ + public boolean configurable() { + return hasConfigMenu; + } + + /** + * The Module options. + */ + private final Map moduleOptions; + + /** + * Gets module configuration. + * + * @return the module configuration + */ + public Map getModuleConfiguration() { + return moduleOptions; + } + + /** + * Sets config option. + * This will fail if the option is not already present in a module. + *

+ * + * @param key the key + * @param value the value + * @return whether the operation was successful. + */ + public boolean setConfigOption(String key, ConfigurationOption value) { + if (moduleOptions.containsKey(key)) { + moduleOptions.replace(key, value); + return true; + } + return false; + } + + /** + * Gets default config. + * + * @return the default config + */ + protected Map getDefaultConfig() { + return new HashMap<>(); + } + + /** + * Add config option. + * + * @param key the key + * @param value the value + */ + protected void addConfigOption(String key, ConfigurationOption value) { + if (!this.setConfigOption(key, value)) { + moduleOptions.put(key, value); + } + } + + /** + * Gets config option. + * + * @param key the key + * @return the config option + */ + public Optional getConfigOption(String key) { + if (moduleOptions.containsKey(key)) { + return Optional.of(moduleOptions.get(key)); + } + return Optional.empty(); + } + + /** + * Gets config entries. + * + * @return the config entries + */ + public List getConfigEntries() { + List entries = new ArrayList<>(); + this.getModuleConfiguration().forEach((name, option) -> entries.add(new PModuleConfigEntry(option, new TranslatableText(name)))); + return entries; + } + + /** + * Equals boolean. + * + * @param other the other + * @return the boolean + */ + public boolean equals(ModuleBase other) { + return Objects.equals(this.moduleName, other.getModuleName()); + } +} diff --git a/src/main/java/pm/j4/petroleum/modules/base/StringWritable.java b/src/main/java/pm/j4/petroleum/modules/base/StringWritable.java new file mode 100644 index 0000000..73ff278 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/modules/base/StringWritable.java @@ -0,0 +1,48 @@ +package pm.j4.petroleum.modules.base; + +/** + * The type String writable. + * + * @param the type parameter + */ +public class StringWritable> { + /** + * The Value. + */ + public T value; + + /** + * Gets type. + * + * @return the type + */ + public String getType() { + return ""; + } + + /** + * Gets value. + * + * @return the value + */ + public T getValue() { + return this.value; + } + + /** + * Gets string value. + * + * @return the string value + */ + public String getStringValue() { + return ""; + } + + /** + * To string value. + * + * @param value the value + */ + public void toStringValue(String value) { + } +} diff --git a/src/main/java/pm/j4/petroleum/modules/base/option/BooleanValue.java b/src/main/java/pm/j4/petroleum/modules/base/option/BooleanValue.java new file mode 100644 index 0000000..e262a6c --- /dev/null +++ b/src/main/java/pm/j4/petroleum/modules/base/option/BooleanValue.java @@ -0,0 +1,41 @@ +package pm.j4.petroleum.modules.base.option; + +import pm.j4.petroleum.modules.base.StringWritable; + +/** + * The type Boolean value. + */ +public class BooleanValue extends StringWritable { + /** + * Instantiates a new Boolean value. + * + * @param value the value + */ + public BooleanValue(String value) { + this.value = Boolean.valueOf(value); + } + + /** + * Instantiates a new Boolean value. + * + * @param value the value + */ + public BooleanValue(boolean value) { + this.value = Boolean.valueOf(value); + } + + @Override + public String getType() { + return "B"; + } + + @Override + public String getStringValue() { + return value.toString(); + } + + @Override + public void toStringValue(String value) { + this.value = Boolean.valueOf(value); + } +} diff --git a/src/main/java/pm/j4/petroleum/modules/base/option/DummyValue.java b/src/main/java/pm/j4/petroleum/modules/base/option/DummyValue.java new file mode 100644 index 0000000..fd26c81 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/modules/base/option/DummyValue.java @@ -0,0 +1,9 @@ +package pm.j4.petroleum.modules.base.option; + +import pm.j4.petroleum.modules.base.StringWritable; + +/** + * The type Dummy value. + */ +public class DummyValue extends StringWritable { +} diff --git a/src/main/java/pm/j4/petroleum/modules/base/option/IntegerValue.java b/src/main/java/pm/j4/petroleum/modules/base/option/IntegerValue.java new file mode 100644 index 0000000..450e605 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/modules/base/option/IntegerValue.java @@ -0,0 +1,46 @@ +package pm.j4.petroleum.modules.base.option; + +import pm.j4.petroleum.modules.base.StringWritable; + +/** + * The type Integer value. + */ +public class IntegerValue extends StringWritable { + /** + * The Type. + */ + public final String type = "I"; + + /** + * Instantiates a new Integer value. + * + * @param value the value + */ + public IntegerValue(String value) { + this.value = Integer.valueOf(value); + } + + /** + * Instantiates a new Integer value. + * + * @param value the value + */ + public IntegerValue(int value) { + this.value = Integer.valueOf(value); + } + + @Override + public String getType() { + return "I"; + } + + @Override + public String getStringValue() { + return value.toString(); + } + + @Override + public void toStringValue(String value) { + this.value = Integer.valueOf(value); + } +} diff --git a/src/main/java/pm/j4/petroleum/modules/base/option/KeybindValue.java b/src/main/java/pm/j4/petroleum/modules/base/option/KeybindValue.java new file mode 100644 index 0000000..b54723e --- /dev/null +++ b/src/main/java/pm/j4/petroleum/modules/base/option/KeybindValue.java @@ -0,0 +1,39 @@ +package pm.j4.petroleum.modules.base.option; + +import net.minecraft.client.options.KeyBinding; +import pm.j4.petroleum.modules.base.StringWritable; + +/** + * The type Keybind value. + */ +public class KeybindValue extends StringWritable { + /** + * Instantiates a new Keybind value. + * + * @param translationKey the translation key + * @param code the code + * @param category the category + */ + public KeybindValue(String translationKey, int code, String category) { + this.value = new KeyBinding(translationKey, code, category); + } + + /** + * Instantiates a new Keybind value. + * + * @param binding the binding + */ + public KeybindValue(KeyBinding binding) { + this.value = binding; + } + + @Override + public String getType() { + return "KB"; + } + + @Override + public String getStringValue() { + return this.value.getDefaultKey().getLocalizedText().getString(); + } +} diff --git a/src/main/java/pm/j4/petroleum/modules/base/option/OptionTypeMatcher.java b/src/main/java/pm/j4/petroleum/modules/base/option/OptionTypeMatcher.java new file mode 100644 index 0000000..d388449 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/modules/base/option/OptionTypeMatcher.java @@ -0,0 +1,29 @@ +package pm.j4.petroleum.modules.base.option; + +import pm.j4.petroleum.modules.base.StringWritable; + +/** + * The type Option type matcher. + */ +public class OptionTypeMatcher { + /** + * Match string writable. + * + * @param type the type + * @param value the value + * @return the string writable + */ + public static StringWritable match(String type, String value) { + if (type == null || type.isEmpty()) { + return new DummyValue(); + } + switch (type) { + case "I": + return new IntegerValue(value); + case "B": + return new BooleanValue(value); + default: + return new DummyValue(); + } + } +} diff --git a/src/main/java/pm/j4/petroleum/modules/base/option/StringValue.java b/src/main/java/pm/j4/petroleum/modules/base/option/StringValue.java new file mode 100644 index 0000000..17bffff --- /dev/null +++ b/src/main/java/pm/j4/petroleum/modules/base/option/StringValue.java @@ -0,0 +1,32 @@ +package pm.j4.petroleum.modules.base.option; + +import pm.j4.petroleum.modules.base.StringWritable; + +/** + * The type String value. + */ +public class StringValue extends StringWritable { + /** + * Instantiates a new String value. + * + * @param value the value + */ + public StringValue(String value) { + this.value = value; + } + + @Override + public String getType() { + return "S"; + } + + @Override + public String getStringValue() { + return this.value; + } + + @Override + public void toStringValue(String value) { + this.value = value; + } +} diff --git a/src/main/java/pm/j4/petroleum/modules/bindings/BindingInfo.java b/src/main/java/pm/j4/petroleum/modules/bindings/BindingInfo.java new file mode 100644 index 0000000..c147d8a --- /dev/null +++ b/src/main/java/pm/j4/petroleum/modules/bindings/BindingInfo.java @@ -0,0 +1,30 @@ +package pm.j4.petroleum.modules.bindings; + +import net.minecraft.client.util.InputUtil; + +/** + * The type Binding info. + */ +public class BindingInfo { + /** + * The Translation key. + */ + public String translationKey; + /** + * The Type. + */ + public InputUtil.Type type; + /** + * The Key. + */ + public int key; + /** + * The Category. + */ + public String category; + + /** + * The Attached function id. + */ + public String attachedModuleName; +} diff --git a/src/main/java/pm/j4/petroleum/modules/bindings/BindingManager.java b/src/main/java/pm/j4/petroleum/modules/bindings/BindingManager.java new file mode 100644 index 0000000..3dbc6bc --- /dev/null +++ b/src/main/java/pm/j4/petroleum/modules/bindings/BindingManager.java @@ -0,0 +1,92 @@ +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.modules.base.ConfigurationOption; +import pm.j4.petroleum.modules.base.ModuleBase; +import pm.j4.petroleum.modules.base.option.KeybindValue; +import pm.j4.petroleum.util.config.ConfigManager; +import pm.j4.petroleum.util.config.GlobalConfig; + +/** + * 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", + false, + true, + true); + } + + @Override + public void init() { + registerBindings(); + super.init(); + } + + @Override + public List getConfigEntries() { + List entries = new ArrayList<>(); + + Map, ModuleBase> mapped = new HashMap<>(); + if (ConfigManager.getConfig().isPresent()) { + Map binds = ConfigManager.getConfig().get().globalConfig.bindings; + System.out.println("Number of bindings: " + binds.size()); + binds.forEach((key, func) -> mapped.put(new ConfigurationOption<>(new KeybindValue(key)), 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.toStringValue(), x, y + fontHeight + 4, 0xFFFFFF); + } + } + }; + entries.add(entry); + }); + return entries; + } + + /** + * Register bindings. + */ + private void registerBindings() { + if (!ConfigManager.getConfig().isPresent()) { + return; + } + GlobalConfig c = ConfigManager.getConfig().get().globalConfig; + Optional mod = PetroleumMod.getMod("petroleum.modmenu"); + if (mod.isPresent() && !c.isBound(mod.get())) { + //TODO + // the only explicit keybinding (for now.) + // once the binding manager has been completed, + // this should be migrated there, as a default binding + KeyBinding binding = new KeyBinding( + "key.petroleum.togglemodmenu", + InputUtil.Type.KEYSYM, + GLFW.GLFW_KEY_RIGHT_CONTROL, + "category.petroleum" + ); + ConfigManager.getConfig().get().globalConfig.setBinding(binding, mod.get()); + } + } +} diff --git a/src/main/java/pm/j4/petroleum/modules/list/ModList.java b/src/main/java/pm/j4/petroleum/modules/list/ModList.java new file mode 100644 index 0000000..44f4573 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/modules/list/ModList.java @@ -0,0 +1,36 @@ +package pm.j4.petroleum.modules.list; + +import java.util.ArrayList; +import java.util.List; +import pm.j4.petroleum.PetroleumMod; +import pm.j4.petroleum.modules.base.ModuleBase; + +/** + * The type Mod list. + */ +public class ModList extends ModuleBase { + /** + * Instantiates a new Mod list. + */ + public ModList() { + super("petroleum.modlist", + true, + true, + true); + } + + /** + * Gets active. + * + * @return the active + */ + public static List getActive() { + List result = new ArrayList<>(); + PetroleumMod.getActiveMods().forEach((mod) -> { + if (!mod.isHidden()) { + result.add(mod); + } + }); + return result; + } +} diff --git a/src/main/java/pm/j4/petroleum/modules/menu/ModMenu.java b/src/main/java/pm/j4/petroleum/modules/menu/ModMenu.java new file mode 100644 index 0000000..fd87943 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/modules/menu/ModMenu.java @@ -0,0 +1,32 @@ +package pm.j4.petroleum.modules.menu; + +import net.minecraft.client.MinecraftClient; +import pm.j4.petroleum.gui.PModMenuScreen; +import pm.j4.petroleum.modules.base.ModuleBase; +import pm.j4.petroleum.util.config.ConfigManager; + +/** + * The type Mod menu. + */ +public class ModMenu extends ModuleBase { + + /** + * Instantiates a new Mod menu. + */ + public ModMenu() { + super("petroleum.modmenu", + true, + true, + true); + } + + @Override + public void activate(MinecraftClient client) { + this.toggle(); + if (ConfigManager.getConfig().get().isModuleEnabled(this.getModuleName())) { + client.openScreen(new PModMenuScreen()); + } else { + client.openScreen(null); + } + } +} \ No newline at end of file diff --git a/src/main/java/pm/j4/petroleum/modules/splash/SplashText.java b/src/main/java/pm/j4/petroleum/modules/splash/SplashText.java new file mode 100644 index 0000000..d998642 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/modules/splash/SplashText.java @@ -0,0 +1,31 @@ +package pm.j4.petroleum.modules.splash; + +import pm.j4.petroleum.PetroleumMod; +import pm.j4.petroleum.modules.base.ModuleBase; + +/** + * The type Splash text. + */ +public class SplashText extends ModuleBase { + /** + * Instantiates a new Splash text. + */ + public SplashText() { + super("petroleum.splashtext", + true, + true, + false); + } + + /** + * Get string. + * + * @return the string + */ + public static String get() { + if (PetroleumMod.modData != null) { + return "Petroleum v" + PetroleumMod.modData.getVersion().getFriendlyString(); + } + return "Petroleum vUnknown"; + } +} diff --git a/src/main/java/pm/j4/petroleum/util/config/Config.java b/src/main/java/pm/j4/petroleum/util/config/Config.java new file mode 100644 index 0000000..c2697d3 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/util/config/Config.java @@ -0,0 +1,59 @@ +package pm.j4.petroleum.util.config; + +import java.util.ArrayList; +import java.util.List; +import pm.j4.petroleum.PetroleumMod; +import pm.j4.petroleum.modules.base.ModuleBase; + +/** + * The type Config. + */ +public abstract class Config { + /** + * The Enabled modules. + */ + public List enabledModules = new ArrayList<>(); + + /** + * Is enabled boolean. + * + * @param mod the mod + * @return the boolean + */ + public boolean isEnabled(String mod) { + return enabledModules.contains(mod); + } + + + /** + * Disable module. + * + * @param mod the mod + */ + public void disableModule(String mod) { + if (isEnabled(mod) && PetroleumMod.isActive(mod) && PetroleumMod.getMod(mod).isPresent()) { + ModuleBase moduleInfo = PetroleumMod.getMod(mod).get(); + if (moduleInfo.isActivatable()) { + enabledModules.remove(mod); + } + } + } + + /** + * Toggle module. + * + * @param mod the mod + */ + public void toggleModule(String mod) { + if (PetroleumMod.isActive(mod) && PetroleumMod.getMod(mod).isPresent()) { + ModuleBase moduleInfo = PetroleumMod.getMod(mod).get(); + if (moduleInfo.isActivatable()) { + if (isEnabled(mod)) { + enabledModules.remove(mod); + } else { + enabledModules.add(mod); + } + } + } + } +} diff --git a/src/main/java/pm/j4/petroleum/util/config/ConfigHolder.java b/src/main/java/pm/j4/petroleum/util/config/ConfigHolder.java new file mode 100644 index 0000000..8b214f9 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/util/config/ConfigHolder.java @@ -0,0 +1,93 @@ +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.modules.base.ModuleBase; + +/** + * The type Config holder. + */ +public class ConfigHolder { + /** + * The Global config. + */ + public GlobalConfig globalConfig; + /** + * The Server configs. + */ + public Map serverConfigs; + + /** + * Is module enabled boolean. + * + * @param module the module + * @return the boolean + */ + public boolean isModuleEnabled(String module) { + + if (!PetroleumMod.isActive(module)) { + return false; + } + if (globalConfig.isEnabled(module)) { + return true; + } + String server = this.getServer(); + if (serverConfigs.containsKey(server)) { + return serverConfigs.get(server).isEnabled(module); + } + return false; + } + + /** + * Gets enabled modules. + * + * @return the enabled modules + */ + public List getEnabledModules() { + List modules = PetroleumMod.getActiveMods(); + return modules.stream().filter(module -> + isModuleEnabled(module.getModuleName()) + ).collect(Collectors.toList()); + } + + /** + * Gets server. + * + * @return the server + */ + public String getServer() { + return PetroleumMod.getServerAddress(); + } + + /** + * Toggle module. + * + * @param module the module + */ + public void toggleModule(String module) { + String server = this.getServer(); + if (serverConfigs.containsKey(server)) { + System.out.println("Toggling module " + module + " on server " + server); + serverConfigs.get(server).toggleModule(module); + } else { + globalConfig.toggleModule(module); + } + } + + /** + * Disable module. + * + * @param module the module + */ + public void disableModule(String module) { + String server = this.getServer(); + if (serverConfigs.containsKey(server)) { + System.out.println("disabling module " + module + " on server " + server); + serverConfigs.get(server).disableModule(module); + } else { + globalConfig.disableModule(module); + } + } +} diff --git a/src/main/java/pm/j4/petroleum/util/config/ConfigManager.java b/src/main/java/pm/j4/petroleum/util/config/ConfigManager.java new file mode 100644 index 0000000..99dc427 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/util/config/ConfigManager.java @@ -0,0 +1,191 @@ +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; + +/** + * The type Config manager. + */ +public class ConfigManager { + /** + * The constant GSON. + */ + public static final Gson GSON = new GsonBuilder() + .registerTypeAdapter(GlobalConfig.class, SerializationHelper.getSerializer()) + .registerTypeAdapter(GlobalConfig.class, SerializationHelper.getDeserializer()) + .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).setPrettyPrinting().create(); + /** + * The constant file. + */ + private static File file; + /** + * The constant config. + */ + private static ConfigHolder config; + + /** + * Prepare config file. + */ + private static void prepareConfigFile() { + if (file != null) { + return; + } + file = new File(FabricLoader.getInstance().getConfigDir().toString(), "petroleum.json"); + } + + /** + * Init config. + */ + public static void initConfig() { + if (config != null) { + return; + } + + config = new ConfigHolder(); + config.globalConfig = new DefaultConfig(); + config.serverConfigs = new HashMap<>(); + + load(); + } + + /** + * Load. + */ + private static void load() { + prepareConfigFile(); + + try { + if (!file.exists()) { + save(); + } + if (file.exists()) { + BufferedReader reader = new BufferedReader(new FileReader(file)); + ConfigHolder parsedConfig = null; + try { + parsedConfig = GSON.fromJson(reader, ConfigHolder.class); + } catch (Exception e) { + System.out.println("Couldn't parse config file"); + e.printStackTrace(); + } + if (parsedConfig != null) { + config = parsedConfig; + } + } + } catch (FileNotFoundException e) { + System.out.println("Couldn't load Petroleum configuration"); + e.printStackTrace(); + } + } + + /** + * Save. + */ + public static void save() { + prepareConfigFile(); + + String json = GSON.toJson(config); + + try (FileWriter fileWriter = new FileWriter(file)) { + fileWriter.write(json); + } catch (IOException e) { + System.out.println("Couldn't save Petroleum configuration"); + e.printStackTrace(); + } + } + + /** + * Gets config. + * + * @return the config + */ + public static Optional getConfig() { + if (config == null) { + return Optional.empty(); + } + return Optional.of(config); + } +} + +/** + * The type Serialization helper. + */ +class SerializationHelper { + + /** + * The constant s. + */ + private static final JsonSerializer s = (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 moduleConfigs = new JsonObject(); + PetroleumMod.getActiveMods().forEach(module -> { + moduleConfigs.add(module.getModuleName(), ctx.serialize(src.serializeModuleConfiguration(module))); + }); + jsonConfig.add("module_configuration", moduleConfigs); + + return jsonConfig; + }; + + /** + * The constant ds. + */ + private static final JsonDeserializer ds = ((json, typeOfT, ctx) -> { + JsonObject obj = json.getAsJsonObject(); + + List bindings = new ArrayList<>(); + if (obj.has("bindings")) { + obj.get("bindings").getAsJsonArray().forEach(b -> bindings.add(ctx.deserialize(b, BindingInfo.class))); + } + List modules = new ArrayList<>(); + if (obj.has("enabled_modules")) { + obj.get("enabled_modules").getAsJsonArray().forEach(m -> modules.add(m.getAsString())); + } + GlobalConfig cfg = new GlobalConfig(); + Map> options; + Type type = new TypeToken>>() { + }.getType(); + if (obj.has("module_configuration")) { + options = ctx.deserialize(obj.get("module_configuration"), type); + } else { + options = new HashMap<>(); + } + 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 getSerializer() { + return s; + } + + /** + * Gets deserializer. + * + * @return the deserializer + */ + public static JsonDeserializer getDeserializer() { + return ds; + } +} \ No newline at end of file diff --git a/src/main/java/pm/j4/petroleum/util/config/DefaultConfig.java b/src/main/java/pm/j4/petroleum/util/config/DefaultConfig.java new file mode 100644 index 0000000..f50bea2 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/util/config/DefaultConfig.java @@ -0,0 +1,15 @@ +package pm.j4.petroleum.util.config; + +import java.util.Collections; + +/** + * The type Default config. + */ +public class DefaultConfig extends GlobalConfig { + /** + * Instantiates a new Default config. + */ + public DefaultConfig() { + this.enabledModules = Collections.singletonList("petroleum.splashtext"); + } +} diff --git a/src/main/java/pm/j4/petroleum/util/config/GlobalConfig.java b/src/main/java/pm/j4/petroleum/util/config/GlobalConfig.java new file mode 100644 index 0000000..0d38215 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/util/config/GlobalConfig.java @@ -0,0 +1,143 @@ +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.base.ConfigurationOption; +import pm.j4.petroleum.modules.base.ModuleBase; +import pm.j4.petroleum.modules.base.option.OptionTypeMatcher; +import pm.j4.petroleum.modules.bindings.BindingInfo; + +/** + * The type Global config. + */ +public class GlobalConfig extends Config { + /** + * The Bindings. + */ + public final Map bindings = new HashMap<>(); + + /** + * Is bound boolean. + * + * @param func the func + * @return the boolean + */ + public boolean isBound(ModuleBase func) { + AtomicBoolean found = new AtomicBoolean(false); + bindings.forEach((key, binding) -> { + if (binding.equals(func)) { + found.set(true); + } + }); + return found.get(); + } + + /** + * Sets binding. + * + * @param bind the bind + * @param func the func + */ + public void setBinding(KeyBinding bind, ModuleBase func) { + if (bindings.containsValue(func)) { + bindings.forEach((key, binding) -> { + if (binding.equals(func)) { + PetroleumMod.removeBind(key); + bindings.remove(key); + } + }); + } + + if (PetroleumMod.isActive(func.getModuleName())) { + PetroleumMod.addBind(bind); + bindings.put(bind, func); + } + } + + /** + * Convert binding. + * + * @param info the info + */ + private void convertBinding(BindingInfo info) { + Optional match = PetroleumMod.getMod(info.attachedModuleName); + match.ifPresent(moduleBase -> setBinding(new KeyBinding( + info.translationKey, + info.type, + info.key, + info.category + ), + moduleBase)); + } + + /** + * Extract binding binding info. + * + * @param b the b + * @param f the f + * @return the binding info + */ + private BindingInfo extractBinding(KeyBinding b, ModuleBase f) { + BindingInfo res = new BindingInfo(); + res.attachedModuleName = f.getModuleName(); + + res.translationKey = b.getTranslationKey(); + InputUtil.Key k = b.getDefaultKey(); + res.type = k.getCategory(); + res.key = k.getCode(); + res.category = b.getCategory(); + + return res; + } + + /** + * Serialize bindings list. + * + * @return the list + */ + public List serializeBindings() { + List b = new ArrayList<>(); + bindings.forEach((k, f) -> b.add(extractBinding(k, f))); + return b; + } + + /** + * Deserialize bindings. + * + * @param info the info + */ + public void deserializeBindings(List info) { + info.forEach(this::convertBinding); + } + + /** + * Serialize module configuration list. + * + * @param module the module + * @return the list + */ + public List serializeModuleConfiguration(ModuleBase module) { + List opts = new ArrayList<>(); + Map configuration = module.getModuleConfiguration(); + configuration.forEach((key, value) -> { + opts.add(new OptionSerializiable(value.getValueType(), value.toStringValue(), key)); + }); + return opts; + } + + /** + * Deserialize module configuration. + * + * @param opts the opts + * @param module the module + */ + public void deserializeModuleConfiguration(List opts, ModuleBase module) { + opts.forEach(option -> { + module.setConfigOption(option.key, new ConfigurationOption<>(OptionTypeMatcher.match(option.type, option.value))); + }); + } +} + diff --git a/src/main/java/pm/j4/petroleum/util/config/OptionSerializiable.java b/src/main/java/pm/j4/petroleum/util/config/OptionSerializiable.java new file mode 100644 index 0000000..0ef5c37 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/util/config/OptionSerializiable.java @@ -0,0 +1,32 @@ +package pm.j4.petroleum.util.config; + +/** + * The type Option serializiable. + */ +public class OptionSerializiable { + /** + * Instantiates a new Option serializiable. + * + * @param type the type + * @param value the value + * @param key the key + */ + public OptionSerializiable(String type, String value, String key) { + this.type = type; + this.value = value; + this.key = key; + } + + /** + * The Type. + */ + public final String type; + /** + * The Value. + */ + public final String value; + /** + * The Key. + */ + public final String key; +} diff --git a/src/main/java/pm/j4/petroleum/util/config/ServerConfig.java b/src/main/java/pm/j4/petroleum/util/config/ServerConfig.java new file mode 100644 index 0000000..9df6464 --- /dev/null +++ b/src/main/java/pm/j4/petroleum/util/config/ServerConfig.java @@ -0,0 +1,11 @@ +package pm.j4.petroleum.util.config; + +/** + * The type Server config. + */ +public class ServerConfig extends Config { + /** + * The Address. + */ + public String address = ""; +} diff --git a/src/main/resources/assets/petroleum/icon.png b/src/main/resources/assets/petroleum/icon.png new file mode 100644 index 0000000..5980ba8 Binary files /dev/null and b/src/main/resources/assets/petroleum/icon.png differ diff --git a/src/main/resources/assets/petroleum/textures/options_background.png b/src/main/resources/assets/petroleum/textures/options_background.png new file mode 100644 index 0000000..d2f690b Binary files /dev/null and b/src/main/resources/assets/petroleum/textures/options_background.png differ diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..c3793af --- /dev/null +++ b/src/main/resources/fabric.mod.json @@ -0,0 +1,37 @@ +{ + "schemaVersion": 1, + "id": "petroleum", + "version": "${version}", + + "name": "Petroleum", + "description": "Burn it down.", + "authors": [ + "janeptrv" + ], + "contact": { + "homepage": "https://j4.pm/", + "sources": "https://github.com/FabricMC/fabric-example-mod" + }, + + "license": "WTFPL", + "icon": "assets/petroleum/icon.png", + + "environment": "*", + "entrypoints": { + "main": [ + "pm.j4.petroleum.PetroleumMod" + ] + }, + "mixins": [ + "petroleum.mixins.json" + ], + + "depends": { + "fabricloader": ">=0.7.4", + "fabric": "*", + "minecraft": "1.16.x" + }, + "suggests": { + "flamingo": "*" + } +} diff --git a/src/main/resources/petroleum.mixins.json b/src/main/resources/petroleum.mixins.json new file mode 100644 index 0000000..2c458f3 --- /dev/null +++ b/src/main/resources/petroleum.mixins.json @@ -0,0 +1,18 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "pm.j4.petroleum.mixin", + "compatibilityLevel": "JAVA_8", + "mixins": [ + ], + "client": [ + "TitleScreenMixin", + "OptionsMenuMixin", + "EntryListWidgetAccessor", + "DebugHudMixin", + "ModListMixin" + ], + "injectors": { + "defaultRequire": 1 + } +}