per player entities

This commit is contained in:
= 2024-11-14 01:42:46 +02:00
parent 0d99f705e8
commit ccea96a6ad
4 changed files with 86 additions and 6 deletions

View file

@ -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());
}

View file

@ -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<UUID, WrapperEntity> entities = new ConcurrentHashMap<>();
private Function<User, WrapperEntity> baseSupplier;
public WrapperPerPlayerEntity(Function<User, WrapperEntity> baseSupplier) {
this.baseSupplier = baseSupplier;
}
public void setBaseSupplier(Function<User, WrapperEntity> baseSupplier) {
this.baseSupplier = baseSupplier;
}
public Function<User, WrapperEntity> 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<WrapperEntity> consumer) {
entities.values().forEach(consumer);
}
public boolean check(Predicate<WrapperEntity> predicate) {
if (entities.isEmpty()) return false;
WrapperEntity e= entities.values().stream().findFirst().get();
return predicate.test(e);
}
public void modify(User user, Consumer<WrapperEntity> 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;
}
}
}

View file

@ -7,6 +7,6 @@ import me.tofaa.entitylib.wrapper.WrapperEntity;
@FunctionalInterface
public interface SpawnPacketProvider<T extends PacketWrapper<T>> extends SpawnPacketProviders {
T provide(User user, WrapperEntity entity);
T provide(WrapperEntity entity);
}

View file

@ -13,7 +13,7 @@ import java.util.Optional;
interface SpawnPacketProviders {
@NotNull SpawnPacketProvider<WrapperPlayServerSpawnExperienceOrb> EXPERIENCE_ORB = (user, entity) -> {
@NotNull SpawnPacketProvider<WrapperPlayServerSpawnExperienceOrb> 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<WrapperPlayServerSpawnEntity> GENERAL = (user, entity) -> {
@NotNull SpawnPacketProvider<WrapperPlayServerSpawnEntity> GENERAL = (entity) -> {
Location location = entity.getLocation();
return new WrapperPlayServerSpawnEntity(
entity.getEntityId(),
@ -40,10 +40,10 @@ interface SpawnPacketProviders {
);
};
@NotNull SpawnPacketProvider<WrapperPlayServerSpawnWeatherEntity> LEGACY_WEATHER_ENTITY = (user, entity) -> {
@NotNull SpawnPacketProvider<WrapperPlayServerSpawnWeatherEntity> LEGACY_WEATHER_ENTITY = (entity) -> {
throw new NotImplementedException();
};
@NotNull SpawnPacketProvider<WrapperPlayServerSpawnPainting> LEGACY_PAINTING = (user, entity) -> {
@NotNull SpawnPacketProvider<WrapperPlayServerSpawnPainting> 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<WrapperPlayServerSpawnLivingEntity> PRE_1_19_LIVING = (user, entity) -> {
@NotNull SpawnPacketProvider<WrapperPlayServerSpawnLivingEntity> PRE_1_19_LIVING = (entity) -> {
Location location = entity.getLocation();
return new WrapperPlayServerSpawnLivingEntity(
entity.getEntityId(),