Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dragon tags & mechs #2620

Merged
merged 11 commits into from
Oct 17, 2024
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package com.denizenscript.denizen.paper.properties;

import com.denizenscript.denizen.nms.NMSHandler;
import com.denizenscript.denizen.nms.NMSVersion;
import com.denizenscript.denizen.objects.EntityTag;
import com.denizenscript.denizen.objects.LocationTag;
import com.denizenscript.denizen.objects.WorldTag;
import com.denizenscript.denizen.utilities.BukkitImplDeprecations;
import com.denizenscript.denizencore.objects.core.ElementTag;
import com.denizenscript.denizencore.objects.core.ListTag;
import org.bukkit.boss.DragonBattle;

public class PaperWorldExtensions {

Expand All @@ -23,6 +29,88 @@ public static void register() {
return new ElementTag(world.getWorld().getNoTickViewDistance());
});

if (NMSHandler.getVersion().isAtLeast(NMSVersion.v1_20)) {

// <--[tag]
mcmonkey4eva marked this conversation as resolved.
Show resolved Hide resolved
// @attribute <WorldTag.gateway_count>
// @returns ElementTag(Number)
// @group paper
// @Plugin Paper
// @description
// Returns the number of end gateway portals.
// Only works if the world is an end world.
// -->
WorldTag.tagProcessor.registerTag(ElementTag.class, "gateway_count", (attribute, object) -> {
DragonBattle battle = object.getWorld().getEnderDragonBattle();
if (battle == null) {
attribute.echoError("Provided world is not an end world!");
return null;
}
return new ElementTag(battle.getGatewayCount());
});

// <--[tag]
// @attribute <WorldTag.healing_crystals>
// @returns ListTag(EntityTag)
// @group paper
// @Plugin Paper
// @description
// Returns a ListTag of the healing end crystals located on top of the obsidian towers.
// Only works if the world is an end world.
// -->
WorldTag.tagProcessor.registerTag(ListTag.class, "healing_crystals", (attribute, object) -> {
DragonBattle battle = object.getWorld().getEnderDragonBattle();
if (battle == null) {
attribute.echoError("Provided world is not an end world!");
return null;
}
return new ListTag(battle.getHealingCrystals(), EntityTag::new);
});

// <--[tag]
// @attribute <WorldTag.respawn_crystals>
// @returns ListTag(EntityTag)
// @group paper
// @Plugin Paper
// @description
// Returns a ListTag of the respawn end crystals located at the end exit portal.
// Only works if the world is an end world.
// -->
WorldTag.tagProcessor.registerTag(ListTag.class, "respawn_crystals", (attribute, object) -> {
DragonBattle battle = object.getWorld().getEnderDragonBattle();
if (battle == null) {
attribute.echoError("Provided world is not an end world!");
return null;
}
return new ListTag(battle.getRespawnCrystals(), EntityTag::new);
});

// <--[mechanism]
// @object WorldTag
// @name spawn_gateway
// @input LocationTag
// @group paper
// @Plugin Paper
// @description
// Spawns a new end gateway portal at the specified location.
// If no location is specified, tries to spawn a new end gateway using default game mechanics.
// Only works if the world is an end world.
// -->
WorldTag.tagProcessor.registerMechanism("spawn_gateway", false, (object, mechanism) -> {
DragonBattle battle = object.getWorld().getEnderDragonBattle();
if (battle == null) {
mechanism.echoError("Cannot spawn gateway in non-end world!");
return;
mcmonkey4eva marked this conversation as resolved.
Show resolved Hide resolved
}
if (!mechanism.hasValue()) {
battle.spawnNewGateway();
}
else if (mechanism.requireObject(LocationTag.class)) {
battle.spawnNewGateway(mechanism.valueAsType(LocationTag.class));
}
});
}

