Skip to content

Dragon tags & mechs #2620

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

Merged
merged 11 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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]
// @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;
}
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;
}
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