diff --git a/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/client/ClientEventHandler.java b/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/client/ClientEventHandler.java index dfa05e8..ce91413 100644 --- a/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/client/ClientEventHandler.java +++ b/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/client/ClientEventHandler.java @@ -3,17 +3,20 @@ import com.therainbowville.minegasm.common.Minegasm; import com.therainbowville.minegasm.config.ClientConfig; import com.therainbowville.minegasm.config.MinegasmConfig; + +import net.minecraft.advancements.FrameType; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; +import net.minecraft.world.phys.Vec3; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; -import net.minecraft.network.chat.TextComponent; import net.minecraft.world.level.LevelAccessor; +import net.minecraft.network.chat.TextComponent; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.ToolAction; import net.minecraftforge.event.TickEvent; @@ -26,12 +29,13 @@ import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.util.*; import java.util.stream.Collectors; - +import java.lang.Thread; @Mod.EventBusSubscriber(modid = Minegasm.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE) public class ClientEventHandler { @@ -43,7 +47,11 @@ public class ClientEventHandler { private static boolean paused = false; private static UUID playerId = null; - + public static void afterConnect() + { + setState(getStateCounter(), 5); + } + private static void clearState() { tickCounter = -1; clientTickCounter = -1; @@ -93,33 +101,46 @@ private static int getIntensity(String type) { normal.put("attack", 60); normal.put("hurt", 0); normal.put("mine", 80); + normal.put("place", 20); normal.put("xpChange", 100); normal.put("harvest", 0); + 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 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); if (MinegasmConfig.mode.equals(ClientConfig.GameplayMode.MASOCHIST)) { return masochist.get(type); @@ -141,11 +162,13 @@ public static void onPlayerTick(TickEvent.PlayerTickEvent event) { float playerHealth = player.getHealth(); float playerFoodLevel = player.getFoodData().getFoodLevel(); + + onPlayerTickFishing(event); tickCounter = (tickCounter + 1) % (20 * (60 * TICKS_PER_SECOND)); // 20 min day cycle if (tickCounter % TICKS_PER_SECOND == 0) { // every 1 sec - if (uuid.equals(playerId)) { + if (uuid.equals(playerId)) { int stateCounter = getStateCounter(); if (MinegasmConfig.mode.equals(ClientConfig.GameplayMode.MASOCHIST)) { @@ -320,6 +343,27 @@ public static void onBreak(BlockEvent.BreakEvent event) } } + @SubscribeEvent + public static void onPlace(BlockEvent.EntityPlaceEvent event){ + try { + UUID uuid = event.getEntity().getUUID(); + + if (uuid.equals(playerId)) { + BlockState blockState = event.getState(); + Block block = blockState.getBlock(); + @SuppressWarnings("ConstantConditions") float blockHardness = block.defaultBlockState().getDestroySpeed(null, null); + + LOGGER.info("Placing: " + block.toString()); + + int duration = Math.max(1, Math.min(5, Math.toIntExact(Math.round(Math.ceil(Math.log(blockHardness + 0.5)))))); + int intensity = Math.toIntExact(Math.round((getIntensity("place") / 100.0 * (blockHardness / 50.0)) * 100)); + setState(getStateCounter(), duration, intensity, true); + } + } catch (Throwable e) { + LOGGER.throwing(e); + } + } + @SubscribeEvent public static void onItemPickup(EntityItemPickupEvent event) { @@ -353,6 +397,51 @@ public static void onXpChange(PlayerXpEvent.XpChange event) } } + public static void onPlayerTickFishing(TickEvent.PlayerTickEvent event) { + try { + Player player = event.player; + + // Vibrate on fish hook + 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) + { + setState(getStateCounter(), 1, getIntensity("fishing"), true); + LOGGER.info("Fishing!"); + } + } + } catch (Throwable e) { + LOGGER.throwing(e); + } + } + + @SubscribeEvent + public static void onAdvancementEvent(AdvancementEvent event) + { + + try { + Player player = event.getPlayer();; + UUID uuid = player.getGameProfile().getId(); + + if (uuid.equals(playerId)) { + LOGGER.info("Advancement Event: " + event); + FrameType type = event.getAdvancement().getDisplay().getFrame(); + int duration = switch (type) { + case TASK -> 5; + case GOAL -> 7; + case CHALLENGE -> 10; + }; + setState(getStateCounter(), duration, getIntensity("advancement"), true); + } + } catch (Throwable e) { + LOGGER.throwing(e); + } + } + @SubscribeEvent public static void onRespawn(PlayerEvent.PlayerRespawnEvent event) { @@ -398,24 +487,27 @@ public static void onWorldEntry(EntityJoinWorldEvent event) { if (entity instanceof Player) { LOGGER.info("Player respawn world: " + entity.toString()); - - try { + + 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()) { setState(getStateCounter(), 5); - player.displayClientMessage(new TextComponent(String.format("Connected to " + ChatFormatting.GREEN + "%s" + ChatFormatting.RESET + " [%d]", ToyController.getDeviceName(), ToyController.getDeviceId())), true); - } else { + if (!MinegasmConfig.stealth){ + player.displayClientMessage(new TextComponent(String.format("Connected to " + ChatFormatting.GREEN + "%s" + ChatFormatting.RESET + " [%d]", ToyController.getDeviceName(), ToyController.getDeviceId())), true); + } + } else if (!MinegasmConfig.stealth){ player.displayClientMessage(new TextComponent(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.18.2/src/main/java/com/therainbowville/minegasm/client/ToyController.java b/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/client/ToyController.java index 2e6f091..4577128 100644 --- a/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/client/ToyController.java +++ b/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/client/ToyController.java @@ -10,10 +10,16 @@ import java.util.List; import java.util.Objects; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.Executors; public class ToyController { private static final Logger LOGGER = LogManager.getLogger(); - private static final ButtplugClientWSClient client = new ButtplugClientWSClient("Minegasm"); + private static ButtplugClientWSClient client = new ButtplugClientWSClient("Minegasm"); private static ButtplugClientDevice device = null; private static boolean shutDownHookAdded = false; public static String lastErrorMessage = ""; @@ -24,9 +30,28 @@ public static boolean connectDevice() { try { device = null; client.disconnect(); + LOGGER.info("URL: " + MinegasmConfig.serverUrl); - client.connect(new URI(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); diff --git a/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/common/Minegasm.java b/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/common/Minegasm.java index 82e8cf7..a0f7955 100644 --- a/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/common/Minegasm.java +++ b/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/common/Minegasm.java @@ -1,13 +1,16 @@ package com.therainbowville.minegasm.common; -import com.therainbowville.minegasm.config.ConfigHolder; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.config.ModConfig; +import net.minecraftforge.client.ConfigGuiHandler; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import com.therainbowville.minegasm.config.ConfigHolder; +import com.therainbowville.minegasm.config.ConfigHelper; + @Mod(Minegasm.MOD_ID) public class Minegasm { @@ -21,5 +24,7 @@ public Minegasm() { context.registerConfig(ModConfig.Type.SERVER, ConfigHolder.SERVER_SPEC); MinecraftForge.EVENT_BUS.register(this); + + ModLoadingContext.get().registerExtensionPoint(ConfigGuiHandler.ConfigGuiFactory.class, ConfigHelper::createConfigGuiFactory); } } diff --git a/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/ClientConfig.java b/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/ClientConfig.java index 7bc1bc2..b8f4827 100644 --- a/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/ClientConfig.java +++ b/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/ClientConfig.java @@ -1,9 +1,11 @@ package com.therainbowville.minegasm.config; import com.therainbowville.minegasm.common.Minegasm; -import net.minecraft.client.Minecraft; import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.fml.mclanguageprovider.MinecraftModLanguageProvider; +import net.minecraftforge.fml.ModLoadingContext; +import net.minecraftforge.fml.config.ModConfig; +import net.minecraftforge.common.ForgeConfigSpec.IntValue; import java.util.Objects; @@ -12,19 +14,38 @@ public final class ClientConfig { final ForgeConfigSpec.BooleanValue vibrate; final ForgeConfigSpec.EnumValue mode; + final ForgeConfigSpec.BooleanValue stealth; 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; + + 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; ClientConfig(final ForgeConfigSpec.Builder builder) { builder.push("buttplug"); serverUrl = builder .translation(Minegasm.MOD_ID + ".config.serverUrl") - .define("serverUrl", "ws://localhost:12345/buttplug"); + .define("serverUrl", DEFAULT_SERVER_URL); builder.pop(); @@ -32,46 +53,83 @@ public final class ClientConfig { vibrate = builder .translation(Minegasm.MOD_ID + ".config.vibrate") - .define("vibrate", true); + .define("vibrate", DEFAULT_VIBRATE); mode = builder .translation(Minegasm.MOD_ID + ".config.mode") - .defineEnum("mode", GameplayMode.NORMAL); + .defineEnum("mode", DEFAULT_MODE); + stealth = builder + .translation(Minegasm.MOD_ID + ".config.stealth") + .define("stealth", DEFAULT_STEALTH); builder.push("intensity"); attackIntensity = builder .comment("Vibration intensity when attacking on custom mode") .translation(Minegasm.MOD_ID + ".config.intensity.attack") - .defineInRange("attackIntensity", 60, 0, 100); + .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", 0, 0, 100); + .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", 80, 0, 100); + .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", 100, 0, 100); + .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", 0, 0, 100); + .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", 0, 0, 100); + .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"), @@ -89,4 +147,6 @@ public String getTranslateKey() { return this.translateKey; } } -} \ No newline at end of file + + +} diff --git a/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/ConfigHelper.java b/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/ConfigHelper.java index 4441fb2..7e07612 100644 --- a/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/ConfigHelper.java +++ b/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/ConfigHelper.java @@ -1,20 +1,72 @@ package com.therainbowville.minegasm.config; +import net.minecraftforge.client.ConfigGuiHandler; +import net.minecraftforge.common.ForgeConfigSpec; + +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.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(); + + // Needs to sleep inbetween, or it can get confused and reset the config + + ConfigHolder.CLIENT.serverUrl.set(buffer.serverUrl); + Thread.sleep(5); + ConfigHolder.CLIENT.vibrate.set(buffer.vibrate); + Thread.sleep(5); + ConfigHolder.CLIENT.mode.set(buffer.mode); + Thread.sleep(5); + ConfigHolder.CLIENT.stealth.set(buffer.stealth); + Thread.sleep(5); + ConfigHolder.CLIENT.attackIntensity.set(buffer.attackIntensity); + Thread.sleep(5); + ConfigHolder.CLIENT.hurtIntensity.set(buffer.hurtIntensity); + Thread.sleep(5); + ConfigHolder.CLIENT.mineIntensity.set(buffer.mineIntensity); + Thread.sleep(5); + ConfigHolder.CLIENT.placeIntensity.set(buffer.placeIntensity); + Thread.sleep(5); + ConfigHolder.CLIENT.xpChangeIntensity.set(buffer.xpChangeIntensity); + Thread.sleep(5); + ConfigHolder.CLIENT.fishingIntensity.set(buffer.fishingIntensity); + Thread.sleep(5); + ConfigHolder.CLIENT.harvestIntensity.set(buffer.harvestIntensity); + Thread.sleep(5); + ConfigHolder.CLIENT.vitalityIntensity.set(buffer.vitalityIntensity); + Thread.sleep(5); + ConfigHolder.CLIENT.advancementIntensity.set(buffer.advancementIntensity); + } catch (Throwable e) + {} + } + + public static ConfigGuiHandler.ConfigGuiFactory createConfigGuiFactory() { + return new ConfigGuiHandler.ConfigGuiFactory((minecraft, screen) -> new ConfigScreen(screen)); + } -} \ No newline at end of file +} diff --git a/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/ConfigScreen.java b/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/ConfigScreen.java new file mode 100644 index 0000000..0694b25 --- /dev/null +++ b/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/ConfigScreen.java @@ -0,0 +1,324 @@ +package com.therainbowville.minegasm.config; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.systems.RenderSystem; +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.components.AbstractWidget; +import net.minecraftforge.client.gui.widget.ForgeSlider; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.narration.NarrationElementOutput; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.chat.Component; +import net.minecraftforge.event.TickEvent; +import net.minecraft.client.Minecraft; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +import com.therainbowville.minegasm.common.Minegasm; +import com.therainbowville.minegasm.client.ToyController; +import com.therainbowville.minegasm.client.ClientEventHandler; +import com.therainbowville.minegasm.config.ClientConfig; +import com.therainbowville.minegasm.config.MinegasmConfig; + +import java.lang.reflect.Field; +import java.lang.Thread; +import java.util.ArrayList; +import java.util.function.IntConsumer; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class ConfigScreen extends Screen { + private static final Logger LOGGER = LogManager.getLogger(); + private final Screen previous; + private boolean pauseMenu; + EditBox wsHost = null; + + public ConfigScreen(Screen previous) { + super(new TextComponent("Minegasm Config")); + this.previous = previous; + pauseMenu = false; + } + + public ConfigScreen(Screen previous, boolean pause) { + super(new TextComponent("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( + this.width / 2 - 155, this.height / 6 + 25, 150, 20, + new TextComponent("Reset Server Url"), button -> { + ConfigHolder.getClientInstance().resetConfigUrl(); + MinegasmConfig.serverUrl = ConfigHolder.getClientInstance().serverUrl.get(); + wsHost.setValue(MinegasmConfig.serverUrl); + } + )); + + PlainTextLabel connectResponse = new PlainTextLabel(this.width / 2 - 155, this.height / 6 + 50, 310, 15, new TextComponent("" + ChatFormatting.GREEN)); + + this.addRenderableWidget(connectResponse); + + Button reconnectButton = new Button( + this.width / 2 + 5, this.height / 6 + 25, 150, 20, + new TextComponent("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(); + } + ); + this.addRenderableWidget(reconnectButton); + + reconnectButton.active = pauseMenu; + + this.addRenderableWidget(CycleButton.onOffBuilder(MinegasmConfig.vibrate) + .create(this.width / 2 - 155, this.height / 6 + 25 * 3, 150, 20, + new TextComponent("Vibration"), (button, value) -> MinegasmConfig.vibrate = value)); + + this.addRenderableWidget(CycleButton.onOffBuilder(MinegasmConfig.stealth) + .create(this.width / 2 + 5, this.height / 6 + 25 * 3, 150, 20, + new TextComponent("Stealth"), (button, value) -> MinegasmConfig.stealth = value)); + + this.addRenderableWidget( + CycleButton.builder((ClientConfig.GameplayMode mode) -> + new TextComponent(switch (mode) { + case NORMAL -> "Normal"; + case MASOCHIST -> "Masochist"; + case HEDONIST -> "Hedonist"; + case CUSTOM -> "Custom"; + })) + .withValues(ClientConfig.GameplayMode.NORMAL, ClientConfig.GameplayMode.MASOCHIST, ClientConfig.GameplayMode.HEDONIST, ClientConfig.GameplayMode.CUSTOM) + .withInitialValue(MinegasmConfig.mode) + .create(this.width / 2 - 155, this.height / 6 + 25 * 4, 150, 20, + new TextComponent("Mode"), (button, value) -> MinegasmConfig.mode = value) + ); + + this.addRenderableWidget(new Button( + this.width / 2 + 5, this.height / 6 + 25 * 4, 150, 20, + new TextComponent("Edit Custom Settings"), button -> minecraft.setScreen(new CustomModeConfigScreen(this, pauseMenu)))); + + this.addRenderableWidget(new Button( + this.width / 2 - 100, this.height - 27, 200, 20, + CommonComponents.GUI_DONE, button -> this.onClose())); + + + } + + @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(PoseStack poseStack, int i, int j, float f) { + if (pauseMenu) + this.renderBackground(poseStack); + else + this.renderDirtBackground(0); + drawCenteredString(poseStack, this.font, this.title, this.width / 2, 15, 0xFFFFFF); + super.render(poseStack, i, j, f); + } + + class PlainTextLabel extends AbstractWidget { + + private static TextComponent text = new TextComponent(""); + private int x; + private int y; + + public PlainTextLabel(int x, int y, int width, int height, TextComponent text) { + super(x, y, width, height, text); + this.x = x; + this.y = y; + } + + public static void setValue(String value) + { + text = new TextComponent(value); + } + + @Override + public void updateNarration(NarrationElementOutput output) { + defaultButtonNarrationText(output); + } + + @Override + public void render(PoseStack poseStack, 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); + drawCenteredString(poseStack, 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(new TextComponent("Minegasm Custom Config")); + this.previous = previous; + pauseMenu = false; + } + + public CustomModeConfigScreen(Screen previous, boolean pause) { + super(new TextComponent("Minegasm Custom Config")); + this.previous = previous; + pauseMenu = pause; + } + + @Override + protected void init() { + try{ + this.addRenderableWidget(new Button( + this.width / 2 + 5, this.height - 27, 150, 20, + CommonComponents.GUI_DONE, button -> this.onClose())); + + 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( + this.width / 2 - 155, this.height - 27, 150, 20, + new TextComponent("Reset Values"), button -> { + ConfigHolder.getClientInstance().resetConfigCustom(); + IntensitiySliderBar.refreshAllValues(); + } + )); + + + } catch (Throwable e) { + LOGGER.throwing(e); + } + } + + @Override + public void onClose() { + IntensitiySliderBar.sliders.clear(); + this.minecraft.setScreen(previous); + } + + @Override + public void render(PoseStack poseStack, int i, int j, float f) { + if (pauseMenu) + this.renderBackground(poseStack); + else + this.renderDirtBackground(0); + drawCenteredString(poseStack, this.font, this.title, this.width / 2, 15, 0xFFFFFF); + super.render(poseStack, 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 + new TextComponent(prefix), // Prefix + new TextComponent(""), // 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); + } + + @Override + public void applyValue() + { +// LOGGER.info("applyValue"); + //responder.accept(this.getValueInt()); + try { + fieldReference.set(null, this.getValueInt()); + } catch (Throwable e) { + LOGGER.throwing(e); + } + } + + public static void refreshAllValues() + { + for (IntensitiySliderBar slider : sliders) + { + slider.refreshValue(); + } + } + + private void refreshValue() + { + try { + this.setValue(fieldReference.getInt(null)); + } catch (Throwable e) { + LOGGER.throwing(e); + } + } + + } +} diff --git a/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/MinegasmConfig.java b/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/MinegasmConfig.java index 52965d5..640b2d4 100644 --- a/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/MinegasmConfig.java +++ b/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/MinegasmConfig.java @@ -18,13 +18,17 @@ public class MinegasmConfig { public static String serverUrl; public static boolean vibrate; - public static Enum mode = ClientConfig.GameplayMode.NORMAL; + public static ClientConfig.GameplayMode mode = ClientConfig.GameplayMode.NORMAL; + public static boolean stealth; 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 @@ -41,4 +45,45 @@ public static void onModConfigEvent(final ModConfigEvent event) { 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 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.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; + } } diff --git a/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/PauseMenuButton.java b/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/PauseMenuButton.java new file mode 100644 index 0000000..2f25404 --- /dev/null +++ b/forge/fg-6.0/1.18.2/src/main/java/com/therainbowville/minegasm/config/PauseMenuButton.java @@ -0,0 +1,130 @@ +package com.therainbowville.minegasm.config; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiComponent; +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.Screen; +import net.minecraft.client.gui.screens.PauseScreen; +import net.minecraft.client.resources.language.I18n; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.resources.ResourceLocation; + +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.event.ScreenEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import org.apache.commons.lang3.mutable.MutableObject; + +import com.therainbowville.minegasm.common.Minegasm; +import com.therainbowville.minegasm.config.ClientConfig; +import com.therainbowville.minegasm.config.MinegasmConfig; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +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(x, y, 20, 20, new TextComponent(""), PauseMenuButton::clicked); + xPos = x; + yPos = y; + } + + @Override + public void renderBg(PoseStack mstack, Minecraft mc, int mouseX, int mouseY) { + mstack.pushPose(); + mstack.translate(xPos + width / 2 - (64 * 0.25f) / 2, yPos + height / 2 - (64 * 0.25f) / 2, 0); + mstack.scale(0.25f, 0.25f, 1); + RenderSystem.setShaderTexture(0, LOGO); + GuiComponent.blit(mstack, 0, 0, 0, 0, 0, 64, 64, 64, 64); + mstack.popPose(); + } + + public static void clicked(Button button) + { + Minecraft.getInstance().setScreen(new ConfigScreen(Minecraft.getInstance().screen, true)); + } + + 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.InitScreenEvent 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.x + offsetX_ + (onLeft ? -20 : w.getWidth()), w.y))); + if (toAdd.getValue() != null) + event.addListener(toAdd.getValue()); + } + } + } +} diff --git a/forge/fg-6.0/1.18.2/src/main/resources/assets/minegasm/textures/logo.png b/forge/fg-6.0/1.18.2/src/main/resources/assets/minegasm/textures/logo.png new file mode 100644 index 0000000..63eaa64 Binary files /dev/null and b/forge/fg-6.0/1.18.2/src/main/resources/assets/minegasm/textures/logo.png differ