diff --git a/gradle.properties b/gradle.properties index f458dcf..3727104 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,6 +11,6 @@ mod_menu_version=2.0.5 halplibe_version=3.5.2 # Mod -mod_version=1.0.0 -mod_group=turniplabs -mod_name=examplemod +mod_version=1.0 +mod_group=midnadimple +mod_name=gamerulesmenu diff --git a/src/main/java/midnadimple/gamerulesmenu/GamerulesMenu.java b/src/main/java/midnadimple/gamerulesmenu/GamerulesMenu.java new file mode 100644 index 0000000..ff7eb17 --- /dev/null +++ b/src/main/java/midnadimple/gamerulesmenu/GamerulesMenu.java @@ -0,0 +1,42 @@ +package midnadimple.gamerulesmenu; + +import net.fabricmc.api.ModInitializer; +import net.minecraft.core.data.gamerule.GameRule; +import net.minecraft.core.data.gamerule.GameRuleCollection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import turniplabs.halplibe.util.GameStartEntrypoint; +import turniplabs.halplibe.util.RecipeEntrypoint; + +import java.util.ArrayList; +import java.util.List; + + +public class GamerulesMenu implements ModInitializer, GameStartEntrypoint, RecipeEntrypoint { + public static final String MOD_ID = "gamerulesmenu"; + public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + + public static GameRuleCollection gameRuleCollection = new GameRuleCollection(); + public static boolean GAMERULE_COLLECTION_EMPTY = true; + public static final List> gameRuleList = new ArrayList<>(); + + @Override + public void onInitialize() { + LOGGER.info("GamerulesMenu initialized."); + } + + @Override + public void beforeGameStart() { + + } + + @Override + public void afterGameStart() { + + } + + @Override + public void onRecipesReady() { + + } +} diff --git a/src/main/java/midnadimple/gamerulesmenu/gui/NewGamerulesMenu.java b/src/main/java/midnadimple/gamerulesmenu/gui/NewGamerulesMenu.java new file mode 100644 index 0000000..c817871 --- /dev/null +++ b/src/main/java/midnadimple/gamerulesmenu/gui/NewGamerulesMenu.java @@ -0,0 +1,137 @@ +package midnadimple.gamerulesmenu.gui; + +import midnadimple.gamerulesmenu.GamerulesMenu; +import midnadimple.gamerulesmenu.interfaces.IGuiCreateWorld; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.render.Tessellator; +import net.minecraft.core.data.gamerule.GameRule; +import net.minecraft.core.data.gamerule.GameRuleBoolean; +import net.minecraft.core.data.registry.Registries; +import net.minecraft.core.lang.I18n; +import net.minecraft.core.sound.SoundCategory; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; + +import java.util.LinkedHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +public class NewGamerulesMenu extends GuiScreen { + private static final I18n loc = I18n.getInstance(); + private final GuiScreen prevGuiScreen; + private boolean cheatsEnabled; + + private GuiButton cheatsButton; + private final LinkedHashMap gameRuleButtons = new LinkedHashMap<>(); + + private static final int BUTTON_BORDER_OFFSET = 40; + private float scrollFloat = 0.0f; + + public NewGamerulesMenu(GuiScreen guiScreen, boolean cheatsEnabled) { + this.prevGuiScreen = guiScreen; + this.cheatsEnabled = cheatsEnabled; + } + + @Override + public void init() { + controlList.add(this.cheatsButton = new GuiButton(0, this.width / 2 - 100, BUTTON_BORDER_OFFSET, 200, 20, "")); + + int i = 2; + for (GameRule gameRule : Registries.GAME_RULES) { + GuiButton guiButton = new GuiButton(i, this.width - BUTTON_BORDER_OFFSET - 60 , (int) (2 * BUTTON_BORDER_OFFSET + (i - 2) * BUTTON_BORDER_OFFSET * 0.75 - scrollFloat), 50, 20, ""); + controlList.add(guiButton); + + Boolean value; + if (GamerulesMenu.GAMERULE_COLLECTION_EMPTY) { + GamerulesMenu.gameRuleList.add(gameRule); + value = (Boolean) gameRule.getDefaultValue(); + } else { + value = (Boolean) GamerulesMenu.gameRuleCollection.getValue(gameRule); + } + gameRuleButtons.put(guiButton, value); + i++; + } + if (GamerulesMenu.GAMERULE_COLLECTION_EMPTY) { + GamerulesMenu.GAMERULE_COLLECTION_EMPTY = false; + } + + controlList.add(new GuiButton(1, this.width / 2 - 100, this.height - BUTTON_BORDER_OFFSET, 200, 20, loc.translateKey("gamerulesmenu.goback"))); + + updateButtons(); + } + + private void updateButtons() { + cheatsButton.displayString = loc.translateKey("gamerulesmenu.cheats") + " "; + if (cheatsEnabled) { + cheatsButton.displayString += loc.translateKey("gamerulesmenu.on"); + } else { + cheatsButton.displayString += loc.translateKey("gamerulesmenu.off"); + } + + gameRuleButtons.forEach((gameRuleButton, gameRuleButtonValue) -> { + if (gameRuleButtonValue) { + gameRuleButton.displayString = loc.translateKey("gamerulesmenu.on"); + } else { + gameRuleButton.displayString = loc.translateKey("gamerulesmenu.off"); + } + }); + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTick) { + GL11.glDisable(2896); + GL11.glDisable(2912); + Tessellator tessellator = Tessellator.instance; + GL11.glBindTexture(3553, this.mc.renderEngine.getTexture("/gui/titlebackground.png")); + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + float f = 32.0f; + tessellator.startDrawingQuads(); + tessellator.setColorOpaque_I(0x404040); + tessellator.addVertexWithUV(0.0, this.height, 0.0, 0.0, (float)this.height / f); + tessellator.addVertexWithUV(this.width, this.height, 0.0, (float)this.width / f, (float)this.height / f); + tessellator.addVertexWithUV(this.width, 0.0, 0.0, (float)this.width / f, 0.0); + tessellator.addVertexWithUV(0.0, 0.0, 0.0, 0.0, 0.0); + tessellator.draw(); + + // Title + drawStringCentered(fontRenderer, loc.translateKey("gamerulesmenu.title"), width / 2, 20, 0xFFFFFF); + + // Gamerules + scrollFloat = Math.max(scrollFloat + (float) Mouse.getDWheel() / -5.0F, 0); + scrollFloat = Math.min(scrollFloat, 25 * gameRuleButtons.size()); + + AtomicInteger i = new AtomicInteger(); + for (GameRule gameRule : GamerulesMenu.gameRuleList) { + drawStringCentered(fontRenderer, gameRule.getKey(), BUTTON_BORDER_OFFSET + 60, (int) (2.15 * BUTTON_BORDER_OFFSET + i.get() * BUTTON_BORDER_OFFSET * 0.75 - scrollFloat), 0xFFFFFF); + i.getAndIncrement(); + } + + i.set(0); + for (GuiButton gameruleButton : gameRuleButtons.keySet()) { + gameruleButton.yPosition =((int) (2 * BUTTON_BORDER_OFFSET + i.getAndIncrement() * BUTTON_BORDER_OFFSET * 0.75 - scrollFloat)); + } + + super.drawScreen(mouseX, mouseY, partialTick); + updateButtons(); + } + + @Override + protected void buttonReleased(GuiButton button) { + if (button.id == 1) { + ((IGuiCreateWorld) prevGuiScreen).gamerules_menu$setCheatsEnabled(cheatsEnabled); + mc.displayGuiScreen(prevGuiScreen); + } else if (button.id == 0) { + cheatsEnabled = !cheatsEnabled; + updateButtons(); + } else { + for (GuiButton gameruleButton : gameRuleButtons.keySet()) { + if (button.id == gameruleButton.id) { + gameRuleButtons.put(gameruleButton, !gameRuleButtons.get(gameruleButton)); + GamerulesMenu.gameRuleCollection.setValue((GameRuleBoolean) GamerulesMenu.gameRuleList.get(button.id-2), gameRuleButtons.get(gameruleButton)); + updateButtons(); + } + } + } + this.mc.sndManager.playSound("random.click", SoundCategory.GUI_SOUNDS, 1.0F, 1.0F); + } +} diff --git a/src/main/java/midnadimple/gamerulesmenu/interfaces/IGuiCreateWorld.java b/src/main/java/midnadimple/gamerulesmenu/interfaces/IGuiCreateWorld.java new file mode 100644 index 0000000..143d5fe --- /dev/null +++ b/src/main/java/midnadimple/gamerulesmenu/interfaces/IGuiCreateWorld.java @@ -0,0 +1,5 @@ +package midnadimple.gamerulesmenu.interfaces; + +public interface IGuiCreateWorld { + void gamerules_menu$setCheatsEnabled(boolean cheatsEnabled); +} diff --git a/src/main/java/midnadimple/gamerulesmenu/mixin/GuiCreateWorldMixin.java b/src/main/java/midnadimple/gamerulesmenu/mixin/GuiCreateWorldMixin.java new file mode 100644 index 0000000..2357909 --- /dev/null +++ b/src/main/java/midnadimple/gamerulesmenu/mixin/GuiCreateWorldMixin.java @@ -0,0 +1,58 @@ +package midnadimple.gamerulesmenu.mixin; + +import midnadimple.gamerulesmenu.GamerulesMenu; +import midnadimple.gamerulesmenu.gui.NewGamerulesMenu; +import midnadimple.gamerulesmenu.interfaces.IGuiCreateWorld; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.core.player.gamemode.Gamemode; +import org.objectweb.asm.Opcodes; +import net.minecraft.client.gui.GuiCreateWorld; +import net.minecraft.client.gui.GuiScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(value = GuiCreateWorld.class, remap = false) +public class GuiCreateWorldMixin extends GuiScreen implements IGuiCreateWorld { + @Shadow + private boolean cheatsEnabled; + @Shadow + private Gamemode selectedGamemode; + + @Unique + protected Minecraft mc = Minecraft.getMinecraft(Minecraft.class); + + @Redirect(method = "buttonPressed", at = @At(value = "FIELD", target = "Lnet/minecraft/client/gui/GuiCreateWorld;cheatsEnabled:Z", opcode = Opcodes.PUTFIELD)) + private void cheatDisabler(GuiCreateWorld guiCreateWorld, boolean value) { + } + + @Inject(method = "buttonPressed", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiCreateWorld;updateButtons()V")) + private void openGamerulesMenu(GuiButton button, CallbackInfo ci) { + // id 3 = cheats button + if (button.id == 3) { + mc.displayGuiScreen(new NewGamerulesMenu(this, cheatsEnabled)); + } + } + + @Inject(method = "updateButtons", at = @At("HEAD")) + private void creativeCheatsEnabler(CallbackInfo ci) { + if (selectedGamemode == Gamemode.creative) { + cheatsEnabled = true; + } + } + + @Inject(method = "buttonPressed", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/world/save/LevelData;setCheatsEnabled(Z)V")) + private void saveGamerules(GuiButton button, CallbackInfo ci) { + mc.theWorld.getLevelData().getGameRules().setValues(GamerulesMenu.gameRuleCollection); + } + + @Override + public void gamerules_menu$setCheatsEnabled(boolean cheatsEnabled) { + this.cheatsEnabled = cheatsEnabled; + } +} diff --git a/src/main/java/turniplabs/examplemod/ExampleMod.java b/src/main/java/turniplabs/examplemod/ExampleMod.java deleted file mode 100644 index 5f188da..0000000 --- a/src/main/java/turniplabs/examplemod/ExampleMod.java +++ /dev/null @@ -1,33 +0,0 @@ -package turniplabs.examplemod; - -import net.fabricmc.api.ModInitializer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import turniplabs.halplibe.helper.BlockBuilder; -import turniplabs.halplibe.util.GameStartEntrypoint; -import turniplabs.halplibe.util.RecipeEntrypoint; - - -public class ExampleMod implements ModInitializer, GameStartEntrypoint, RecipeEntrypoint { - public static final String MOD_ID = "examplemod"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - @Override - public void onInitialize() { - LOGGER.info("ExampleMod initialized."); - } - - @Override - public void beforeGameStart() { - - } - - @Override - public void afterGameStart() { - - } - - @Override - public void onRecipesReady() { - - } -} diff --git a/src/main/resources/examplemod.mixins.json b/src/main/resources/examplemod.mixins.json deleted file mode 100644 index e98223c..0000000 --- a/src/main/resources/examplemod.mixins.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "turniplabs.examplemod.mixin", - "compatibilityLevel": "JAVA_8", - "mixins": [ - ], - "client": [ - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 898f6fc..07b29bb 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,16 +1,16 @@ { "schemaVersion": 1, - "id": "examplemod", + "id": "gamerulesmenu", "version": "${version}", - "name": "Example Mod", - "description": "This mod aims to help new BTA modders.", + "name": "Gamerules Menu", + "description": "This mod adds a menu for configuring Gamerules when creating worlds", "authors": [ - "Turnip Labs" + "midnadimple" ], "contact": { "homepage": "", - "sources": "" + "sources": "https://github.com/midnadimple/gamesrules-menu" }, "icon": "icon.png", @@ -19,20 +19,20 @@ "environment": "*", "entrypoints": { "main": [ - "turniplabs.examplemod.ExampleMod" + "midnadimple.gamerulesmenu.GamerulesMenu" ], "beforeGameStart": [ - "turniplabs.examplemod.ExampleMod" + "midnadimple.gamerulesmenu.GamerulesMenu" ], "afterGameStart": [ - "turniplabs.examplemod.ExampleMod" + "midnadimple.gamerulesmenu.GamerulesMenu" ], "recipesReady": [ - "turniplabs.examplemod.ExampleMod" + "midnadimple.gamerulesmenu.GamerulesMenu" ] }, "mixins": [ - "examplemod.mixins.json" + "gamerulesmenu.mixins.json" ], "depends": { diff --git a/src/main/resources/gamerulesmenu.mixins.json b/src/main/resources/gamerulesmenu.mixins.json new file mode 100644 index 0000000..916a265 --- /dev/null +++ b/src/main/resources/gamerulesmenu.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "midnadimple.gamerulesmenu.mixin", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "GuiCreateWorldMixin" + ], + "client": [ + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/main/resources/lang/examplemod/en_US.lang b/src/main/resources/lang/examplemod/en_US.lang deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/resources/lang/gamerulesmenu/en_US.lang b/src/main/resources/lang/gamerulesmenu/en_US.lang new file mode 100644 index 0000000..3fef47f --- /dev/null +++ b/src/main/resources/lang/gamerulesmenu/en_US.lang @@ -0,0 +1,6 @@ +gui.create_world.button.cheats=Gamerules... +gamerulesmenu.cheats=Cheats: +gamerulesmenu.on=ON +gamerulesmenu.off=OFF +gamerulesmenu.goback=Go Back +gamerulesmenu.title=Gamerules