9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-23 00:49:20 +00:00

added MEG & BM support

This commit is contained in:
XiaoMoMi
2025-04-01 03:42:17 +08:00
parent 61762e314d
commit 8ecc78b28a
21 changed files with 240 additions and 123 deletions

View File

@@ -7,6 +7,7 @@ repositories {
maven("https://repo.rapture.pw/repository/maven-releases/") // slime world
maven("https://repo.infernalsuite.com/repository/maven-snapshots/") // slime world
maven("https://repo.momirealms.net/releases/")
maven("https://mvn.lumine.io/repository/maven-public/") // model engine
}
dependencies {
@@ -23,6 +24,10 @@ dependencies {
compileOnly("com.sk89q.worldedit:worldedit-bukkit:7.2.19")
// SlimeWorld
compileOnly("com.infernalsuite.asp:api:4.0.0-SNAPSHOT")
// ModelEngine
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.8")
// BetterModels
compileOnly("io.github.toxicity188:BetterModel:1.4.2")
}
java {

View File

@@ -0,0 +1,22 @@
package net.momirealms.craftengine.bukkit.compatibility.bettermodel;
import net.momirealms.craftengine.core.entity.Entity;
import net.momirealms.craftengine.core.entity.furniture.AbstractExternalModel;
public class BetterModelModel extends AbstractExternalModel {
public BetterModelModel(String id) {
super(id);
}
@Override
public String plugin() {
return "BetterModel";
}
@Override
public void bindModel(Entity entity) {
org.bukkit.entity.Entity bukkitEntity = (org.bukkit.entity.Entity) entity.literalObject();
BetterModelUtils.bindModel(bukkitEntity, id());
}
}

View File

@@ -0,0 +1,16 @@
package net.momirealms.craftengine.bukkit.compatibility.bettermodel;
import kr.toxicity.model.api.BetterModel;
import kr.toxicity.model.api.data.renderer.BlueprintRenderer;
import org.bukkit.entity.Entity;
public class BetterModelUtils {
public static void bindModel(Entity base, String id) {
BlueprintRenderer renderer = BetterModel.inst().modelManager().renderer(id);
if (renderer == null) {
throw new NullPointerException("Could not find BetterModel blueprint " + id);
}
renderer.create(base);
}
}

View File

@@ -0,0 +1,22 @@
package net.momirealms.craftengine.bukkit.compatibility.modelengine;
import net.momirealms.craftengine.core.entity.Entity;
import net.momirealms.craftengine.core.entity.furniture.AbstractExternalModel;
public class ModelEngineModel extends AbstractExternalModel {
public ModelEngineModel(String id) {
super(id);
}
@Override
public String plugin() {
return "ModelEngine";
}
@Override
public void bindModel(Entity entity) {
org.bukkit.entity.Entity bukkitEntity = (org.bukkit.entity.Entity) entity.literalObject();
ModelEngineUtils.bindModel(bukkitEntity, id());
}
}

View File

@@ -0,0 +1,15 @@
package net.momirealms.craftengine.bukkit.compatibility.modelengine;
import com.ticxo.modelengine.api.ModelEngineAPI;
import com.ticxo.modelengine.api.model.ActiveModel;
import com.ticxo.modelengine.api.model.ModeledEntity;
import org.bukkit.entity.Entity;
public class ModelEngineUtils {
public static void bindModel(Entity base, String id) {
ModeledEntity modeledEntity = ModelEngineAPI.createModeledEntity(base);
ActiveModel activeModel = ModelEngineAPI.createActiveModel(id);
modeledEntity.addModel(activeModel, true);
}
}

View File

@@ -140,9 +140,6 @@ furniture:
- "xxx:invalid_furniture"
# Whether to hide the entity containing metadata
hide-base-entity: true
# Removed collision box entity texture
removed-collision-box-entity-texture-1_20_2: true
removed-collision-box-entity-texture-1_20: false
image:
# Prevent players from using images set in minecraft:default font

View File

@@ -0,0 +1,65 @@
package net.momirealms.craftengine.bukkit.entity;
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.entity.Entity;
import net.momirealms.craftengine.core.util.Direction;
import net.momirealms.craftengine.core.world.World;
import java.lang.ref.WeakReference;
public class BukkitEntity extends Entity {
private final WeakReference<org.bukkit.entity.Entity> entity;
public BukkitEntity(org.bukkit.entity.Entity entity) {
this.entity = new WeakReference<>(entity);
}
@Override
public double x() {
return literalObject().getLocation().getX();
}
@Override
public double y() {
return literalObject().getLocation().getY();
}
@Override
public double z() {
return literalObject().getLocation().getZ();
}
@Override
public void tick() {
}
@Override
public int entityID() {
return literalObject().getEntityId();
}
@Override
public float getXRot() {
return literalObject().getLocation().getYaw();
}
@Override
public float getYRot() {
return literalObject().getLocation().getPitch();
}
@Override
public World level() {
return new BukkitWorld(literalObject().getWorld());
}
@Override
public Direction getDirection() {
return Direction.NORTH;
}
@Override
public org.bukkit.entity.Entity literalObject() {
return this.entity.get();
}
}

View File

@@ -1,5 +1,7 @@
package net.momirealms.craftengine.bukkit.entity.furniture;
import net.momirealms.craftengine.bukkit.compatibility.bettermodel.BetterModelModel;
import net.momirealms.craftengine.bukkit.compatibility.modelengine.ModelEngineModel;
import net.momirealms.craftengine.bukkit.entity.furniture.hitbox.InteractionHitBox;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
@@ -39,7 +41,7 @@ public class BukkitFurnitureManager implements FurnitureManager {
private final Map<Key, CustomFurniture> byId = new HashMap<>();
private final Map<Integer, LoadedFurniture> furnitureByBaseEntityId = new ConcurrentHashMap<>(256, 0.5f);
private final Map<Integer, LoadedFurniture> furnitureByInteractionEntityId = new ConcurrentHashMap<>(512, 0.5f);
private final Map<Integer, LoadedFurniture> furnitureByEntityId = new ConcurrentHashMap<>(512, 0.5f);
// Event listeners
private final Listener dismountListener;
private final FurnitureEventListener furnitureEventListener;
@@ -150,6 +152,16 @@ public class BukkitFurnitureManager implements FurnitureManager {
}
}
// external model providers
Optional<ExternalModel> externalModel;
if (placementArguments.containsKey("model-engine")) {
externalModel = Optional.of(new ModelEngineModel(placementArguments.get("model-engine").toString()));
} else if (placementArguments.containsKey("better-model")) {
externalModel = Optional.of(new BetterModelModel(placementArguments.get("better-model").toString()));
} else {
externalModel = Optional.empty();
}
// add hitboxes
List<Map<String, Object>> hitboxConfigs = (List<Map<String, Object>>) placementArguments.getOrDefault("hitboxes", List.of());
List<HitBox> hitboxes = new ArrayList<>();
@@ -158,7 +170,7 @@ public class BukkitFurnitureManager implements FurnitureManager {
hitboxes.add(hitBox);
hitBox.optionCollider().ifPresent(colliders::add);
}
if (hitboxes.isEmpty()) {
if (hitboxes.isEmpty() && externalModel.isEmpty()) {
hitboxes.add(InteractionHitBox.DEFAULT);
}
@@ -176,7 +188,8 @@ public class BukkitFurnitureManager implements FurnitureManager {
hitboxes.toArray(new HitBox[0]),
colliders.toArray(new Collider[0]),
rotationRule,
alignmentRule
alignmentRule,
externalModel
));
} else {
placements.put(anchorType, new CustomFurniture.Placement(
@@ -184,7 +197,8 @@ public class BukkitFurnitureManager implements FurnitureManager {
hitboxes.toArray(new HitBox[0]),
colliders.toArray(new Collider[0]),
RotationRule.ANY,
AlignmentRule.CENTER
AlignmentRule.CENTER,
externalModel
));
}
}
@@ -252,8 +266,8 @@ public class BukkitFurnitureManager implements FurnitureManager {
}
@Nullable
public LoadedFurniture getLoadedFurnitureByInteractionEntityId(int entityId) {
return this.furnitureByInteractionEntityId.get(entityId);
public LoadedFurniture getLoadedFurnitureByEntityId(int entityId) {
return this.furnitureByEntityId.get(entityId);
}
protected void handleBaseFurnitureUnload(Entity entity) {
@@ -261,8 +275,8 @@ public class BukkitFurnitureManager implements FurnitureManager {
LoadedFurniture furniture = this.furnitureByBaseEntityId.remove(id);
if (furniture != null) {
furniture.destroySeats();
for (int sub : furniture.hitBoxEntityIds()) {
this.furnitureByInteractionEntityId.remove(sub);
for (int sub : furniture.entityIds()) {
this.furnitureByEntityId.remove(sub);
}
}
}
@@ -284,7 +298,7 @@ public class BukkitFurnitureManager implements FurnitureManager {
}
LoadedFurniture furniture = addNewFurniture(display, customFurniture, getAnchorType(entity, customFurniture));
for (Player player : display.getTrackedPlayers()) {
this.plugin.adapt(player).furnitureView().computeIfAbsent(furniture.baseEntityId(), k -> new ArrayList<>()).addAll(furniture.subEntityIds());
this.plugin.adapt(player).furnitureView().computeIfAbsent(furniture.baseEntityId(), k -> new ArrayList<>()).addAll(furniture.fakeEntityIds());
this.plugin.networkManager().sendPacket(player, furniture.spawnPacket(player));
}
}
@@ -331,8 +345,8 @@ public class BukkitFurnitureManager implements FurnitureManager {
private synchronized LoadedFurniture addNewFurniture(ItemDisplay display, CustomFurniture furniture, AnchorType anchorType) {
LoadedFurniture loadedFurniture = new LoadedFurniture(display, furniture, anchorType);
this.furnitureByBaseEntityId.put(loadedFurniture.baseEntityId(), loadedFurniture);
for (int entityId : loadedFurniture.hitBoxEntityIds()) {
this.furnitureByInteractionEntityId.put(entityId, loadedFurniture);
for (int entityId : loadedFurniture.entityIds()) {
this.furnitureByEntityId.put(entityId, loadedFurniture);
}
return loadedFurniture;
}

View File

@@ -1,5 +1,6 @@
package net.momirealms.craftengine.bukkit.entity.furniture;
import net.momirealms.craftengine.bukkit.entity.BukkitEntity;
import net.momirealms.craftengine.bukkit.nms.CollisionEntity;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.util.EntityUtils;
@@ -36,9 +37,10 @@ public class LoadedFurniture {
private final CollisionEntity[] collisionEntities;
// cache
private final List<Integer> fakeEntityIds;
private final List<Integer> hitBoxEntityIds;
private final List<Integer> entityIds;
private final Map<Integer, HitBox> hitBoxes;
private final boolean minimized;
private final boolean hasExternalModel;
// seats
private final Set<Vector3f> occupiedSeats = Collections.synchronizedSet(new HashSet<>());
private final Vector<Entity> seats = new Vector<>();
@@ -58,8 +60,22 @@ public class LoadedFurniture {
this.hitBoxes = new HashMap<>();
this.minimized = furniture.settings().minimized();
List<Integer> fakeEntityIds = new ArrayList<>();
List<Integer> hitBoxEntityIds = new ArrayList<>();
List<Integer> mainEntityIds = new ArrayList<>();
mainEntityIds.add(this.baseEntityId);
CustomFurniture.Placement placement = furniture.getPlacement(anchorType);
// bind external furniture
Optional<ExternalModel> optionalExternal = placement.externalModel();
if (optionalExternal.isPresent()) {
try {
optionalExternal.get().bindModel(new BukkitEntity(baseEntity));
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to load external model for furniture " + id, e);
}
hasExternalModel = true;
} else {
hasExternalModel = false;
}
double yawInRadius = Math.toRadians(180 - this.location.getYaw());
Quaternionf conjugated = QuaternionUtils.toQuaternionf(0, yawInRadius, 0).conjugate();
@@ -83,7 +99,7 @@ public class LoadedFurniture {
int[] ids = hitBox.acquireEntityIds(Reflections.instance$Entity$ENTITY_COUNTER::incrementAndGet);
for (int entityId : ids) {
fakeEntityIds.add(entityId);
hitBoxEntityIds.add(entityId);
mainEntityIds.add(entityId);
hitBox.addSpawnPackets(ids, x, y, z, yaw, conjugated, (packet, canBeMinimized) -> {
packets.add(packet);
if (this.minimized && !canBeMinimized) {
@@ -102,7 +118,7 @@ public class LoadedFurniture {
CraftEngine.instance().logger().warn("Failed to init spawn packets for furniture " + id, e);
}
this.fakeEntityIds = fakeEntityIds;
this.hitBoxEntityIds = hitBoxEntityIds;
this.entityIds = mainEntityIds;
int colliderSize = placement.colliders().length;
this.collisionEntities = new CollisionEntity[colliderSize];
if (colliderSize != 0) {
@@ -215,12 +231,12 @@ public class LoadedFurniture {
}
@NotNull
public List<Integer> hitBoxEntityIds() {
return Collections.unmodifiableList(this.hitBoxEntityIds);
public List<Integer> entityIds() {
return Collections.unmodifiableList(this.entityIds);
}
@NotNull
public List<Integer> subEntityIds() {
public List<Integer> fakeEntityIds() {
return Collections.unmodifiableList(this.fakeEntityIds);
}
@@ -239,6 +255,10 @@ public class LoadedFurniture {
return this.furniture;
}
public boolean hasExternalModel() {
return hasExternalModel;
}
public void spawnSeatEntityForPlayer(org.bukkit.entity.Player player, Seat seat) {
Location location = this.calculateSeatLocation(seat);
Entity seatEntity = seat.limitPlayerRotation() ?

View File

@@ -8,7 +8,6 @@ import org.joml.Vector3f;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class HappyGhastHitBox extends AbstractHitBox {

View File

@@ -13,7 +13,6 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class InteractionHitBox extends AbstractHitBox {

View File

@@ -3,7 +3,6 @@ package net.momirealms.craftengine.bukkit.entity.furniture.hitbox;
import net.momirealms.craftengine.bukkit.entity.data.InteractionEntityData;
import net.momirealms.craftengine.bukkit.entity.data.ShulkerData;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.util.DirectionUtils;
import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.core.entity.furniture.*;
import net.momirealms.craftengine.core.util.Direction;

View File

@@ -557,7 +557,7 @@ public class PacketConsumers {
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> PICK_ITEM_FROM_ENTITY = (user, event, packet) -> {
try {
int entityId = (int) Reflections.field$ServerboundPickItemFromEntityPacket$id.get(packet);
LoadedFurniture furniture = BukkitFurnitureManager.instance().getLoadedFurnitureByInteractionEntityId(entityId);
LoadedFurniture furniture = BukkitFurnitureManager.instance().getLoadedFurnitureByEntityId(entityId);
if (furniture == null) return;
Player player = (Player) user.platformPlayer();
if (player == null) return;
@@ -618,9 +618,9 @@ public class PacketConsumers {
int entityId = (int) Reflections.field$ClientboundAddEntityPacket$entityId.get(packet);
LoadedFurniture furniture = BukkitFurnitureManager.instance().getLoadedFurnitureByBaseEntityId(entityId);
if (furniture != null) {
user.furnitureView().computeIfAbsent(furniture.baseEntityId(), k -> new ArrayList<>()).addAll(furniture.subEntityIds());
user.furnitureView().computeIfAbsent(furniture.baseEntityId(), k -> new ArrayList<>()).addAll(furniture.fakeEntityIds());
user.sendPacket(furniture.spawnPacket((Player) user.platformPlayer()), false);
if (ConfigManager.hideBaseEntity()) {
if (ConfigManager.hideBaseEntity() && !furniture.hasExternalModel()) {
event.setCancelled(true);
}
}
@@ -675,7 +675,7 @@ public class PacketConsumers {
Object action = Reflections.field$ServerboundInteractPacket$action.get(packet);
Object actionType = Reflections.method$ServerboundInteractPacket$Action$getType.invoke(action);
if (actionType == null) return;
LoadedFurniture furniture = BukkitFurnitureManager.instance().getLoadedFurnitureByInteractionEntityId(entityId);
LoadedFurniture furniture = BukkitFurnitureManager.instance().getLoadedFurnitureByEntityId(entityId);
if (furniture == null) return;
Location location = furniture.baseEntity().getLocation();
BukkitServerPlayer serverPlayer = (BukkitServerPlayer) user;

View File

@@ -596,6 +596,11 @@ public class BukkitServerPlayer extends Player {
return playerRef.get();
}
@Override
public org.bukkit.entity.Player literalObject() {
return platformPlayer();
}
@Override
public Map<Integer, List<Integer>> furnitureView() {
return this.furnitureView;