From 05e8ba9cb3bae1dd1ce72b72ae7cdb7490adb25e Mon Sep 17 00:00:00 2001 From: Hydroxycobalamin <54799651+Hydroxycobalamin@users.noreply.github.com> Date: Sun, 2 Oct 2022 21:46:33 +0200 Subject: [PATCH] Add paper-only WorldGameRuleChangeEvent (#2383) * add paper only WorldGameRuleChangeEvent * fix typo in name * add meta determine option * fix world matcher * add switch, improve meta, minor cleanup --- .../denizen/paper/PaperModule.java | 1 + .../WorldGameRuleChangeScriptEvent.java | 144 ++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 paper/src/main/java/com/denizenscript/denizen/paper/events/WorldGameRuleChangeScriptEvent.java diff --git a/paper/src/main/java/com/denizenscript/denizen/paper/PaperModule.java b/paper/src/main/java/com/denizenscript/denizen/paper/PaperModule.java index 4a5c44c1e8..bf09fd88b8 100644 --- a/paper/src/main/java/com/denizenscript/denizen/paper/PaperModule.java +++ b/paper/src/main/java/com/denizenscript/denizen/paper/PaperModule.java @@ -55,6 +55,7 @@ public static void init() { ScriptEvent.registerScriptEvent(ServerResourcesReloadedScriptEvent.class); ScriptEvent.registerScriptEvent(TNTPrimesScriptEvent.class); ScriptEvent.registerScriptEvent(UnknownCommandScriptEvent.class); + ScriptEvent.registerScriptEvent(WorldGameRuleChangeScriptEvent.class); // Properties PropertyParser.registerProperty(EntityArmsRaised.class, EntityTag.class); diff --git a/paper/src/main/java/com/denizenscript/denizen/paper/events/WorldGameRuleChangeScriptEvent.java b/paper/src/main/java/com/denizenscript/denizen/paper/events/WorldGameRuleChangeScriptEvent.java new file mode 100644 index 0000000000..e7aecab35e --- /dev/null +++ b/paper/src/main/java/com/denizenscript/denizen/paper/events/WorldGameRuleChangeScriptEvent.java @@ -0,0 +1,144 @@ +package com.denizenscript.denizen.paper.events; + + +import com.denizenscript.denizen.events.BukkitScriptEvent; +import com.denizenscript.denizen.objects.EntityTag; +import com.denizenscript.denizen.objects.LocationTag; +import com.denizenscript.denizen.objects.PlayerTag; +import com.denizenscript.denizen.objects.WorldTag; +import com.denizenscript.denizen.utilities.implementation.BukkitScriptEntryData; +import com.denizenscript.denizencore.objects.ObjectTag; +import com.denizenscript.denizencore.objects.core.ElementTag; +import com.denizenscript.denizencore.scripts.ScriptEntryData; +import com.denizenscript.denizencore.utilities.CoreUtilities; +import io.papermc.paper.event.world.WorldGameRuleChangeEvent; +import org.bukkit.command.BlockCommandSender; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.entity.minecart.CommandMinecart; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + + +public class WorldGameRuleChangeScriptEvent extends BukkitScriptEvent implements Listener { + + // <--[event] + // @Events + // gamerule changes (in ) + // + // @Plugin Paper + // + // @Group Paper + // + // @Triggers when a gamerule changes. + // + // @Switch gamerule: to only process the event if the gamerule matches a specific gamerule. + // + // @Context + // returns the name of the GameRule which was changed. Refer to <@link ur https://jd.papermc.io/paper/1.19/org/bukkit/GameRule.html>. + // returns the new value of the GameRule. + // returns the world where the GameRule is applied. + // returns type of source. Can be: PLAYER, COMMAND_BLOCK, COMMAND_MINECART, SERVER. + // returns the command block's location (if the command was run from one). + // returns the EntityTag of the command minecart (if the command was run from one). + // + // @Determine + // "VALUE:" + ElementTag(Number) or ElementTag(Boolean) to set the value of the GameRule. + // + // @Player when the sender of the command is a player. + // + // --> + + public WorldGameRuleChangeScriptEvent() { + registerCouldMatcher("gamerule changes (in )"); + registerSwitches("gamerule"); + } + + public WorldGameRuleChangeEvent event; + + public WorldTag world; + public CommandSender source; + + @Override + public boolean matches(ScriptPath path) { + if (path.eventArgLowerAt(2).equals("in") && !world.tryAdvancedMatcher(path.eventArgLowerAt(3))) { + return false; + } + if (!runGenericSwitchCheck(path, "gamerule", event.getGameRule().getName())) { + return false; + } + return super.matches(path); + } + + @Override + public ObjectTag getContext(String name) { + switch (name) { + case "gamerule": return new ElementTag(event.getGameRule().getName()); + case "value": return new ElementTag(event.getValue()); + case "source_type": return getSourceType(); + case "command_block_location": return getCommandBlock(); + case "command_minecart": return getCommandMinecart(); + case "world": return world; + } + return super.getContext(name); + } + + @Override + public boolean applyDetermination(ScriptPath path, ObjectTag determinationObj) { + if (determinationObj instanceof ElementTag) { + String lower = CoreUtilities.toLowerCase(determinationObj.toString()); + if (lower.startsWith("value:")) { + ElementTag value = new ElementTag(lower.substring("value:".length())); + if (value.isInt() || value.isBoolean()) { + event.setValue(value.toString()); + return true; + } + } + } + return super.applyDetermination(path, determinationObj); + } + + @Override + public ScriptEntryData getScriptEntryData() { + PlayerTag player = null; + if (source instanceof Player) { + player = new PlayerTag((Player) source); + } + return new BukkitScriptEntryData(player, null); + } + + @EventHandler + public void onGameRuleChanged(WorldGameRuleChangeEvent event) { + this.source = event.getCommandSender(); + this.world = new WorldTag(event.getWorld()); + this.event = event; + fire(event); + } + + public LocationTag getCommandBlock() { + if (source instanceof BlockCommandSender) + return new LocationTag(((BlockCommandSender) source).getBlock().getLocation()); + return null; + } + + public EntityTag getCommandMinecart() { + if (source instanceof CommandMinecart) + return new EntityTag(((CommandMinecart) source)); + return null; + } + + public ElementTag getSourceType() { + if (source instanceof Player) { + return new ElementTag("player"); + } + else if (source instanceof BlockCommandSender) { + return new ElementTag("command_block"); + } + else if (source instanceof CommandMinecart) { + return new ElementTag("command_minecart"); + } + else { + return new ElementTag("server"); + } + } +}