From ff4efa13a008f8ff548571877735bbc81615c87c Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Sun, 7 Sep 2025 05:50:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B9=E5=9D=97=E5=AE=9E=E4=BD=93=EF=BC=8C?= =?UTF-8?q?=E7=BB=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/block/BukkitBlockManager.java | 21 ++++ .../bukkit/block/BukkitCustomBlock.java | 6 +- .../renderer/BukkitBlockEntityElement.java | 106 ++++++++++++++++++ .../renderer/BukkitBlockEntityRenderer.java | 81 +++++++++++++ .../bukkit/entity/data/DisplayEntityData.java | 8 +- .../furniture/BukkitFurnitureManager.java | 3 +- .../entity/furniture/hitbox/CustomHitBox.java | 2 +- .../furniture/hitbox/HappyGhastHitBox.java | 2 +- .../furniture/hitbox/InteractionHitBox.java | 2 +- .../furniture/hitbox/ShulkerHitBox.java | 2 +- .../bukkit/plugin/gui/BukkitGuiManager.java | 2 +- .../bukkit/world/BukkitCEWorld.java | 11 +- .../core/block/AbstractBlockManager.java | 29 ++++- .../core/block/AbstractCustomBlock.java | 15 ++- .../core/block/BlockStateAppearance.java | 13 +++ .../craftengine/core/block/CustomBlock.java | 2 +- .../core/block/ImmutableBlockState.java | 10 +- .../entity/render/BlockEntityElement.java | 32 ++++++ .../entity/render/BlockEntityRenderer.java | 9 -- .../render/BlockEntityRendererConfig.java | 86 +------------- .../furniture/AbstractFurnitureManager.java | 10 +- .../core/entity/furniture/HitBoxFactory.java | 5 +- .../craftengine/core/item/ItemSettings.java | 10 +- .../core/item/modifier/DyedColorModifier.java | 3 +- .../model/generation/display/DisplayMeta.java | 7 +- .../craftengine/core/util/MiscUtils.java | 36 ------ .../core/util/ResourceConfigUtils.java | 38 +++++++ gradle.properties | 2 +- 28 files changed, 377 insertions(+), 176 deletions(-) create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/BukkitBlockEntityElement.java create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/BukkitBlockEntityRenderer.java create mode 100644 core/src/main/java/net/momirealms/craftengine/core/block/BlockStateAppearance.java create mode 100644 core/src/main/java/net/momirealms/craftengine/core/block/entity/render/BlockEntityElement.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java index f32cb3a5b..c72d5abe3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java @@ -7,6 +7,8 @@ import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.momirealms.craftengine.bukkit.block.entity.renderer.BukkitBlockEntityElement; +import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.injector.BlockGenerator; @@ -23,7 +25,10 @@ import net.momirealms.craftengine.bukkit.util.RegistryUtils; import net.momirealms.craftengine.bukkit.util.TagUtils; import net.momirealms.craftengine.core.block.*; import net.momirealms.craftengine.core.block.behavior.EmptyBlockBehavior; +import net.momirealms.craftengine.core.block.entity.render.BlockEntityElement; import net.momirealms.craftengine.core.block.parser.BlockStateParser; +import net.momirealms.craftengine.core.entity.Billboard; +import net.momirealms.craftengine.core.entity.ItemDisplayContext; import net.momirealms.craftengine.core.plugin.config.StringKeyConstructor; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import net.momirealms.craftengine.core.registry.BuiltInRegistries; @@ -684,4 +689,20 @@ public final class BukkitBlockManager extends AbstractBlockManager { } return FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.BLOCK, KeyUtils.toResourceLocation(id)) != MBlocks.AIR; } + + @Override + protected BlockEntityElement createBlockEntityElement(Map arguments) { + Key itemId = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(arguments.get("item"), "")); + return new BukkitBlockEntityElement( + LazyReference.lazyReference(() -> BukkitItemManager.instance().createWrappedItem(itemId, null)), + ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("scale", 1f), "scale"), + ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", 0.5f), "position"), + ResourceConfigUtils.getAsVector3f(arguments.get("translation"), "translation"), + ResourceConfigUtils.getAsFloat(arguments.getOrDefault("pitch", 0f), "pitch"), + ResourceConfigUtils.getAsFloat(arguments.getOrDefault("yaw", 0f), "yaw"), + ResourceConfigUtils.getAsQuaternionf(arguments.getOrDefault("rotation", 0f), "rotation"), + ItemDisplayContext.valueOf(arguments.getOrDefault("display-context", "none").toString().toUpperCase(Locale.ROOT)), + Billboard.valueOf(arguments.getOrDefault("billboard", "fixed").toString().toUpperCase(Locale.ROOT)) + ); + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java index 84f1cbfe3..c70387f2e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java @@ -39,7 +39,7 @@ public final class BukkitCustomBlock extends AbstractCustomBlock { @NotNull Key id, @NotNull Holder.Reference holder, @NotNull Map> properties, - @NotNull Map appearances, + @NotNull Map appearances, @NotNull Map variantMapper, @NotNull BlockSettings settings, @NotNull Map>> events, @@ -200,7 +200,7 @@ public final class BukkitCustomBlock extends AbstractCustomBlock { public static class BuilderImpl implements Builder { protected final Key id; protected Map> properties; - protected Map appearances; + protected Map appearances; protected Map variantMapper; protected BlockSettings settings; protected List> behavior; @@ -218,7 +218,7 @@ public final class BukkitCustomBlock extends AbstractCustomBlock { } @Override - public Builder appearances(Map appearances) { + public Builder appearances(Map appearances) { this.appearances = appearances; return this; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/BukkitBlockEntityElement.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/BukkitBlockEntityElement.java new file mode 100644 index 000000000..93c1ff950 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/BukkitBlockEntityElement.java @@ -0,0 +1,106 @@ +package net.momirealms.craftengine.bukkit.block.entity.renderer; + +import net.momirealms.craftengine.bukkit.entity.data.ItemDisplayEntityData; +import net.momirealms.craftengine.core.block.entity.render.BlockEntityElement; +import net.momirealms.craftengine.core.entity.Billboard; +import net.momirealms.craftengine.core.entity.ItemDisplayContext; +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.util.LazyReference; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +import java.util.ArrayList; +import java.util.List; + +public class BukkitBlockEntityElement implements BlockEntityElement { + private final LazyReference> lazyMetadataPacket; + private final LazyReference> item; + private final Vector3f scale; + private final Vector3f position; + private final Vector3f translation; + private final float xRot; + private final float yRot; + private final Quaternionf rotation; + private final ItemDisplayContext displayContext; + private final Billboard billboard; + + public BukkitBlockEntityElement(LazyReference> item, + Vector3f scale, + Vector3f position, + Vector3f translation, + float xRot, + float yRot, + Quaternionf rotation, + ItemDisplayContext displayContext, + Billboard billboard) { + this.item = item; + this.scale = scale; + this.position = position; + this.translation = translation; + this.xRot = xRot; + this.yRot = yRot; + this.rotation = rotation; + this.displayContext = displayContext; + this.billboard = billboard; + this.lazyMetadataPacket = LazyReference.lazyReference(() -> { + List dataValues = new ArrayList<>(); + ItemDisplayEntityData.DisplayedItem.addEntityDataIfNotDefaultValue(item.get().getLiteralObject(), dataValues); + ItemDisplayEntityData.Scale.addEntityDataIfNotDefaultValue(this.scale, dataValues); + ItemDisplayEntityData.RotationLeft.addEntityDataIfNotDefaultValue(this.rotation, dataValues); + ItemDisplayEntityData.BillboardConstraints.addEntityDataIfNotDefaultValue(this.billboard.id(), dataValues); + ItemDisplayEntityData.Translation.addEntityDataIfNotDefaultValue(this.translation, dataValues); + ItemDisplayEntityData.DisplayType.addEntityDataIfNotDefaultValue(this.displayContext.id(), dataValues); + return dataValues; + }); + } + + @Override + public Item item() { + return this.item.get(); + } + + @Override + public Vector3f scale() { + return this.scale; + } + + @Override + public Vector3f translation() { + return this.translation; + } + + @Override + public Vector3f position() { + return this.position; + } + + @Override + public float yRot() { + return this.yRot; + } + + @Override + public float xRot() { + return this.xRot; + } + + @Override + public Billboard billboard() { + return billboard; + } + + @Override + public ItemDisplayContext displayContext() { + return displayContext; + } + + @Override + public Quaternionf rotation() { + return rotation; + } + + @Override + public LazyReference> metadataValues() { + return this.lazyMetadataPacket; + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/BukkitBlockEntityRenderer.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/BukkitBlockEntityRenderer.java new file mode 100644 index 000000000..d7f354018 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/entity/renderer/BukkitBlockEntityRenderer.java @@ -0,0 +1,81 @@ +package net.momirealms.craftengine.bukkit.block.entity.renderer; + +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import net.momirealms.craftengine.bukkit.nms.FastNMS; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MEntityTypes; +import net.momirealms.craftengine.core.block.entity.render.BlockEntityElement; +import net.momirealms.craftengine.core.block.entity.render.BlockEntityRenderer; +import net.momirealms.craftengine.core.block.entity.render.BlockEntityRendererConfig; +import net.momirealms.craftengine.core.entity.player.Player; +import net.momirealms.craftengine.core.world.BlockPos; +import org.joml.Vector3f; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class BukkitBlockEntityRenderer extends BlockEntityRenderer { + private final Object cachedSpawnPacket; + private final Object cachedDespawnPacket; + private final WeakReference chunkHolder; + + public BukkitBlockEntityRenderer(WeakReference chunkHolder, + BlockEntityRendererConfig config, + BlockPos pos) { + this.chunkHolder = chunkHolder; + BlockEntityElement[] elements = config.elements(); + IntList ids = new IntArrayList(elements.length); + List spawnPackets = new ArrayList<>(elements.length); + for (BlockEntityElement element : elements) { + int entityId = CoreReflections.instance$Entity$ENTITY_COUNTER.incrementAndGet(); + Vector3f position = element.position(); + spawnPackets.add(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket( + entityId, UUID.randomUUID(), pos.x() + position.x, pos.y() + position.y, pos.z() + position.z, + element.xRot(), element.yRot(), MEntityTypes.ITEM_DISPLAY, 0, CoreReflections.instance$Vec3$Zero, 0 + )); + spawnPackets.add(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket( + entityId, element.metadataValues().get() + )); + ids.add(entityId); + } + this.cachedSpawnPacket = FastNMS.INSTANCE.constructor$ClientboundBundlePacket(spawnPackets); + this.cachedDespawnPacket = FastNMS.INSTANCE.constructor$ClientboundRemoveEntitiesPacket(ids); + } + + @Override + public void despawn() { + List players = FastNMS.INSTANCE.method$ChunkHolder$getPlayers(this.chunkHolder.get()); + if (players.isEmpty()) return; + for (Object player : players) { + FastNMS.INSTANCE.method$ServerPlayerConnection$send( + FastNMS.INSTANCE.field$Player$connection(player), + this.cachedDespawnPacket + ); + } + } + + @Override + public void spawn() { + List players = FastNMS.INSTANCE.method$ChunkHolder$getPlayers(this.chunkHolder.get()); + if (players.isEmpty()) return; + for (Object player : players) { + FastNMS.INSTANCE.method$ServerPlayerConnection$send( + FastNMS.INSTANCE.field$Player$connection(player), + this.cachedSpawnPacket + ); + } + } + + @Override + public void spawn(Player player) { + player.sendPacket(this.cachedSpawnPacket, false); + } + + @Override + public void despawn(Player player) { + player.sendPacket(this.cachedDespawnPacket, false); + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/DisplayEntityData.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/DisplayEntityData.java index a052feedb..b5f4bcd94 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/DisplayEntityData.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/DisplayEntityData.java @@ -15,10 +15,10 @@ public class DisplayEntityData extends BaseEntityData { public static final DisplayEntityData TransformationInterpolationDuration = of(DisplayEntityData.class, EntityDataValue.Serializers$INT, 0, VersionHelper.isOrAbove1_20_2()); public static final DisplayEntityData PositionRotationInterpolationDuration = of(DisplayEntityData.class, EntityDataValue.Serializers$INT, 0, VersionHelper.isOrAbove1_20_2()); - public static final DisplayEntityData Translation = of(DisplayEntityData.class, EntityDataValue.Serializers$VECTOR3, new Vector3f(0f), true); - public static final DisplayEntityData Scale = of(DisplayEntityData.class, EntityDataValue.Serializers$VECTOR3, new Vector3f(1f), true); - public static final DisplayEntityData RotationLeft = of(DisplayEntityData.class, EntityDataValue.Serializers$QUATERNION, new Quaternionf(0f, 0f, 0f, 1f), true); - public static final DisplayEntityData RotationRight = of(DisplayEntityData.class, EntityDataValue.Serializers$QUATERNION, new Quaternionf(0f, 0f, 0f, 1f), true); + public static final DisplayEntityData Translation = of(DisplayEntityData.class, EntityDataValue.Serializers$VECTOR3, new Vector3f(0f), true); + public static final DisplayEntityData Scale = of(DisplayEntityData.class, EntityDataValue.Serializers$VECTOR3, new Vector3f(1f), true); + public static final DisplayEntityData RotationLeft = of(DisplayEntityData.class, EntityDataValue.Serializers$QUATERNION, new Quaternionf(0f, 0f, 0f, 1f), true); + public static final DisplayEntityData RotationRight = of(DisplayEntityData.class, EntityDataValue.Serializers$QUATERNION, new Quaternionf(0f, 0f, 0f, 1f), true); /** * Billboard Constraints (0 = FIXED, 1 = VERTICAL, 2 = HORIZONTAL, 3 = CENTER) */ 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 d9fb9c01d..3a8f53497 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 @@ -16,6 +16,7 @@ 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.ResourceConfigUtils; import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.WorldPosition; import org.bukkit.*; @@ -350,7 +351,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { plugin.logger().warn("Failed to get vector3f for player " + player.getName() + "'s seat"); return; } - Vector3f seatPos = MiscUtils.getAsVector3f(vector3f, "seat"); + Vector3f seatPos = ResourceConfigUtils.getAsVector3f(vector3f, "seat"); furniture.removeOccupiedSeat(seatPos); if (player.getVehicle() != null) return; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/CustomHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/CustomHitBox.java index b76dcd24e..763c9a654 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/CustomHitBox.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/CustomHitBox.java @@ -84,7 +84,7 @@ public class CustomHitBox extends AbstractHitBox { @Override public HitBox create(Map arguments) { - Vector3f position = MiscUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position"); + Vector3f position = ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position"); float scale = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("scale", 1), "scale"); String type = (String) arguments.getOrDefault("entity-type", "slime"); EntityType entityType = Registry.ENTITY_TYPE.get(new NamespacedKey("minecraft", type)); 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 4e67ffd02..fde041616 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 @@ -124,7 +124,7 @@ public class HappyGhastHitBox extends AbstractHitBox { boolean blocksBuilding = ResourceConfigUtils.getAsBoolean(arguments.getOrDefault("blocks-building", true), "blocks-building"); return new HappyGhastHitBox( HitBoxFactory.getSeats(arguments), - MiscUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position"), + ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position"), scale, canUseOn, blocksBuilding, canBeHitByProjectile, hardCollision ); } 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 3fad43d0d..cd0d1a523 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 @@ -93,7 +93,7 @@ public class InteractionHitBox extends AbstractHitBox { @Override public HitBox create(Map arguments) { - Vector3f position = MiscUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position"); + Vector3f position = ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position"); float width; float height; if (arguments.containsKey("scale")) { 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 96db4da42..5f72065db 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 @@ -280,7 +280,7 @@ public class ShulkerHitBox extends AbstractHitBox { @Override public HitBox create(Map arguments) { - Vector3f position = MiscUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position"); + Vector3f position = ResourceConfigUtils.getAsVector3f(arguments.getOrDefault("position", "0"), "position"); float scale = ResourceConfigUtils.getAsFloat(arguments.getOrDefault("scale", "1"), "scale"); byte peek = (byte) ResourceConfigUtils.getAsInt(arguments.getOrDefault("peek", 0), "peek"); Direction directionEnum = Optional.ofNullable(arguments.get("direction")).map(it -> Direction.valueOf(it.toString().toUpperCase(Locale.ENGLISH))).orElse(Direction.UP); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/gui/BukkitGuiManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/gui/BukkitGuiManager.java index 40a39ed12..e01f4d056 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/gui/BukkitGuiManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/gui/BukkitGuiManager.java @@ -144,7 +144,7 @@ public class BukkitGuiManager implements GuiManager, Listener { simpleStorageBlockEntity.onPlayerClose(this.plugin.adapt(player)); } } - + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) public void onInventoryClose(PlayerQuitEvent event) { Player player = event.getPlayer(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitCEWorld.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitCEWorld.java index 93f3727cc..3ad6e4caa 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitCEWorld.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitCEWorld.java @@ -1,5 +1,7 @@ package net.momirealms.craftengine.bukkit.world; +import net.momirealms.craftengine.bukkit.block.entity.renderer.BukkitBlockEntityRenderer; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.util.LightUtils; import net.momirealms.craftengine.core.block.entity.render.BlockEntityRenderer; import net.momirealms.craftengine.core.block.entity.render.BlockEntityRendererConfig; @@ -7,10 +9,13 @@ import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.util.SectionPosUtils; import net.momirealms.craftengine.core.world.BlockPos; import net.momirealms.craftengine.core.world.CEWorld; +import net.momirealms.craftengine.core.world.ChunkPos; import net.momirealms.craftengine.core.world.World; import net.momirealms.craftengine.core.world.chunk.storage.StorageAdaptor; import net.momirealms.craftengine.core.world.chunk.storage.WorldDataStorage; +import java.lang.ref.WeakReference; + public class BukkitCEWorld extends CEWorld { public BukkitCEWorld(World world, StorageAdaptor adaptor) { @@ -41,6 +46,10 @@ public class BukkitCEWorld extends CEWorld { @Override public BlockEntityRenderer createBlockEntityRenderer(BlockEntityRendererConfig config, BlockPos pos) { - return null; + Object serverLevel = this.world.serverWorld(); + Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(serverLevel); + long chunkKey = ChunkPos.asLong(pos.x() >> 4, pos.z() >> 4); + Object chunkHolder = FastNMS.INSTANCE.method$ServerChunkCache$getVisibleChunkIfPresent(chunkSource, chunkKey); + return new BukkitBlockEntityRenderer(new WeakReference<>(chunkHolder), config, pos); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java b/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java index ce78d8bf1..2ecd81814 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java @@ -4,6 +4,9 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import net.momirealms.craftengine.core.block.entity.render.BlockEntityElement; +import net.momirealms.craftengine.core.block.entity.render.BlockEntityRenderer; +import net.momirealms.craftengine.core.block.entity.render.BlockEntityRendererConfig; import net.momirealms.craftengine.core.block.properties.Properties; import net.momirealms.craftengine.core.block.properties.Property; import net.momirealms.craftengine.core.loot.LootTable; @@ -166,6 +169,8 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem protected abstract CustomBlock.Builder platformBuilder(Key id); + protected abstract BlockEntityElement createBlockEntityElement(Map arguments); + public class BlockParser implements ConfigParser { public static final String[] CONFIG_SECTION_NAME = new String[]{"blocks", "block"}; @@ -208,7 +213,7 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem BlockSettings settings = BlockSettings.fromMap(id, MiscUtils.castToMap(section.get("settings"), true)); // 读取基础外观配置 Map> properties; - Map appearances; + Map appearances; Map variants; // 读取states区域 Map stateSection = MiscUtils.castToMap(ResourceConfigUtils.requireNonNullOrThrow( @@ -221,11 +226,13 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem // 获取原版外观的注册表id int appearanceId = pluginFormattedBlockStateToRegistryId(ResourceConfigUtils.requireNonEmptyStringOrThrow( stateSection.get("state"), "warning.config.block.state.missing_state")); + Optional blockEntityRenderer = parseBlockEntityRender(stateSection.get("entity-renderer")); + // 为原版外观赋予外观模型并检查模型冲突 this.arrangeModelForStateAndVerify(appearanceId, ResourceConfigUtils.get(stateSection, "model", "models")); // 设置参数 properties = Map.of(); - appearances = Map.of("", appearanceId); + appearances = Map.of("", new BlockStateAppearance(appearanceId, blockEntityRenderer)); variants = Map.of("", new BlockStateVariant("", settings, getInternalBlockId(internalId, appearanceId))); } // 多方块状态 @@ -234,7 +241,10 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem appearances = parseBlockAppearances(ResourceConfigUtils.getAsMap(ResourceConfigUtils.requireNonNullOrThrow(stateSection.get("appearances"), "warning.config.block.state.missing_appearances"), "appearances")); variants = parseBlockVariants( ResourceConfigUtils.getAsMap(ResourceConfigUtils.requireNonNullOrThrow(stateSection.get("variants"), "warning.config.block.state.missing_variants"), "variants"), - it -> appearances.getOrDefault(it, -1), settings + it -> { + BlockStateAppearance blockStateAppearance = appearances.get(it); + return blockStateAppearance == null ? -1 : blockStateAppearance.stateRegistryId(); + }, settings ); } @@ -278,18 +288,25 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem return internalBlockRegistryId; } - private Map parseBlockAppearances(Map appearancesSection) { - Map appearances = new HashMap<>(); + private Map parseBlockAppearances(Map appearancesSection) { + Map appearances = new HashMap<>(); for (Map.Entry entry : appearancesSection.entrySet()) { Map appearanceSection = ResourceConfigUtils.getAsMap(entry.getValue(), entry.getKey()); int appearanceId = pluginFormattedBlockStateToRegistryId(ResourceConfigUtils.requireNonEmptyStringOrThrow( appearanceSection.get("state"), "warning.config.block.state.missing_state")); this.arrangeModelForStateAndVerify(appearanceId, ResourceConfigUtils.get(appearanceSection, "model", "models")); - appearances.put(entry.getKey(), appearanceId); + appearances.put(entry.getKey(), new BlockStateAppearance(appearanceId, parseBlockEntityRender(appearanceSection.get("entity-renderer")))); } return appearances; } + private Optional parseBlockEntityRender(Object arguments) { + if (arguments == null) return Optional.empty(); + List elements = ResourceConfigUtils.parseConfigAsList(arguments, AbstractBlockManager.this::createBlockEntityElement); + if (elements.isEmpty()) return Optional.empty(); + return Optional.of(new BlockEntityRendererConfig(elements.toArray(new BlockEntityElement[0]))); + } + @NotNull private Map> parseBlockProperties(Map propertiesSection) { Map> properties = new HashMap<>(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/AbstractCustomBlock.java b/core/src/main/java/net/momirealms/craftengine/core/block/AbstractCustomBlock.java index 9a965a5ec..f69e2061d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/AbstractCustomBlock.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/AbstractCustomBlock.java @@ -38,7 +38,7 @@ public abstract class AbstractCustomBlock implements CustomBlock { @NotNull Key id, @NotNull Holder.Reference holder, @NotNull Map> properties, - @NotNull Map appearances, + @NotNull Map appearances, @NotNull Map variantMapper, @NotNull BlockSettings settings, @NotNull Map>> events, @@ -72,16 +72,21 @@ public abstract class AbstractCustomBlock implements CustomBlock { throw new LocalizedResourceConfigException("warning.config.block.state.property.invalid_format", nbtString); } BlockStateVariant blockStateVariant = entry.getValue(); - int vanillaStateRegistryId = appearances.getOrDefault(blockStateVariant.appearance(), -1); + + BlockStateAppearance blockStateAppearance = appearances.getOrDefault(blockStateVariant.appearance(), BlockStateAppearance.INVALID); + int stateId; // This should never happen - if (vanillaStateRegistryId == -1) { - vanillaStateRegistryId = appearances.values().iterator().next(); + if (blockStateAppearance.isInvalid()) { + stateId = appearances.values().iterator().next().stateRegistryId(); + } else { + stateId = blockStateAppearance.stateRegistryId(); } // Late init states ImmutableBlockState state = possibleStates.getFirst(); state.setSettings(blockStateVariant.settings()); - state.setVanillaBlockState(BlockRegistryMirror.stateByRegistryId(vanillaStateRegistryId)); + state.setVanillaBlockState(BlockRegistryMirror.stateByRegistryId(stateId)); state.setCustomBlockState(BlockRegistryMirror.stateByRegistryId(blockStateVariant.internalRegistryId())); + blockStateAppearance.blockEntityRenderer().ifPresent(state::setEntityRenderer); } // double check if there's any invalid state diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockStateAppearance.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockStateAppearance.java new file mode 100644 index 000000000..9bd5565f8 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockStateAppearance.java @@ -0,0 +1,13 @@ +package net.momirealms.craftengine.core.block; + +import net.momirealms.craftengine.core.block.entity.render.BlockEntityRendererConfig; + +import java.util.Optional; + +public record BlockStateAppearance(int stateRegistryId, Optional blockEntityRenderer) { + public static final BlockStateAppearance INVALID = new BlockStateAppearance(-1, Optional.empty()); + + public boolean isInvalid() { + return this.stateRegistryId < 0; + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/CustomBlock.java b/core/src/main/java/net/momirealms/craftengine/core/block/CustomBlock.java index 13948d536..744d0f4c9 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/CustomBlock.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/CustomBlock.java @@ -45,7 +45,7 @@ public interface CustomBlock { Builder events(Map>> events); - Builder appearances(Map appearances); + Builder appearances(Map appearances); Builder behavior(List> behavior); diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/ImmutableBlockState.java b/core/src/main/java/net/momirealms/craftengine/core/block/ImmutableBlockState.java index 9a3a2b65d..b733743a4 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/ImmutableBlockState.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/ImmutableBlockState.java @@ -32,7 +32,7 @@ public final class ImmutableBlockState extends BlockStateHolder { private BlockSettings settings; private BlockEntityType blockEntityType; @Nullable - private BlockEntityRendererConfig rendererConfig; + private BlockEntityRendererConfig renderer; ImmutableBlockState( Holder owner, @@ -71,7 +71,11 @@ public final class ImmutableBlockState extends BlockStateHolder { @Nullable public BlockEntityRendererConfig entityRenderer() { - return this.rendererConfig; + return this.renderer; + } + + public void setEntityRenderer(@Nullable BlockEntityRendererConfig rendererConfig) { + this.renderer = rendererConfig; } @Override @@ -94,7 +98,7 @@ public final class ImmutableBlockState extends BlockStateHolder { } public boolean hasBlockEntityRenderer() { - return this.rendererConfig != null; + return this.renderer != null; } public BlockStateWrapper customBlockState() { diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/BlockEntityElement.java b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/BlockEntityElement.java new file mode 100644 index 000000000..07939e997 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/BlockEntityElement.java @@ -0,0 +1,32 @@ +package net.momirealms.craftengine.core.block.entity.render; + +import net.momirealms.craftengine.core.entity.Billboard; +import net.momirealms.craftengine.core.entity.ItemDisplayContext; +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.util.LazyReference; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +import java.util.List; + +public interface BlockEntityElement { + Item item(); + + Vector3f scale(); + + Vector3f translation(); + + Vector3f position(); + + float yRot(); + + float xRot(); + + Billboard billboard(); + + ItemDisplayContext displayContext(); + + Quaternionf rotation(); + + LazyReference> metadataValues(); +} \ No newline at end of file diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/BlockEntityRenderer.java b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/BlockEntityRenderer.java index 6414fb396..2b1e5e7a0 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/BlockEntityRenderer.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/BlockEntityRenderer.java @@ -3,15 +3,6 @@ package net.momirealms.craftengine.core.block.entity.render; import net.momirealms.craftengine.core.entity.player.Player; public abstract class BlockEntityRenderer { - private final int entityId; - - public BlockEntityRenderer(int entityId) { - this.entityId = entityId; - } - - public int entityId() { - return this.entityId; - } public abstract void spawn(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/BlockEntityRendererConfig.java b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/BlockEntityRendererConfig.java index be4cdffbe..e49a3f164 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/BlockEntityRendererConfig.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/entity/render/BlockEntityRendererConfig.java @@ -1,88 +1,4 @@ package net.momirealms.craftengine.core.block.entity.render; -import net.momirealms.craftengine.core.entity.ItemDisplayContext; -import net.momirealms.craftengine.core.item.Item; - -public class BlockEntityRendererConfig { - private final float yRot; - private final float xRot; - private final ItemDisplayContext displayContext; - private final Item item; - private final float scale; - - public BlockEntityRendererConfig(ItemDisplayContext displayContext, - float yRot, - float xRot, - Item item, - float scale) { - this.displayContext = displayContext; - this.yRot = yRot; - this.xRot = xRot; - this.item = item; - this.scale = scale; - } - - public ItemDisplayContext displayContext() { - return displayContext; - } - - public Item item() { - return item; - } - - public float xRot() { - return xRot; - } - - public float yRot() { - return yRot; - } - - public float scale() { - return scale; - } - - public static Builder builder() { - return new Builder(); - } - - public static class Builder { - private ItemDisplayContext displayContext = ItemDisplayContext.NONE; - private Item item; - private float xRot; - private float yRot; - private float scale = 1f; - - public Builder() { - } - - public Builder displayContext(ItemDisplayContext displayContext) { - this.displayContext = displayContext; - return this; - } - - public Builder item(Item item) { - this.item = item; - return this; - } - - public Builder xRot(float xRot) { - this.xRot = xRot; - return this; - } - - public Builder yRot(float yRot) { - this.yRot = yRot; - return this; - } - - public Builder scale(float scale) { - this.scale = scale; - return this; - } - - public BlockEntityRendererConfig build() { - return new BlockEntityRendererConfig(this.displayContext, this.yRot, this.xRot, this.item, this.scale); - } - } +public record BlockEntityRendererConfig(BlockEntityElement[] elements) { } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/AbstractFurnitureManager.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/AbstractFurnitureManager.java index abc819e6a..f343eb7ea 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/AbstractFurnitureManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/AbstractFurnitureManager.java @@ -98,7 +98,7 @@ public abstract class AbstractFurnitureManager implements FurnitureManager { // anchor type AnchorType anchorType = AnchorType.valueOf(entry.getKey().toUpperCase(Locale.ENGLISH)); Map placementArguments = MiscUtils.castToMap(entry.getValue(), false); - Optional optionalLootSpawnOffset = Optional.ofNullable(placementArguments.get("loot-spawn-offset")).map(it -> MiscUtils.getAsVector3f(it, "loot-spawn-offset")); + Optional optionalLootSpawnOffset = Optional.ofNullable(placementArguments.get("loot-spawn-offset")).map(it -> ResourceConfigUtils.getAsVector3f(it, "loot-spawn-offset")); // furniture display elements List elements = new ArrayList<>(); List> elementConfigs = (List>) placementArguments.getOrDefault("elements", List.of()); @@ -108,10 +108,10 @@ public abstract class AbstractFurnitureManager implements FurnitureManager { .applyDyedColor(ResourceConfigUtils.getAsBoolean(element.getOrDefault("apply-dyed-color", true), "apply-dyed-color")) .billboard(ResourceConfigUtils.getOrDefault(element.get("billboard"), o -> Billboard.valueOf(o.toString().toUpperCase(Locale.ENGLISH)), Billboard.FIXED)) .transform(ResourceConfigUtils.getOrDefault(element.get("transform"), o -> ItemDisplayContext.valueOf(o.toString().toUpperCase(Locale.ENGLISH)), ItemDisplayContext.NONE)) - .scale(MiscUtils.getAsVector3f(element.getOrDefault("scale", "1"), "scale")) - .position(MiscUtils.getAsVector3f(element.getOrDefault("position", "0"), "position")) - .translation(MiscUtils.getAsVector3f(element.getOrDefault("translation", "0"), "translation")) - .rotation(MiscUtils.getAsQuaternionf(element.getOrDefault("rotation", "0"), "rotation")) + .scale(ResourceConfigUtils.getAsVector3f(element.getOrDefault("scale", "1"), "scale")) + .position(ResourceConfigUtils.getAsVector3f(element.getOrDefault("position", "0"), "position")) + .translation(ResourceConfigUtils.getAsVector3f(element.getOrDefault("translation", "0"), "translation")) + .rotation(ResourceConfigUtils.getAsQuaternionf(element.getOrDefault("rotation", "0"), "rotation")) .build(); elements.add(furnitureElement); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBoxFactory.java b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBoxFactory.java index 3720eb9bd..1f06c8846 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBoxFactory.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/furniture/HitBoxFactory.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.entity.furniture; import net.momirealms.craftengine.core.util.MiscUtils; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; import java.util.List; import java.util.Map; @@ -15,8 +16,8 @@ public interface HitBoxFactory { return seats.stream() .map(arg -> { String[] split = arg.split(" "); - if (split.length == 1) return new Seat(MiscUtils.getAsVector3f(split[0], "seats"), 0, false); - return new Seat(MiscUtils.getAsVector3f(split[0], "seats"), Float.parseFloat(split[1]), true); + if (split.length == 1) return new Seat(ResourceConfigUtils.getAsVector3f(split[0], "seats"), 0, false); + return new Seat(ResourceConfigUtils.getAsVector3f(split[0], "seats"), Float.parseFloat(split[1]), true); }) .toArray(Seat[]::new); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java index f8d5ad125..b53902ccf 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java @@ -399,9 +399,9 @@ public class ItemSettings { Key customTridentItemId = Key.of(ResourceConfigUtils.requireNonEmptyStringOrThrow(args.get("item"), "warning.config.item.settings.projectile.missing_item")); ItemDisplayContext displayType = ItemDisplayContext.valueOf(args.getOrDefault("display-transform", "NONE").toString().toUpperCase(Locale.ENGLISH)); Billboard billboard = Billboard.valueOf(args.getOrDefault("billboard", "FIXED").toString().toUpperCase(Locale.ENGLISH)); - Vector3f translation = MiscUtils.getAsVector3f(args.getOrDefault("translation", "0"), "translation"); - Vector3f scale = MiscUtils.getAsVector3f(args.getOrDefault("scale", "1"), "scale"); - Quaternionf rotation = MiscUtils.getAsQuaternionf(ResourceConfigUtils.get(args, "rotation-left", "rotation"), "rotation-left"); + Vector3f translation = ResourceConfigUtils.getAsVector3f(args.getOrDefault("translation", "0"), "translation"); + Vector3f scale = ResourceConfigUtils.getAsVector3f(args.getOrDefault("scale", "1"), "scale"); + Quaternionf rotation = ResourceConfigUtils.getAsQuaternionf(ResourceConfigUtils.get(args, "rotation"), "rotation"); ProjectileType type = Optional.ofNullable(args.get("type")).map(String::valueOf).map(it -> ProjectileType.valueOf(it.toUpperCase(Locale.ENGLISH))).orElse(null); double range = ResourceConfigUtils.getAsDouble(args.getOrDefault("range", 1), "range"); return settings -> settings.projectileMeta(new ProjectileMeta(customTridentItemId, displayType, billboard, scale, translation, rotation, range, type)); @@ -426,14 +426,14 @@ public class ItemSettings { if (value instanceof Integer i) { return settings -> settings.dyeColor(Color.fromDecimal(i)); } else { - return settings -> settings.dyeColor(Color.fromVector3f(MiscUtils.getAsVector3f(value, "dye-color"))); + return settings -> settings.dyeColor(Color.fromVector3f(ResourceConfigUtils.getAsVector3f(value, "dye-color"))); } })); registerFactory("firework-color", (value -> { if (value instanceof Integer i) { return settings -> settings.fireworkColor(Color.fromDecimal(i)); } else { - return settings -> settings.fireworkColor(Color.fromVector3f(MiscUtils.getAsVector3f(value, "firework-color"))); + return settings -> settings.fireworkColor(Color.fromVector3f(ResourceConfigUtils.getAsVector3f(value, "firework-color"))); } })); registerFactory("food", (value -> { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/DyedColorModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/DyedColorModifier.java index 2ce36e797..73cc1c0ae 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/DyedColorModifier.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/DyedColorModifier.java @@ -7,6 +7,7 @@ import net.momirealms.craftengine.core.item.ItemDataModifierFactory; import net.momirealms.craftengine.core.util.Color; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; import org.jetbrains.annotations.Nullable; import org.joml.Vector3f; @@ -54,7 +55,7 @@ public class DyedColorModifier implements SimpleNetworkItemDataModifier { if (arg instanceof Integer integer) { return new DyedColorModifier<>(Color.fromDecimal(integer)); } else { - Vector3f vector3f = MiscUtils.getAsVector3f(arg, "dyed-color"); + Vector3f vector3f = ResourceConfigUtils.getAsVector3f(arg, "dyed-color"); return new DyedColorModifier<>(Color.fromVector3f(vector3f)); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/display/DisplayMeta.java b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/display/DisplayMeta.java index 31549e547..8b9b51f2e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/display/DisplayMeta.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/model/generation/display/DisplayMeta.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.pack.model.generation.display; import net.momirealms.craftengine.core.util.MiscUtils; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; import org.joml.Vector3f; import java.util.Map; @@ -10,15 +11,15 @@ public record DisplayMeta(Vector3f rotation, Vector3f translation, Vector3f scal public static DisplayMeta fromMap(Map map) { Vector3f rotation = null; if (map.containsKey("rotation")) { - rotation = MiscUtils.getAsVector3f(map.get("rotation"), "rotation"); + rotation = ResourceConfigUtils.getAsVector3f(map.get("rotation"), "rotation"); } Vector3f translation = null; if (map.containsKey("translation")) { - translation = MiscUtils.getAsVector3f(map.get("translation"), "translation"); + translation = ResourceConfigUtils.getAsVector3f(map.get("translation"), "translation"); } Vector3f scale = null; if (map.containsKey("scale")) { - scale = MiscUtils.getAsVector3f(map.get("scale"), "scale"); + scale = ResourceConfigUtils.getAsVector3f(map.get("scale"), "scale"); } return new DisplayMeta(rotation, translation, scale); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/MiscUtils.java b/core/src/main/java/net/momirealms/craftengine/core/util/MiscUtils.java index ed0c90d9c..df5b8e924 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/MiscUtils.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/MiscUtils.java @@ -78,42 +78,6 @@ public class MiscUtils { return List.of(); } - public static Vector3f getAsVector3f(Object o, String option) { - if (o == null) return new Vector3f(); - if (o instanceof List list && list.size() == 3) { - return new Vector3f(Float.parseFloat(list.get(0).toString()), Float.parseFloat(list.get(1).toString()), Float.parseFloat(list.get(2).toString())); - } else { - String stringFormat = o.toString(); - String[] split = stringFormat.split(","); - if (split.length == 3) { - return new Vector3f(Float.parseFloat(split[0]), Float.parseFloat(split[1]), Float.parseFloat(split[2])); - } else if (split.length == 1) { - return new Vector3f(Float.parseFloat(split[0])); - } else { - throw new LocalizedResourceConfigException("warning.config.type.vector3f", stringFormat, option); - } - } - } - - public static Quaternionf getAsQuaternionf(Object o, String option) { - if (o == null) return new Quaternionf(); - if (o instanceof List list && list.size() == 4) { - return new Quaternionf(Float.parseFloat(list.get(0).toString()), Float.parseFloat(list.get(1).toString()), Float.parseFloat(list.get(2).toString()), Float.parseFloat(list.get(3).toString())); - } else { - String stringFormat = o.toString(); - String[] split = stringFormat.split(","); - if (split.length == 4) { - return new Quaternionf(Float.parseFloat(split[0]), Float.parseFloat(split[1]), Float.parseFloat(split[2]), Float.parseFloat(split[3])); - } else if (split.length == 3) { - return QuaternionUtils.toQuaternionf((float) Math.toRadians(Float.parseFloat(split[2])), (float) Math.toRadians(Float.parseFloat(split[1])), (float) Math.toRadians(Float.parseFloat(split[0]))); - } else if (split.length == 1) { - return QuaternionUtils.toQuaternionf(0, (float) -Math.toRadians(Float.parseFloat(split[0])), 0); - } else { - throw new LocalizedResourceConfigException("warning.config.type.quaternionf", stringFormat, option); - } - } - } - @SuppressWarnings("unchecked") public static void deepMergeMaps(Map baseMap, Map mapToMerge) { for (Map.Entry entry : mapToMerge.entrySet()) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/ResourceConfigUtils.java b/core/src/main/java/net/momirealms/craftengine/core/util/ResourceConfigUtils.java index 9f240f7dd..b62402aa4 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/ResourceConfigUtils.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/ResourceConfigUtils.java @@ -4,6 +4,8 @@ import com.mojang.datafixers.util.Either; import net.momirealms.craftengine.core.plugin.locale.LocalizedException; import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException; import org.jetbrains.annotations.Nullable; +import org.joml.Quaternionf; +import org.joml.Vector3f; import java.util.*; import java.util.function.Function; @@ -223,4 +225,40 @@ public final class ResourceConfigUtils { } throw new LocalizedResourceConfigException("warning.config.type.map", String.valueOf(obj), option); } + + public static Vector3f getAsVector3f(Object o, String option) { + if (o == null) return new Vector3f(); + if (o instanceof List list && list.size() == 3) { + return new Vector3f(Float.parseFloat(list.get(0).toString()), Float.parseFloat(list.get(1).toString()), Float.parseFloat(list.get(2).toString())); + } else { + String stringFormat = o.toString(); + String[] split = stringFormat.split(","); + if (split.length == 3) { + return new Vector3f(Float.parseFloat(split[0]), Float.parseFloat(split[1]), Float.parseFloat(split[2])); + } else if (split.length == 1) { + return new Vector3f(Float.parseFloat(split[0])); + } else { + throw new LocalizedResourceConfigException("warning.config.type.vector3f", stringFormat, option); + } + } + } + + public static Quaternionf getAsQuaternionf(Object o, String option) { + if (o == null) return new Quaternionf(); + if (o instanceof List list && list.size() == 4) { + return new Quaternionf(Float.parseFloat(list.get(0).toString()), Float.parseFloat(list.get(1).toString()), Float.parseFloat(list.get(2).toString()), Float.parseFloat(list.get(3).toString())); + } else { + String stringFormat = o.toString(); + String[] split = stringFormat.split(","); + if (split.length == 4) { + return new Quaternionf(Float.parseFloat(split[0]), Float.parseFloat(split[1]), Float.parseFloat(split[2]), Float.parseFloat(split[3])); + } else if (split.length == 3) { + return QuaternionUtils.toQuaternionf((float) Math.toRadians(Float.parseFloat(split[2])), (float) Math.toRadians(Float.parseFloat(split[1])), (float) Math.toRadians(Float.parseFloat(split[0]))); + } else if (split.length == 1) { + return QuaternionUtils.toQuaternionf(0, (float) -Math.toRadians(Float.parseFloat(split[0])), 0); + } else { + throw new LocalizedResourceConfigException("warning.config.type.quaternionf", stringFormat, option); + } + } + } } diff --git a/gradle.properties b/gradle.properties index b9cf6317c..7f34bd693 100644 --- a/gradle.properties +++ b/gradle.properties @@ -50,7 +50,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.5 anti_grief_version=0.20 -nms_helper_version=1.0.76 +nms_helper_version=1.0.77 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.33.1