diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index fcc317b..d305e06 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -5,17 +5,13 @@
-
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
@@ -299,6 +295,7 @@
+
diff --git a/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java b/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java
index 0b6380d..5276ee7 100644
--- a/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java
+++ b/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java
@@ -2,6 +2,7 @@ package me.tofaa.entitylib;
import com.github.retrooper.packetevents.PacketEventsAPI;
import me.tofaa.entitylib.tick.TickContainer;
+import me.tofaa.entitylib.wrapper.WrapperEntity;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
@@ -25,6 +26,7 @@ public interface EntityLibAPI {
void onEnable();
+
/**
* Creates a wrapped world for the platform specific world.
* @param world The platform specific world handle.
diff --git a/api/src/main/java/me/tofaa/entitylib/utils/Check.java b/api/src/main/java/me/tofaa/entitylib/utils/Check.java
new file mode 100644
index 0000000..82816ea
--- /dev/null
+++ b/api/src/main/java/me/tofaa/entitylib/utils/Check.java
@@ -0,0 +1,64 @@
+package me.tofaa.entitylib.utils;
+
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.text.MessageFormat;
+import java.util.Objects;
+
+/**
+ * Convenient class to check for common exceptions. Taken from Minestom
+ */
+public final class Check {
+
+ private Check() {}
+
+ @Contract("null, _ -> fail")
+ public static void notNull(@Nullable Object object, @NotNull String reason) {
+ if (Objects.isNull(object)) {
+ throw new NullPointerException(reason);
+ }
+ }
+
+ @Contract("null, _, _ -> fail")
+ public static void notNull(@Nullable Object object, @NotNull String reason, Object... arguments) {
+ if (Objects.isNull(object)) {
+ throw new NullPointerException(MessageFormat.format(reason, arguments));
+ }
+ }
+
+ @Contract("true, _ -> fail")
+ public static void argCondition(boolean condition, @NotNull String reason) {
+ if (condition) {
+ throw new IllegalArgumentException(reason);
+ }
+ }
+
+ @Contract("true, _, _ -> fail")
+ public static void argCondition(boolean condition, @NotNull String reason, Object... arguments) {
+ if (condition) {
+ throw new IllegalArgumentException(MessageFormat.format(reason, arguments));
+ }
+ }
+
+ @Contract("_ -> fail")
+ public static void fail(@NotNull String reason) {
+ throw new IllegalArgumentException(reason);
+ }
+
+ @Contract("true, _ -> fail")
+ public static void stateCondition(boolean condition, @NotNull String reason) {
+ if (condition) {
+ throw new IllegalStateException(reason);
+ }
+ }
+
+ @Contract("true, _, _ -> fail")
+ public static void stateCondition(boolean condition, @NotNull String reason, Object... arguments) {
+ if (condition) {
+ throw new IllegalStateException(MessageFormat.format(reason, arguments));
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java
index 3790363..ddc4fda 100644
--- a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java
@@ -45,6 +45,10 @@ public class WrapperEntity implements Tickable {
this.viewers = new HashSet<>();
}
+ public boolean spawn(Location location) {
+ return spawn(null, location);
+ }
+
public boolean spawn(WorldWrapper> world, Location location) {
if (spawned) return false;
this.location = location;
@@ -117,6 +121,14 @@ public class WrapperEntity implements Tickable {
teleport(world, location, onGround);
}
+ public void teleport(@NotNull Location location, boolean onGround) {
+ teleport(null, location, onGround);
+ }
+
+ public void teleport(@NotNull Location location) {
+ teleport(null, location, onGround);
+ }
+
/**
* Adds a viewer to the viewers set. The viewer will receive all packets and be informed of this addition
* @param uuid the uuid of the user to add
@@ -160,6 +172,10 @@ public class WrapperEntity implements Tickable {
addViewerSilently(user.getUUID());
}
+ /**
+ * Removes a viewer from the viewers set of this entity. The viewer will be informed of this removal and will no longer receive any packets
+ * @param UUID the uuid of the user to remove
+ */
public void removeViewer(UUID uuid) {
if (!viewers.remove(uuid)) {
return;
@@ -167,6 +183,10 @@ public class WrapperEntity implements Tickable {
sendPacket(uuid, new WrapperPlayServerDestroyEntities(entityId));
}
+ /**
+ * Removes a viewer from the viewers set of this entity. The viewer will be informed of this removal and will no longer receive any packets
+ * @param user the user to remove
+ */
public void removeViewer(User user) {
removeViewer(user.getUUID());
}
diff --git a/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/Hologram.java b/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/Hologram.java
index 5d684f6..a2bc891 100644
--- a/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/Hologram.java
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/hologram/Hologram.java
@@ -22,7 +22,6 @@ public interface Hologram {
return new LegacyHologram<>(world, location, lines);
}
-
@NotNull Location getLocation();
@NotNull WorldWrapper getWorld();
diff --git a/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/ExtraConversionUtil.java b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/ExtraConversionUtil.java
new file mode 100644
index 0000000..75e554d
--- /dev/null
+++ b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/ExtraConversionUtil.java
@@ -0,0 +1,23 @@
+package me.tofaa.entitylib.spigot;
+
+import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
+import com.github.retrooper.packetevents.protocol.player.HumanoidArm;
+import org.bukkit.entity.Pose;
+import org.bukkit.inventory.MainHand;
+
+public final class ExtraConversionUtil {
+
+ private ExtraConversionUtil() {
+
+ }
+
+ public static EntityPose fromBukkitPose(Pose pose) {
+ return EntityPose.values()[pose.ordinal()];
+ }
+
+ public static HumanoidArm fromBukkitHand(MainHand hand) {
+ if (hand == MainHand.RIGHT) return HumanoidArm.RIGHT;
+ return HumanoidArm.LEFT;
+ }
+
+}
diff --git a/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotWorld.java b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotWorld.java
index cecd18e..f01c7b5 100644
--- a/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotWorld.java
+++ b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotWorld.java
@@ -4,8 +4,17 @@ import com.github.retrooper.packetevents.protocol.world.Location;
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
import me.tofaa.entitylib.common.AbstractWorldWrapper;
+import me.tofaa.entitylib.meta.EntityMeta;
+import me.tofaa.entitylib.meta.types.LivingEntityMeta;
+import me.tofaa.entitylib.meta.types.PlayerMeta;
+import me.tofaa.entitylib.utils.Check;
import me.tofaa.entitylib.wrapper.WrapperEntity;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.World;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class SpigotWorld extends AbstractWorldWrapper {
@@ -18,7 +27,31 @@ public class SpigotWorld extends AbstractWorldWrapper {
@Override
public @NotNull T cloneEntity(@NotNull Object platformEntity, @NotNull Location location) {
- return null;
+ Check.stateCondition(!(platformEntity instanceof Entity), "Entity must be a Bukkit entity");
+ Entity e = (Entity) platformEntity;
+ EntityMeta meta = EntityMeta.createMeta(e.getEntityId(), SpigotConversionUtil.fromBukkitEntityType(e.getType()));
+ meta.setHasNoGravity(!e.hasGravity());
+ meta.setCustomNameVisible(e.isCustomNameVisible());
+ meta.setCustomName(LegacyComponentSerializer.legacyAmpersand().deserialize(e.getCustomName()));
+ meta.setPose(ExtraConversionUtil.fromBukkitPose(e.getPose()));
+ meta.setOnFire(e.getFireTicks() > 0);
+ meta.setSilent(e.isSilent());
+ meta.setHasGlowingEffect(e.isGlowing());
+ if (e instanceof LivingEntity) {
+ LivingEntity le = (LivingEntity) e;
+ LivingEntityMeta lm = (LivingEntityMeta) meta;
+ lm.setHealth((float) le.getHealth());
+ lm.setFlyingWithElytra(le.isGliding());
+ }
+ if (e instanceof Player) {
+ Player p = (Player) e;
+ PlayerMeta pm = (PlayerMeta) meta;
+ pm.setSneaking(p.isSneaking());
+ pm.setSprinting(p.isSprinting());
+ pm.setSwimming(p.isSwimming());
+ pm.setActiveHand(ExtraConversionUtil.fromBukkitHand(p.getMainHand()));
+ }
+ return null; // TODO;
}
@Override