From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Sat, 9 Jan 2021 15:26:04 +0100
Subject: [PATCH] Add EntityTeleportHinderedEvent

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

diff --git a/src/main/java/net/pl3x/purpur/event/entity/EntityTeleportHinderedEvent.java b/src/main/java/net/pl3x/purpur/event/entity/EntityTeleportHinderedEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..e6fcc4027cb70061b804460b39e00cca273d35ad
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/event/entity/EntityTeleportHinderedEvent.java
@@ -0,0 +1,117 @@
+package net.pl3x.purpur.event.entity;
+
+import org.bukkit.entity.Entity;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Fired when an entity is hindered from teleporting.
+ */
+public class EntityTeleportHinderedEvent extends EntityEvent {
+  private static final HandlerList handlers = new HandlerList();
+
+  @NotNull
+  private final Reason reason;
+
+  @Nullable
+  private final TeleportCause teleportCause;
+
+  private boolean retry = false;
+
+  public EntityTeleportHinderedEvent(@NotNull Entity what, @NotNull Reason reason,
+      @Nullable TeleportCause teleportCause) {
+    super(what);
+    this.reason = reason;
+    this.teleportCause = teleportCause;
+  }
+
+  /**
+   * @return why the teleport was hindered.
+   */
+  @NotNull
+  public Reason getReason() {
+    return reason;
+  }
+
+  /**
+   * @return why the teleport occurred if cause was given, otherwise {@code null}.
+   */
+  @Nullable
+  public TeleportCause getTeleportCause() {
+    return teleportCause;
+  }
+
+  /**
+   * Whether the teleport should be retried.
+   * <p>
+   * Note that this can put the server in a never-ending loop of trying to teleport someone resulting in a stack
+   * overflow. Do not retry more than necessary.
+   * </p>
+   *
+   * @return whether the teleport should be retried.
+   */
+  public boolean shouldRetry() {
+    return retry;
+  }
+
+  /**
+   * Sets whether the teleport should be retried.
+   * <p>
+   * Note that this can put the server in a never-ending loop of trying to teleport someone resulting in a stack
+   * overflow. Do not retry more than necessary.
+   * </p>
+   *
+   * @param retry whether the teleport should be retried.
+   */
+  public void setShouldRetry(boolean retry) {
+    this.retry = retry;
+  }
+
+  /**
+   * Calls the event and tests if should retry.
+   *
+   * @return whether the teleport should be retried.
+   */
+  @Override
+  public boolean callEvent() {
+    super.callEvent();
+    return shouldRetry();
+  }
+
+  @Override
+  @NotNull
+  public HandlerList getHandlers() {
+    return handlers;
+  }
+
+  @NotNull
+  public static HandlerList getHandlerList() {
+    return handlers;
+  }
+
+  /**
+   * Reason for hindrance in teleports.
+   */
+  public enum Reason {
+    /**
+     * The teleported entity is a passenger of another entity.
+     */
+    IS_PASSENGER,
+
+    /**
+     * The teleported entity has passengers.
+     */
+    IS_VEHICLE,
+
+    /**
+     * The teleport event was cancelled.
+     * <p>
+     * This is only caused by players teleporting.
+     * </p>
+     */
+    EVENT_CANCELLED,
+  }
+}
