Skip to content

Commit

Permalink
Add teleport cause to event, command, new tag (#2289)
Browse files Browse the repository at this point in the history
* Add teleport cause to event, command, new tag

* Improve accuracy of teleport cause meta
  • Loading branch information
Morphan1 committed Dec 22, 2021
1 parent b010a2c commit e315f15
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 12 deletions.
Expand Up @@ -17,6 +17,18 @@

public class EntityTeleportScriptEvent extends BukkitScriptEvent implements Listener {

// <--[language]
// @name Teleport Cause
// @group Useful Lists
// @description
// Possible player teleport causes: <@link url https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/player/PlayerTeleportEvent.TeleportCause.html>
// These are used in <@link event entity teleports>, <@link tag server.teleport_causes>, <@link command teleport>, ...
// Note that these causes will only work for player entities.
//
// Additionally, Denizen provides two basic teleport causes for non-player entity teleport events: ENTITY_PORTAL and ENTITY_TELEPORT.
// These additional causes are not usable in <@link command teleport>, and will not show in <@link tag server.teleport_causes>.
// -->

// <--[event]
// @Events
// entity teleports
Expand All @@ -37,8 +49,7 @@ public class EntityTeleportScriptEvent extends BukkitScriptEvent implements List
// <context.entity> returns the EntityTag.
// <context.origin> returns the LocationTag the entity teleported from.
// <context.destination> returns the LocationTag the entity teleported to.
// <context.cause> returns an ElementTag of the teleport cause. Can be:
// COMMAND, END_PORTAL, ENDER_PEARL, NETHER_PORTAL, PLUGIN, END_GATEWAY, CHORUS_FRUIT, SPECTATE, UNKNOWN, ENTITY_TELEPORT, or ENTITY_PORTAL
// <context.cause> returns an ElementTag of the teleport cause - see <@link language teleport cause> for causes.
//
// @Determine
// "ORIGIN:" + LocationTag to change the location the entity teleported from.
Expand Down
Expand Up @@ -736,14 +736,18 @@ public World getWorld() {
}

public void spawnAt(Location location) {
spawnAt(location, TeleportCause.PLUGIN);
}

public void spawnAt(Location location, TeleportCause cause) {
if (location.getWorld() == null) {
Debug.echoError("Cannot teleport or spawn entity at location '" + new LocationTag(location) + "' because it is missing a world.");
return;
}
// If the entity is already spawned, teleport it.
if (isCitizensNPC()) {
if (getDenizenNPC().getCitizen().isSpawned()) {
getDenizenNPC().getCitizen().teleport(location, TeleportCause.PLUGIN);
getDenizenNPC().getCitizen().teleport(location, cause);
}
else {
if (getDenizenNPC().getCitizen().spawn(location)) {
Expand All @@ -761,7 +765,7 @@ public void spawnAt(Location location) {
}
}
else if (isUnique() && entity != null) {
teleport(location);
teleport(location, cause);
}
else {
if (entity_type != null) {
Expand Down Expand Up @@ -942,15 +946,19 @@ public void remove() {
}

public void teleport(Location location) {
teleport(location, TeleportCause.PLUGIN);
}

public void teleport(Location location, TeleportCause cause) {
if (isCitizensNPC()) {
getDenizenNPC().getCitizen().teleport(location, TeleportCause.PLUGIN);
getDenizenNPC().getCitizen().teleport(location, cause);
}
else if (isFake) {
NMSHandler.getEntityHelper().snapPositionTo(entity, location.toVector());
NMSHandler.getEntityHelper().look(entity, location.getYaw(), location.getPitch());
}
else {
getBukkitEntity().teleport(location);
getBukkitEntity().teleport(location, cause);
if (entity.getWorld().equals(location.getWorld())) { // Force the teleport through (for things like mounts)
NMSHandler.getEntityHelper().teleport(entity, location);
}
Expand Down
Expand Up @@ -7,11 +7,13 @@
import com.denizenscript.denizen.objects.LocationTag;
import com.denizenscript.denizencore.exceptions.InvalidArgumentsException;
import com.denizenscript.denizencore.objects.Argument;
import com.denizenscript.denizencore.objects.core.ElementTag;
import com.denizenscript.denizencore.objects.core.ListTag;
import com.denizenscript.denizencore.objects.notable.Notable;
import com.denizenscript.denizencore.objects.notable.NoteManager;
import com.denizenscript.denizencore.scripts.ScriptEntry;
import com.denizenscript.denizencore.scripts.commands.AbstractCommand;
import org.bukkit.event.player.PlayerTeleportEvent;

import java.util.Collections;
import java.util.List;
Expand All @@ -21,23 +23,24 @@ public class TeleportCommand extends AbstractCommand {

public TeleportCommand() {
setName("teleport");
setSyntax("teleport (<entity>|...) [<location>]");
setRequiredArguments(1, 2);
setSyntax("teleport (<entity>|...) [<location>] (cause:<cause>)");
setRequiredArguments(1, 3);
isProcedural = false;
}

// <--[command]
// @Name Teleport
// @Syntax teleport (<entity>|...) [<location>]
// @Syntax teleport (<entity>|...) [<location>] (cause:<cause>)
// @Required 1
// @Maximum 2
// @Maximum 3
// @Short Teleports the entity(s) to a new location.
// @Synonyms tp
// @Group entity
//
// @Description
// Teleports the entity or entities to the new location.
// Entities can be teleported between worlds using this command.
// You may optionally specify a teleport cause for player entities, allowing proper teleport event handling. When not specified, this is "PLUGIN". See <@link language teleport cause> for causes.
//
// @Tags
// <EntityTag.location>
Expand All @@ -61,6 +64,10 @@ public TeleportCommand() {
// @Usage
// Use to teleport the NPC to a location that was noted wih the <@link command note> command.
// - teleport <npc> my_prenoted_location
//
// @Usage
// Use to teleport a player to some location, and inform events that it was caused by a nether portal.
// - teleport <player> <server.flag[nether_hub_location]> cause:nether_portal
// -->

@Override
Expand All @@ -85,6 +92,10 @@ else if (!scriptEntry.hasObject("entities")
else if (arg.matches("npc") && Utilities.entryHasNPC(scriptEntry)) {
scriptEntry.addObject("entities", Collections.singletonList(Utilities.getEntryNPC(scriptEntry).getDenizenEntity()));
}
else if (!scriptEntry.hasObject("cause")
&& arg.matchesEnum(PlayerTeleportEvent.TeleportCause.values())) {
scriptEntry.addObject("cause", arg.asElement());
}
else {
arg.reportUnhandled();
}
Expand All @@ -101,16 +112,18 @@ else if (arg.matches("npc") && Utilities.entryHasNPC(scriptEntry)) {
public void execute(final ScriptEntry scriptEntry) {
LocationTag location = scriptEntry.getObjectTag("location");
List<EntityTag> entities = (List<EntityTag>) scriptEntry.getObject("entities");
ElementTag cause = scriptEntry.getElement("cause");
if (scriptEntry.dbCallShouldDebug()) {
Debug.report(scriptEntry, getName(), location, db("entities", entities));
Debug.report(scriptEntry, getName(), location, db("entities", entities), cause);
}
PlayerTeleportEvent.TeleportCause causeEnum = cause == null ? PlayerTeleportEvent.TeleportCause.PLUGIN : PlayerTeleportEvent.TeleportCause.valueOf(cause.asString().toUpperCase());
for (EntityTag entity : entities) {
if (entity.isFake && entity.getWorld().equals(location.getWorld())) {
NMSHandler.getEntityHelper().snapPositionTo(entity.getBukkitEntity(), location.toVector());
NMSHandler.getEntityHelper().look(entity.getBukkitEntity(), location.getYaw(), location.getPitch());
return;
}
entity.spawnAt(location);
entity.spawnAt(location, causeEnum);
}
}
}
Expand Up @@ -52,6 +52,7 @@
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.inventory.*;
import org.bukkit.loot.LootContext;
import org.bukkit.loot.LootTable;
Expand Down Expand Up @@ -675,6 +676,23 @@ else if (recipe instanceof CookingRecipe<?>) {
return;
}

// <--[tag]
// @attribute <server.teleport_causes>
// @returns ListTag
// @description
// Returns a list of all registered player teleport causes.
// Generally used with <@link event entity teleports>.
// See <@link language teleport cause> for the current list of causes.
// -->
if (attribute.startsWith("teleport_causes")) {
ListTag list = new ListTag();
for (PlayerTeleportEvent.TeleportCause teleportCause : PlayerTeleportEvent.TeleportCause.values()) {
list.add(teleportCause.name());
}
event.setReplacedObject(list.getObjectAttribute(attribute.fulfill(1)));
return;
}

// <--[tag]
// @attribute <server.biome_types>
// @returns ListTag(BiomeTag)
Expand Down

0 comments on commit e315f15

Please sign in to comment.