// <--[mechanism]
// @object WorldTag
// @name view_distance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.denizenscript.denizen.events.BukkitScriptEvent;
import com.denizenscript.denizen.nms.NMSHandler;
import com.denizenscript.denizen.nms.NMSVersion;
import com.denizenscript.denizen.nms.abstracts.BiomeNMS;
import com.denizenscript.denizen.utilities.flags.WorldFlagHandler;
import com.denizenscript.denizencore.flags.AbstractFlagTracker;
Expand Down Expand Up @@ -837,6 +838,7 @@ else if (time >= 12500) {
registerTag(LocationTag.class, "dragon_portal_location", (attribute, object) -> {
DragonBattle battle = object.getWorld().getEnderDragonBattle();
if (battle == null) {
attribute.echoError("Provided world is not an end world!");
return null;
}
if (battle.getEndPortalLocation() == null) {
Expand Down Expand Up @@ -1006,6 +1008,100 @@ else if (time >= 12500) {
registerTag(ElementTag.class, "is_night", (attribute, world) -> {
return new ElementTag(NMSHandler.worldHelper.isNight(world.getWorld()));
});

// <--[tag]
// @attribute <WorldTag.first_dragon_killed>
// @returns ElementTag(Boolean)
// @mechanism WorldTag.first_dragon_killed
// @description
// Returns whether the ender dragon has been killed in this world before.
// Only works if the world is an end world.
// -->
registerTag(ElementTag.class, "first_dragon_killed", (attribute, object) -> {
DragonBattle battle = object.getWorld().getEnderDragonBattle();
if (battle == null) {
attribute.echoError("Provided world is not an end world!");
return null;
}
return new ElementTag(battle.hasBeenPreviouslyKilled());
});

// <--[mechanism]
// @object WorldTag
// @name respawn_dragon
// @description
// Initiates the respawn sequence of the ender dragon as if a player placed 4 end crystals on the portal.
// Only works if the world is an end world.
// -->
tagProcessor.registerMechanism("respawn_dragon", false, (object, mechanism) -> {
DragonBattle battle = object.getWorld().getEnderDragonBattle();
if (battle == null) {
mechanism.echoError("Provided world is not an end world!");
return;
}
battle.initiateRespawn();
});

// <--[mechanism]
// @object WorldTag
// @name reset_crystals
// @description
// Resets the end crystals located on the obsidian pillars in this world.
// Only works if the world is an end world.
// -->
tagProcessor.registerMechanism("reset_crystals", false, (object, mechanism) -> {
DragonBattle battle = object.getWorld().getEnderDragonBattle();
if (battle == null) {
mechanism.echoError("Provided world is not an end world!");
return;
mcmonkey4eva marked this conversation as resolved.
Show resolved Hide resolved
}
battle.resetCrystals();
});

// <--[mechanism]
// @object WorldTag
// @name respawn_phase
// @input ElementTag
// @description
// Set the current respawn phase of the ender dragon. Valid phases can be found at <@link url https://jd.papermc.io/paper/1.21.1/org/bukkit/boss/DragonBattle.RespawnPhase.html>
// Only works if the world is an end world.
// -->
tagProcessor.registerMechanism("respawn_phase", false, ElementTag.class, (object, mechanism, input) -> {
DragonBattle battle = object.getWorld().getEnderDragonBattle();
if (battle == null) {
mechanism.echoError("Provided world is not an end world!");
return;
}
if (mechanism.requireEnum(DragonBattle.RespawnPhase.class)) {
battle.setRespawnPhase(input.asEnum(DragonBattle.RespawnPhase.class));
}
});

if (NMSHandler.getVersion().isAtLeast(NMSVersion.v1_20)) {

// <--[mechanism]
// @object WorldTag
// @name first_dragon_killed
// @input ElementTag(Boolean)
// @description
// Set whether the first ender dragon was killed already.
// Toggling this value won't really affect anything in the end world, but may be useful when creating custom end worlds.
// Only works if the world is an end world.
// @tags
// <WorldTag.first_dragon_killed>
// -->
tagProcessor.registerMechanism("first_dragon_killed", false, ElementTag.class, (object, mechanism, input) -> {
DragonBattle battle = object.getWorld().getEnderDragonBattle();
if (battle == null) {
mechanism.echoError("Provided world is not an end world!");
return;
}
if (mechanism.requireBoolean()) {
battle.setPreviouslyKilled(input.asBoolean());
}
});
}

}

public static ObjectTagProcessor<WorldTag> tagProcessor = new ObjectTagProcessor<>();
Expand Down