Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,22 @@

public interface EntityData<T> {

Object serializer();
int id();
Object entityDataAccessor();
T defaultValue();

default Object createEntityDataIfNotDefaultValue(T value) {
if (defaultValue().equals(value)) return null;
return EntityDataValue.create(id(), serializer(), value);
return EntityDataValue.create(entityDataAccessor(), value);
}

default void addEntityDataIfNotDefaultValue(T value, List<Object> list) {
if (!defaultValue().equals(value)) {
list.add(EntityDataValue.create(id(), serializer(), value));
list.add(EntityDataValue.create(entityDataAccessor(), value));
}
}

default void addEntityData(T value, List<Object> list) {
list.add(EntityDataValue.create(id(), serializer(), value));
list.add(EntityDataValue.create(entityDataAccessor(), value));
}

static <T> EntityData<T> of(int id, Object serializer, T defaultValue) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ private EntityDataValue() {
throw new IllegalAccessError("Utility class");
}

public static Object create(int id, Object serializer, Object value) {
Object entityDataAccessor = FastNMS.INSTANCE.constructor$EntityDataAccessor(id, serializer);
public static Object create(Object entityDataAccessor, Object value) {
return FastNMS.INSTANCE.method$SynchedEntityData$DataValue$create(entityDataAccessor, value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package net.momirealms.craftengine.bukkit.entity.data;

import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;

public class PlayerData<T> extends LivingEntityData<T> {
public static final PlayerData<Object> Pose = new PlayerData<>(6, EntityDataValue.Serializers$POSE, CoreReflections.instance$Pose$STANDING);
public static final PlayerData<Byte> Skin = new PlayerData<>(17, EntityDataValue.Serializers$BYTE, (byte) 0);
public static final PlayerData<Byte> Hand = new PlayerData<>(18, EntityDataValue.Serializers$BYTE, (byte) 0);
public static final PlayerData<Object> LShoulder = new PlayerData<>(19, EntityDataValue.Serializers$COMPOUND_TAG, CoreReflections.instance$CompoundTag$Empty);
public static final PlayerData<Object> RShoulder = new PlayerData<>(20, EntityDataValue.Serializers$COMPOUND_TAG, CoreReflections.instance$CompoundTag$Empty);

public PlayerData(int id, Object serializer, T defaultValue) {
super(id, serializer, defaultValue);
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@
package net.momirealms.craftengine.bukkit.entity.data;

import net.momirealms.craftengine.bukkit.nms.FastNMS;

public class SimpleEntityData<T> implements EntityData<T> {
private final int id;
private final Object serializer;
private final Object entityDataAccessor;
private final T defaultValue;

public SimpleEntityData(int id, Object serializer, T defaultValue) {
this.id = id;
this.serializer = serializer;
this.entityDataAccessor = FastNMS.INSTANCE.constructor$EntityDataAccessor(id, serializer);
this.defaultValue = defaultValue;
}

@Override
public int id() {
return id;
}

@Override
public Object serializer() {
return serializer;
public T defaultValue() {
return this.defaultValue;
}

@Override
public T defaultValue() {
return defaultValue;
public Object entityDataAccessor() {
return this.entityDataAccessor;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import net.momirealms.craftengine.bukkit.entity.BukkitEntity;
import net.momirealms.craftengine.bukkit.entity.furniture.seat.BukkitSeatEntity;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.network.BukkitNetworkManager;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.util.EntityUtils;
import net.momirealms.craftengine.bukkit.util.LegacyAttributeUtils;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
import net.momirealms.craftengine.bukkit.util.LocationUtils;
import net.momirealms.craftengine.bukkit.util.PlayerUtils;
import net.momirealms.craftengine.core.entity.furniture.*;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.ArrayUtils;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.QuaternionUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
import net.momirealms.craftengine.core.world.WorldPosition;
import net.momirealms.craftengine.core.world.collision.AABB;
import org.bukkit.Location;
import org.bukkit.attribute.Attribute;
import org.bukkit.entity.*;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -50,7 +51,7 @@ public class BukkitFurniture implements Furniture {
private final boolean hasExternalModel;
// seats
private final Set<Vector3f> occupiedSeats = Collections.synchronizedSet(new HashSet<>());
private final Vector<WeakReference<Entity>> seats = new Vector<>();
private final Map<Integer, BukkitSeatEntity> seats = Collections.synchronizedMap(new HashMap<>());
// cached spawn packet
private Object cachedSpawnPacket;
private Object cachedMinimizedSpawnPacket;
Expand Down Expand Up @@ -190,24 +191,13 @@ public void destroy() {
if (entity != null)
entity.destroy();
}
for (WeakReference<Entity> r : this.seats) {
Entity entity = r.get();
if (entity == null) continue;
for (Entity passenger : entity.getPassengers()) {
entity.removePassenger(passenger);
}
entity.remove();
}
this.seats.clear();
destroySeats();
}

@Override
public void destroySeats() {
for (WeakReference<Entity> entity : this.seats) {
Entity e = entity.get();
if (e != null) {
e.remove();
}
for (BukkitSeatEntity seat : this.seats.values()) {
seat.destroy();
}
this.seats.clear();
}
Expand Down Expand Up @@ -295,7 +285,13 @@ public boolean hasExternalModel() {

@Override
public void spawnSeatEntityForPlayer(net.momirealms.craftengine.core.entity.player.Player player, Seat seat) {
spawnSeatEntityForPlayer((Player) player.platformPlayer(), seat);
BukkitSeatEntity seatEntity = (BukkitSeatEntity) seat.spawn(player, this);
this.seats.put(seatEntity.playerID(), seatEntity);
player.setSeat(seatEntity);
BukkitServerPlayer serverPlayer = (BukkitServerPlayer) player;
for (Player p : PlayerUtils.getTrackedBy(serverPlayer.platformPlayer())) {
BukkitNetworkManager.instance().getOnlineUser(p).entityPacketHandlers().put(seatEntity.playerID(), seatEntity);
}
}

@Override
Expand All @@ -318,39 +314,7 @@ public void save() {
}
}

private void spawnSeatEntityForPlayer(org.bukkit.entity.Player player, Seat seat) {
Location location = this.calculateSeatLocation(seat);
Entity seatEntity = seat.limitPlayerRotation() ?
EntityUtils.spawnEntity(player.getWorld(), VersionHelper.isOrAbove1_20_2() ? location.subtract(0,0.9875,0) : location.subtract(0,0.990625,0), EntityType.ARMOR_STAND, entity -> {
ArmorStand armorStand = (ArmorStand) entity;
if (VersionHelper.isOrAbove1_21_3()) {
Objects.requireNonNull(armorStand.getAttribute(Attribute.MAX_HEALTH)).setBaseValue(0.01);
} else {
LegacyAttributeUtils.setMaxHealth(armorStand);
}
armorStand.setSmall(true);
armorStand.setInvisible(true);
armorStand.setSilent(true);
armorStand.setInvulnerable(true);
armorStand.setArms(false);
armorStand.setCanTick(false);
armorStand.setAI(false);
armorStand.setGravity(false);
armorStand.setPersistent(false);
armorStand.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_SEAT_BASE_ENTITY_KEY, PersistentDataType.INTEGER, this.baseEntityId());
armorStand.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_SEAT_VECTOR_3F_KEY, PersistentDataType.STRING, seat.offset().x + ", " + seat.offset().y + ", " + seat.offset().z);
}) :
EntityUtils.spawnEntity(player.getWorld(), VersionHelper.isOrAbove1_20_2() ? location : location.subtract(0,0.25,0), EntityType.ITEM_DISPLAY, entity -> {
ItemDisplay itemDisplay = (ItemDisplay) entity;
itemDisplay.setPersistent(false);
itemDisplay.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_SEAT_BASE_ENTITY_KEY, PersistentDataType.INTEGER, this.baseEntityId());
itemDisplay.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_SEAT_VECTOR_3F_KEY, PersistentDataType.STRING, seat.offset().x + ", " + seat.offset().y + ", " + seat.offset().z);
});
this.seats.add(new WeakReference<>(seatEntity));
seatEntity.addPassenger(player);
}

private Location calculateSeatLocation(Seat seat) {
public Location calculateSeatLocation(Seat seat) {
Vector3f offset = QuaternionUtils.toQuaternionf(0, Math.toRadians(180 - this.location.getYaw()), 0).conjugate().transform(new Vector3f(seat.offset()));
double yaw = seat.yaw() + this.location.getYaw();
if (yaw < -180) yaw += 360;
Expand All @@ -359,4 +323,12 @@ private Location calculateSeatLocation(Seat seat) {
newLocation.add(offset.x, offset.y + 0.6, -offset.z);
return newLocation;
}

public BukkitSeatEntity seatByEntityId(int id) {
return this.seats.get(id);
}

public void removeSeatEntity(int id) {
this.seats.remove(id);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package net.momirealms.craftengine.bukkit.entity.furniture;

import net.momirealms.craftengine.bukkit.api.BukkitAdaptors;
import net.momirealms.craftengine.bukkit.entity.furniture.hitbox.InteractionHitBox;
import net.momirealms.craftengine.bukkit.entity.furniture.seat.BukkitSeatEntity;
import net.momirealms.craftengine.bukkit.nms.CollisionEntity;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
Expand All @@ -14,7 +16,6 @@
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.sound.SoundData;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MiscUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
import net.momirealms.craftengine.core.world.WorldPosition;
import org.bukkit.*;
Expand All @@ -24,7 +25,6 @@
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joml.Vector3f;

import java.io.IOException;
import java.util.Collection;
Expand All @@ -37,7 +37,6 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
public static final NamespacedKey FURNITURE_KEY = KeyUtils.toNamespacedKey(FurnitureManager.FURNITURE_KEY);
public static final NamespacedKey FURNITURE_EXTRA_DATA_KEY = KeyUtils.toNamespacedKey(FurnitureManager.FURNITURE_EXTRA_DATA_KEY);
public static final NamespacedKey FURNITURE_SEAT_BASE_ENTITY_KEY = KeyUtils.toNamespacedKey(FurnitureManager.FURNITURE_SEAT_BASE_ENTITY_KEY);
public static final NamespacedKey FURNITURE_SEAT_VECTOR_3F_KEY = KeyUtils.toNamespacedKey(FurnitureManager.FURNITURE_SEAT_VECTOR_3F_KEY);
public static final NamespacedKey FURNITURE_COLLISION = KeyUtils.toNamespacedKey(FurnitureManager.FURNITURE_COLLISION);
public static Class<?> COLLISION_ENTITY_CLASS = Interaction.class;
public static Object NMS_COLLISION_ENTITY_TYPE = MEntityTypes.instance$EntityType$INTERACTION;
Expand Down Expand Up @@ -320,20 +319,17 @@ protected void handleDismount(Player player, Entity entity) {
}

protected void tryLeavingSeat(@NotNull Player player, @NotNull Entity vehicle) {
Integer baseFurniture = vehicle.getPersistentDataContainer().get(FURNITURE_SEAT_BASE_ENTITY_KEY, PersistentDataType.INTEGER);
if (baseFurniture == null) return;
vehicle.remove();
BukkitFurniture furniture = loadedFurnitureByRealEntityId(baseFurniture);
net.momirealms.craftengine.core.entity.player.Player serverPlayer = BukkitAdaptors.adapt(player);
BukkitSeatEntity seatEntity = (BukkitSeatEntity) serverPlayer.seat();
if (seatEntity == null || seatEntity.literalObject() != vehicle) return;

BukkitFurniture furniture = seatEntity.furniture();
if (furniture == null) {
seatEntity.destroy();
return;
}
String vector3f = vehicle.getPersistentDataContainer().get(BukkitFurnitureManager.FURNITURE_SEAT_VECTOR_3F_KEY, PersistentDataType.STRING);
if (vector3f == null) {
plugin.logger().warn("Failed to get vector3f for player " + player.getName() + "'s seat");
return;
}
Vector3f seatPos = MiscUtils.getAsVector3f(vector3f, "seat");
furniture.removeOccupiedSeat(seatPos);

seatEntity.dismount(serverPlayer);

if (player.getVehicle() != null) return;
Location vehicleLocation = vehicle.getLocation();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.destroystokyo.paper.event.entity.EntityAddToWorldEvent;
import com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent;
import net.momirealms.craftengine.bukkit.api.BukkitAdaptors;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.ItemDisplay;
Expand All @@ -10,7 +12,9 @@
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.event.player.PlayerAnimationEvent;
import org.bukkit.event.player.PlayerArmorStandManipulateEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.event.world.EntitiesLoadEvent;
Expand Down Expand Up @@ -123,12 +127,30 @@ public void onPlayerDeath(PlayerDeathEvent event) {

// do not allow players to put item on seats
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onInteractArmorStand(PlayerInteractAtEntityEvent event) {
Entity clicked = event.getRightClicked();
if (clicked instanceof ArmorStand armorStand) {
Integer baseFurniture = armorStand.getPersistentDataContainer().get(BukkitFurnitureManager.FURNITURE_SEAT_BASE_ENTITY_KEY, PersistentDataType.INTEGER);
if (baseFurniture == null) return;
event.setCancelled(true);
}
public void onInteractArmorStand(PlayerArmorStandManipulateEvent event) {
ArmorStand clicked = event.getRightClicked();
Integer baseFurniture = clicked.getPersistentDataContainer().get(BukkitFurnitureManager.FURNITURE_SEAT_BASE_ENTITY_KEY, PersistentDataType.INTEGER);
if (baseFurniture == null) return;
event.setCancelled(true);
}

@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onMainHandChange(PlayerItemHeldEvent event) {
Player player = event.getPlayer();
if (player.getVehicle() == null) return;
BukkitServerPlayer serverPlayer = BukkitAdaptors.adapt(player);
if (serverPlayer.seat() == null) return;

serverPlayer.seat().event(serverPlayer, event);
}

@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerAnimation(PlayerAnimationEvent event) {
Player player = event.getPlayer();
if (player.getVehicle() == null) return;
BukkitServerPlayer serverPlayer = BukkitAdaptors.adapt(player);
if (serverPlayer.seat() == null) return;

serverPlayer.seat().event(serverPlayer, event);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@

public class BukkitHitBoxTypes extends HitBoxTypes {

public static void init() {}

static {
public static void init() {
register(INTERACTION, InteractionHitBox.FACTORY);
register(SHULKER, ShulkerHitBox.FACTORY);
register(HAPPY_GHAST, HappyGhastHitBox.FACTORY);
register(CUSTOM, CustomHitBox.FACTORY);
}

static {
//register(INTERACTION, InteractionHitBox.FACTORY);
//register(SHULKER, ShulkerHitBox.FACTORY);
//register(HAPPY_GHAST, HappyGhastHitBox.FACTORY);
//register(CUSTOM, CustomHitBox.FACTORY);
}
}
Loading