diff --git a/bukkit/compatibility/build.gradle.kts b/bukkit/compatibility/build.gradle.kts index 71a1c68ae..171607a61 100644 --- a/bukkit/compatibility/build.gradle.kts +++ b/bukkit/compatibility/build.gradle.kts @@ -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 { diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/bettermodel/BetterModelModel.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/bettermodel/BetterModelModel.java new file mode 100644 index 000000000..aeec3c863 --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/bettermodel/BetterModelModel.java @@ -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()); + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/bettermodel/BetterModelUtils.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/bettermodel/BetterModelUtils.java new file mode 100644 index 000000000..93696e7f5 --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/bettermodel/BetterModelUtils.java @@ -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); + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/modelengine/ModelEngineModel.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/modelengine/ModelEngineModel.java new file mode 100644 index 000000000..cba3b00ce --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/modelengine/ModelEngineModel.java @@ -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()); + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/modelengine/ModelEngineUtils.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/modelengine/ModelEngineUtils.java new file mode 100644 index 000000000..8276dac0c --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/modelengine/ModelEngineUtils.java @@ -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); + } +} diff --git a/bukkit/loader/src/main/resources/config.yml b/bukkit/loader/src/main/resources/config.yml index 7dc8f070f..5624e7bd8 100644 --- a/bukkit/loader/src/main/resources/config.yml +++ b/bukkit/loader/src/main/resources/config.yml @@ -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 diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/BukkitEntity.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/BukkitEntity.java new file mode 100644 index 000000000..d61bfce98 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/BukkitEntity.java @@ -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 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(); + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java index 9a7a74142..cbb986e9f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java @@ -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 byId = new HashMap<>(); private final Map furnitureByBaseEntityId = new ConcurrentHashMap<>(256, 0.5f); - private final Map furnitureByInteractionEntityId = new ConcurrentHashMap<>(512, 0.5f); + private final Map 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; + 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> hitboxConfigs = (List>) placementArguments.getOrDefault("hitboxes", List.of()); List 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; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java index cb2addc6b..b275da8bf 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java @@ -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 fakeEntityIds; - private final List hitBoxEntityIds; + private final List entityIds; private final Map hitBoxes; private final boolean minimized; + private final boolean hasExternalModel; // seats private final Set occupiedSeats = Collections.synchronizedSet(new HashSet<>()); private final Vector seats = new Vector<>(); @@ -58,8 +60,22 @@ public class LoadedFurniture { this.hitBoxes = new HashMap<>(); this.minimized = furniture.settings().minimized(); List fakeEntityIds = new ArrayList<>(); - List hitBoxEntityIds = new ArrayList<>(); + List mainEntityIds = new ArrayList<>(); + mainEntityIds.add(this.baseEntityId); + CustomFurniture.Placement placement = furniture.getPlacement(anchorType); + // bind external furniture + Optional 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 hitBoxEntityIds() { - return Collections.unmodifiableList(this.hitBoxEntityIds); + public List entityIds() { + return Collections.unmodifiableList(this.entityIds); } @NotNull - public List subEntityIds() { + public List 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() ? diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/HappyGhastHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/HappyGhastHitBox.java index 64883d486..e87230357 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/HappyGhastHitBox.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/HappyGhastHitBox.java @@ -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 { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/InteractionHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/InteractionHitBox.java index b14dc9816..d895dfb88 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/InteractionHitBox.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/InteractionHitBox.java @@ -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 { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java index a91c42b81..57aa921a4 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java @@ -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; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index 469532c46..b32e40ab0 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -557,7 +557,7 @@ public class PacketConsumers { public static final TriConsumer 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; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java index 030a31379..e362f2fc5 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java @@ -596,6 +596,11 @@ public class BukkitServerPlayer extends Player { return playerRef.get(); } + @Override + public org.bukkit.entity.Player literalObject() { + return platformPlayer(); + } + @Override public Map> furnitureView() { return this.furnitureView; diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/Entity.java b/core/src/main/java/net/momirealms/craftengine/core/entity/Entity.java index 57afad7cc..fd45a8f1c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/Entity.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/Entity.java @@ -22,4 +22,6 @@ public abstract class Entity { public abstract World level(); public abstract Direction getDirection(); + + public abstract Object literalObject(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/AbstractExternalModel.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/AbstractExternalModel.java new file mode 100644 index 000000000..12e4a3c60 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/AbstractExternalModel.java @@ -0,0 +1,13 @@ +package net.momirealms.craftengine.core.entity.furniture; + +public abstract class AbstractExternalModel implements ExternalModel { + protected final String id; + + public AbstractExternalModel(String id) { + this.id = id; + } + + public String id() { + return id; + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/CustomFurniture.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/CustomFurniture.java index b92f2fe51..b0b59d4dd 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/CustomFurniture.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/CustomFurniture.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.EnumMap; +import java.util.Optional; public class CustomFurniture { private final Key id; @@ -55,7 +56,11 @@ public class CustomFurniture { return placements.get(anchorType); } - public record Placement(FurnitureElement[] elements, HitBox[] hitBoxes, Collider[] colliders, - RotationRule rotationRule, AlignmentRule alignmentRule) { + public record Placement(FurnitureElement[] elements, + HitBox[] hitBoxes, + Collider[] colliders, + RotationRule rotationRule, + AlignmentRule alignmentRule, + Optional externalModel) { } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/ExternalModel.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/ExternalModel.java new file mode 100644 index 000000000..5a12ba446 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/ExternalModel.java @@ -0,0 +1,12 @@ +package net.momirealms.craftengine.core.entity.furniture; + +import net.momirealms.craftengine.core.entity.Entity; + +public interface ExternalModel { + + String plugin(); + + String id(); + + void bindModel(Entity entity); +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBox.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBox.java index 2d91741fd..3978e2f20 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBox.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBox.java @@ -6,7 +6,6 @@ import org.joml.Vector3f; import java.util.Optional; import java.util.function.BiConsumer; -import java.util.function.Consumer; import java.util.function.Supplier; public interface HitBox { diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java index 3980f39f5..131012a03 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java @@ -27,9 +27,6 @@ import org.jetbrains.annotations.NotNull; import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; -import javax.imageio.ImageIO; -import java.awt.*; -import java.awt.image.BufferedImage; import java.io.*; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -38,7 +35,6 @@ import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.util.List; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; @@ -499,7 +495,6 @@ public abstract class AbstractPackManager implements PackManager { this.generateCustomSounds(generatedPackPath); this.generateClientLang(generatedPackPath); this.generateEquipments(generatedPackPath); - this.generateShulker(generatedPackPath); Path zipFile = resourcePackPath(); try { @@ -530,81 +525,6 @@ public abstract class AbstractPackManager implements PackManager { } } - private void generateShulker(Path generatedPackPath) { - try { - if (ConfigManager.removedCollisionBoxEntityTextureLegacy()) { - File shulkerFile = generatedPackPath.resolve("assets/minecraft/textures/entity/shulker/shulker.png").toFile(); - shulkerFile.getParentFile().mkdirs(); - if (!shulkerFile.exists()) { - try (OutputStream out = new FileOutputStream(shulkerFile)) { - out.write(SHULKER_PNG.get(0)); - } - } else { - this.modifyShulker(shulkerFile, shulkerFile); - } - } - if (ConfigManager.removedCollisionBoxEntityTexture()) { - File overlaysFile = generatedPackPath.resolve("1_20_2_ce/assets/minecraft/textures/entity/shulker/shulker.png").toFile(); - overlaysFile.getParentFile().mkdirs(); - File shulkerFile = generatedPackPath.resolve("assets/minecraft/textures/entity/shulker/shulker.png").toFile(); - File packMetaFile = generatedPackPath.resolve("pack.mcmeta").toFile(); - boolean modifyPackMetaFile = false; - if (!shulkerFile.exists() && packMetaFile.exists()) { - try (OutputStream out = new FileOutputStream(overlaysFile)) { - out.write(SHULKER_PNG.get(0)); - } - modifyPackMetaFile = true; - } else if (packMetaFile.exists()) { - this.modifyShulker(shulkerFile, overlaysFile); - modifyPackMetaFile = true; - } - if (modifyPackMetaFile) { - JsonObject packMcmeta = GsonHelper.readJsonFile(packMetaFile.toPath()).getAsJsonObject(); - JsonArray entries = packMcmeta.getAsJsonObject("overlays").getAsJsonArray("entries"); - JsonObject entrie = new JsonObject(); - JsonObject formats = new JsonObject(); - formats.addProperty("min_inclusive", 16); - formats.addProperty("max_inclusive", 34); - entrie.add("formats", formats); - entrie.addProperty("directory", "1_20_2_ce"); - entries.add(entrie); - GsonHelper.writeJsonFile(packMcmeta, packMetaFile.toPath()); - } - } - } catch (IOException e) { - this.plugin.logger().warn("Error creating shulker.png", e); - } - } - - private void modifyShulker(File shulkerFile, File saveFile) throws IOException { - BufferedImage originalImage = ImageIO.read(shulkerFile); - BufferedImage argbImage; - if (originalImage.getType() == BufferedImage.TYPE_INT_ARGB) { - argbImage = originalImage; - } else { - argbImage = new BufferedImage( - originalImage.getWidth(), - originalImage.getHeight(), - BufferedImage.TYPE_INT_ARGB - ); - Graphics2D g = argbImage.createGraphics(); - g.drawImage(originalImage, 0, 0, null); - g.dispose(); - } - int startX = 0; - int startY = argbImage.getHeight() - 12; - int width = 24; - int heightRegion = 12; - for (int y = startY; y < startY + heightRegion; y++) { - for (int x = startX; x < startX + width; x++) { - int pixel = argbImage.getRGB(x, y); - int transparentPixel = pixel & 0x00FFFFFF; - argbImage.setRGB(x, y, transparentPixel); - } - } - ImageIO.write(argbImage, "PNG", saveFile); - } - private void generateEquipments(Path generatedPackPath) { for (EquipmentGeneration generator : this.plugin.itemManager().equipmentsToGenerate()) { EquipmentData equipmentData = generator.modernData(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigManager.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigManager.java index 6cf57a455..46586334c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigManager.java @@ -104,8 +104,6 @@ public class ConfigManager implements Reloadable { protected boolean furniture$remove_invalid_furniture_on_chunk_load$enable; protected Set furniture$remove_invalid_furniture_on_chunk_load$list; protected boolean furniture$hide_base_entity; - protected boolean furniture$removed_collision_box_entity_texture_1_20_2; - protected boolean furniture$removed_collision_box_entity_texture_1_20; protected boolean block$sound_system$enable; protected boolean recipe$enable; @@ -262,8 +260,6 @@ public class ConfigManager implements Reloadable { furniture$remove_invalid_furniture_on_chunk_load$enable = config.getBoolean("furniture.remove-invalid-furniture-on-chunk-load.enable", false); furniture$remove_invalid_furniture_on_chunk_load$list = new HashSet<>(config.getStringList("furniture.remove-invalid-furniture-on-chunk-load.list")); furniture$hide_base_entity = config.getBoolean("furniture.hide-base-entity", true); - furniture$removed_collision_box_entity_texture_1_20_2 = config.getBoolean("furniture.removed-collision-box-entity-texture-1_20_2", true); - furniture$removed_collision_box_entity_texture_1_20 = config.getBoolean("furniture.removed-collision-box-entity-texture-1_20", false); // block block$sound_system$enable = config.getBoolean("block.sound-system.enable", true); @@ -557,14 +553,6 @@ public class ConfigManager implements Reloadable { return instance().furniture$hide_base_entity; } - public static boolean removedCollisionBoxEntityTexture() { - return instance().furniture$removed_collision_box_entity_texture_1_20_2; - } - - public static boolean removedCollisionBoxEntityTextureLegacy() { - return instance().furniture$removed_collision_box_entity_texture_1_20; - } - public YamlDocument loadOrCreateYamlData(String fileName) { File file = new File(this.plugin.dataFolderFile(), fileName); if (!file.exists()) {