From d7769b036760a03ce092c5123c98abf989cc3123 Mon Sep 17 00:00:00 2001 From: RSwoop <47505753+RSwoop@users.noreply.github.com> Date: Mon, 5 Aug 2024 17:07:00 +0200 Subject: [PATCH] Add 1.20.6 (forge) --- .github/workflows/gradle-forge-1.20.6.yml | 23 ++ forge/fg-6.0/1.20.6/build.gradle | 233 ++++++++++++ forge/fg-6.0/1.20.6/gradle.properties | 31 ++ .../minegasm/client/ClientEventHandler.java | 280 +++++++++++++++ .../minegasm/client/ToyController.java | 134 +++++++ .../common/AbstractVibrationState.java | 119 +++++++ .../minegasm/common/Minegasm.java | 28 ++ .../common/VibrationStateAdvancement.java | 41 +++ .../minegasm/common/VibrationStateAttack.java | 32 ++ .../minegasm/common/VibrationStateClient.java | 20 ++ .../minegasm/common/VibrationStateFish.java | 30 ++ .../common/VibrationStateHarvest.java | 24 ++ .../minegasm/common/VibrationStateHurt.java | 32 ++ .../minegasm/common/VibrationStateMine.java | 48 +++ .../minegasm/common/VibrationStatePlace.java | 31 ++ .../common/VibrationStateVitality.java | 57 +++ .../common/VibrationStateXpChange.java | 49 +++ .../minegasm/config/ClientConfig.java | 179 ++++++++++ .../minegasm/config/ConfigHelper.java | 72 ++++ .../minegasm/config/ConfigHolder.java | 34 ++ .../minegasm/config/ConfigScreen.java | 337 ++++++++++++++++++ .../minegasm/config/MinegasmConfig.java | 93 +++++ .../minegasm/config/PauseMenuButton.java | 120 +++++++ .../minegasm/config/ServerConfig.java | 11 + .../mixin/ClientAdvancementsMixin.java | 42 +++ .../minegasm/mixin/LocalPlayerMixin.java | 53 +++ .../mixin/MultiPlayerGameModeMixin.java | 63 ++++ .../src/main/resources/META-INF/mods.toml | 74 ++++ .../assets/minegasm/textures/logo.png | Bin 0 -> 2752 bytes .../1.20.6/src/main/resources/minegasm.png | Bin 0 -> 123484 bytes .../src/main/resources/mixins.minegasm.json | 11 + .../1.20.6/src/main/resources/pack.mcmeta | 8 + 32 files changed, 2309 insertions(+) create mode 100644 .github/workflows/gradle-forge-1.20.6.yml create mode 100644 forge/fg-6.0/1.20.6/build.gradle create mode 100644 forge/fg-6.0/1.20.6/gradle.properties create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/client/ClientEventHandler.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/client/ToyController.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/AbstractVibrationState.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/Minegasm.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateAdvancement.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateAttack.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateClient.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateFish.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateHarvest.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateHurt.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateMine.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStatePlace.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateVitality.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateXpChange.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ClientConfig.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ConfigHelper.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ConfigHolder.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ConfigScreen.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/MinegasmConfig.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/PauseMenuButton.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ServerConfig.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/mixin/ClientAdvancementsMixin.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/mixin/LocalPlayerMixin.java create mode 100644 forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/mixin/MultiPlayerGameModeMixin.java create mode 100644 forge/fg-6.0/1.20.6/src/main/resources/META-INF/mods.toml create mode 100644 forge/fg-6.0/1.20.6/src/main/resources/assets/minegasm/textures/logo.png create mode 100644 forge/fg-6.0/1.20.6/src/main/resources/minegasm.png create mode 100644 forge/fg-6.0/1.20.6/src/main/resources/mixins.minegasm.json create mode 100644 forge/fg-6.0/1.20.6/src/main/resources/pack.mcmeta diff --git a/.github/workflows/gradle-forge-1.20.6.yml b/.github/workflows/gradle-forge-1.20.6.yml new file mode 100644 index 0000000..2517af6 --- /dev/null +++ b/.github/workflows/gradle-forge-1.20.6.yml @@ -0,0 +1,23 @@ +name: Build 1.20.6 + +on: + workflow_dispatch: + push: + branches: [ main ] + paths: + - 'forge/fg-6.0/1.20.6/**' + - '.github/workflows/fg-6.0.yml' + - '.github/workflows/gradle-forge-1.20.6.yml' + pull_request: + branches: [ main ] + paths: + - 'forge/fg-6.0/1.20.6/**' + - '.github/workflows/fg-6.0.yml' + - '.github/workflows/gradle-forge-1.20.6.yml' + +jobs: + build: + uses: ./.github/workflows/fg-6.0.yml + with: + version: 1.20.6 + java-version: 21 \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/build.gradle b/forge/fg-6.0/1.20.6/build.gradle new file mode 100644 index 0000000..a9e7fd3 --- /dev/null +++ b/forge/fg-6.0/1.20.6/build.gradle @@ -0,0 +1,233 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + +plugins { + id 'eclipse' + id 'idea' + id 'maven-publish' + id 'net.minecraftforge.gradle' version '[6.0.24,6.2)' + id 'com.github.johnrengelman.shadow' version '8.1.1' + id 'org.spongepowered.mixin' version '0.7.+' +} + +version = mod_version +group = mod_group_id + +base { + archivesName = mod_id +} + +// Mojang ships Java 21 to end users in 1.20.5+, so your mod should target Java 21. +java.toolchain.languageVersion = JavaLanguageVersion.of(21) + +println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}" +minecraft { + // The mappings can be changed at any time and must be in the following format. + // Channel: Version: + // official MCVersion Official field/method names from Mojang mapping files + // parchment YYYY.MM.DD-MCVersion Open community-sourced parameter names and javadocs layered on top of official + // + // You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. + // See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md + // + // Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge + // Additional setup is needed to use their mappings: https://parchmentmc.org/docs/getting-started + // + // Use non-default mappings at your own risk. They may not always work. + // Simply re-run your setup task after changing the mappings to update your workspace. + mappings channel: mapping_channel, version: mapping_version + + // Tell FG to not automatically create the reobf tasks, as we now use Official mappings at runtime, If you don't use them at dev time then you'll have to fix your reobf yourself. + reobf = false + + // When true, this property will have all Eclipse/IntelliJ IDEA run configurations run the "prepareX" task for the given run configuration before launching the game. + // In most cases, it is not necessary to enable. + // enableEclipsePrepareRuns = true + // enableIdeaPrepareRuns = true + + // This property allows configuring Gradle's ProcessResources task(s) to run on IDE output locations before launching the game. + // It is REQUIRED to be set to true for this template to function. + // See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html + copyIdeResources = true + + // When true, this property will add the folder name of all declared run configurations to generated IDE run configurations. + // The folder name can be set on a run configuration using the "folderName" property. + // By default, the folder name of a run configuration is the name of the Gradle project containing it. + // generateRunFolders = true + + // This property enables access transformers for use in development. + // They will be applied to the Minecraft artifact. + // The access transformer file can be anywhere in the project. + // However, it must be at "META-INF/accesstransformer.cfg" in the final mod jar to be loaded by Forge. + // This default location is a best practice to automatically put the file in the right place in the final jar. + // See https://docs.minecraftforge.net/en/latest/advanced/accesstransformers/ for more information. + // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') + + // Default run configurations. + // These can be tweaked, removed, or duplicated as needed. + runs { + // applies to all the run configs below + configureEach { + workingDirectory project.file('run') + + // Recommended logging data for a userdev environment + // The markers can be added/remove as needed separated by commas. + // "SCAN": For mods scan. + // "REGISTRIES": For firing of registry events. + // "REGISTRYDUMP": For getting the contents of all registries. + property 'forge.logging.markers', 'REGISTRIES' + + // Recommended logging level for the console + // You can set various levels here. + // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels + property 'forge.logging.console.level', 'debug' + + mods { + "${mod_id}" { + source sourceSets.main + } + } + } + + client { + // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. + property 'forge.enabledGameTestNamespaces', mod_id + } + + server { + property 'forge.enabledGameTestNamespaces', mod_id + args '--nogui' + } + + // This run config launches GameTestServer and runs all registered gametests, then exits. + // By default, the server will crash when no gametests are provided. + // The gametest system is also enabled by default for other run configs under the /test command. + gameTestServer { + property 'forge.enabledGameTestNamespaces', mod_id + } + + data { + // example of overriding the workingDirectory set in configureEach above + workingDirectory project.file('run-data') + + // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. + args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') + } + } +} + +// Include resources generated by data generators. +sourceSets.main.resources { srcDir 'src/generated/resources' } + +repositories { + // Put repositories for dependencies here + // ForgeGradle automatically adds the Forge maven and Maven Central for you + + // If you have mod jar dependencies in ./libs, you can declare them as a repository like so. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html#sub:flat_dir_resolver + // flatDir { + // dir 'libs' + // } +} + +configurations { + shade + implementation.extendsFrom shade +} + +dependencies { + // Specify the version of Minecraft to use. + // Any artifact can be supplied so long as it has a "userdev" classifier artifact and is a compatible patcher artifact. + // The "userdev" classifier will be requested and setup by ForgeGradle. + // If the group id is "net.minecraft" and the artifact id is one of ["client", "server", "joined"], + // then special handling is done to allow a setup of a vanilla dependency without the use of an external repository. + minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" + annotationProcessor 'org.spongepowered:mixin:0.8.5:processor' + shade 'io.github.blackspherefollower:buttplug4j.connectors.jetty.websocket.client:3.1.105' + + // Example mod dependency with JEI - using fg.deobf() ensures the dependency is remapped to your development mappings + // The JEI API is declared for compile time use, while the full JEI artifact is used at runtime + // compileOnly fg.deobf("mezz.jei:jei-${mc_version}-common-api:${jei_version}") + // compileOnly fg.deobf("mezz.jei:jei-${mc_version}-forge-api:${jei_version}") + // runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}-forge:${jei_version}") + + // Example mod dependency using a mod jar from ./libs with a flat dir repository + // This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar + // The group id is ignored when searching -- in this case, it is "blank" + // implementation fg.deobf("blank:coolmod-${mc_version}:${coolmod_version}") + + // For more info: + // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html + // http://www.gradle.org/docs/current/userguide/dependency_management.html + + // Hack fix for now, force jopt-simple to be exactly 5.0.4 because Mojang ships that version, but some transitive dependencies request 6.0+ + implementation('net.sf.jopt-simple:jopt-simple:5.0.4') { version { strictly '5.0.4' } } +} + +// This block of code expands all declared replace properties in the specified resource targets. +// A missing property will result in an error. Properties are expanded using ${} Groovy notation. +// When "copyIdeResources" is enabled, this will also run before the game launches in IDE environments. +// See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html +tasks.named('processResources', ProcessResources).configure { + var replaceProperties = [ + minecraft_version : minecraft_version, minecraft_version_range: minecraft_version_range, + forge_version : forge_version, forge_version_range: forge_version_range, + loader_version_range : loader_version_range, + mod_id : mod_id, mod_name: mod_name, mod_license: mod_license, mod_version: mod_version, + mod_authors : mod_authors, mod_description: mod_description, + mod_issue_tracker_url: mod_issue_tracker_url, mod_update_json_url: mod_update_json_url, + mod_display_url : mod_display_url, mod_logo_file: mod_logo_file + ] + inputs.properties replaceProperties + + filesMatching(['META-INF/mods.toml', 'pack.mcmeta']) { + expand replaceProperties + [project: project] + } +} + +mixin { + // MixinGradle Settings + add sourceSets.main, "mixins.${mod_id}.refmap.json" + config "mixins.${mod_id}.json" +} + +// Example for how to get properties into the manifest for reading at runtime. +tasks.named('jar', Jar).configure { + archiveClassifier = 'slim' + manifest { + attributes([ + 'Specification-Title' : mod_id, + 'Specification-Vendor' : mod_authors, + 'Specification-Version' : '1', // We are version 1 of ourselves + 'Implementation-Title' : project.name, + 'Implementation-Version' : project.jar.archiveVersion, + 'Implementation-Vendor' : mod_authors, + 'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + ]) + } +} + +tasks.named('shadowJar', ShadowJar) { + enableRelocation true + relocationPrefix "com.therainbowville.repack" + archiveClassifier = "${minecraft_version}-Forge-${forge_version}" + configurations = [project.configurations.shade] + mergeServiceFiles() +} + +assemble.dependsOn shadowJar + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation +} + +tasks.register("prepareKotlinBuildScriptModel") {} + +// Merge the resources and classes into the same directory. +// This is done because java expects modules to be in a single directory. +// And if we have it in multiple we have to do performance intensive hacks like having the UnionFileSystem +// This will eventually be migrated to ForgeGradle so modders don't need to manually do it. But that is later. +sourceSets.each { + def dir = layout.buildDirectory.dir("sourcesSets/$it.name") + it.output.resourcesDir = dir + it.java.destinationDirectory = dir +} diff --git a/forge/fg-6.0/1.20.6/gradle.properties b/forge/fg-6.0/1.20.6/gradle.properties new file mode 100644 index 0000000..98d1c1d --- /dev/null +++ b/forge/fg-6.0/1.20.6/gradle.properties @@ -0,0 +1,31 @@ +## Environment Properties +# The Minecraft version must agree with the Forge version to get a valid artifact +minecraft_version=1.20.6 +# The Minecraft version range can use any release version of Minecraft as bounds. +# Snapshots, pre-releases, and release candidates are not guaranteed to sort properly +# as they do not follow standard versioning conventions. +minecraft_version_range=[1.20.6,1.21) +# The Forge version must agree with the Minecraft version to get a valid artifact +forge_version=50.1.0 +# The Forge version range can use any version of Forge as bounds or match the loader version range +forge_version_range=[0,) +# The loader version range can only use the major version of Forge/FML as bounds +loader_version_range=[0,) +# The mapping channel to use for mappings. +# The default set of supported mapping channels are ["official", "snapshot", "snapshot_nodoc", "stable", "stable_nodoc"]. +# Additional mapping channels can be registered through the "channelProviders" extension in a Gradle plugin. +# +# | Channel | Version | | +# |-----------|----------------------|--------------------------------------------------------------------------------| +# | official | MCVersion | Official field/method names from Mojang mapping files | +# | parchment | YYYY.MM.DD-MCVersion | Open community-sourced parameter names and javadocs layered on top of official | +# +# You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. +# See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md +# +# Parchment is an unofficial project maintained by ParchmentMC, separate from Minecraft Forge. +# Additional setup is needed to use their mappings, see https://parchmentmc.org/docs/getting-started +mapping_channel=official +# The mapping version to query from the mapping channel. +# This must match the format required by the mapping channel. +mapping_version=1.20.6 \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/client/ClientEventHandler.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/client/ClientEventHandler.java new file mode 100644 index 0000000..2bcd28b --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/client/ClientEventHandler.java @@ -0,0 +1,280 @@ +package com.therainbowville.minegasm.client; + +import com.therainbowville.minegasm.common.*; +import com.therainbowville.minegasm.config.MinegasmConfig; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraftforge.event.TickEvent; +import net.minecraftforge.event.entity.EntityJoinLevelEvent; +import net.minecraftforge.event.entity.living.LivingHurtEvent; +import net.minecraftforge.event.entity.player.*; +import net.minecraftforge.event.level.BlockEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import org.apache.logging.log4j.LogManager; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +@Mod.EventBusSubscriber(modid = Minegasm.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE) +public class ClientEventHandler { + private static final org.apache.logging.log4j.Logger LOGGER = LogManager.getLogger(); + + private static int tickCounter = -1; + private static int clientTickCounter = -1; + private static boolean paused = false; + private static UUID playerId = null; + + private static Map vibrationStates = new HashMap(); + + static { + vibrationStates.put("advancement", new VibrationStateAdvancement()); + vibrationStates.put("attack", new VibrationStateAttack()); + vibrationStates.put("fish", new VibrationStateFish()); + vibrationStates.put("hurt", new VibrationStateHurt()); + vibrationStates.put("mine", new VibrationStateMine()); + vibrationStates.put("place", new VibrationStatePlace()); + vibrationStates.put("harvest", new VibrationStateHarvest((VibrationStateMine) vibrationStates.get("mine"))); + vibrationStates.put("vitality", new VibrationStateVitality()); + vibrationStates.put("xpChange", new VibrationStateXpChange()); + vibrationStates.put("generic", new VibrationStateClient()); + } + + public static void afterConnect() { + //setState(getStateCounter(), 5); + ((VibrationStateClient) vibrationStates.get("generic")).setVibration(5, 1); + } + + private static double getIntensity() { + double intensity = 0; + for (Map.Entry state : vibrationStates.entrySet()) { + intensity = Math.max(intensity, state.getValue().getIntensity()); +// LOGGER.info(state.getKey() + ": " + state.getValue().getIntensity()); + + } + return intensity / 100; + } + + private static void tickAll() { + for (AbstractVibrationState state : vibrationStates.values()) { + state.onTick(); + } + } + + private static void resetAll() { + for (AbstractVibrationState state : vibrationStates.values()) { + state.resetState(); + } + } + + private static boolean isPlayer(Entity entity) { + try { + if (entity instanceof Player) { + Player player = (Player) entity; + ; + UUID uuid = player.getGameProfile().getId(); + return uuid.equals(playerId); + } + } catch (Throwable e) { + LOGGER.throwing(e); + } + return false; + } + + private static void clearState() { + tickCounter = -1; + clientTickCounter = -1; + paused = false; + resetAll(); + } + + @SubscribeEvent + public static void onPlayerTick(TickEvent.PlayerTickEvent event) { + try { + if (event.phase == TickEvent.Phase.END && isPlayer(event.player)) { + Player player = event.player; + + tickCounter = (tickCounter + 1) % 100; + + + if (tickCounter % MinegasmConfig.tickFrequency == 0) // TODO: Add ticks per second config option (Default: Every tick) + { + tickAll(); + + ((VibrationStateVitality) vibrationStates.get("vitality")).onTick(player); + ((VibrationStateFish) vibrationStates.get("fish")).onTick(player); + + double newVibrationLevel = getIntensity(); + + if (ToyController.currentVibrationLevel != newVibrationLevel) + ToyController.setVibrationLevel(newVibrationLevel); + } + + } + } catch (Throwable e) { + LOGGER.throwing(e); + } + } + + @SubscribeEvent + public static void onClientTick(TickEvent.ClientTickEvent event) { + if (event.phase == TickEvent.Phase.END) { + if (tickCounter >= 0) { + if (tickCounter != clientTickCounter) { + clientTickCounter = tickCounter; + paused = false; + } else { + if (!paused) { + paused = true; + LOGGER.debug("Pausing"); + ToyController.setVibrationLevel(0); + } + + if (paused) { + LOGGER.trace("Paused"); + } + } + } + } + } + + @SubscribeEvent + public static void onAttack(AttackEntityEvent event) { + if (isPlayer(event.getEntity())) { + ((VibrationStateAttack) vibrationStates.get("attack")).onAttack(); + } + } + + @SubscribeEvent + public static void onCriticalHit(CriticalHitEvent event) { + LOGGER.debug("Critical: " + event.isVanillaCritical()); + } + + @SubscribeEvent + public static void onHurt(LivingHurtEvent event) { + if (isPlayer(event.getEntity())) { + ((VibrationStateHurt) vibrationStates.get("hurt")).onHurt(); + } + } + + @SubscribeEvent + public static void onBreak(BlockEvent.BreakEvent event) { + if (isPlayer(event.getPlayer())) { + ((VibrationStateMine) vibrationStates.get("mine")).onBreak(event.getState()); + } + } + + // Triggers when player starts to break block + @SubscribeEvent + public static void onHarvest(PlayerEvent.HarvestCheck event) { + if (isPlayer(event.getEntity())) { + ((VibrationStateHarvest) vibrationStates.get("harvest")).onHarvest(); + } + } + + @SubscribeEvent + public static void onPlace(BlockEvent.EntityPlaceEvent event) { + if (isPlayer(event.getEntity())) { + ((VibrationStatePlace) vibrationStates.get("place")).onPlace(); + } + } + + public static void onPlace() { + ((VibrationStatePlace) vibrationStates.get("place")).onPlace(); + } + + + @SubscribeEvent + public static void onItemPickup(EntityItemPickupEvent event) { + LOGGER.info("Pickup item: " + event.getItem().toString()); + } + + @SubscribeEvent + public static void onXpPickup(PlayerXpEvent.PickupXp event) { + //LOGGER.info("Pickup XP: " + event.getOrb().xpValue); + } + + @SubscribeEvent + public static void onXpChange(PlayerXpEvent.XpChange event) { + if (isPlayer(event.getEntity())) { + ((VibrationStateXpChange) vibrationStates.get("xpChange")).onXpChange(((Player) event.getEntity()).totalExperience, event.getAmount()); + } + } + + + @SubscribeEvent + public static void onAdvancementEvent(AdvancementEvent.AdvancementEarnEvent event) { + if (isPlayer(event.getEntity())) { + ((VibrationStateAdvancement) vibrationStates.get("advancement")).onAdvancement(event); + } + } + + @SubscribeEvent + public static void onRespawn(PlayerEvent.PlayerRespawnEvent event) { + Entity entity = event.getEntity(); + if (!entity.level().isClientSide()) { + return; + } + + if (entity instanceof Player) { + LOGGER.info("Client Entered world: " + entity.toString()); + + try { + Player player = (Player) entity; + UUID uuid = player.getGameProfile().getId(); + + if (uuid.equals(Minecraft.getInstance().player.getGameProfile().getId())) { + LOGGER.info("Player in: " + player.getGameProfile().getName() + " " + player.getGameProfile().getId().toString()); + clearState(); + ToyController.setVibrationLevel(0); + playerId = uuid; + } + } catch (Throwable e) { + LOGGER.throwing(e); + } + } + + } + + @SubscribeEvent + public static void onWorldEntry(EntityJoinLevelEvent event) { + Entity entity = event.getEntity(); + if (!entity.level().isClientSide()) { + return; + } + + if (ToyController.isConnected) return; + + if (entity instanceof Player) { + LOGGER.info("Player respawn world: " + entity.toString()); + + new Thread(() -> { + try { + Player player = (Player) entity; + UUID uuid = player.getGameProfile().getId(); + + if (uuid.equals(Minecraft.getInstance().player.getGameProfile().getId())) { + LOGGER.info("Player in: " + player.getGameProfile().getName() + " " + player.getGameProfile().getId().toString()); + LOGGER.info("Stealth: " + MinegasmConfig.stealth); + if (ToyController.connectDevice()) { + ((VibrationStateClient) vibrationStates.get("generic")).setVibration(5, 1); + if (!MinegasmConfig.stealth) { + player.displayClientMessage(Component.literal(String.format("Connected to " + ChatFormatting.GREEN + "%s" + ChatFormatting.RESET + " [%d]", ToyController.getDeviceName(), ToyController.getDeviceId())), true); + } + } else if (!MinegasmConfig.stealth) { + player.displayClientMessage(Component.literal(String.format(ChatFormatting.YELLOW + "Minegasm " + ChatFormatting.RESET + "failed to start\n%s", ToyController.getLastErrorMessage())), false); + } + playerId = uuid; + } + } catch (Throwable e) { + LOGGER.throwing(e); + } + }).start(); + } + } +} + diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/client/ToyController.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/client/ToyController.java new file mode 100644 index 0000000..7999ae4 --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/client/ToyController.java @@ -0,0 +1,134 @@ +package com.therainbowville.minegasm.client; + +import com.therainbowville.minegasm.config.MinegasmConfig; +import io.github.blackspherefollower.buttplug4j.client.ButtplugClientDevice; +import io.github.blackspherefollower.buttplug4j.connectors.jetty.websocket.client.ButtplugClientWSClient; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.net.URI; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.*; + +public class ToyController { + private static final Logger LOGGER = LogManager.getLogger(); + public static String lastErrorMessage = ""; + public static boolean isConnected = false; + public static double currentVibrationLevel = 0; + private static ButtplugClientWSClient client = new ButtplugClientWSClient("Minegasm"); + private static ButtplugClientDevice device = null; + private static boolean shutDownHookAdded = false; + + public static boolean connectDevice() { + try { + device = null; + client.disconnect(); + + LOGGER.info("URL: " + MinegasmConfig.serverUrl); + + ExecutorService executor = Executors.newSingleThreadExecutor(); + Future future = executor.submit(new Callable() { + public Void call() throws Exception { + client.connect(new URI(MinegasmConfig.serverUrl)); + return null; + } + }); + + try { + future.get(3, TimeUnit.SECONDS); + } catch (TimeoutException e) { + future.cancel(true); + client = new ButtplugClientWSClient("Minegasm"); + throw new TimeoutException("Could not find WebSocket"); + } finally { + executor.shutdownNow(); + } + + client.startScanning(); + + Thread.sleep(5000); + client.requestDeviceList(); + + LOGGER.info("Enumerating devices..."); + + List devices = client.getDevices(); + + int nDevices = devices.size(); + LOGGER.info(nDevices); + + if (nDevices < 1) { + lastErrorMessage = "No device found"; + } + + for (ButtplugClientDevice dev : devices) { + if (dev.getScalarVibrateCount() != 0) { + LOGGER.info(dev.getDisplayName()); + device = dev; + try { + device.sendScalarVibrateCmd(0); + } catch (Exception e) { + e.printStackTrace(); + } + break; + } + } + + if (Objects.nonNull(device) && !shutDownHookAdded) { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + LOGGER.info("Disconnecting devices..."); + client.stopAllDevices(); + client.disconnect(); + } catch (Exception e) { + e.printStackTrace(); + } + })); + + shutDownHookAdded = true; + } + + isConnected = true; + } catch (Exception e) { + lastErrorMessage = e.getMessage(); + LOGGER.error(e.getMessage(), e); + } + + return Objects.nonNull(device); + } + + public static void setVibrationLevel(double level) { + if (Objects.isNull(device)) return; + + if (MinegasmConfig.vibrate) { + try { + device.sendScalarVibrateCmd(level); + currentVibrationLevel = level; + } catch (Exception e) { + e.printStackTrace(); + } + } else { + if (currentVibrationLevel > 0) { + try { + level = 0; + device.sendScalarVibrateCmd(level); + currentVibrationLevel = level; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + public static String getDeviceName() { + return (Objects.nonNull(device)) ? device.getDisplayName() : ""; + } + + public static long getDeviceId() { + return (Objects.nonNull(device)) ? device.getDeviceIndex() : -1; + } + + public static String getLastErrorMessage() { + return lastErrorMessage; + } +} diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/AbstractVibrationState.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/AbstractVibrationState.java new file mode 100644 index 0000000..db103e1 --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/AbstractVibrationState.java @@ -0,0 +1,119 @@ +package com.therainbowville.minegasm.common; + +import com.therainbowville.minegasm.config.ClientConfig; +import com.therainbowville.minegasm.config.MinegasmConfig; +import org.apache.logging.log4j.LogManager; + +import java.util.HashMap; +import java.util.Map; + +// Architecture inspired from https://github.com/Fyustorm/mInetiface +public abstract class AbstractVibrationState { + + protected static final org.apache.logging.log4j.Logger LOGGER = LogManager.getLogger(); + protected final float streakCountdownAmount; + protected float intensity; + + protected float vibrationCountdown; + protected float vibrationFeedbackCountdown; + + protected AbstractVibrationState(float streakSeconds) { + streakCountdownAmount = streakSeconds; + vibrationCountdown = 0; + vibrationFeedbackCountdown = 0; + intensity = 0; + } + + protected static boolean accumulationEnabled() { + return MinegasmConfig.mode.equals(ClientConfig.GameplayMode.ACCUMULATION); + } + + public static int getIntensity(String type) { + Map normal = new HashMap<>(); + normal.put("attack", 60); + normal.put("hurt", 0); + normal.put("mine", 80); + normal.put("place", 20); + normal.put("xpChange", 100); + normal.put("harvest", 10); + normal.put("fishing", 50); + normal.put("vitality", 0); + normal.put("advancement", 100); + + Map masochist = new HashMap<>(); + masochist.put("attack", 0); + masochist.put("hurt", 100); + masochist.put("mine", 0); + masochist.put("place", 0); + masochist.put("xpChange", 0); + masochist.put("fishing", 0); + masochist.put("harvest", 0); + masochist.put("vitality", 10); + masochist.put("advancement", 0); + + Map hedonist = new HashMap<>(); + hedonist.put("attack", 60); + hedonist.put("hurt", 10); + hedonist.put("mine", 80); + hedonist.put("place", 20); + hedonist.put("xpChange", 100); + hedonist.put("fishing", 50); + hedonist.put("harvest", 20); + hedonist.put("vitality", 10); + hedonist.put("advancement", 100); + + Map accumulation = new HashMap<>(); + accumulation.put("attack", 1); + accumulation.put("hurt", 1); + accumulation.put("mine", 1); + accumulation.put("place", 1); + accumulation.put("xpChange", 1); + accumulation.put("fishing", 50); + accumulation.put("harvest", 10); + accumulation.put("vitality", 0); + accumulation.put("advancement", 1); + + Map custom = new HashMap<>(); + custom.put("attack", MinegasmConfig.attackIntensity); + custom.put("hurt", MinegasmConfig.hurtIntensity); + custom.put("mine", MinegasmConfig.mineIntensity); + custom.put("place", MinegasmConfig.placeIntensity); + custom.put("xpChange", MinegasmConfig.xpChangeIntensity); + custom.put("fishing", MinegasmConfig.fishingIntensity); + custom.put("harvest", MinegasmConfig.harvestIntensity); + custom.put("vitality", MinegasmConfig.vitalityIntensity); + custom.put("advancement", MinegasmConfig.advancementIntensity); + + + return switch (MinegasmConfig.mode) { + case NORMAL -> normal.get(type); + case MASOCHIST -> masochist.get(type); + case HEDONIST -> hedonist.get(type); + case ACCUMULATION -> accumulation.get(type); + case CUSTOM -> custom.get(type); + }; + } + + public void onTick() { + if (accumulationEnabled()) { + if (vibrationCountdown > 0) + vibrationCountdown--; + else if (intensity > 0) { + intensity = Math.max(0, intensity - 5); + vibrationCountdown = streakCountdownAmount * MinegasmConfig.ticksPerSecond; + } + } else { + vibrationCountdown = Math.max(0, vibrationCountdown - 1); + } + + vibrationFeedbackCountdown = Math.max(0, vibrationFeedbackCountdown - 1); + } + + public void resetState() { + vibrationCountdown = 0; + vibrationFeedbackCountdown = 0; + intensity = 0; + } + + public abstract int getIntensity(); +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/Minegasm.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/Minegasm.java new file mode 100644 index 0000000..59099a1 --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/Minegasm.java @@ -0,0 +1,28 @@ +package com.therainbowville.minegasm.common; + +import com.therainbowville.minegasm.config.ConfigHelper; +import com.therainbowville.minegasm.config.ConfigHolder; +import net.minecraftforge.client.ConfigScreenHandler; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.ModLoadingContext; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.config.ModConfig; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +@Mod(Minegasm.MOD_ID) +public class Minegasm { + public static final String MOD_ID = "minegasm"; + public static final String NAME = "Minegasm"; + private static final Logger LOGGER = LogManager.getLogger(); + + public Minegasm() { + ModLoadingContext context = ModLoadingContext.get(); + context.registerConfig(ModConfig.Type.CLIENT, ConfigHolder.CLIENT_SPEC); + context.registerConfig(ModConfig.Type.SERVER, ConfigHolder.SERVER_SPEC); + + MinecraftForge.EVENT_BUS.register(this); + + ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class, ConfigHelper::createConfigScreenFactory); + } +} diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateAdvancement.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateAdvancement.java new file mode 100644 index 0000000..1ab7e6d --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateAdvancement.java @@ -0,0 +1,41 @@ +package com.therainbowville.minegasm.common; + +import com.therainbowville.minegasm.config.MinegasmConfig; +import net.minecraft.advancements.Advancement; +import net.minecraft.advancements.AdvancementType; +import net.minecraftforge.event.entity.player.AdvancementEvent.AdvancementEarnEvent; + +public class VibrationStateAdvancement extends AbstractVibrationState { + public VibrationStateAdvancement() { + super(0); + } + + public void onAdvancement(AdvancementEarnEvent event) { + if (getIntensity("advancement") == 0) return; + try { + LOGGER.info("Advancement Event: " + event); + Advancement advancement = event.getAdvancement().value(); + AdvancementType type = advancement.display().get().getType(); + int duration = switch (type) { + case TASK -> 5; + case GOAL -> 7; + case CHALLENGE -> 10; + }; + + vibrationCountdown = duration * MinegasmConfig.ticksPerSecond; + vibrationFeedbackCountdown = 1.5f * MinegasmConfig.ticksPerSecond; + } catch (Throwable e) { + LOGGER.throwing(e); + } + } + + public int getIntensity() { + if (accumulationEnabled()) + return Math.toIntExact(Math.round(intensity)); + else if (vibrationFeedbackCountdown > 0) + return Math.min(100, getIntensity("advancement") + 20); + else if (vibrationCountdown > 0) + return getIntensity("advancement"); + else return 0; + } +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateAttack.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateAttack.java new file mode 100644 index 0000000..e88e47a --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateAttack.java @@ -0,0 +1,32 @@ +package com.therainbowville.minegasm.common; + +import com.therainbowville.minegasm.config.MinegasmConfig; + +public class VibrationStateAttack extends AbstractVibrationState { + public VibrationStateAttack() { + super(3); + } + + public void onAttack() { + if (getIntensity("attack") == 0) return; + + if (accumulationEnabled()) { + intensity = Math.min(100, intensity + 5); + vibrationCountdown = streakCountdownAmount * MinegasmConfig.ticksPerSecond; + vibrationFeedbackCountdown = 1 * 0; + } else { + vibrationCountdown = 3 * MinegasmConfig.ticksPerSecond; + vibrationFeedbackCountdown = 1 * MinegasmConfig.ticksPerSecond; + } + } + + public int getIntensity() { + if (accumulationEnabled()) + return Math.toIntExact(Math.round(intensity)); + else if (vibrationFeedbackCountdown > 0) + return Math.min(100, getIntensity("attack") + 20); + else if (vibrationCountdown > 0) + return getIntensity("attack"); + else return 0; + } +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateClient.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateClient.java new file mode 100644 index 0000000..559ba3d --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateClient.java @@ -0,0 +1,20 @@ +package com.therainbowville.minegasm.common; + +import com.therainbowville.minegasm.config.MinegasmConfig; + +public class VibrationStateClient extends AbstractVibrationState { + public VibrationStateClient() { + super(0); + } + + public void setVibration(int intensity, int durationSeconds) { + intensity = intensity; + vibrationCountdown = durationSeconds * MinegasmConfig.ticksPerSecond; + } + + public int getIntensity() { + if (vibrationCountdown > 0) + return Math.toIntExact(Math.round(intensity)); + else return 0; + } +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateFish.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateFish.java new file mode 100644 index 0000000..d55d5bb --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateFish.java @@ -0,0 +1,30 @@ +package com.therainbowville.minegasm.common; + +import com.therainbowville.minegasm.config.MinegasmConfig; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.Vec3; + +public class VibrationStateFish extends AbstractVibrationState { + public VibrationStateFish() { + super(0); + } + + public void onTick(Player player) { + if (player.fishing != null) { + Vec3 vector = player.fishing.getDeltaMovement(); + double x = vector.x(); + double y = vector.y(); + double z = vector.z(); + if (y < -0.075 && !player.level().getFluidState(player.fishing.blockPosition()).isEmpty() && x == 0 && z == 0) { + vibrationCountdown = 1.5f * MinegasmConfig.ticksPerSecond; + LOGGER.info("Fishing!"); + } + } + } + + public int getIntensity() { + if (vibrationCountdown > 0) + return getIntensity("fishing"); + else return 0; + } +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateHarvest.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateHarvest.java new file mode 100644 index 0000000..a4ed4a5 --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateHarvest.java @@ -0,0 +1,24 @@ +package com.therainbowville.minegasm.common; + +public class VibrationStateHarvest extends AbstractVibrationState { + private VibrationStateMine mineState; + + public VibrationStateHarvest(VibrationStateMine state) { + super(0); + mineState = state; + } + + public void onHarvest() { + vibrationCountdown = 3; + mineState.onHarvest(); + } + + public int getIntensity() { + if (vibrationCountdown > 0) { + if (accumulationEnabled()) + return Math.min(100, mineState.getIntensity() + 20); + else + return getIntensity("harvest"); + } else return 0; + } +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateHurt.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateHurt.java new file mode 100644 index 0000000..117e19d --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateHurt.java @@ -0,0 +1,32 @@ +package com.therainbowville.minegasm.common; + +import com.therainbowville.minegasm.config.MinegasmConfig; + +public class VibrationStateHurt extends AbstractVibrationState { + public VibrationStateHurt() { + super(3); + } + + public void onHurt() { + if (getIntensity("hurt") == 0) return; + + if (accumulationEnabled()) { + intensity = Math.min(100, intensity + 10); + vibrationCountdown = streakCountdownAmount * MinegasmConfig.ticksPerSecond; + vibrationFeedbackCountdown = 1 * MinegasmConfig.ticksPerSecond; + } else { + vibrationCountdown = 3 * MinegasmConfig.ticksPerSecond; + vibrationFeedbackCountdown = 1 * MinegasmConfig.ticksPerSecond; + } + } + + public int getIntensity() { + if (accumulationEnabled()) + return Math.toIntExact(Math.round(intensity)); + else if (vibrationFeedbackCountdown > 0) + return Math.min(100, getIntensity("hurt") + 20); + else if (vibrationCountdown > 0) + return getIntensity("hurt"); + else return 0; + } +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateMine.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateMine.java new file mode 100644 index 0000000..5d1228e --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateMine.java @@ -0,0 +1,48 @@ +package com.therainbowville.minegasm.common; + +import com.therainbowville.minegasm.config.MinegasmConfig; +import net.minecraft.world.level.block.state.BlockState; + +public class VibrationStateMine extends AbstractVibrationState { + public VibrationStateMine() { + super(5); + } + + public void onBreak(BlockState block) { + if (getIntensity("mine") == 0) return; + + String blockName = block.getBlock().getName().getString(); + if (accumulationEnabled()) { + if (blockName.contains("Ore")) { + intensity = Math.min(100, intensity + 1); + vibrationCountdown = streakCountdownAmount * MinegasmConfig.ticksPerSecond; + vibrationFeedbackCountdown = 1 * MinegasmConfig.ticksPerSecond; + } else { + intensity = Math.min(100, intensity + .25f); + vibrationCountdown = streakCountdownAmount * MinegasmConfig.ticksPerSecond; + } + } else { + if (blockName.contains("Ore")) { + vibrationCountdown = 3 * MinegasmConfig.ticksPerSecond; + vibrationFeedbackCountdown = 1 * MinegasmConfig.ticksPerSecond; + } else + vibrationCountdown = 3 * MinegasmConfig.ticksPerSecond; + } + } + + public void onHarvest() { + if (accumulationEnabled()) { + vibrationCountdown = Math.max(3, vibrationCountdown); + } + } + + public int getIntensity() { + if (accumulationEnabled()) + return Math.toIntExact(Math.round(intensity)); + else if (vibrationFeedbackCountdown > 0) + return Math.min(100, getIntensity("mine") + 20); + else if (vibrationCountdown > 0) + return getIntensity("mine"); + else return 0; + } +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStatePlace.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStatePlace.java new file mode 100644 index 0000000..0ba025c --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStatePlace.java @@ -0,0 +1,31 @@ +package com.therainbowville.minegasm.common; + +import com.therainbowville.minegasm.config.MinegasmConfig; + +public class VibrationStatePlace extends AbstractVibrationState { + public VibrationStatePlace() { + super(5); + } + + public void onPlace() { + if (getIntensity("place") == 0) return; + + if (accumulationEnabled()) { + intensity = Math.min(100, intensity + .5f); + vibrationCountdown = streakCountdownAmount * MinegasmConfig.ticksPerSecond; + vibrationFeedbackCountdown = 1 * MinegasmConfig.ticksPerSecond; + } else { + vibrationCountdown = 3 * MinegasmConfig.ticksPerSecond; + } + } + + public int getIntensity() { + if (accumulationEnabled()) + return Math.toIntExact(Math.round(intensity)); + else if (vibrationFeedbackCountdown > 0) + return Math.min(100, getIntensity("place") + 20); + else if (vibrationCountdown > 0) + return getIntensity("place"); + else return 0; + } +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateVitality.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateVitality.java new file mode 100644 index 0000000..6892ceb --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateVitality.java @@ -0,0 +1,57 @@ +package com.therainbowville.minegasm.common; + +import com.therainbowville.minegasm.config.ClientConfig; +import com.therainbowville.minegasm.config.MinegasmConfig; +import net.minecraft.world.entity.player.Player; + +public class VibrationStateVitality extends AbstractVibrationState { + private int intensityCooldown; + private boolean targetMet; + + public VibrationStateVitality() { + super(1); + intensityCooldown = 0; + targetMet = false; + } + + public void onTick(Player player) { + float playerHealth = player.getHealth(); + float playerFoodLevel = player.getFoodData().getFoodLevel(); + + if ((MinegasmConfig.mode.equals(ClientConfig.GameplayMode.MASOCHIST) && playerHealth > 0 && playerHealth <= 1) + || (!MinegasmConfig.mode.equals(ClientConfig.GameplayMode.MASOCHIST) && playerHealth >= 20 && playerFoodLevel >= 20)) { + + if (targetMet == false) { + targetMet = true; + vibrationFeedbackCountdown = 3 * MinegasmConfig.ticksPerSecond; + } + } else + targetMet = false; + +// if (accumulationEnabled() && targetMet) +// { +// if (intensityCooldown == 0) { +// intensity = Math.min(100, intensity + .1f); +// intensityCooldown = 10 * 20; +// } +// vibrationCountdown = streakCountdownAmount; +// intensityCooldown = Math.max(0, intensityCooldown - 1); +// } else + if (targetMet) { + vibrationCountdown = 1; + } + } + + public int getIntensity() { + if (getIntensity("vitality") == 0) return 0; + + //if (accumulationEnabled()) + //return Math.toIntExact(Math.round(intensity)); + //else + if (vibrationFeedbackCountdown > 0) + return Math.min(100, getIntensity("vitality") + 20); + else if (vibrationCountdown > 0) + return getIntensity("vitality"); + else return 0; + } +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateXpChange.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateXpChange.java new file mode 100644 index 0000000..4b3fec6 --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/common/VibrationStateXpChange.java @@ -0,0 +1,49 @@ +package com.therainbowville.minegasm.common; + +import com.therainbowville.minegasm.config.MinegasmConfig; + +public class VibrationStateXpChange extends AbstractVibrationState { + private int lastLevel; + + public VibrationStateXpChange() { + super(1); + lastLevel = -1; + } + + // Code adapted from https://github.com/Fyustorm/mInetiface + public void onXpChange(int level, int amount) { + if (amount == 0 || getIntensity("xpChange") == 0) + return; + + if (lastLevel == -1) { + lastLevel = level; + } + + if (lastLevel != level) { + amount *= 2; + } + + lastLevel = level; + + if (accumulationEnabled()) { + intensity = Math.min(100, intensity + amount / 5); + vibrationCountdown = streakCountdownAmount * MinegasmConfig.ticksPerSecond; + vibrationFeedbackCountdown = 1 * MinegasmConfig.ticksPerSecond; + } else { + int duration = Math.toIntExact(Math.round(Math.ceil(Math.log(amount + 0.5)))); + vibrationCountdown = duration * MinegasmConfig.ticksPerSecond; + vibrationFeedbackCountdown = 1 * MinegasmConfig.ticksPerSecond; + } + } + + public int getIntensity() { + if (accumulationEnabled()) + return Math.toIntExact(Math.round(intensity)); + else if (vibrationFeedbackCountdown > 0) + return Math.min(100, getIntensity("xpChange") + 20); + else if (vibrationCountdown > 0) + return getIntensity("xpChange"); + else return 0; + } +} + diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ClientConfig.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ClientConfig.java new file mode 100644 index 0000000..d68ff8b --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ClientConfig.java @@ -0,0 +1,179 @@ +package com.therainbowville.minegasm.config; + +import com.therainbowville.minegasm.common.Minegasm; +import net.minecraftforge.common.ForgeConfigSpec; + +import java.util.Objects; + +public final class ClientConfig { + static final String DEFAULT_SERVER_URL = "ws://localhost:12345/buttplug"; + static final boolean DEFAULT_VIBRATE = true; + static final GameplayMode DEFAULT_MODE = GameplayMode.NORMAL; + static final boolean DEFAULT_STEALTH = false; + static final int DEFAULT_ATTACK_INTENSITY = 60; + static final int DEFAULT_HURT_INTENSITY = 0; + static final int DEFAULT_MINE_INTENSITY = 80; + static final int DEFAULT_PLACE_INTENSITY = 20; + static final int DEFAULT_XP_CHANGE_INTENSITY = 100; + static final int DEFAULT_FISHING_INTENSITY = 50; + static final int DEFAULT_HARVEST_INTENSITY = 0; + static final int DEFAULT_VITALITY_INTENSITY = 0; + static final int DEFAULT_ADVANCEMENT_INTENSITY = 100; + final ForgeConfigSpec.ConfigValue serverUrl; + final ForgeConfigSpec.BooleanValue vibrate; + final ForgeConfigSpec.EnumValue mode; + final ForgeConfigSpec.BooleanValue stealth; + final ForgeConfigSpec.EnumValue tickFrequency; + final ForgeConfigSpec.IntValue attackIntensity; + final ForgeConfigSpec.IntValue hurtIntensity; + final ForgeConfigSpec.IntValue mineIntensity; + final ForgeConfigSpec.IntValue placeIntensity; + final ForgeConfigSpec.IntValue xpChangeIntensity; + final ForgeConfigSpec.IntValue fishingIntensity; + final ForgeConfigSpec.IntValue harvestIntensity; + final ForgeConfigSpec.IntValue vitalityIntensity; + final ForgeConfigSpec.IntValue advancementIntensity; + + + ClientConfig(final ForgeConfigSpec.Builder builder) { + builder.push("buttplug"); + + serverUrl = builder + .translation(Minegasm.MOD_ID + ".config.serverUrl") + .define("serverUrl", DEFAULT_SERVER_URL); + + builder.pop(); + + builder.push("minegasm"); + + vibrate = builder + .translation(Minegasm.MOD_ID + ".config.vibrate") + .define("vibrate", DEFAULT_VIBRATE); + mode = builder + .translation(Minegasm.MOD_ID + ".config.mode") + .defineEnum("mode", DEFAULT_MODE); + stealth = builder + .translation(Minegasm.MOD_ID + ".config.stealth") + .define("stealth", DEFAULT_STEALTH); + + tickFrequency = builder + .translation(Minegasm.MOD_ID + ".config.mode") + .defineEnum("tickFrequency", TickFrequencyOptions.EVERY_TICK); + + builder.push("intensity"); + + attackIntensity = builder + .comment("Vibration intensity when attacking on custom mode") + .translation(Minegasm.MOD_ID + ".config.intensity.attack") + .defineInRange("attackIntensity", DEFAULT_ATTACK_INTENSITY, 0, 100); + + hurtIntensity = builder + .comment("Vibration intensity when hurting on custom mode") + .translation(Minegasm.MOD_ID + ".config.intensity.hurt") + .defineInRange("hurtIntensity", DEFAULT_HURT_INTENSITY, 0, 100); + + mineIntensity = builder + .comment("Vibration intensity when mining on custom mode") + .translation(Minegasm.MOD_ID + ".config.intensity.mine") + .defineInRange("mineIntensity", DEFAULT_MINE_INTENSITY, 0, 100); + + placeIntensity = builder + .comment("Vibration intensity when placing blocks on custom mode") + .translation(Minegasm.MOD_ID + ".config.intensity.place") + .defineInRange("placeIntensity", DEFAULT_PLACE_INTENSITY, 0, 100); + + xpChangeIntensity = builder + .comment("Vibration intensity when gaining XP on custom mode") + .translation(Minegasm.MOD_ID + ".config.intensity.xp_change") + .defineInRange("xpChangeIntensity", DEFAULT_XP_CHANGE_INTENSITY, 0, 100); + + fishingIntensity = builder + .comment("Vibration intensity when fishing on custom mode") + .translation(Minegasm.MOD_ID + ".config.intensity.fishing") + .defineInRange("fishingIntensity", DEFAULT_FISHING_INTENSITY, 0, 100); + + harvestIntensity = builder + .comment("Vibration intensity when harvesting on custom mode") + .translation(Minegasm.MOD_ID + ".config.intensity.harvest") + .defineInRange("harvestIntensity", DEFAULT_HARVEST_INTENSITY, 0, 100); + + vitalityIntensity = builder + .comment("Vibration intensity on high level of player's vitality on custom mode") + .translation(Minegasm.MOD_ID + ".config.intensity.vitality") + .defineInRange("vitalityIntensity", DEFAULT_VITALITY_INTENSITY, 0, 100); + + advancementIntensity = builder + .comment("Vibration intensity on achieving advancement on custom mode") + .translation(Minegasm.MOD_ID + ".config.intensity.advancement") + .defineInRange("advancementIntensity", DEFAULT_ADVANCEMENT_INTENSITY, 0, 100); + + builder.pop(); + builder.pop(); + } + + public void resetConfigUrl() { + ConfigHolder.CLIENT.serverUrl.set(DEFAULT_SERVER_URL); + } + + public void resetConfigCustom() { + ConfigHolder.CLIENT.attackIntensity.set(DEFAULT_ATTACK_INTENSITY); + ConfigHolder.CLIENT.hurtIntensity.set(DEFAULT_HURT_INTENSITY); + ConfigHolder.CLIENT.mineIntensity.set(DEFAULT_MINE_INTENSITY); + ConfigHolder.CLIENT.placeIntensity.set(DEFAULT_PLACE_INTENSITY); + ConfigHolder.CLIENT.xpChangeIntensity.set(DEFAULT_XP_CHANGE_INTENSITY); + ConfigHolder.CLIENT.fishingIntensity.set(DEFAULT_FISHING_INTENSITY); + ConfigHolder.CLIENT.harvestIntensity.set(DEFAULT_HARVEST_INTENSITY); + ConfigHolder.CLIENT.vitalityIntensity.set(DEFAULT_VITALITY_INTENSITY); + ConfigHolder.CLIENT.advancementIntensity.set(DEFAULT_ADVANCEMENT_INTENSITY); + } + + public enum GameplayMode { + NORMAL("gui." + Minegasm.MOD_ID + ".config.mode.normal"), + MASOCHIST("gui." + Minegasm.MOD_ID + ".config.mode.masochist"), + HEDONIST("gui." + Minegasm.MOD_ID + ".config.mode.hedonist"), + ACCUMULATION("gui." + Minegasm.MOD_ID + ".config.mode.accumulation"), + CUSTOM("gui." + Minegasm.MOD_ID + ".config.mode.custom"); + + private final String translateKey; + + GameplayMode(String translateKey) { + this.translateKey = + Objects.requireNonNull(translateKey, "translateKey"); + } + + public String getTranslateKey() { + return this.translateKey; + } + } + + public enum TickFrequencyOptions { + EVERY_TICK(1), + EVERY_OTHER_TICK(2), + EVERY_5_TICKS(5), + EVERY_10_TICKS(10), + EVERY_20_TICKS(20), + EVERY_30_TICKS(30), + EVERY_40_TICKS(40), + EVERY_50_TICKS(50); + + private int value; + + TickFrequencyOptions(int value) { + this.value = value; + } + + public static TickFrequencyOptions fromInt(int value) { + for (TickFrequencyOptions type : values()) { + if (type.getInt() == value) { + return type; + } + } + return null; + } + + public int getInt() { + return value; + } + } + +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ConfigHelper.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ConfigHelper.java new file mode 100644 index 0000000..ddaa8ce --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ConfigHelper.java @@ -0,0 +1,72 @@ +package com.therainbowville.minegasm.config; + +import net.minecraftforge.client.ConfigScreenHandler; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public final class ConfigHelper { + private static final Logger LOGGER = LogManager.getLogger(); + + public static void bakeClient() { + MinegasmConfig.serverUrl = ConfigHolder.CLIENT.serverUrl.get(); + MinegasmConfig.vibrate = ConfigHolder.CLIENT.vibrate.get(); + MinegasmConfig.mode = ConfigHolder.CLIENT.mode.get(); + MinegasmConfig.stealth = ConfigHolder.CLIENT.stealth.get(); + MinegasmConfig.tickFrequency = ConfigHolder.CLIENT.tickFrequency.get().getInt(); + MinegasmConfig.ticksPerSecond = Math.max(0, 20f / MinegasmConfig.tickFrequency); + + MinegasmConfig.attackIntensity = ConfigHolder.CLIENT.attackIntensity.get(); + MinegasmConfig.hurtIntensity = ConfigHolder.CLIENT.hurtIntensity.get(); + MinegasmConfig.mineIntensity = ConfigHolder.CLIENT.mineIntensity.get(); + MinegasmConfig.placeIntensity = ConfigHolder.CLIENT.placeIntensity.get(); + MinegasmConfig.xpChangeIntensity = ConfigHolder.CLIENT.xpChangeIntensity.get(); + MinegasmConfig.fishingIntensity = ConfigHolder.CLIENT.fishingIntensity.get(); + MinegasmConfig.harvestIntensity = ConfigHolder.CLIENT.harvestIntensity.get(); + MinegasmConfig.vitalityIntensity = ConfigHolder.CLIENT.vitalityIntensity.get(); + MinegasmConfig.advancementIntensity = ConfigHolder.CLIENT.advancementIntensity.get(); + } + + public static void bakeServer() { + } + + public static void saveClient() { + try { + + MinegasmConfigBuffer buffer = new MinegasmConfigBuffer(); + +// Field[] fields = MinegasmConfigBuffer.class.getFields(); + +// for (Field field : fields) +// { +// Field configField = ConfigHolder.CLIENT.getClass().getDeclaredField(field.getName()); // Get Corisponding Field in CLIENT +// Class configFieldClass = configField.getType(); // Get the configField Class +// Method method = configFieldClass.getMethod("set", Object.class); +// LOGGER.info(method); +// method.invoke(configField.get(ConfigHolder.CLIENT), field.get(buffer)); +// } + + ConfigHolder.CLIENT.serverUrl.set(buffer.serverUrl); + ConfigHolder.CLIENT.vibrate.set(buffer.vibrate); + ConfigHolder.CLIENT.mode.set(buffer.mode); + ConfigHolder.CLIENT.stealth.set(buffer.stealth); + ConfigHolder.CLIENT.tickFrequency.set(ClientConfig.TickFrequencyOptions.fromInt(buffer.tickFrequency)); + + ConfigHolder.CLIENT.attackIntensity.set(buffer.attackIntensity); + ConfigHolder.CLIENT.hurtIntensity.set(buffer.hurtIntensity); + ConfigHolder.CLIENT.mineIntensity.set(buffer.mineIntensity); + ConfigHolder.CLIENT.placeIntensity.set(buffer.placeIntensity); + ConfigHolder.CLIENT.xpChangeIntensity.set(buffer.xpChangeIntensity); + ConfigHolder.CLIENT.fishingIntensity.set(buffer.fishingIntensity); + ConfigHolder.CLIENT.harvestIntensity.set(buffer.harvestIntensity); + ConfigHolder.CLIENT.vitalityIntensity.set(buffer.vitalityIntensity); + ConfigHolder.CLIENT.advancementIntensity.set(buffer.advancementIntensity); + } catch (Throwable e) { + LOGGER.info(e); + } + } + + public static ConfigScreenHandler.ConfigScreenFactory createConfigScreenFactory() { + return new ConfigScreenHandler.ConfigScreenFactory((minecraft, screen) -> new ConfigScreen(screen)); + } + +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ConfigHolder.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ConfigHolder.java new file mode 100644 index 0000000..b13ac9f --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ConfigHolder.java @@ -0,0 +1,34 @@ +package com.therainbowville.minegasm.config; + +import net.minecraftforge.common.ForgeConfigSpec; +import org.apache.commons.lang3.tuple.Pair; + +public final class ConfigHolder { + + public static final ForgeConfigSpec CLIENT_SPEC; + public static final ForgeConfigSpec SERVER_SPEC; + static final ClientConfig CLIENT; + static final ServerConfig SERVER; + + static { + { + final Pair specPair = new ForgeConfigSpec.Builder().configure(ClientConfig::new); + CLIENT = specPair.getLeft(); + CLIENT_SPEC = specPair.getRight(); + } + { + final Pair specPair = new ForgeConfigSpec.Builder().configure(ServerConfig::new); + SERVER = specPair.getLeft(); + SERVER_SPEC = specPair.getRight(); + } + } + + public static ClientConfig getClientInstance() { + return CLIENT; + } + + public static ServerConfig getServerInstance() { + return SERVER; + } + +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ConfigScreen.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ConfigScreen.java new file mode 100644 index 0000000..79b36bf --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ConfigScreen.java @@ -0,0 +1,337 @@ +package com.therainbowville.minegasm.config; + +import com.therainbowville.minegasm.client.ClientEventHandler; +import com.therainbowville.minegasm.client.ToyController; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.CycleButton; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.narration.NarrationElementOutput; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; +import net.minecraftforge.client.gui.widget.ForgeSlider; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.lang.reflect.Field; +import java.util.ArrayList; + +public class ConfigScreen extends Screen { + private static final Logger LOGGER = LogManager.getLogger(); + private final Screen previous; + EditBox wsHost = null; + private boolean pauseMenu; + + public ConfigScreen(Screen previous) { + super(Component.literal("Minegasm Config")); + this.previous = previous; + pauseMenu = false; + } + + public ConfigScreen(Screen previous, boolean pause) { + super(Component.literal("Minegasm Config")); + this.previous = previous; + pauseMenu = pause; + } + + @Override + protected void init() { + wsHost = new EditBox(Minecraft.getInstance().font, this.width / 2 - 100, this.height / 6, 200, 20, null); + wsHost.setValue(MinegasmConfig.serverUrl); + this.addRenderableWidget(wsHost); + + wsHost.setResponder(s -> { + LOGGER.info(s); + MinegasmConfig.serverUrl = s; + }); + + this.addRenderableWidget(new Button.Builder(Component.literal("Reset Server Url"), button -> { + ConfigHolder.getClientInstance().resetConfigUrl(); + MinegasmConfig.serverUrl = ConfigHolder.getClientInstance().serverUrl.get(); + wsHost.setValue(MinegasmConfig.serverUrl); + }).pos(this.width / 2 - 155, this.height / 6 + 25) + .size(150, 20) + .build() + ); + + PlainTextLabel connectResponse = new PlainTextLabel(this.width / 2 - 155, this.height / 6 + 50, 310, 15, Component.literal("" + ChatFormatting.GREEN)); + + this.addRenderableWidget(connectResponse); + + Button reconnectButton = new Button.Builder(Component.literal("Reconnect"), button -> { + button.active = false; + connectResponse.setValue("Connecting"); + new Thread(() -> { + if (ToyController.connectDevice()) { + ClientEventHandler.afterConnect(); + button.active = true; + connectResponse.setValue(String.format("Connected to " + ChatFormatting.GREEN + "%s" + ChatFormatting.RESET + " [%d]", ToyController.getDeviceName(), ToyController.getDeviceId())); + } else { + button.active = true; + connectResponse.setValue(String.format(ChatFormatting.YELLOW + "Minegasm " + ChatFormatting.RESET + "failed to start: %s", ToyController.getLastErrorMessage())); + } + + }).start(); + }) + .pos(this.width / 2 + 5, this.height / 6 + 25) + .size(150, 20) + .build(); + + this.addRenderableWidget(reconnectButton); + + reconnectButton.active = pauseMenu; + + this.addRenderableWidget(CycleButton.onOffBuilder(MinegasmConfig.vibrate) + .create(this.width / 2 - 155, this.height / 6 + 25 * 3, 150, 20, + Component.literal("Vibration"), (button, value) -> MinegasmConfig.vibrate = value)); + + this.addRenderableWidget(CycleButton.onOffBuilder(MinegasmConfig.stealth) + .create(this.width / 2 + 5, this.height / 6 + 25 * 3, 150, 20, + Component.literal("Stealth"), (button, value) -> MinegasmConfig.stealth = value)); + + this.addRenderableWidget( + CycleButton.builder((ClientConfig.GameplayMode mode) -> + Component.literal(switch (mode) { + case NORMAL -> "Normal"; + case MASOCHIST -> "Masochist"; + case HEDONIST -> "Hedonist"; + case ACCUMULATION -> "Accumulation"; + case CUSTOM -> "Custom"; + })) + .withValues(ClientConfig.GameplayMode.NORMAL, ClientConfig.GameplayMode.MASOCHIST, ClientConfig.GameplayMode.HEDONIST, ClientConfig.GameplayMode.ACCUMULATION, ClientConfig.GameplayMode.CUSTOM) + .withInitialValue(MinegasmConfig.mode) + .create(this.width / 2 - 155, this.height / 6 + 25 * 4, 150, 20, + Component.literal("Mode"), (button, value) -> { + MinegasmConfig.mode = value; + }) + ); + + this.addRenderableWidget(new Button.Builder(Component.literal("Edit Custom Settings"), button -> minecraft.setScreen(new CustomModeConfigScreen(this, pauseMenu))) + .pos(this.width / 2 + 5, this.height / 6 + 25 * 4) + .size(150, 20) + .build() + ); + + this.addRenderableWidget( + CycleButton.builder((Integer tickFrequency) -> + Component.literal(switch (tickFrequency) { + case 1 -> "Every Tick"; + case 2 -> "Every Other Tick"; + case 5 -> "Every 5 Ticks"; + case 10 -> "Every 10 Ticks"; + case 20 -> "Every Second"; + default -> "Every " + Float.toString(tickFrequency / 20f) + " Seconds"; + })) + .withValues(1, 2, 5, 10, 20, 30, 40, 50) + .withInitialValue(MinegasmConfig.tickFrequency) + .create(this.width / 2 - 100, this.height / 6 + 25 * 5, 200, 20, + Component.literal("Tick Frequency"), (button, value) -> { + MinegasmConfig.tickFrequency = value; + MinegasmConfig.ticksPerSecond = Math.max(0, 20f / MinegasmConfig.tickFrequency); + LOGGER.info("TPS: " + MinegasmConfig.ticksPerSecond); + } + ) + ); + + this.addRenderableWidget(new Button.Builder(CommonComponents.GUI_DONE, button -> this.onClose()) + .pos(this.width / 2 - 100, this.height - 27) + .size(200, 20) + .build() + ); + + + } + + @Override + public void tick() { + super.tick(); + + // Add ticking logic for EditBox in editBox +// if (this.wsHost != null) +// this.wsHost.tick(); + } + + @Override + public void onClose() { + PlainTextLabel.setValue(""); + this.minecraft.setScreen(previous); + MinegasmConfig.save(); + } + + @Override + public void render(GuiGraphics graphics, int i, int j, float f) { +// if (pauseMenu) +// this.renderTransparentBackground(graphics); +// else +// this.renderDirtBackground(graphics); + graphics.drawCenteredString(this.font, this.title, this.width / 2, 15, 0xFFFFFF); + super.render(graphics, i, j, f); + } + + class PlainTextLabel extends AbstractWidget { + + private static Component text = Component.literal(""); + private int x; + private int y; + + public PlainTextLabel(int x, int y, int width, int height, Component text) { + super(x, y, width, height, text); + this.x = x; + this.y = y; + } + + public static void setValue(String value) { + text = Component.literal(value); + } + + @Override + public void updateWidgetNarration(NarrationElementOutput output) { + defaultButtonNarrationText(output); + } + + @Override + public void renderWidget(GuiGraphics graphics, int i, int j, float f) { + if (text == null || text.getString().isEmpty()) + return; + +// RenderSystem.setShaderColor(1, 1, 1, 1); +// Minecraft.getInstance().font.draw(poseStack, text.getString(), x, y, 0xFFFFFF); + graphics.drawCenteredString(Minecraft.getInstance().font, text.getString(), Minecraft.getInstance().screen.width / 2, this.y + this.height / 4, 0xFFFFFF); + } + } + +} + +class CustomModeConfigScreen extends Screen { + private static final Logger LOGGER = LogManager.getLogger(); + private final Screen previous; + private boolean pauseMenu; + + public CustomModeConfigScreen(Screen previous) { + super(Component.literal("Minegasm Custom Config")); + this.previous = previous; + pauseMenu = false; + } + + public CustomModeConfigScreen(Screen previous, boolean pause) { + super(Component.literal("Minegasm Custom Config")); + this.previous = previous; + pauseMenu = pause; + } + + @Override + protected void init() { + try { + this.addRenderableWidget(new Button.Builder(CommonComponents.GUI_DONE, button -> this.onClose()) + .pos(this.width / 2 + 5, this.height - 27) + .size(150, 20) + .build() + ); + + IntensitiySliderBar.sliders.clear(); + + // Attack + this.addRenderableWidget(new IntensitiySliderBar(this, "Attack: ", MinegasmConfig.class.getField("attackIntensity"))); + + // Hurt + this.addRenderableWidget(new IntensitiySliderBar(this, "Hurt: ", MinegasmConfig.class.getField("hurtIntensity"))); + + // Mine + this.addRenderableWidget(new IntensitiySliderBar(this, "Mine: ", MinegasmConfig.class.getField("mineIntensity"))); + + // Place + this.addRenderableWidget(new IntensitiySliderBar(this, "Place: ", MinegasmConfig.class.getField("placeIntensity"))); + + // XP Change + this.addRenderableWidget(new IntensitiySliderBar(this, "XP Change: ", MinegasmConfig.class.getField("xpChangeIntensity"))); + + // Fishing + this.addRenderableWidget(new IntensitiySliderBar(this, "Fishing: ", MinegasmConfig.class.getField("fishingIntensity"))); + + // Harvest + this.addRenderableWidget(new IntensitiySliderBar(this, "Harvest: ", MinegasmConfig.class.getField("harvestIntensity"))); + + // Vitality + this.addRenderableWidget(new IntensitiySliderBar(this, "Vitality: ", MinegasmConfig.class.getField("vitalityIntensity"))); + + // Advancement + this.addRenderableWidget(new IntensitiySliderBar(this, "Advancement: ", MinegasmConfig.class.getField("advancementIntensity"))); + + this.addRenderableWidget(new Button.Builder(Component.literal("Reset Values"), button -> { + ConfigHolder.getClientInstance().resetConfigCustom(); + IntensitiySliderBar.refreshAllValues(); + }) + .pos(this.width / 2 - 155, this.height - 27) + .size(150, 20) + .build() + ); + + + } catch (Throwable e) { + LOGGER.throwing(e); + } + } + + @Override + public void onClose() { + IntensitiySliderBar.sliders.clear(); + this.minecraft.setScreen(previous); + } + + @Override + public void render(GuiGraphics graphics, int i, int j, float f) { +// if (pauseMenu) +// this.renderTransparentBackground(graphics); +// else +// this.renderDirtBackground(graphics); + graphics.drawCenteredString(this.font, this.title, this.width / 2, 15, 0xFFFFFF); + super.render(graphics, i, j, f); + } + + private class IntensitiySliderBar extends ForgeSlider { + public static ArrayList sliders = new ArrayList(); + private Field fieldReference; + + IntensitiySliderBar(CustomModeConfigScreen parent, String prefix, Field field) throws Exception { + super(parent.width / 2 + (sliders.size() % 2 == 1 ? 5 : -155), // x pos + parent.height / 6 + 25 * (int) Math.floor(sliders.size() / 2), // y pos + 150, 20, // Width, height + Component.literal(prefix), // Prefix + Component.literal(""), // Suffix + 0, 100, field.getInt(null), 1, 1, true); // Min, Max, Default value, stepsize, percision, drawstring + fieldReference = field; +// LOGGER.info("S: " + sliders.size() + " X: " + parent.width / 2 + (sliders.size() % 2 == 1 ? 5 : -155) + " Y: " + parent.height / 6 + 25 * (int)Math.floor(sliders.size() / 2)); + sliders.add(this); + } + + public static void refreshAllValues() { + for (IntensitiySliderBar slider : sliders) { + slider.refreshValue(); + } + } + + @Override + public void applyValue() { +// LOGGER.info("applyValue"); + //responder.accept(this.getValueInt()); + try { + fieldReference.set(null, this.getValueInt()); + } catch (Throwable e) { + LOGGER.throwing(e); + } + } + + private void refreshValue() { + try { + this.setValue(fieldReference.getInt(null)); + } catch (Throwable e) { + LOGGER.throwing(e); + } + } + + } +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/MinegasmConfig.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/MinegasmConfig.java new file mode 100644 index 0000000..301e2f9 --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/MinegasmConfig.java @@ -0,0 +1,93 @@ +package com.therainbowville.minegasm.config; + +import com.therainbowville.minegasm.common.Minegasm; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.config.ModConfig; +import net.minecraftforge.fml.event.config.ModConfigEvent; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + + +@Mod.EventBusSubscriber(modid = Minegasm.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD) +public class MinegasmConfig { + private static final Logger LOGGER = LogManager.getLogger(); + + // Client + public static String serverUrl; + + public static boolean vibrate; + public static ClientConfig.GameplayMode mode = ClientConfig.GameplayMode.NORMAL; + public static boolean stealth; + public static int tickFrequency; + public static float ticksPerSecond; + + public static int attackIntensity; + public static int hurtIntensity; + public static int mineIntensity; + public static int placeIntensity; + public static int xpChangeIntensity; + public static int fishingIntensity; + public static int harvestIntensity; + public static int vitalityIntensity; + public static int advancementIntensity; + + // Server + // -- none at the moment + + @SubscribeEvent + public static void onModConfigEvent(final ModConfigEvent event) { + final ModConfig config = event.getConfig(); + // Re-bake the configs when they change + if (config.getSpec() == ConfigHolder.CLIENT_SPEC) { + ConfigHelper.bakeClient(); + LOGGER.debug("Baked client config"); + } else if (config.getSpec() == ConfigHolder.SERVER_SPEC) { + ConfigHelper.bakeServer(); + LOGGER.debug("Baked server config"); + } + } + + public static void save() { + ConfigHelper.saveClient(); + } + +} + +class MinegasmConfigBuffer { + public String serverUrl; + + public boolean vibrate; + public ClientConfig.GameplayMode mode = ClientConfig.GameplayMode.NORMAL; + public boolean stealth; + public int tickFrequency; + + public int attackIntensity; + public int hurtIntensity; + public int mineIntensity; + public int placeIntensity; + public int xpChangeIntensity; + public int fishingIntensity; + public int harvestIntensity; + public int vitalityIntensity; + public int advancementIntensity; + + MinegasmConfigBuffer() { + this.serverUrl = MinegasmConfig.serverUrl; + this.vibrate = MinegasmConfig.vibrate; + this.mode = MinegasmConfig.mode; + this.stealth = MinegasmConfig.stealth; + this.tickFrequency = MinegasmConfig.tickFrequency; + + this.attackIntensity = MinegasmConfig.attackIntensity; + this.hurtIntensity = MinegasmConfig.hurtIntensity; + this.mineIntensity = MinegasmConfig.mineIntensity; + this.placeIntensity = MinegasmConfig.placeIntensity; + this.xpChangeIntensity = MinegasmConfig.xpChangeIntensity; + this.fishingIntensity = MinegasmConfig.fishingIntensity; + this.harvestIntensity = MinegasmConfig.harvestIntensity; + this.vitalityIntensity = MinegasmConfig.vitalityIntensity; + this.advancementIntensity = MinegasmConfig.advancementIntensity; + } +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/PauseMenuButton.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/PauseMenuButton.java new file mode 100644 index 0000000..68313af --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/PauseMenuButton.java @@ -0,0 +1,120 @@ +package com.therainbowville.minegasm.config; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.therainbowville.minegasm.common.Minegasm; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.screens.PauseScreen; +import net.minecraft.client.resources.language.I18n; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.client.event.ScreenEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import org.apache.commons.lang3.mutable.MutableObject; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +// Adapted from https://github.com/Creators-of-Create/Create/ +public class PauseMenuButton extends Button { + private static final Logger LOGGER = LogManager.getLogger(); + private static ResourceLocation LOGO = new ResourceLocation(Minegasm.MOD_ID, "textures/logo.png"); + + int xPos; + int yPos; + + public PauseMenuButton(int x, int y) { + super(new Button.Builder(Component.literal(""), PauseMenuButton::clicked).pos(x, y).size(20, 20)); + xPos = x; + yPos = y; + } + + public static void clicked(Button button) { + Minecraft.getInstance().setScreen(new ConfigScreen(Minecraft.getInstance().screen, true)); + } + + @Override + public void renderWidget(GuiGraphics graphics, int i, int j, float k) { + super.renderWidget(graphics, i, j, k); + graphics.pose().pushPose(); + graphics.pose().translate(xPos + width / 2 - (64 * 0.25f) / 2, yPos + height / 2 - (64 * 0.25f) / 2, 0); + graphics.pose().scale(0.25f, 0.25f, 1); + RenderSystem.setShaderTexture(0, LOGO); + graphics.blit(LOGO, 0, 0, 0, 0, 64, 64, 64, 64); + graphics.pose().popPose(); + } + + public static class SingleMenuRow { + public final String left, right; + + public SingleMenuRow(String left, String right) { + this.left = I18n.get(left); + this.right = I18n.get(right); + } + + public SingleMenuRow(String center) { + this(center, center); + } + } + + public static class MenuRows { + public static final MenuRows MAIN_MENU = new MenuRows(Arrays.asList( + new SingleMenuRow("menu.singleplayer"), + new SingleMenuRow("menu.multiplayer"), + new SingleMenuRow("fml.menu.mods", "menu.online"), + new SingleMenuRow("narrator.button.language", "narrator.button.accessibility") + )); + + public static final MenuRows INGAME_MENU = new MenuRows(Arrays.asList( + new SingleMenuRow("menu.returnToGame"), + new SingleMenuRow("gui.advancements", "gui.stats"), + new SingleMenuRow("menu.sendFeedback", "menu.reportBugs"), + new SingleMenuRow("menu.options", "menu.shareToLan"), + new SingleMenuRow("menu.returnToMenu") + )); + + protected final List leftButtons, rightButtons; + + public MenuRows(List variants) { + leftButtons = variants.stream().map(r -> r.left).collect(Collectors.toList()); + rightButtons = variants.stream().map(r -> r.right).collect(Collectors.toList()); + } + } + + @Mod.EventBusSubscriber(modid = Minegasm.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE) + public class PauseMenuButtonScreen { + + @SubscribeEvent + public static void onGuiInit(ScreenEvent.Init event) { + if (event.getScreen() instanceof PauseScreen) { // Make sure GUI is Escape menu + MenuRows menu = MenuRows.INGAME_MENU; + int rowIdx = 3; + int offsetX = 4; + boolean onLeft = offsetX < 0; + String target = (onLeft ? menu.leftButtons : menu.rightButtons).get(rowIdx - 1); + + int offsetX_ = offsetX; + MutableObject toAdd = new MutableObject<>(null); + event.getListenersList() + .stream() + .filter(w -> w instanceof AbstractWidget) + .map(w -> (AbstractWidget) w) + .filter(w -> w.getMessage() + .getString() + .equals(target)) + .findFirst() + .ifPresent(w -> toAdd + .setValue(new PauseMenuButton(w.getX() + offsetX_ + (onLeft ? -20 : w.getWidth()), w.getY()))); + if (toAdd.getValue() != null) + event.addListener(toAdd.getValue()); + } + } + } +} diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ServerConfig.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ServerConfig.java new file mode 100644 index 0000000..d1fde10 --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/config/ServerConfig.java @@ -0,0 +1,11 @@ +package com.therainbowville.minegasm.config; + +import net.minecraftforge.common.ForgeConfigSpec; + +final class ServerConfig { + + ServerConfig(final ForgeConfigSpec.Builder builder) { + builder.push("general"); + builder.pop(); + } +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/mixin/ClientAdvancementsMixin.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/mixin/ClientAdvancementsMixin.java new file mode 100644 index 0000000..c21233b --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/mixin/ClientAdvancementsMixin.java @@ -0,0 +1,42 @@ +package com.therainbowville.minegasm.mixin; + +import com.therainbowville.minegasm.client.ClientEventHandler; +import net.minecraft.advancements.AdvancementHolder; +import net.minecraft.advancements.AdvancementProgress; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientAdvancements; +import net.minecraft.network.protocol.game.ClientboundUpdateAdvancementsPacket; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; +import net.minecraftforge.event.entity.player.AdvancementEvent.AdvancementEarnEvent; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +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 java.util.Map; + +@Mixin(ClientAdvancements.class) +public class ClientAdvancementsMixin { + private static final Minecraft minecraft = Minecraft.getInstance(); + private static Logger LOGGER = LogManager.getLogger(); + + @Inject(method = "update", at = @At("HEAD"), cancellable = true) + public void onUpdate(ClientboundUpdateAdvancementsPacket advancementInfoPacket, CallbackInfo ci) { + if (Minecraft.getInstance().isLocalServer()) { + return; + } + LOGGER.info("Advancement updated"); + + for (Map.Entry entry : advancementInfoPacket.getProgress().entrySet()) { + if (entry.getValue().isDone()) { + AdvancementHolder advancement = ((ClientAdvancements) (Object) this).get(entry.getKey()); + Player player = minecraft.player; + AdvancementEarnEvent event = new AdvancementEarnEvent(player, advancement); + ClientEventHandler.onAdvancementEvent(event); + } + } + } +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/mixin/LocalPlayerMixin.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/mixin/LocalPlayerMixin.java new file mode 100644 index 0000000..d2eb738 --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/mixin/LocalPlayerMixin.java @@ -0,0 +1,53 @@ +package com.therainbowville.minegasm.mixin; + +import com.therainbowville.minegasm.client.ClientEventHandler; +import net.minecraft.client.Minecraft; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraftforge.event.entity.living.LivingHurtEvent; +import net.minecraftforge.event.entity.player.PlayerXpEvent.XpChange; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +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.CallbackInfoReturnable; + +@Mixin(LocalPlayer.class) +public class LocalPlayerMixin { + private static Logger LOGGER = LogManager.getLogger(); + +/* @Inject(method = "heal", at = @At("HEAD"), cancellable = true) + public void onHeal(float amount, CallbackInfo ci) { + if (amount > 0) { + LivingHealEvent event = new LivingHealEvent((LocalPlayer) (Object) this, amount); + ClientEventHandler.onHeal(event); + } + }*/ + + @Inject(method = "hurt", at = @At("HEAD"), cancellable = true) + public void onHurt(DamageSource source, float amount, CallbackInfoReturnable cir) { + if (Minecraft.getInstance().isLocalServer()) { + return; + } + + if (amount > 0) { + LivingHurtEvent event = new LivingHurtEvent((LocalPlayer) (Object) this, source, amount); + ClientEventHandler.onHurt(event); + } + } + + @Inject(method = "setExperienceValues", at = @At("HEAD"), cancellable = true) + public void onSetExperienceValues(float xpProgress, int totalXp, int experienceLevel, CallbackInfo ci) { + if (Minecraft.getInstance().isLocalServer()) { + return; + } + + int amount = totalXp - ((LocalPlayer) (Object) this).totalExperience; + if (amount > 0) { + XpChange event = new XpChange((LocalPlayer) (Object) this, amount); + ClientEventHandler.onXpChange(event); + } + } +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/mixin/MultiPlayerGameModeMixin.java b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/mixin/MultiPlayerGameModeMixin.java new file mode 100644 index 0000000..a50385d --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/java/com/therainbowville/minegasm/mixin/MultiPlayerGameModeMixin.java @@ -0,0 +1,63 @@ +package com.therainbowville.minegasm.mixin; + +import com.therainbowville.minegasm.client.ClientEventHandler; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.core.BlockPos; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraftforge.event.level.BlockEvent.BreakEvent; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +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.CallbackInfoReturnable; + +@Mixin(MultiPlayerGameMode.class) +public class MultiPlayerGameModeMixin { + private static Logger LOGGER = LogManager.getLogger(); + + boolean placedBlock; + + @Inject(method = "destroyBlock", at = @At("HEAD"), cancellable = true) + public void onDestroyBlock(BlockPos blockPos, CallbackInfoReturnable cir) { + if (Minecraft.getInstance().isLocalServer()) { + return; + } + + Player player = Minecraft.getInstance().player; + if (player != null) { + BreakEvent event = new BreakEvent(player.level(), blockPos, player.level().getBlockState(blockPos), player); + ClientEventHandler.onBreak(event); + } + } + + @Inject(method = "performUseItemOn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;useOn(Lnet/minecraft/world/item/context/UseOnContext;)Lnet/minecraft/world/InteractionResult;"), cancellable = true) + public void onUseItemOn(LocalPlayer player, InteractionHand hand, BlockHitResult result, CallbackInfoReturnable cir) { + if (Minecraft.getInstance().isLocalServer()) { + return; + } + + if (player.getItemInHand(hand).getItem() instanceof BlockItem) { + this.placedBlock = true; + } + + } + + @Inject(method = "performUseItemOn", at = @At("RETURN"), cancellable = true) + public void onUseItemOnReturn(LocalPlayer player, InteractionHand hand, BlockHitResult result, CallbackInfoReturnable cir) { + if (Minecraft.getInstance().isLocalServer() || !this.placedBlock) { + return; + } + + if (cir.getReturnValue() == InteractionResult.SUCCESS) { + ClientEventHandler.onPlace(); + } + this.placedBlock = false; + } +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/resources/META-INF/mods.toml b/forge/fg-6.0/1.20.6/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..daa7061 --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/resources/META-INF/mods.toml @@ -0,0 +1,74 @@ +# This is an example mods.toml file. It contains the data relating to the loading mods. +# There are several mandatory fields (#mandatory), and many more that are optional (#optional). +# The overall format is standard TOML format, v0.5.0. +# Note that there are a couple of TOML lists in this file. +# Find more information on toml format here: https://github.com/toml-lang/toml +# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml +modLoader = "javafml" #mandatory +# A version range to match for said mod loader - for regular FML @Mod it will be the forge version +loaderVersion = "${loader_version_range}" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. +# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. +# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. +license = "${mod_license}" +# A URL to refer people to when problems occur with this mod +#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional +issueTrackerURL = "${mod_issue_tracker_url}" +# A list of mods - how many allowed here is determined by the individual mod loader +[[mods]] #mandatory +# The modid of the mod +modId = "${mod_id}" #mandatory +# The version number of the mod +version = "${mod_version}" #mandatory +# A display name for the mod +displayName = "${mod_name}" #mandatory +# A URL to query for updates for this mod. See the JSON update specification https://docs.minecraftforge.net/en/latest/misc/updatechecker/ +#updateJSONURL="https://change.me.example.invalid/updates.json" #optional +updateJSONURL = "${mod_update_json_url}" +# A URL for the "homepage" for this mod, displayed in the mod UI +#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional +displayURL = "${mod_display_url}" +# A file name (in the root of the mod JAR) containing a logo for display +#logoFile="examplemod.png" #optional +logoFile = "${mod_logo_file}" +# A text field displayed in the mod UI +#credits="" #optional +# A text field displayed in the mod UI +authors = "${mod_authors}" #optional +# Display Test controls the display for your mod in the server connection screen +# MATCH_VERSION means that your mod will cause a red X if the versions on client and server differ. This is the default behaviour and should be what you choose if you have server and client elements to your mod. +# IGNORE_SERVER_VERSION means that your mod will not cause a red X if it's present on the server but not on the client. This is what you should use if you're a server only mod. +# IGNORE_ALL_VERSION means that your mod will not cause a red X if it's present on the client or the server. This is a special case and should only be used if your mod has no server component. +# NONE means that no display test is set on your mod. You need to do this yourself, see IExtensionPoint.DisplayTest for more information. You can define any scheme you wish with this value. +# IMPORTANT NOTE: this is NOT an instruction as to which environments (CLIENT or DEDICATED SERVER) your mod loads on. Your mod should load (and maybe do nothing!) whereever it finds itself. +#displayTest="MATCH_VERSION" # MATCH_VERSION is the default if nothing is specified (#optional) + +# The description text for the mod (multi line!) (#mandatory) +description = '''${mod_description}''' +# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. +[[dependencies.${ mod_id }]] #optional +# the modid of the dependency +modId = "forge" #mandatory +# Does this dependency have to exist - if not, ordering below must be specified +mandatory = true #mandatory +# The version range of the dependency +versionRange = "${forge_version_range}" #mandatory +# An ordering relationship for the dependency - BEFORE or AFTER required if the dependency is not mandatory +# BEFORE - This mod is loaded BEFORE the dependency +# AFTER - This mod is loaded AFTER the dependency +ordering = "NONE" +# Side this dependency is applied on - BOTH, CLIENT, or SERVER +side = "BOTH" +# Here's another dependency +[[dependencies.${ mod_id }]] +modId = "minecraft" +mandatory = true +# This version range declares a minimum of the current minecraft version up to but not including the next major version +versionRange = "${minecraft_version_range}" +ordering = "NONE" +side = "BOTH" + +# Features are specific properties of the game environment, that you may want to declare you require. This example declares +# that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't +# stop your mod loading on the server for example. +#[features.${mod_id}] +#openGLVersion="[3.2,)" \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/resources/assets/minegasm/textures/logo.png b/forge/fg-6.0/1.20.6/src/main/resources/assets/minegasm/textures/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..63eaa64199223d242b187312c62be06e959e4875 GIT binary patch literal 2752 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%0A@w{fBIQzjX9^1am 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 literal 0 HcmV?d00001 diff --git a/forge/fg-6.0/1.20.6/src/main/resources/mixins.minegasm.json b/forge/fg-6.0/1.20.6/src/main/resources/mixins.minegasm.json new file mode 100644 index 0000000..7c64560 --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/resources/mixins.minegasm.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "com.therainbowville.minegasm.mixin", + "compatibilityLevel": "JAVA_8", + "refmap": "mixins.minegasm.refmap.json", + "mixins": [ + "ClientAdvancementsMixin", + "LocalPlayerMixin", + "MultiPlayerGameModeMixin" + ] +} \ No newline at end of file diff --git a/forge/fg-6.0/1.20.6/src/main/resources/pack.mcmeta b/forge/fg-6.0/1.20.6/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..eca79ae --- /dev/null +++ b/forge/fg-6.0/1.20.6/src/main/resources/pack.mcmeta @@ -0,0 +1,8 @@ +{ + "pack": { + "description": { + "text": "${mod_id} resources" + }, + "pack_format": 15 + } +} \ No newline at end of file