diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitPlatform.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitPlatform.java index e1055644a..6e1545272 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitPlatform.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitPlatform.java @@ -2,10 +2,12 @@ package net.momirealms.craftengine.bukkit.plugin; import com.google.gson.JsonElement; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.momirealms.craftengine.bukkit.api.BukkitAdaptors; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistryOps; import net.momirealms.craftengine.core.plugin.Platform; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; +import net.momirealms.craftengine.core.world.World; import net.momirealms.sparrow.nbt.CompoundTag; import net.momirealms.sparrow.nbt.Tag; import org.bukkit.Bukkit; @@ -51,4 +53,13 @@ public class BukkitPlatform implements Platform { public Tag javaToSparrowNBT(Object object) { return MRegistryOps.JAVA.convertTo(MRegistryOps.SPARROW_NBT, object); } + + @Override + public World getWorld(String name) { + org.bukkit.World world = Bukkit.getWorld(name); + if (world == null) { + return null; + } + return BukkitAdaptors.adapt(world); + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java index 4ec9a9a20..5b9512f15 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java @@ -37,10 +37,8 @@ import net.momirealms.craftengine.core.util.Direction; import net.momirealms.craftengine.core.util.IntIdentityList; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.VersionHelper; -import net.momirealms.craftengine.core.world.BlockPos; -import net.momirealms.craftengine.core.world.Vec3d; +import net.momirealms.craftengine.core.world.*; import net.momirealms.craftengine.core.world.World; -import net.momirealms.craftengine.core.world.WorldEvents; import net.momirealms.craftengine.core.world.chunk.ChunkStatus; import net.momirealms.craftengine.core.world.collision.AABB; import org.bukkit.*; @@ -48,6 +46,7 @@ import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeInstance; import org.bukkit.block.Block; import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; @@ -1094,4 +1093,10 @@ public class BukkitServerPlayer extends Player { public void clearTrackedChunks() { this.trackedChunks.clear(); } + + @Override + public void teleport(WorldPosition worldPosition) { + Location location = new Location((org.bukkit.World) worldPosition.world().platformWorld(), worldPosition.x(), worldPosition.y(), worldPosition.z(), worldPosition.yRot(), worldPosition.xRot()); + this.platformPlayer().teleportAsync(location, PlayerTeleportEvent.TeleportCause.PLUGIN); + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java b/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java index 6675659ba..3ed4302fc 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java @@ -8,6 +8,8 @@ import net.momirealms.craftengine.core.plugin.network.NetWorkUser; import net.momirealms.craftengine.core.sound.SoundSource; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.world.BlockPos; +import net.momirealms.craftengine.core.world.Position; +import net.momirealms.craftengine.core.world.WorldPosition; import org.jetbrains.annotations.NotNull; public abstract class Player extends AbstractEntity implements NetWorkUser { @@ -148,4 +150,6 @@ public abstract class Player extends AbstractEntity implements NetWorkUser { public abstract void clearPotionEffects(); public abstract CooldownData cooldown(); + + public abstract void teleport(WorldPosition worldPosition); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java index 276dc3ee8..b2759fd4b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java @@ -35,6 +35,7 @@ import net.momirealms.craftengine.core.plugin.logger.filter.LogFilter; import net.momirealms.craftengine.core.plugin.network.NetworkManager; import net.momirealms.craftengine.core.plugin.scheduler.SchedulerAdapter; import net.momirealms.craftengine.core.sound.SoundManager; +import net.momirealms.craftengine.core.world.World; import net.momirealms.craftengine.core.world.WorldManager; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.core.Logger; diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/Platform.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/Platform.java index 03e0c52b2..3ab8e0267 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/Platform.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/Platform.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.plugin; import com.google.gson.JsonElement; +import net.momirealms.craftengine.core.world.World; import net.momirealms.sparrow.nbt.Tag; public interface Platform { @@ -14,4 +15,6 @@ public interface Platform { Tag snbtToSparrowNBT(String nbt); Tag javaToSparrowNBT(Object object); + + World getWorld(String name); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/event/EventFunctions.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/event/EventFunctions.java index fbb129296..bfde55253 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/event/EventFunctions.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/event/EventFunctions.java @@ -42,6 +42,7 @@ public class EventFunctions { register(CommonFunctions.REMOVE_FURNITURE, new RemoveFurnitureFunction.FactoryImpl<>(EventConditions::fromMap)); register(CommonFunctions.REPLACE_FURNITURE, new ReplaceFurnitureFunction.FactoryImpl<>(EventConditions::fromMap)); register(CommonFunctions.MYTHIC_MOBS_SKILL, new MythicMobsSkillFunction.FactoryImpl<>(EventConditions::fromMap)); + register(CommonFunctions.TELEPORT, new TeleportFunction.FactoryImpl<>(EventConditions::fromMap)); } public static void register(Key key, FunctionFactory factory) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CommonFunctions.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CommonFunctions.java index bede6e946..5f1d6d787 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CommonFunctions.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/CommonFunctions.java @@ -31,4 +31,6 @@ public final class CommonFunctions { public static final Key REMOVE_FURNITURE = Key.of("craftengine:remove_furniture"); public static final Key REPLACE_FURNITURE = Key.of("craftengine:replace_furniture"); public static final Key MYTHIC_MOBS_SKILL = Key.of("craftengine:mythic_mobs_skill"); + public static final Key TELEPORT = Key.of("craftengine:teleport"); + public static final Key TOAST = Key.of("craftengine:toast"); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/TeleportFunction.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/TeleportFunction.java new file mode 100644 index 000000000..1455c93ab --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/function/TeleportFunction.java @@ -0,0 +1,104 @@ +package net.momirealms.craftengine.core.plugin.context.function; + +import net.momirealms.craftengine.core.entity.player.Player; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.Platform; +import net.momirealms.craftengine.core.plugin.context.*; +import net.momirealms.craftengine.core.plugin.context.number.NumberProvider; +import net.momirealms.craftengine.core.plugin.context.number.NumberProviders; +import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextParameters; +import net.momirealms.craftengine.core.plugin.context.selector.PlayerSelector; +import net.momirealms.craftengine.core.plugin.context.selector.PlayerSelectors; +import net.momirealms.craftengine.core.plugin.context.text.TextProvider; +import net.momirealms.craftengine.core.plugin.context.text.TextProviders; +import net.momirealms.craftengine.core.util.AdventureHelper; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.MiscUtils; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import net.momirealms.craftengine.core.world.Vec3d; +import net.momirealms.craftengine.core.world.WorldPosition; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Text; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Consumer; + +public class TeleportFunction extends AbstractConditionalFunction { + private final PlayerSelector selector; + @Nullable + private final TextProvider world; + private final NumberProvider x; + private final NumberProvider y; + private final NumberProvider z; + private final NumberProvider pitch; + private final NumberProvider yaw; + + public TeleportFunction(List> predicates, @Nullable PlayerSelector selector, @Nullable TextProvider world, + NumberProvider x, NumberProvider y, NumberProvider z, NumberProvider pitch, NumberProvider yaw) { + super(predicates); + this.selector = selector; + this.world = world; + this.x = x; + this.y = y; + this.z = z; + this.pitch = pitch; + this.yaw = yaw; + } + + @Override + public void runInternal(CTX ctx) { + if (this.selector == null) { + ctx.getOptionalParameter(DirectContextParameters.PLAYER).ifPresent(it -> { + it.teleport(new WorldPosition( + Optional.ofNullable(this.world).map(w -> w.get(ctx)).map(w -> CraftEngine.instance().platform().getWorld(w)).orElse(it.world()), + this.x.getDouble(ctx), + this.y.getDouble(ctx), + this.z.getDouble(ctx), + this.pitch.getFloat(ctx), + this.yaw.getFloat(ctx)) + ); + }); + } else { + for (Player viewer : this.selector.get(ctx)) { + RelationalContext relationalContext = ViewerContext.of(ctx, PlayerOptionalContext.of(viewer, ContextHolder.EMPTY)); + viewer.teleport(new WorldPosition( + Optional.ofNullable(this.world).map(w -> w.get(relationalContext)).map(w -> CraftEngine.instance().platform().getWorld(w)).orElse(viewer.world()), + this.x.getDouble(relationalContext), + this.y.getDouble(relationalContext), + this.z.getDouble(relationalContext), + this.pitch.getFloat(relationalContext), + this.yaw.getFloat(relationalContext)) + ); + } + } + } + + @Override + public Key type() { + return CommonFunctions.TELEPORT; + } + + public static class FactoryImpl extends AbstractFactory { + + public FactoryImpl(java.util.function.Function, Condition> factory) { + super(factory); + } + + @Override + public Function create(Map arguments) { + TextProvider world = Optional.ofNullable(arguments.get("world")).map(String::valueOf).map(TextProviders::fromString).orElse(null); + NumberProvider x = NumberProviders.fromObject(ResourceConfigUtils.requireNonNullOrThrow(arguments.get("x"), "warning.config.function.teleport.missing_x")); + NumberProvider y = NumberProviders.fromObject(ResourceConfigUtils.requireNonNullOrThrow(arguments.get("y"), "warning.config.function.teleport.missing_y")); + NumberProvider z = NumberProviders.fromObject(ResourceConfigUtils.requireNonNullOrThrow(arguments.get("z"), "warning.config.function.teleport.missing_z")); + NumberProvider yaw = NumberProviders.fromObject(arguments.getOrDefault("yaw", 0)); + NumberProvider pitch = NumberProviders.fromObject(arguments.getOrDefault("pitch", 0)); + return new TeleportFunction<>( + getPredicates(arguments), + PlayerSelectors.fromObject(arguments.get("target"), conditionFactory()), + world, x, y, z, pitch, yaw + ); + } + } +}