diff --git a/Docs/BukkitPlugins.md b/Docs/BukkitPlugins.md
index 3ff76ffb7..477d9abe3 100644
--- a/Docs/BukkitPlugins.md
+++ b/Docs/BukkitPlugins.md
@@ -35,6 +35,7 @@ Supported Plugins: (And the sources we acquired Jar files from.)
- Sentinel (https://www.spigotmc.org/resources/sentinel.22017/)
- ShopKeepers (https://www.spigotmc.org/resources/shopkeepers.80756/)
- SkillAPI (http://dev.bukkit.org/bukkit-plugins/skillapi/)
+- SuperiorSkyblock2 (https://www.spigotmc.org/resources/superiorskyblock2.87411/)
- TerrainControl/OpenTerrainGenerator (https://github.com/PG85/OpenTerrainGenerator)
- Towny (https://github.com/TownyAdvanced/Towny)
- TownyChat (https://github.com/TownyAdvanced/Towny)
diff --git a/pom.xml b/pom.xml
index 10bf06f15..c19e7dc02 100644
--- a/pom.xml
+++ b/pom.xml
@@ -316,6 +316,13 @@
system
${basedir}/lib/SkillAPI.jar
+
+ com.bgsoftware
+ SuperiorSkyblock
+ 2025.2.1
+ system
+ ${basedir}/lib/SuperiorSkyblock2.jar
+
com.khorn
TerrainControl
diff --git a/src/main/java/com/denizenscript/depenizen/bukkit/Depenizen.java b/src/main/java/com/denizenscript/depenizen/bukkit/Depenizen.java
index eb68c5730..265aab6e1 100644
--- a/src/main/java/com/denizenscript/depenizen/bukkit/Depenizen.java
+++ b/src/main/java/com/denizenscript/depenizen/bukkit/Depenizen.java
@@ -150,6 +150,7 @@ public void registerCoreBridges() {
registerBridge("Sentinel", () -> new SentinelBridge());
registerBridge("Shopkeepers", () -> new ShopkeepersBridge());
registerBridge("SkillAPI", () -> new SkillAPIBridge());
+ registerBridge("SuperiorSkyblock2", () -> new SuperiorSkyblockBridge());
registerBridge("TerrainControl", () -> new TerrainControlBridge());
registerBridge("Towny", () -> new TownyBridge());
registerBridge("TownyChat", () -> new TownyChatBridge());
diff --git a/src/main/java/com/denizenscript/depenizen/bukkit/bridges/SuperiorSkyblockBridge.java b/src/main/java/com/denizenscript/depenizen/bukkit/bridges/SuperiorSkyblockBridge.java
new file mode 100644
index 000000000..1a9b4b802
--- /dev/null
+++ b/src/main/java/com/denizenscript/depenizen/bukkit/bridges/SuperiorSkyblockBridge.java
@@ -0,0 +1,33 @@
+package com.denizenscript.depenizen.bukkit.bridges;
+
+import com.denizenscript.denizencore.events.ScriptEvent;
+import com.denizenscript.denizencore.objects.ObjectFetcher;
+import com.denizenscript.denizencore.tags.TagManager;
+import com.denizenscript.depenizen.bukkit.Bridge;
+import com.denizenscript.depenizen.bukkit.events.superiorskyblock.*;
+import com.denizenscript.depenizen.bukkit.objects.superiorskyblock.SuperiorSkyblockIslandTag;
+import com.denizenscript.depenizen.bukkit.properties.superiorskyblock.*;
+
+public class SuperiorSkyblockBridge extends Bridge {
+
+ @Override
+ public void init() {
+ ScriptEvent.registerScriptEvent(SuperiorSkyblockIslandCreatedScriptEvent.class);
+ ScriptEvent.registerScriptEvent(SuperiorSkyblockIslandDisbandedScriptEvent.class);
+ SuperiorSkyblockLocationExtensions.register();
+ SuperiorSkyblockPlayerExtensions.register();
+ ObjectFetcher.registerWithObjectFetcher(SuperiorSkyblockIslandTag.class, SuperiorSkyblockIslandTag.tagProcessor);
+
+ // <--[tag]
+ // @attribute ]>
+ // @returns SuperiorSkyblockIslandTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Returns the superiorskyblock island tag with the given uuid.
+ // Refer to <@link objecttype SuperiorSkyblockIslandTag> for more information.
+ // -->
+ TagManager.registerTagHandler(SuperiorSkyblockIslandTag.class, SuperiorSkyblockIslandTag.class, "superiorskyblock_island", (attribute, param) -> {
+ return param;
+ });
+ }
+}
diff --git a/src/main/java/com/denizenscript/depenizen/bukkit/events/superiorskyblock/SuperiorSkyblockIslandCreatedScriptEvent.java b/src/main/java/com/denizenscript/depenizen/bukkit/events/superiorskyblock/SuperiorSkyblockIslandCreatedScriptEvent.java
new file mode 100644
index 000000000..5a93c3097
--- /dev/null
+++ b/src/main/java/com/denizenscript/depenizen/bukkit/events/superiorskyblock/SuperiorSkyblockIslandCreatedScriptEvent.java
@@ -0,0 +1,68 @@
+package com.denizenscript.depenizen.bukkit.events.superiorskyblock;
+
+import com.bgsoftware.superiorskyblock.api.events.IslandCreateEvent;
+import com.denizenscript.denizen.events.BukkitScriptEvent;
+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.depenizen.bukkit.objects.superiorskyblock.SuperiorSkyblockIslandTag;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+
+public class SuperiorSkyblockIslandCreatedScriptEvent extends BukkitScriptEvent implements Listener {
+
+ // <--[event]
+ // @Events
+ // superiorskyblock island created
+ //
+ // @Triggers when an island is created
+ //
+ // @Cancellable true
+ //
+ // @Context
+ // returns a SuperiorSkyblockIslandTag of the island.
+ //
+ // @Determine
+ // "TELEPORT:" to set whether the player will automatically teleport to the island once it's generated.
+ //
+ // @Plugin Depenizen, SuperiorSkyblock
+ //
+ // @Player Always.
+ //
+ // @Group Depenizen
+ //
+ // -->
+
+ public SuperiorSkyblockIslandCreatedScriptEvent() {
+ registerCouldMatcher("superiorskyblock island created");
+ this.registerOptionalDetermination("teleport", ElementTag.class, (evt, context, value) -> {
+ if (value.isBoolean()) {
+ evt.event.setTeleport(value.asBoolean());
+ return true;
+ }
+ return false;
+ });
+ }
+
+ public IslandCreateEvent event;
+
+ @Override
+ public ScriptEntryData getScriptEntryData() {
+ return new BukkitScriptEntryData(event.getPlayer().asPlayer());
+ }
+
+ @Override
+ public ObjectTag getContext(String name) {
+ return switch (name) {
+ case "island" -> new SuperiorSkyblockIslandTag(event.getIsland());
+ default -> super.getContext(name);
+ };
+ }
+
+ @EventHandler
+ public void onIslandCreate(IslandCreateEvent event) {
+ this.event = event;
+ fire(event);
+ }
+}
diff --git a/src/main/java/com/denizenscript/depenizen/bukkit/events/superiorskyblock/SuperiorSkyblockIslandDisbandedScriptEvent.java b/src/main/java/com/denizenscript/depenizen/bukkit/events/superiorskyblock/SuperiorSkyblockIslandDisbandedScriptEvent.java
new file mode 100644
index 000000000..c95918a33
--- /dev/null
+++ b/src/main/java/com/denizenscript/depenizen/bukkit/events/superiorskyblock/SuperiorSkyblockIslandDisbandedScriptEvent.java
@@ -0,0 +1,57 @@
+package com.denizenscript.depenizen.bukkit.events.superiorskyblock;
+
+import com.bgsoftware.superiorskyblock.api.events.IslandDisbandEvent;
+import com.denizenscript.denizen.events.BukkitScriptEvent;
+import com.denizenscript.denizen.utilities.implementation.BukkitScriptEntryData;
+import com.denizenscript.denizencore.objects.ObjectTag;
+import com.denizenscript.denizencore.scripts.ScriptEntryData;
+import com.denizenscript.depenizen.bukkit.objects.superiorskyblock.SuperiorSkyblockIslandTag;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+
+public class SuperiorSkyblockIslandDisbandedScriptEvent extends BukkitScriptEvent implements Listener {
+
+ // <--[event]
+ // @Events
+ // superiorskyblock island disbanded
+ //
+ // @Triggers when an island is disbanded
+ //
+ // @Cancellable true
+ //
+ // @Context
+ // returns a SuperiorSkyblockIslandTag of the island.
+ //
+ // @Plugin Depenizen, SuperiorSkyblock
+ //
+ // @Player Always.
+ //
+ // @Group Depenizen
+ //
+ // -->
+
+ public SuperiorSkyblockIslandDisbandedScriptEvent() {
+ registerCouldMatcher("superiorskyblock island disbanded");
+ }
+
+ public IslandDisbandEvent event;
+
+ @Override
+ public ScriptEntryData getScriptEntryData() {
+ return new BukkitScriptEntryData(event.getPlayer().asPlayer());
+ }
+
+ @Override
+ public ObjectTag getContext(String name) {
+ return switch (name) {
+ case "island" -> new SuperiorSkyblockIslandTag(event.getIsland());
+ default -> super.getContext(name);
+ };
+ }
+
+ @EventHandler
+ public void onIslandDisband(IslandDisbandEvent event) {
+ this.event = event;
+ fire(event);
+ }
+}
diff --git a/src/main/java/com/denizenscript/depenizen/bukkit/objects/superiorskyblock/SuperiorSkyblockIslandTag.java b/src/main/java/com/denizenscript/depenizen/bukkit/objects/superiorskyblock/SuperiorSkyblockIslandTag.java
new file mode 100644
index 000000000..b6c241b6c
--- /dev/null
+++ b/src/main/java/com/denizenscript/depenizen/bukkit/objects/superiorskyblock/SuperiorSkyblockIslandTag.java
@@ -0,0 +1,839 @@
+package com.denizenscript.depenizen.bukkit.objects.superiorskyblock;
+
+import com.bgsoftware.superiorskyblock.SuperiorSkyblockPlugin;
+import com.bgsoftware.superiorskyblock.api.SuperiorSkyblockAPI;
+import com.bgsoftware.superiorskyblock.api.enums.MemberRemoveReason;
+import com.bgsoftware.superiorskyblock.api.enums.Rating;
+import com.bgsoftware.superiorskyblock.api.island.Island;
+import com.bgsoftware.superiorskyblock.api.island.IslandFlag;
+import com.bgsoftware.superiorskyblock.api.world.Dimension;
+import com.bgsoftware.superiorskyblock.api.wrappers.SuperiorPlayer;
+import com.denizenscript.denizen.objects.*;
+import com.denizenscript.denizencore.objects.*;
+import com.denizenscript.denizencore.objects.core.*;
+import com.denizenscript.denizencore.tags.Attribute;
+import com.denizenscript.denizencore.tags.ObjectTagProcessor;
+import com.denizenscript.denizencore.tags.TagContext;
+import com.bgsoftware.superiorskyblock.api.wrappers.WorldPosition;
+import com.denizenscript.denizencore.utilities.CoreUtilities;
+import com.denizenscript.denizencore.utilities.debugging.Debug;
+import com.denizenscript.denizencore.utilities.text.StringHolder;
+import org.bukkit.Registry;
+
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.util.Map;
+import java.util.UUID;
+
+public class SuperiorSkyblockIslandTag implements ObjectTag, Adjustable {
+
+ // <--[ObjectType]
+ // @name SuperiorSkyblockIslandTag
+ // @prefix superiorskyblock_island
+ // @base ElementTag
+ // @format
+ // The identity format is .
+ // For example, 'superiorskyblock_island@460e96b9-7a0e-416d-b2c3-4508164b8b1b'.
+ //
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // A SuperiorSkyblockIslandTag represents a SuperiorSkyblock island.
+ // -->
+
+ @Fetchable("superiorskyblock_island")
+ public static SuperiorSkyblockIslandTag valueOf(String string, TagContext context) {
+ if (string.startsWith("superiorskyblock_island@")) {
+ string = string.substring("superiorskyblock_island@".length());
+ }
+ try {
+ UUID uuid = UUID.fromString(string);
+ Island island = uuid.equals(spawnIsland) ? SuperiorSkyblockAPI.getSpawnIsland() : SuperiorSkyblockAPI.getIslandByUUID(uuid);
+ if (island != null) {
+ return new SuperiorSkyblockIslandTag(island);
+ }
+ if (context == null || context.showErrors()) {
+ Debug.echoError("SuperiorSkyblockIslandTag returning null: UUID '" + string + "' is valid, but doesn't match any island.");
+ }
+ return null;
+ }
+ catch (IllegalArgumentException e) {
+ if (context == null || context.showErrors()) {
+ Debug.echoError("SuperiorSkyblockIslandTag returning null: Invalid UUID '" + string + "' specified.");
+ }
+ return null;
+ }
+ }
+
+ // Yes, this is the actual UUID that is associated with the spawn island.
+ public static final UUID spawnIsland = UUID.fromString("00000000-0000-0000-0000-000000000000");
+
+ public static boolean matches(String string) {
+ if (string.startsWith("superiorskyblock_island@")) {
+ return true;
+ }
+ return valueOf(string, CoreUtilities.noDebugContext) != null;
+ }
+
+ public SuperiorSkyblockIslandTag(Island island) {
+ this.island = island;
+ }
+
+ Island island;
+
+ String prefix = "SuperiorSkyblockIsland";
+
+ @Override
+ public String getPrefix() {
+ return prefix;
+ }
+
+ @Override
+ public ObjectTag setPrefix(String prefix) {
+ this.prefix = prefix;
+ return this;
+ }
+
+ @Override
+ public boolean isUnique() {
+ return true;
+ }
+
+ @Override
+ public String identify() {
+ return "superiorskyblock_island@" + island.getUniqueId();
+ }
+
+ @Override
+ public String identifySimple() {
+ return identify();
+ }
+
+ @Override
+ public String toString() {
+ return identify();
+ }
+
+ @Override
+ public ObjectTag getObjectAttribute(Attribute attribute) {
+ return tagProcessor.getObjectAttribute(this, attribute);
+ }
+
+ @Override
+ public void adjust(Mechanism mechanism) {
+ tagProcessor.processMechanism(this, mechanism);
+ }
+
+ @Override
+ public void applyProperty(Mechanism mechanism) {
+ mechanism.echoError("Cannot apply Properties to a Superior Skyblock Island!");
+ }
+
+ public Island getIsland() {
+ return island;
+ }
+
+ public static SuperiorPlayer getSuperiorPlayer(PlayerTag player) {
+ return SuperiorSkyblockAPI.getPlayer(player.getUUID());
+ }
+
+ public static void register() {
+
+ // <--[tag]
+ // @attribute
+ // @returns ElementTag(Decimal)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Returns the current average rating of an island.
+ // -->
+ tagProcessor.registerTag(ElementTag.class, "average_rating", (attribute, object) -> {
+ return new ElementTag(object.getIsland().getTotalRating());
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ElementTag(Decimal)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @mechanism SuperiorSkyblockIslandTag.balance
+ // @description
+ // Returns the bank balance of an island.
+ // -->
+ tagProcessor.registerTag(ElementTag.class, "balance", (attribute, object) -> {
+ if (object.getIsland().isSpawn()) {
+ attribute.echoError("Spawn islands do not have a balance.");
+ return null;
+ }
+ return new ElementTag(object.getIsland().getIslandBank().getBalance());
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ListTag(PlayerTag)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @mechanism SuperiorSkyblockIslandTag.ban_player
+ // @mechanism SuperiorSkyblockIslandTag.unban_player
+ // @description
+ // Returns the players banned on an island.
+ // -->
+ tagProcessor.registerTag(ListTag.class, "banned_players", (attribute, object) -> {
+ return new ListTag(object.getIsland().getBannedPlayers(), player -> new PlayerTag(player.asPlayer()));
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns BiomeTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @mechanism SuperiorSkyblockIslandTag.biome
+ // @description
+ // Returns the current biome of an island.
+ // -->
+ tagProcessor.registerTag(BiomeTag.class, "biome", (attribute, object) -> {
+ return new BiomeTag(object.getIsland().getBiome());
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ElementTag(Decimal)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @mechanism SuperiorSkyblockIslandTag.bonus_level
+ // @description
+ // Returns the bonus level of an island.
+ // -->
+ tagProcessor.registerTag(ElementTag.class, "bonus_level", (attribute, object) -> {
+ return new ElementTag(object.getIsland().getBonusLevel());
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ElementTag(Decimal)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @mechanism SuperiorSkyblockIslandTag.bonus_worth
+ // @description
+ // Returns the bonus worth of an island.
+ // -->
+ tagProcessor.registerTag(ElementTag.class, "bonus_worth", (attribute, object) -> {
+ return new ElementTag(object.getIsland().getBonusWorth());
+ });
+
+ // <--[tag]
+ // @attribute ]>
+ // @returns LocationTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Returns the center of an island in the provided world.
+ // -->
+ tagProcessor.registerTag(LocationTag.class, WorldTag.class, "center", (attribute, object, value) -> {
+ if (SuperiorSkyblockAPI.getProviders().getWorldsProvider().isIslandsWorld(value.getWorld())) {
+ return new LocationTag(object.getIsland().getCenter(SuperiorSkyblockAPI.getProviders().getWorldsProvider().getIslandsWorldDimension(value.getWorld())));
+ }
+ else {
+ attribute.echoError("The provided world does not contain islands.");
+ return null;
+ }
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ListTag(PlayerTag)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @mechanism SuperiorSkyblockIslandTag.add_coop_member
+ // @mechanism SuperiorSkyblockIslandTag.kick_coop_member
+ // @description
+ // Returns the coop members of an island.
+ // -->
+ tagProcessor.registerTag(ListTag.class, "coop_members", (attribute, object) -> {
+ return new ListTag(object.getIsland().getCoopPlayers(), player -> new PlayerTag(player.asPlayer()));
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns TimeTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Returns the time an island was created.
+ // -->
+ tagProcessor.registerTag(TimeTag.class, "creation_time", (attribute, object) -> {
+ return new TimeTag(LocalDateTime.parse(object.getIsland().getCreationTimeDate(), DateTimeFormatter.ofPattern(SuperiorSkyblockPlugin.getPlugin().getSettings().getDateFormat())).atZone(ZoneOffset.UTC));
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns CuboidTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Returns the boundaries of an island.
+ // -->
+ tagProcessor.registerTag(CuboidTag.class, "cuboid", (attribute, object) -> {
+ return new CuboidTag(object.getIsland().getMinimum(), object.getIsland().getMaximum());
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ListTag(PlayerTag)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Returns the players currently within the bounds of an island.
+ // -->
+ tagProcessor.registerTag(ListTag.class, "current_visitors", (attribute, object) -> {
+ return new ListTag(object.getIsland().getAllPlayersInside(), player -> new PlayerTag(player.asPlayer()));
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ElementTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Returns the description of an island. This may be empty if an island does not have one set.
+ // -->
+ tagProcessor.registerTag(ElementTag.class, "description", (attribute, object) -> {
+ return new ElementTag(object.getIsland().getDescription(), true);
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ListTag(LocationTag)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Returns the home locations of an island.
+ // -->
+ tagProcessor.registerTag(ListTag.class, "homes", (attribute, object) -> {
+ ListTag values = new ListTag();
+ for (Map.Entry map : object.getIsland().getIslandHomes().entrySet()) {
+ WorldPosition pos = map.getValue();
+ values.addObject(new LocationTag(pos.getX(), pos.getY(), pos.getZ(), SuperiorSkyblockAPI.getProviders().getWorldsProvider().getIslandsWorld(object.getIsland(), map.getKey()).getName()));
+ }
+ return values;
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ElementTag(Boolean)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Returns whether this is the spawn island.
+ // -->
+ tagProcessor.registerTag(ElementTag.class, "is_spawn_island", (attribute, object) -> {
+ return new ElementTag(object.getIsland().isSpawn());
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns PlayerTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @mechanism
+ // @description
+ // Returns the leader of an island.
+ // -->
+ tagProcessor.registerTag(PlayerTag.class, "leader", (attribute, object) -> {
+ if (object.getIsland().isSpawn()) {
+ attribute.echoError("Spawn islands do not have a leader.");
+ return null;
+ }
+ return new PlayerTag(object.getIsland().getOwner().asPlayer());
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ElementTag(Decimal)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Returns the level of an island.
+ // -->
+ tagProcessor.registerTag(ElementTag.class, "level", (attribute, object) -> {
+ return new ElementTag(object.getIsland().getIslandLevel());
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ElementTag(Boolean)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @mechanism SuperiorSkyblockIslandTag.locked
+ // @description
+ // Returns whether an island is locked to visitors.
+ // -->
+ tagProcessor.registerTag(ElementTag.class, "locked", (attribute, object) -> {
+ return new ElementTag(object.getIsland().isLocked());
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ListTag(PlayerTag)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @mechanism
+ // @mechanism
+ // @description
+ // Returns the members of an island, including the leader.
+ // -->
+ tagProcessor.registerTag(ListTag.class, "members", (attribute, object) -> {
+ return new ListTag(object.getIsland().getIslandMembers(true), player -> new PlayerTag(player.asPlayer()));
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ElementTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @mechanism SuperiorSkyblockIslandTag.name
+ // @description
+ // Returns the name of an island.
+ // -->
+ tagProcessor.registerTag(ElementTag.class, "name", (attribute, object) -> {
+ return new ElementTag(object.getIsland().getName(), true);
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ElementTag(Decimal)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @mechanism SuperiorSkyblockIslandTag.recalculate_worth
+ // @description
+ // Returns the net worth of an island. Includes money in the bank.
+ // -->
+ tagProcessor.registerTag(ElementTag.class, "net_worth", (attribute, object) -> {
+ return new ElementTag(object.getIsland().getWorth());
+ });
+
+ // <--[tag]
+ // @attribute ]>
+ // @returns ElementTag(Number)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Returns the rating a player gave an island, or null if the player hasn't given one.
+ // -->
+ tagProcessor.registerTag(ElementTag.class, PlayerTag.class, "rating", (attribute, object, player) -> {
+ Rating rating = object.getIsland().getRating(getSuperiorPlayer(player));
+ return rating.getValue() > -1 ? new ElementTag(rating.getValue()) : null;
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ElementTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Returns the schematic used to create an island.
+ // -->
+ tagProcessor.registerTag(ElementTag.class, "schematic", (attribute, object) -> {
+ return new ElementTag(object.getIsland().getSchematicName(), true);
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns MapTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @mechanism
+ // @description
+ // Returns the settings of an island.
+ // -->
+ tagProcessor.registerTag(MapTag.class, "settings", (attribute, object) -> {
+ MapTag values = new MapTag();
+ for (IslandFlag flag : IslandFlag.values()) {
+ values.putObject(flag.getName(), new ElementTag(object.getIsland().hasSettingsEnabled(flag)));
+ }
+ return values;
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ElementTag(Number)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @mechanism SuperiorSkyblockIslandTag.size
+ // @description
+ // Returns the world border width of an island.
+ // -->
+ tagProcessor.registerTag(ElementTag.class, "size", (attribute, object) -> {
+ return new ElementTag(object.getIsland().getIslandSize());
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ElementTag(Number)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @mechanism SuperiorSkyblockIslandTag.team_limit
+ // @description
+ // Returns the maximum amount of players on an island's team.
+ // -->
+ tagProcessor.registerTag(ElementTag.class, "team_limit", (attribute, object) -> {
+ return new ElementTag(object.getIsland().getTeamLimit());
+ });
+
+ // <--[tag]
+ // @attribute
+ // @returns ElementTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Returns the uuid of an island.
+ // -->
+ tagProcessor.registerTag(ElementTag.class, "uuid", (attribute, object) -> {
+ return new ElementTag(object.getIsland().getUniqueId().toString(), true);
+ });
+
+ // <--[mechanism]
+ // @object SuperiorSkyblockIslandTag
+ // @name add_coop_member
+ // @input PlayerTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Adds a coop member to an island's team.
+ // @tags
+ //
+ // -->
+ tagProcessor.registerMechanism("add_coop_member", false, PlayerTag.class, (object, mechanism, value) -> {
+ if (object.getIsland().isSpawn()) {
+ mechanism.echoError("Spawn islands cannot have a team of players.");
+ }
+ else if (object.getIsland().getCoopPlayers().contains(getSuperiorPlayer(value))) {
+ mechanism.echoError("This player is already part of the island.");
+ }
+ else {
+ object.getIsland().addCoop(getSuperiorPlayer(value));
+ }
+ });
+
+ // <--[mechanism]
+ // @object SuperiorSkyblockIslandTag
+ // @name add_member
+ // @input PlayerTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Adds a member to an island's team.
+ // @tags
+ //
+ // -->
+ tagProcessor.registerMechanism("add_member", false, PlayerTag.class, (object, mechanism, value) -> {
+ if (object.getIsland().isSpawn()) {
+ mechanism.echoError("Spawn islands cannot have a team of players.");
+ }
+ else if (object.getIsland().getIslandMembers(true).contains(getSuperiorPlayer(value))) {
+ mechanism.echoError("This player is already part of the island.");
+ }
+ else {
+ object.getIsland().addMember(getSuperiorPlayer(value), SuperiorSkyblockPlugin.getPlugin().getRoles().getDefaultRole());
+ }
+ });
+
+ // <--[mechanism]
+ // @object SuperiorSkyblockIslandTag
+ // @name balance
+ // @input ElementTag(Decimal)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Changes an island's bank balance.
+ // @tags
+ //
+ // -->
+ tagProcessor.registerMechanism("balance", false, ElementTag.class, (object, mechanism, value) -> {
+ if (object.getIsland().isSpawn()) {
+ mechanism.echoError("Spawn islands cannot have a balance.");
+ }
+ else if (mechanism.requireDouble()) {
+ object.getIsland().getIslandBank().setBalance(value.asBigDecimal());
+ }
+ });
+
+ // <--[mechanism]
+ // @object SuperiorSkyblockIslandTag
+ // @name ban_player
+ // @input PlayerTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Bans a player from an island.
+ // @tags
+ //
+ // -->
+ tagProcessor.registerMechanism("ban_player", false, PlayerTag.class, (object, mechanism, value) -> {
+ if (object.getIsland().isSpawn()) {
+ mechanism.echoError("Spawn islands cannot have banned players.");
+ }
+ else if (object.getIsland().getBannedPlayers().contains(getSuperiorPlayer(value))) {
+ mechanism.echoError("This player is already banned from the island.");
+ }
+ else {
+ object.getIsland().banMember(getSuperiorPlayer(value));
+ }
+ });
+
+ // <--[mechanism]
+ // @object SuperiorSkyblockIslandTag
+ // @name biome
+ // @input BiomeTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Sets the biome of an island.
+ // @tags
+ //
+ // -->
+ tagProcessor.registerMechanism("biome", false, BiomeTag.class, (object, mechanism, value) -> {
+ object.getIsland().setBiome(Registry.BIOME.get(value.getBiome().getKey()));
+ });
+
+ // <--[mechanism]
+ // @object SuperiorSkyblockIslandTag
+ // @name bonus_level
+ // @input ElementTag(Decimal)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Sets the bonus level given to an island.
+ // @tags
+ //
+ // -->
+ tagProcessor.registerMechanism("bonus_level", false, ElementTag.class, (object, mechanism, value) -> {
+ if (mechanism.requireDouble()) {
+ object.getIsland().setBonusLevel(value.asBigDecimal());
+ }
+ });
+
+ // <--[mechanism]
+ // @object SuperiorSkyblockIslandTag
+ // @name bonus_worth
+ // @input ElementTag(Decimal)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Controls the bonus worth given to an island.
+ // @tags
+ //
+ // -->
+ tagProcessor.registerMechanism("bonus_worth", false, ElementTag.class, (object, mechanism, value) -> {
+ if (mechanism.requireDouble()) {
+ object.getIsland().setBonusWorth(value.asBigDecimal());
+ }
+ });
+
+ // <--[mechanism]
+ // @object SuperiorSkyblockIslandTag
+ // @name description
+ // @input ElementTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Changes an island's description. Leave blank to remove.
+ // @tags
+ //
+ // -->
+ tagProcessor.registerMechanism("description", false, ElementTag.class, (object, mechanism, value) -> {
+ if (object.getIsland().isSpawn()) {
+ mechanism.echoError("Spawn islands cannot have a description.");
+ }
+ else {
+ object.getIsland().setDescription(value.asString());
+ }
+ });
+
+ // <--[mechanism]
+ // @object SuperiorSkyblockIslandTag
+ // @name kick_coop_member
+ // @input PlayerTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Kick a coop member from an island's team.
+ // @tags
+ //
+ // -->
+ tagProcessor.registerMechanism("kick_coop_member", false, PlayerTag.class, (object, mechanism, value) -> {
+ if (!(object.getIsland().getCoopPlayers().contains(getSuperiorPlayer(value)))) {
+ mechanism.echoError("This player is already not a part of this island.");
+ }
+ else {
+ object.getIsland().removeCoop(getSuperiorPlayer(value));
+ }
+ });
+
+ // <--[mechanism]
+ // @object SuperiorSkyblockIslandTag
+ // @name kick_member
+ // @input PlayerTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Kick a member from an island's team.
+ // @tags
+ //
+ // -->
+ tagProcessor.registerMechanism("kick_member", false, PlayerTag.class, (object, mechanism, value) -> {
+ if (!(object.getIsland().getIslandMembers(true).contains(getSuperiorPlayer(value)))) {
+ mechanism.echoError("This player is already not a part of this island.");
+ }
+ else {
+ object.getIsland().removeMember(getSuperiorPlayer(value), MemberRemoveReason.KICK);
+ }
+ });
+
+ // <--[mechanism]
+ // @object SuperiorSkyblockIslandTag
+ // @name leader
+ // @input PlayerTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Transfers island leadership to the specified player.
+ // Since only one player can have the 'Leader' role at a time, the current leader will be shifted to the 'Admin' role.
+ // @tags
+ //
+ // -->
+ tagProcessor.registerMechanism("leader", false, PlayerTag.class, (object, mechanism, value) -> {
+ object.getIsland().transferIsland(getSuperiorPlayer(value));
+ });
+
+ // <--[mechanism]
+ // @object SuperiorSkyblockIslandTag
+ // @name locked
+ // @input ElementTag(Boolean)
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Changes whether an island is locked to visitors.
+ // @tags
+ //
+ // -->
+ tagProcessor.registerMechanism("locked", false, ElementTag.class, (object, mechanism, value) -> {
+ if (object.getIsland().isSpawn()) {
+ mechanism.echoError("Spawn islands cannot be locked.");
+ }
+ else if (mechanism.requireBoolean()) {
+ object.getIsland().setLocked(value.asBoolean());
+ }
+ });
+
+ // <--[mechanism]
+ // @object SuperiorSkyblockIslandTag
+ // @name name
+ // @input ElementTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Changes an island's name. Multiple islands cannot have the same name.
+ // @tags
+ //
+ // -->
+ tagProcessor.registerMechanism("name", false, ElementTag.class, (object, mechanism, value) -> {
+ if (object.getIsland().isSpawn()) {
+ mechanism.echoError("Spawn islands cannot have a name.");
+ }
+ else if (value.asString().isEmpty()) {
+ mechanism.echoError("You cannot have an island with no name.");
+ }
+ else if (SuperiorSkyblockAPI.getIsland(value.asString()) != null) {
+ mechanism.echoError("There is already an island with the name '" + value + "'.");
+ }
+ else {
+ object.getIsland().setName(value.toString());
+ }
+ });
+
+ // <--[mechanism]
+ // @object SuperiorSkyblockIslandTag
+ // @name recalculate_worth
+ // @input None
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Recalculates an island's net worth.
+ // @tags
+ //
+ // -->
+ tagProcessor.registerMechanism("recalculate_worth", false, (object, mechanism) -> {
+ object.getIsland().calcIslandWorth(null);
+ });
+
+ // <--[mechanism]
+ // @object SuperiorSkyblockIslandTag
+ // @name settings
+ // @input MapTag
+ // @plugin Depenizen, SuperiorSkyblock
+ // @description
+ // Controls the settings of an island.
+ // Valid settings are ALWAYS_DAY, ALWAYS_MIDDLE_DAY, ALWAYS_MIDDLE_NIGHT, ALWAYS_NIGHT, ALWAYS_RAIN, ALWAYS_SHINY, CREEPER_EXPLOSION, CROPS_GROWTH, EGG_LAY, ENDERMAN_GRIEF, FIRE_SPREAD,
+ // GHAST_FIREBALL, LAVA_FLOW, NATURAL_ANIMALS_SPAWN, NATURAL_MONSTER_SPAWN, PVP, SPAWNER_ANIMALS_SPAWN, SPAWNER_MONSTER_SPAWN, TNT_EXPLOSION, TREE_GROWTH, WATER_FLOW, and WITHER_EXPLOSION.
+ // @example
+ // # Enables pvp and disables creeper explosions.
+ // - adjust <[island]> settings: