diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/WorldTag.java b/plugin/src/main/java/com/denizenscript/denizen/objects/WorldTag.java index fd5ec4eeca..88eb4e0c71 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/WorldTag.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/WorldTag.java @@ -4,6 +4,7 @@ import com.denizenscript.denizen.nms.NMSHandler; import com.denizenscript.denizen.nms.NMSVersion; import com.denizenscript.denizen.nms.abstracts.BiomeNMS; +import com.denizenscript.denizen.utilities.BukkitImplDeprecations; import com.denizenscript.denizen.utilities.flags.WorldFlagHandler; import com.denizenscript.denizencore.flags.AbstractFlagTracker; import com.denizenscript.denizencore.flags.FlaggableObject; @@ -614,8 +615,10 @@ public static void register() { // @returns DurationTag // @description // Returns the relative in-game time of this world as a duration. + // @deprecated Use <@link tag WorldTag.time_duration> instead. // --> if (attribute.startsWith("duration", 2)) { + BukkitImplDeprecations.timeDuration.warn(attribute.context); attribute.fulfill(1); return new DurationTag(object.getWorld().getTime()); } @@ -625,8 +628,10 @@ public static void register() { // @returns DurationTag // @description // Returns the in-game time of this world. + // @deprecated Use <@link tag WorldTag.time_full> instead. // --> else if (attribute.startsWith("full", 2)) { + BukkitImplDeprecations.timeFull.warn(attribute.context); attribute.fulfill(1); return new DurationTag(object.getWorld().getFullTime()); } @@ -636,8 +641,10 @@ else if (attribute.startsWith("full", 2)) { // @returns ElementTag // @description // Returns the time as 'day', 'night', 'dawn', or 'dusk'. + // @deprecated Use <@link tag WorldTag.time_period> instead. // --> else if (attribute.startsWith("period", 2)) { + BukkitImplDeprecations.timePeriod.warn(attribute.context); attribute.fulfill(1); long time = object.getWorld().getTime(); @@ -663,6 +670,52 @@ else if (time >= 12500) { } }); + // <--[tag] + // @attribute + // @returns DurationTag + // @description + // Returns the relative in-game time of this world as a duration. + // --> + registerTag(DurationTag.class, "time_duration", (attribute1, object1) -> { + return new DurationTag(object1.getWorld().getTime()); + }); + + // <--[tag] + // @attribute + // @returns DurationTag + // @description + // Returns the in-game time of this world. + // --> + registerTag(DurationTag.class, "time_full", (attribute, object) -> { + return new DurationTag(object.getWorld().getFullTime()); + }); + + // <--[tag] + // @attribute + // @returns ElementTag + // @description + // Returns the time as 'day', 'night', 'dawn', or 'dusk'. + // --> + registerTag(ElementTag.class, "time_period", (attribute, object) -> {; + long time = object.getWorld().getTime(); + String period; + + if (time >= 23000) { + period = "dawn"; + } + else if (time >= 13500) { + period = "night"; + } + else if (time >= 12500) { + period = "dusk"; + } + else { + period = "day"; + } + + return new ElementTag(period); + }); + // <--[tag] // @attribute // @returns ElementTag(Number) @@ -1104,32 +1157,6 @@ else if (time >= 12500) { }); } - } - - public static ObjectTagProcessor tagProcessor = new ObjectTagProcessor<>(); - - public static void registerTag(Class returnType, String name, TagRunnable.ObjectInterface runnable, String... variants) { - tagProcessor.registerTag(returnType, name, (attribute, object) -> { - if (object.getWorld() == null) { - attribute.echoError("World '" + object.world_name + "' is unloaded, cannot process tag."); - return null; - } - return runnable.run(attribute, object); - }, variants); - } - - @Override - public ObjectTag getObjectAttribute(Attribute attribute) { - return tagProcessor.getObjectAttribute(this, attribute); - } - - public void applyProperty(Mechanism mechanism) { - mechanism.echoError("Cannot apply properties to a world!"); - } - - @Override - public void adjust(Mechanism mechanism) { - // <--[mechanism] // @object WorldTag // @name ambient_spawn_limit @@ -1139,10 +1166,11 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("ambient_spawn_limit") - && mechanism.requireInteger()) { - getWorld().setAmbientSpawnLimit(mechanism.getValue().asInt()); - } + tagProcessor.registerMechanism("ambient_spawn_limit", false, ElementTag.class, (object, mechanism, input) -> { + if (mechanism.requireInteger()) { + object.getWorld().setAmbientSpawnLimit(input.asInt()); + } + }); // <--[mechanism] // @object WorldTag @@ -1153,10 +1181,11 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("animal_spawn_limit") - && mechanism.requireInteger()) { - getWorld().setAnimalSpawnLimit(mechanism.getValue().asInt()); - } + tagProcessor.registerMechanism("animal_spawn_limit", false, ElementTag.class, (object, mechanism, input) -> { + if (mechanism.requireInteger()) { + object.getWorld().setAnimalSpawnLimit(input.asInt()); + } + }); // <--[mechanism] // @object WorldTag @@ -1167,10 +1196,11 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("auto_save") - && mechanism.requireBoolean()) { - getWorld().setAutoSave(mechanism.getValue().asBoolean()); - } + tagProcessor.registerMechanism("auto_save", false, ElementTag.class, (object, mechanism, input) -> { + if (mechanism.requireBoolean()) { + object.getWorld().setAutoSave(input.asBoolean()); + } + }); // <--[mechanism] // @object WorldTag @@ -1182,12 +1212,11 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("difficulty") && mechanism.requireEnum(Difficulty.class)) { - Difficulty diff = mechanism.getValue().asEnum(Difficulty.class); - if (diff != null) { - getWorld().setDifficulty(diff); + tagProcessor.registerMechanism("difficulty", false, ElementTag.class, (object, mechanism, input) -> { + if (mechanism.requireEnum(Difficulty.class)) { + object.getWorld().setDifficulty(input.asEnum(Difficulty.class)); } - } + }); // <--[mechanism] // @object WorldTag @@ -1198,9 +1227,11 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("hardcore") && mechanism.requireBoolean()) { - getWorld().setHardcore(mechanism.getValue().asBoolean()); - } + tagProcessor.registerMechanism("hardcore", false, ElementTag.class, (object, mechanism, input) -> { + if (mechanism.requireBoolean()) { + object.getWorld().setHardcore(input.asBoolean()); + } + }); // <--[mechanism] // @object WorldTag @@ -1209,9 +1240,9 @@ public void adjust(Mechanism mechanism) { // @description // Saves the world to file. // --> - if (mechanism.matches("save")) { - getWorld().save(); - } + tagProcessor.registerMechanism("save", false, (object, mechanism) -> { + object.getWorld().save(); + }); // <--[mechanism] // @object WorldTag @@ -1221,10 +1252,10 @@ public void adjust(Mechanism mechanism) { // Unloads the world from the server without saving chunks, then destroys all data that is part of the world. // Require config setting 'Commands.Delete.Allow file deletion'. // --> - if (mechanism.matches("destroy")) { - File folder = getWorld().getWorldFolder(); - unloadWorldClean(mechanism, false); - if (getWorld() != null) { + tagProcessor.registerMechanism("destroy", false, (object, mechanism) -> { + File folder = object.getWorld().getWorldFolder(); + object.unloadWorldClean(mechanism, false); + if (object.getWorld() != null) { return; } if (!CoreConfiguration.allowFileDeletion) { @@ -1237,8 +1268,7 @@ public void adjust(Mechanism mechanism) { catch (Exception ex) { Debug.echoError(ex); } - return; - } + }); // <--[mechanism] // @object WorldTag @@ -1247,10 +1277,9 @@ public void adjust(Mechanism mechanism) { // @description // Unloads the world from the server without saving chunks. // --> - if (mechanism.matches("force_unload")) { - unloadWorldClean(mechanism, false); - return; - } + tagProcessor.registerMechanism("force_unload", false, (object, mechanism) -> { + object.unloadWorldClean(mechanism, false); + }); // <--[mechanism] // @object WorldTag @@ -1261,9 +1290,11 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("full_time") && mechanism.requireInteger()) { - getWorld().setFullTime(mechanism.getValue().asInt()); - } + tagProcessor.registerMechanism("full_time", false, ElementTag.class, (object, mechanism, input) -> { + if (mechanism.requireInteger()) { + object.getWorld().setFullTime(input.asInt()); + } + }); // <--[mechanism] // @object WorldTag @@ -1274,9 +1305,11 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("keep_spawn") && mechanism.requireBoolean()) { - getWorld().setKeepSpawnInMemory(mechanism.getValue().asBoolean()); - } + tagProcessor.registerMechanism("keep_spawn", false, ElementTag.class, (object, mechanism, input) -> { + if (mechanism.requireBoolean()) { + object.getWorld().setKeepSpawnInMemory(input.asBoolean()); + } + }); // <--[mechanism] // @object WorldTag @@ -1287,9 +1320,11 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("monster_spawn_limit") && mechanism.requireInteger()) { - getWorld().setMonsterSpawnLimit(mechanism.getValue().asInt()); - } + tagProcessor.registerMechanism("monster_spawn_limit", false, ElementTag.class, (object, mechanism, input) -> { + if (mechanism.requireInteger()) { + object.getWorld().setMonsterSpawnLimit(input.asInt()); + } + }); // <--[mechanism] // @object WorldTag @@ -1300,9 +1335,11 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("allow_pvp") && mechanism.requireBoolean()) { - getWorld().setPVP(mechanism.getValue().asBoolean()); - } + tagProcessor.registerMechanism("allow_pvp", false, ElementTag.class, (object, mechanism, input) -> { + if (mechanism.requireBoolean()) { + object.getWorld().setPVP(input.asBoolean()); + } + }); // <--[mechanism] // @object WorldTag @@ -1313,10 +1350,9 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("spawn_location") && mechanism.requireObject(LocationTag.class)) { - LocationTag loc = mechanism.valueAsType(LocationTag.class); - getWorld().setSpawnLocation(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), loc.getYaw()); - } + tagProcessor.registerMechanism("spawn_location", false, LocationTag.class, (object, mechanism, input) -> { + object.getWorld().setSpawnLocation(input.getBlockX(), input.getBlockY(), input.getBlockZ(), input.getYaw()); + }); // <--[mechanism] // @object WorldTag @@ -1327,9 +1363,11 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("storming") && mechanism.requireBoolean()) { - getWorld().setStorm(mechanism.getValue().asBoolean()); - } + tagProcessor.registerMechanism("storming", false, ElementTag.class, (object, mechanism, input) -> { + if (mechanism.requireBoolean()) { + object.getWorld().setStorm(input.asBoolean()); + } + }); // <--[mechanism] // @object WorldTag @@ -1340,9 +1378,9 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("thunder_duration") && mechanism.requireObject(DurationTag.class)) { - getWorld().setThunderDuration(mechanism.valueAsType(DurationTag.class).getTicksAsInt()); - } + tagProcessor.registerMechanism("thunder_duration", false, DurationTag.class, (object, mechanism, input) -> { + object.getWorld().setThunderDuration(input.getTicksAsInt()); + }); // <--[mechanism] // @object WorldTag @@ -1353,9 +1391,11 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("thundering") && mechanism.requireBoolean()) { - getWorld().setThundering(mechanism.getValue().asBoolean()); - } + tagProcessor.registerMechanism("thundering", false, ElementTag.class, (object, mechanism, input) -> { + if (mechanism.requireBoolean()) { + object.getWorld().setThundering(input.asBoolean()); + } + }); // <--[mechanism] // @object WorldTag @@ -1366,9 +1406,9 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("ticks_per_animal_spawns") && mechanism.requireObject(DurationTag.class)) { - getWorld().setTicksPerAnimalSpawns(mechanism.valueAsType(DurationTag.class).getTicksAsInt()); - } + tagProcessor.registerMechanism("ticks_per_animal_spawns", false, DurationTag.class, (object, mechanism, input) -> { + object.getWorld().setTicksPerAnimalSpawns(input.getTicksAsInt()); + }); // <--[mechanism] // @object WorldTag @@ -1379,9 +1419,9 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("ticks_per_monster_spawns") && mechanism.requireObject(DurationTag.class)) { - getWorld().setTicksPerMonsterSpawns(mechanism.valueAsType(DurationTag.class).getTicksAsInt()); - } + tagProcessor.registerMechanism("ticks_per_monster_spawns", false, DurationTag.class, (object, mechanism, input) -> { + object.getWorld().setTicksPerMonsterSpawns(input.getTicksAsInt()); + }); // <--[mechanism] // @object WorldTag @@ -1392,9 +1432,9 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("time") && mechanism.requireInteger()) { - getWorld().setTime(mechanism.getValue().asInt()); - } + tagProcessor.registerMechanism("time", false, ElementTag.class, (object, mechanism, input) -> { + object.getWorld().setTime(input.asInt()); + }); // <--[mechanism] // @object WorldTag @@ -1403,10 +1443,9 @@ public void adjust(Mechanism mechanism) { // @description // Unloads the world from the server and saves chunks. // --> - if (mechanism.matches("unload")) { - unloadWorldClean(mechanism, true); - return; - } + tagProcessor.registerMechanism("unload", false, (object, mechanism) -> { + object.unloadWorldClean(mechanism, true); + }); // <--[mechanism] // @object WorldTag @@ -1417,9 +1456,11 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("water_animal_spawn_limit") && mechanism.requireInteger()) { - getWorld().setWaterAnimalSpawnLimit(mechanism.getValue().asInt()); - } + tagProcessor.registerMechanism("water_animal_spawn_limit", false, ElementTag.class, (object, mechanism, input) -> { + if (mechanism.requireInteger()) { + object.getWorld().setWaterAnimalSpawnLimit(input.asInt()); + } + }); // <--[mechanism] // @object WorldTag @@ -1430,9 +1471,9 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("weather_duration") && mechanism.requireObject(DurationTag.class)) { - getWorld().setWeatherDuration(mechanism.valueAsType(DurationTag.class).getTicksAsInt()); - } + tagProcessor.registerMechanism("weather_duration", false, DurationTag.class, (object, mechanism, input) -> { + object.getWorld().setWeatherDuration(input.getTicksAsInt()); + }); // <--[mechanism] // @object WorldTag @@ -1442,10 +1483,11 @@ public void adjust(Mechanism mechanism) { // Advances this world's day the specified number of ticks WITHOUT firing any events. // Useful for manually adjusting the daylight cycle without firing an event every tick, for example. // --> - if (mechanism.matches("advance_ticks") && mechanism.requireInteger()) { - World world = getWorld(); - NMSHandler.worldHelper.setDayTime(world, world.getFullTime() + mechanism.getValue().asInt()); - } + tagProcessor.registerMechanism("advance_ticks", false, ElementTag.class, (object, mechanism, input) -> { + if (mechanism.requireInteger()) { + NMSHandler.worldHelper.setDayTime(object.getWorld(), object.getWorld().getFullTime() + input.asInt()); + } + }); // <--[mechanism] // @object WorldTag @@ -1456,9 +1498,9 @@ public void adjust(Mechanism mechanism) { // @tags // // --> - if (mechanism.matches("duration_since_created") && mechanism.requireObject(DurationTag.class)) { - NMSHandler.worldHelper.setGameTime(getWorld(), mechanism.valueAsType(DurationTag.class).getTicks()); - } + tagProcessor.registerMechanism("duration_since_created", false, DurationTag.class, (object, mechanism, input) -> { + NMSHandler.worldHelper.setGameTime(object.getWorld(), input.getTicksAsInt()); + }); // <--[mechanism] // @object WorldTag @@ -1468,9 +1510,9 @@ public void adjust(Mechanism mechanism) { // Skips to the next day as if enough players slept through the night. // NOTE: This ignores the doDaylightCycle gamerule! // --> - if (mechanism.matches("skip_night")) { + tagProcessor.registerMechanism("skip_night", false, (object, mechanism) -> { // general logic from NMS world tick - World world = getWorld(); + World world = object.getWorld(); long worldTime = world.getFullTime(); long nextDay = worldTime + 24000L; TimeSkipEvent event = new TimeSkipEvent(world, TimeSkipEvent.SkipReason.NIGHT_SKIP, nextDay - nextDay % 24000L - worldTime); @@ -1482,14 +1524,44 @@ public void adjust(Mechanism mechanism) { NMSHandler.worldHelper.wakeUpAllPlayers(world); } // minor change: prior to 1.18, hasStorm/isRaining was not checked - if (getGameRuleOrDefault(GameRule.DO_WEATHER_CYCLE) && world.hasStorm()) { + if (world.getGameRuleValue(GameRule.DO_WEATHER_CYCLE) == null) { + if (world.getGameRuleDefault(GameRule.DO_WEATHER_CYCLE) == null) { + throw new IllegalStateException("World " + world.getName() + " contains no GameRule " + GameRule.DO_WEATHER_CYCLE.getName()); + } + } + if (world.hasStorm()) { NMSHandler.worldHelper.clearWeather(world); } - } + }); + + } + + public static ObjectTagProcessor tagProcessor = new ObjectTagProcessor<>(); + public static void registerTag(Class returnType, String name, TagRunnable.ObjectInterface runnable, String... variants) { + tagProcessor.registerTag(returnType, name, (attribute, object) -> { + if (object.getWorld() == null) { + attribute.echoError("World '" + object.world_name + "' is unloaded, cannot process tag."); + return null; + } + return runnable.run(attribute, object); + }, variants); + } + + @Override + public ObjectTag getObjectAttribute(Attribute attribute) { + return tagProcessor.getObjectAttribute(this, attribute); + } + + @Override + public void adjust(Mechanism mechanism) { tagProcessor.processMechanism(this, mechanism); } + public void applyProperty(Mechanism mechanism) { + mechanism.echoError("Cannot apply properties to a world!"); + } + public void unloadWorldClean(Mechanism mechanism, boolean doSave) { for (Player pl : new ArrayList<>(getWorld().getPlayers())) { if (pl.isOnline()) { diff --git a/plugin/src/main/java/com/denizenscript/denizen/utilities/BukkitImplDeprecations.java b/plugin/src/main/java/com/denizenscript/denizen/utilities/BukkitImplDeprecations.java index 7be2570b99..974f9d1523 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/utilities/BukkitImplDeprecations.java +++ b/plugin/src/main/java/com/denizenscript/denizen/utilities/BukkitImplDeprecations.java @@ -344,6 +344,15 @@ public class BukkitImplDeprecations { // Bad candidate for bumping, targets extremely commonly used naming, some of which may be hard to remove (eg stored in flag data). public static Warning oldSpigotNames = new FutureWarning("oldSpigotNames", "Several features (particles, entities, etc.) had alternative naming added by Spigot, which are now deprecated in favor of the official Minecraft naming; see relevant feature's meta docs for more information."); + // Added 2024/12/23, deprecate officially by 2028. + public static Warning timePeriod = new FutureWarning("timePeriod", "'time.period' is deprecated in favor of 'time_period'."); + + // Added 2024/12/23, deprecate officially by 2028. + public static Warning timeFull = new FutureWarning("timeFull", "'time.full' is deprecated in favor of 'time_full'."); + + // Added 2024/12/23, deprecate officially by 2028. + public static Warning timeDuration = new FutureWarning("timeDuration", "'time.duration' is deprecated in favor of 'time_duration'."); + // ==================== PAST deprecations of things that are already gone but still have a warning left behind ==================== // Removed upstream 2023/10/29 without warning.