diff --git a/examples/postInit/custom/vanilla.groovy b/examples/postInit/custom/vanilla.groovy index ef005dee7..88e7d2ae5 100644 --- a/examples/postInit/custom/vanilla.groovy +++ b/examples/postInit/custom/vanilla.groovy @@ -260,3 +260,8 @@ eventManager.listen(EnderTeleportEvent) { event -> command.registerCommand('groovy_test') { server, sender, args -> sender.sendMessage('Hello from GroovyScript') } + +// Default GameRules +gameRule.add('doDaylightCycle', 'false') +gameRule.add(['mobGriefing': 'false', 'keepInventory': 'true']) +gameRule.setWarnNewGameRule(true) diff --git a/src/main/java/com/cleanroommc/groovyscript/command/GSCommand.java b/src/main/java/com/cleanroommc/groovyscript/command/GSCommand.java index 92040b404..0b7ef8e80 100644 --- a/src/main/java/com/cleanroommc/groovyscript/command/GSCommand.java +++ b/src/main/java/com/cleanroommc/groovyscript/command/GSCommand.java @@ -4,6 +4,7 @@ import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.compat.mods.jei.JeiPlugin; +import com.cleanroommc.groovyscript.compat.vanilla.VanillaModule; import com.cleanroommc.groovyscript.documentation.Documentation; import com.cleanroommc.groovyscript.helper.StyleConstant; import com.cleanroommc.groovyscript.network.NetworkHandler; @@ -25,6 +26,7 @@ import java.io.File; import java.util.Arrays; import java.util.List; +import java.util.Objects; public class GSCommand extends CommandTreeBase { @@ -58,6 +60,11 @@ public GSCommand() { addSubcommand(new InfoLookingCommand()); addSubcommand(new InfoSelfCommand()); + addSubcommand(new SimpleCommand("applyDefaultGameRules", (server, sender, args) -> { + VanillaModule.gameRule.setDefaultGameRules(Objects.requireNonNull(server.getServer()).getEntityWorld().getGameRules()); + sender.sendMessage(new TextComponentString("Applied the default GameRules to the current world.")); + })); + addSubcommand(new SimpleCommand("wiki", (server, sender, args) -> sender.sendMessage(getTextForUrl("GroovyScript wiki", "Click to open wiki in browser", new TextComponentString("https://cleanroommc.com/groovy-script/"))), "doc", "docs", "documentation")); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/GameRule.java b/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/GameRule.java new file mode 100644 index 000000000..3b02fe6c2 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/GameRule.java @@ -0,0 +1,54 @@ +package com.cleanroommc.groovyscript.compat.vanilla; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IScriptReloadable; +import com.cleanroommc.groovyscript.api.documentation.annotations.MethodDescription; +import com.cleanroommc.groovyscript.registry.NamedRegistry; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import net.minecraft.world.GameRules; + +import java.util.Map; + +public class GameRule extends NamedRegistry implements IScriptReloadable { + + private static final String LOG_MESSAGE = "Could not find an already existing rule with the name {}. This may be intentional! If it is, you can disable this via `gameRule.setWarnNewGameRule(false)`"; + private final Map defaultGameRules = new Object2ObjectOpenHashMap<>(); + private boolean warnNewGameRule; + + @GroovyBlacklist + public void setDefaultGameRules(GameRules gameRules) { + defaultGameRules.forEach((k, v) -> { + if (warnNewGameRule && !gameRules.hasRule(k)) GroovyLog.get().warn(LOG_MESSAGE, k); + GroovyLog.get().debug("Setting the GameRule '{}' to the value '{}'", k, v); + gameRules.setOrCreateGameRule(k, v); + }); + GroovyLog.get().debug("Set or created {} GameRules", defaultGameRules.size()); + } + + @MethodDescription + public void add(String gameRule, String value) { + defaultGameRules.put(gameRule, value); + } + + @MethodDescription + public void add(Map gameRules) { + defaultGameRules.putAll(gameRules); + } + + @MethodDescription + public void setWarnNewGameRule(boolean value) { + warnNewGameRule = value; + } + + @Override + @GroovyBlacklist + public void onReload() { + defaultGameRules.clear(); + warnNewGameRule = false; + } + + @Override + @GroovyBlacklist + public void afterScriptLoad() {} +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/VanillaModule.java b/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/VanillaModule.java index a698d2029..74ee1c544 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/VanillaModule.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/vanilla/VanillaModule.java @@ -27,6 +27,7 @@ public class VanillaModule extends GroovyPropertyContainer implements IScriptRel public static final Rarity rarity = new Rarity(); public static final InWorldCrafting inWorldCrafting = new InWorldCrafting(); public static final Command command = new Command(); + public static final GameRule gameRule = new GameRule(); public static void initializeBinding() { GroovyScript.getSandbox().registerBinding(crafting); @@ -38,6 +39,7 @@ public static void initializeBinding() { GroovyScript.getSandbox().registerBinding(rarity); GroovyScript.getSandbox().registerBinding(inWorldCrafting); GroovyScript.getSandbox().registerBinding(command); + GroovyScript.getSandbox().registerBinding(gameRule); ExpansionHelper.mixinClass(ItemStack.class, ItemStackExpansion.class); ExpansionHelper.mixinClass(ICommandSender.class, CommandSenderExpansion.class); @@ -54,6 +56,7 @@ public void onReload() { player.onReload(); inWorldCrafting.onReload(); command.onReload(); + gameRule.onReload(); } @Override diff --git a/src/main/java/com/cleanroommc/groovyscript/event/EventHandler.java b/src/main/java/com/cleanroommc/groovyscript/event/EventHandler.java index 99f81c5b4..43d91ccdd 100644 --- a/src/main/java/com/cleanroommc/groovyscript/event/EventHandler.java +++ b/src/main/java/com/cleanroommc/groovyscript/event/EventHandler.java @@ -37,6 +37,7 @@ import net.minecraftforge.common.config.ConfigManager; import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.world.ExplosionEvent; +import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.client.event.ConfigChangedEvent; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.eventhandler.EventPriority; @@ -78,6 +79,11 @@ public static void registerTextures(TextureStitchEvent.Post event) { GroovyFluid.initTextures(event.getMap()); } + @SubscribeEvent + public static void createSpawnPosition(WorldEvent.CreateSpawnPosition event) { + VanillaModule.gameRule.setDefaultGameRules(event.getWorld().getGameRules()); + } + @SubscribeEvent public static void playerLogin(PlayerEvent.PlayerLoggedInEvent event) { // clear all errors and post diff --git a/src/main/java/com/cleanroommc/groovyscript/sandbox/SandboxData.java b/src/main/java/com/cleanroommc/groovyscript/sandbox/SandboxData.java index 443b47f0d..3f863ed32 100644 --- a/src/main/java/com/cleanroommc/groovyscript/sandbox/SandboxData.java +++ b/src/main/java/com/cleanroommc/groovyscript/sandbox/SandboxData.java @@ -51,9 +51,9 @@ public static void initialize(File minecraftHome, Logger log) { cachePath = new File(SandboxData.minecraftHome, "cache" + File.separator + "groovy"); // If we are launching with the environment variable set to use the examples folder, use the examples folder for easy and consistent testing. if (Boolean.parseBoolean(System.getProperty("groovyscript.use_examples_folder"))) { - scriptPath = new File(minecraftHome.getParentFile(), "examples"); + scriptPath = new File(SandboxData.minecraftHome.getParentFile(), "examples"); } else { - scriptPath = new File(minecraftHome, "groovy"); + scriptPath = new File(SandboxData.minecraftHome, "groovy"); } try { scriptPath = scriptPath.getCanonicalFile();