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 9584452..99d5155 100644 --- a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java +++ b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java @@ -92,6 +92,11 @@ public class WrapperEntity implements Tickable { return true; } + public PacketWrapper getSpawnPacket(User user) { + // TODO: Version/EntityType compatibility + return SpawnPacketProvider.GENERAL.provide(this); + } + public boolean spawn(Location location) { return spawn(location, EntityLib.getApi().getDefaultContainer()); } diff --git a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPerPlayerEntity.java b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPerPlayerEntity.java new file mode 100644 index 0000000..e27f286 --- /dev/null +++ b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPerPlayerEntity.java @@ -0,0 +1,75 @@ +package me.tofaa.entitylib.wrapper; + + +import com.github.retrooper.packetevents.protocol.player.User; +import com.github.retrooper.packetevents.protocol.world.Location; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; + +/** + * Generic utility for per player wrapper entities. + * These spawn in the same spot for everyone. + */ +public class WrapperPerPlayerEntity { + + private final Map entities = new ConcurrentHashMap<>(); + private Function baseSupplier; + + public WrapperPerPlayerEntity(Function baseSupplier) { + this.baseSupplier = baseSupplier; + } + + public void setBaseSupplier(Function baseSupplier) { + this.baseSupplier = baseSupplier; + } + + public Function getBaseSupplier() { + return baseSupplier; + } + + public void spawn(Location location) { + if (check(WrapperEntity::isSpawned)) { + return; + } + execute(e -> e.spawn(location)); + } + + public void addViewer(User user) { + getEntityOf(user).addViewer(user); + } + + public void removeViewer(User user) { + getEntityOf(user).removeViewer(user); + } + + public void execute(Consumer consumer) { + entities.values().forEach(consumer); + } + + public boolean check(Predicate predicate) { + if (entities.isEmpty()) return false; + WrapperEntity e= entities.values().stream().findFirst().get(); + return predicate.test(e); + } + + public void modify(User user, Consumer consumer) { + consumer.accept(getEntityOf(user)); + } + + public WrapperEntity getEntityOf(User user) { + if (this.entities.containsKey(user.getUUID())) { + return this.entities.get(user.getUUID()); + } + else { + WrapperEntity e = baseSupplier.apply(user); + this.entities.put(user.getUUID(), e); + return e; + } + } + +} diff --git a/api/src/main/java/me/tofaa/entitylib/wrapper/spawning/SpawnPacketProvider.java b/api/src/main/java/me/tofaa/entitylib/wrapper/spawning/SpawnPacketProvider.java index 75c6086..04de61e 100644 --- a/api/src/main/java/me/tofaa/entitylib/wrapper/spawning/SpawnPacketProvider.java +++ b/api/src/main/java/me/tofaa/entitylib/wrapper/spawning/SpawnPacketProvider.java @@ -7,6 +7,6 @@ import me.tofaa.entitylib.wrapper.WrapperEntity; @FunctionalInterface public interface SpawnPacketProvider> extends SpawnPacketProviders { - T provide(User user, WrapperEntity entity); + T provide(WrapperEntity entity); } diff --git a/api/src/main/java/me/tofaa/entitylib/wrapper/spawning/SpawnPacketProviders.java b/api/src/main/java/me/tofaa/entitylib/wrapper/spawning/SpawnPacketProviders.java index c4fa136..0e92838 100644 --- a/api/src/main/java/me/tofaa/entitylib/wrapper/spawning/SpawnPacketProviders.java +++ b/api/src/main/java/me/tofaa/entitylib/wrapper/spawning/SpawnPacketProviders.java @@ -13,7 +13,7 @@ import java.util.Optional; interface SpawnPacketProviders { - @NotNull SpawnPacketProvider EXPERIENCE_ORB = (user, entity) -> { + @NotNull SpawnPacketProvider EXPERIENCE_ORB = (entity) -> { Check.stateCondition(!(entity instanceof WrapperExperienceOrbEntity), "Attempted to use spawn packet provider for Experience orbs on a non ExperienceOrb entity. Please use an instance of WrapperExperienceOrbEntity."); WrapperExperienceOrbEntity expEntity = (WrapperExperienceOrbEntity) entity; return new WrapperPlayServerSpawnExperienceOrb( @@ -25,7 +25,7 @@ interface SpawnPacketProviders { ); }; - @NotNull SpawnPacketProvider GENERAL = (user, entity) -> { + @NotNull SpawnPacketProvider GENERAL = (entity) -> { Location location = entity.getLocation(); return new WrapperPlayServerSpawnEntity( entity.getEntityId(), @@ -40,10 +40,10 @@ interface SpawnPacketProviders { ); }; - @NotNull SpawnPacketProvider LEGACY_WEATHER_ENTITY = (user, entity) -> { + @NotNull SpawnPacketProvider LEGACY_WEATHER_ENTITY = (entity) -> { throw new NotImplementedException(); }; - @NotNull SpawnPacketProvider LEGACY_PAINTING = (user, entity) -> { + @NotNull SpawnPacketProvider LEGACY_PAINTING = (entity) -> { Check.stateCondition(!(entity.getEntityMeta() instanceof PaintingMeta), "Attempted to use spawn packet provider for paintings but not using an entity with PaintingMeta."); PaintingMeta meta = entity.getEntityMeta(PaintingMeta.class); return new WrapperPlayServerSpawnPainting( @@ -55,7 +55,7 @@ interface SpawnPacketProviders { ); }; - @NotNull SpawnPacketProvider PRE_1_19_LIVING = (user, entity) -> { + @NotNull SpawnPacketProvider PRE_1_19_LIVING = (entity) -> { Location location = entity.getLocation(); return new WrapperPlayServerSpawnLivingEntity( entity.getEntityId(),