From c935e381b754d2e8e456af7038ca65e9b982564e Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Fri, 21 Dec 2018 16:56:10 +1000 Subject: [PATCH] Added a method to teleport entities across worlds. --- .../sk89q/worldedit/bukkit/BukkitEntity.java | 10 ++ .../sk89q/worldedit/bukkit/BukkitPlayer.java | 5 + .../com/sk89q/worldedit/entity/Entity.java | 8 + .../extension/platform/PlayerProxy.java | 5 + .../worldedit/extent/ChangeSetExtent.java | 6 + .../extent/clipboard/StoredEntity.java | 5 + .../util/gson/BlockVectorAdapter.java | 46 +++++ .../sk89q/worldedit/util/gson/GsonUtil.java | 2 + .../worldedit/util/gson/VectorAdapter.java | 4 +- .../sk89q/worldedit/forge/ForgeEntity.java | 6 + .../sk89q/worldedit/forge/ForgePlayer.java | 6 + .../sk89q/worldedit/sponge/SpongeAdapter.java | 168 ++++++++++++++++++ .../sk89q/worldedit/sponge/SpongeEntity.java | 10 ++ .../sk89q/worldedit/sponge/SpongePlayer.java | 8 + 14 files changed, 287 insertions(+), 2 deletions(-) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/BlockVectorAdapter.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitEntity.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitEntity.java index 595a7fc9c..a5c7b0a60 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitEntity.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitEntity.java @@ -71,6 +71,16 @@ public class BukkitEntity implements Entity { } } + @Override + public boolean setLocation(Location location) { + org.bukkit.entity.Entity entity = entityRef.get(); + if (entity != null) { + return entity.teleport(BukkitAdapter.adapt(location)); + } else { + return false; + } + } + @Override public BaseEntity getState() { org.bukkit.entity.Entity entity = entityRef.get(); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java index 6e2182337..1d86a4fa8 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java @@ -236,6 +236,11 @@ public class BukkitPlayer extends AbstractPlayerActor { nativeLocation.getPitch()); } + @Override + public boolean setLocation(com.sk89q.worldedit.util.Location location) { + return player.teleport(BukkitAdapter.adapt(location)); + } + @Nullable @Override public T getFacet(Class cls) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Entity.java b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Entity.java index ef806ce7c..31bff6968 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Entity.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Entity.java @@ -54,6 +54,14 @@ public interface Entity extends Faceted { */ Location getLocation(); + /** + * Sets the location of this entity. + * + * @param location the new location of the entity + * @return if the teleport worked + */ + boolean setLocation(Location location); + /** * Get the extent that this entity is on. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java index b8f6eb22f..8d3b5434c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java @@ -115,6 +115,11 @@ public class PlayerProxy extends AbstractPlayerActor { return new Location(loc.getExtent(), loc.toVector().add(offset), loc.getDirection()); } + @Override + public boolean setLocation(Location location) { + return basePlayer.setLocation(location); + } + @Override public void setPosition(Vector3 pos, float pitch, float yaw) { basePlayer.setPosition(pos, pitch, yaw); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java index 2e5dc9d01..3bca28dab 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java @@ -115,6 +115,12 @@ public class ChangeSetExtent extends AbstractDelegateExtent { return entity.getLocation(); } + @Override + public boolean setLocation(Location location) { + // TODO Add a changeset for this. + return entity.setLocation(location); + } + @Override public Extent getExtent() { return entity.getExtent(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/StoredEntity.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/StoredEntity.java index 4b56e5e06..ebece5abf 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/StoredEntity.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/StoredEntity.java @@ -68,6 +68,11 @@ abstract class StoredEntity implements Entity { return location; } + @Override + public boolean setLocation(Location location) { + throw new IllegalArgumentException("StoredEntities are immutable"); + } + @Override public Extent getExtent() { return location.getExtent(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/BlockVectorAdapter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/BlockVectorAdapter.java new file mode 100644 index 000000000..8b86b7542 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/BlockVectorAdapter.java @@ -0,0 +1,46 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.util.gson; + +import com.google.gson.JsonArray; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.sk89q.worldedit.math.BlockVector3; + +import java.lang.reflect.Type; + +public class BlockVectorAdapter implements JsonDeserializer { + + @Override + public BlockVector3 deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + JsonArray jsonArray = json.getAsJsonArray(); + if (jsonArray.size() != 3) { + throw new JsonParseException("Expected array of 3 length for BlockVector3"); + } + + double x = jsonArray.get(0).getAsInt(); + double y = jsonArray.get(1).getAsInt(); + double z = jsonArray.get(2).getAsInt(); + + return BlockVector3.at(x, y, z); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/GsonUtil.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/GsonUtil.java index 5d73c68ea..358cd143d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/GsonUtil.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/GsonUtil.java @@ -21,6 +21,7 @@ package com.sk89q.worldedit.util.gson; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; /** @@ -39,6 +40,7 @@ public final class GsonUtil { public static GsonBuilder createBuilder() { GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(Vector3.class, new VectorAdapter()); + gsonBuilder.registerTypeAdapter(BlockVector3.class, new BlockVectorAdapter()); return gsonBuilder; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/VectorAdapter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/VectorAdapter.java index ec164d045..c76311299 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/VectorAdapter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/VectorAdapter.java @@ -29,7 +29,7 @@ import com.sk89q.worldedit.math.Vector3; import java.lang.reflect.Type; /** - * Deserializes {@code Vector}s for GSON. + * Deserializes {@code Vector3}s for GSON. */ public class VectorAdapter implements JsonDeserializer { @@ -37,7 +37,7 @@ public class VectorAdapter implements JsonDeserializer { public Vector3 deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonArray jsonArray = json.getAsJsonArray(); if (jsonArray.size() != 3) { - throw new JsonParseException("Expected array of 3 length for Vector"); + throw new JsonParseException("Expected array of 3 length for Vector3"); } double x = jsonArray.get(0).getAsDouble(); diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntity.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntity.java index b5cd5f516..e4b391fe0 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntity.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntity.java @@ -76,6 +76,12 @@ class ForgeEntity implements Entity { } } + @Override + public boolean setLocation(Location location) { + // TODO + return false; + } + @Override public Extent getExtent() { net.minecraft.entity.Entity entity = entityRef.get(); diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java index 98842e5b8..007c08c23 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java @@ -88,6 +88,12 @@ public class ForgePlayer extends AbstractPlayerActor { this.player.rotationPitch); } + @Override + public boolean setLocation(Location location) { + // TODO + return false; + } + @Override public com.sk89q.worldedit.world.World getWorld() { return ForgeWorldEdit.inst.getWorld(this.player.world); diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java new file mode 100644 index 000000000..f5df77298 --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java @@ -0,0 +1,168 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.sponge; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.flowpowered.math.vector.Vector3d; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.math.Vector3; +import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.world.World; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.entity.living.player.Player; + +/** + * Adapts between Sponge and WorldEdit equivalent objects. + */ +public class SpongeAdapter { + + private SpongeAdapter() { + } + + /** + * Create a WorldEdit world from a Sponge extent. + * + * @param world the Sponge extent + * @return a WorldEdit world + */ + public static World checkWorld(org.spongepowered.api.world.extent.Extent world) { + checkNotNull(world); + if (world instanceof org.spongepowered.api.world.World) { + return adapt((org.spongepowered.api.world.World) world); + } else { + throw new IllegalArgumentException("Extent type is not a world"); + } + } + + /** + * Create a WorldEdit world from a Sponge world. + * + * @param world the Sponge world + * @return a WorldEdit world + */ + public static World adapt(org.spongepowered.api.world.World world) { + checkNotNull(world); + return SpongeWorldEdit.inst().getWorld(world); + } + + /** + * Create a WorldEdit Player from a Sponge Player. + * + * @param player The Sponge player + * @return The WorldEdit player + */ + public static SpongePlayer adapt(Player player) { + return SpongeWorldEdit.inst().wrapPlayer(player); + } + + /** + * Create a Bukkit Player from a WorldEdit Player. + * + * @param player The WorldEdit player + * @return The Bukkit player + */ + public static Player adapt(com.sk89q.worldedit.entity.Player player) { + return ((SpongePlayer) player).getPlayer(); + } + + /** + * Create a Sponge world from a WorldEdit world. + * + * @param world the WorldEdit world + * @return a Sponge world + */ + public static org.spongepowered.api.world.World adapt(World world) { + checkNotNull(world); + if (world instanceof SpongeWorld) { + return ((SpongeWorld) world).getWorld(); + } else { + org.spongepowered.api.world.World match = Sponge.getServer().getWorld(world.getName()).orElse(null); + if (match != null) { + return match; + } else { + throw new IllegalArgumentException("Can't find a Sponge world for " + world); + } + } + } + + /** + * Create a WorldEdit location from a Sponge location. + * + * @param location the Sponge location + * @return a WorldEdit location + */ + public static Location adapt(org.spongepowered.api.world.Location location, Vector3d rotation) { + checkNotNull(location); + Vector3 position = asVector(location); + return new Location( + adapt(location.getExtent()), + position, + (float) rotation.getX(), + (float) rotation.getY()); + } + + /** + * Create a Sponge location from a WorldEdit location. + * + * @param location the WorldEdit location + * @return a Sponge location + */ + public static org.spongepowered.api.world.Location adapt(Location location) { + checkNotNull(location); + Vector3 position = location.toVector(); + return new org.spongepowered.api.world.Location<>( + adapt((World) location.getExtent()), + position.getX(), position.getY(), position.getZ()); + } + + /** + * Create a Sponge rotation from a WorldEdit location. + * + * @param location the WorldEdit location + * @return a Sponge rotation + */ + public static Vector3d adaptRotation(Location location) { + checkNotNull(location); + return new Vector3d(location.getPitch(), location.getYaw(), 0); + } + + /** + * Create a WorldEdit Vector from a Bukkit location. + * + * @param location The Bukkit location + * @return a WorldEdit vector + */ + public static Vector3 asVector(org.spongepowered.api.world.Location location) { + checkNotNull(location); + return Vector3.at(location.getX(), location.getY(), location.getZ()); + } + + /** + * Create a WorldEdit BlockVector from a Bukkit location. + * + * @param location The Bukkit location + * @return a WorldEdit vector + */ + public static BlockVector3 asBlockVector(org.spongepowered.api.world.Location location) { + checkNotNull(location); + return BlockVector3.at(location.getX(), location.getY(), location.getZ()); + } +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntity.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntity.java index 9aa728310..db070d9f1 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntity.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntity.java @@ -66,6 +66,16 @@ class SpongeEntity implements Entity { } } + @Override + public boolean setLocation(Location location) { + org.spongepowered.api.entity.Entity entity = entityRef.get(); + if (entity != null) { + return entity.setLocation(SpongeAdapter.adapt(location)); + } else { + return false; + } + } + @Override public Extent getExtent() { org.spongepowered.api.entity.Entity entity = entityRef.get(); diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java index 08f7b47c3..3a4d74edd 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java @@ -96,6 +96,11 @@ public class SpongePlayer extends AbstractPlayerActor { return SpongeWorldEdit.inst().getAdapter().adapt(entityLoc, entityRot); } + @Override + public boolean setLocation(Location location) { + return player.setLocation(SpongeAdapter.adapt(location)); + } + @Override public com.sk89q.worldedit.world.World getWorld() { return SpongeWorldEdit.inst().getAdapter().getWorld(player.getWorld()); @@ -248,4 +253,7 @@ public class SpongePlayer extends AbstractPlayerActor { } + public Player getPlayer() { + return player; + } }