diff --git a/api/bukkit-api/src/main/java/kr/toxicity/model/api/bukkit/entity/BaseBukkitEntity.java b/api/bukkit-api/src/main/java/kr/toxicity/model/api/bukkit/entity/BaseBukkitEntity.java index db9c4237b..1249d96c4 100644 --- a/api/bukkit-api/src/main/java/kr/toxicity/model/api/bukkit/entity/BaseBukkitEntity.java +++ b/api/bukkit-api/src/main/java/kr/toxicity/model/api/bukkit/entity/BaseBukkitEntity.java @@ -78,6 +78,24 @@ public interface BaseBukkitEntity extends BaseEntity, PersistentDataHolder { return TransformedItemStack.empty(); } + /** + * Returns the item in the entity's helmet slot. + * + * @return the helmet item + * @since 2.0.1 + */ + @Override + default @NotNull TransformedItemStack helmet() { + if (entity() instanceof LivingEntity livingEntity) { + var equipment = livingEntity.getEquipment(); + if (equipment != null) { + var helmet = equipment.getHelmet(); + if (helmet != null) return TransformedItemStack.of(BukkitAdapter.adapt(helmet)); + } + } + return TransformedItemStack.empty(); + } + /** * Retrieves the model data stored in the entity's persistent data container. * diff --git a/api/src/main/java/kr/toxicity/model/api/bone/BoneTags.java b/api/src/main/java/kr/toxicity/model/api/bone/BoneTags.java index 103b432be..84eafaa16 100644 --- a/api/src/main/java/kr/toxicity/model/api/bone/BoneTags.java +++ b/api/src/main/java/kr/toxicity/model/api/bone/BoneTags.java @@ -72,6 +72,18 @@ public enum BoneTags implements BoneTag { PlatformItemTransform.THIRDPERSON_RIGHTHAND, BaseEntity::mainHand ), "pri", "ri"), + /** + * Entity's helmet item + *

+ * A built-in scale correction of {@code 0.5} is applied because + * {@link PlatformItemTransform#HEAD} renders items at 2× the scale + * relative to the animation bone coordinate system. + *

+ */ + HEAD_ITEM(BoneItemMapper.entity( + PlatformItemTransform.HEAD, + entity -> entity.helmet().withScale(0.5f) + ), "phi"), /** * Player head */ diff --git a/api/src/main/java/kr/toxicity/model/api/entity/BaseEntity.java b/api/src/main/java/kr/toxicity/model/api/entity/BaseEntity.java index ce1414014..a7c59afd9 100644 --- a/api/src/main/java/kr/toxicity/model/api/entity/BaseEntity.java +++ b/api/src/main/java/kr/toxicity/model/api/entity/BaseEntity.java @@ -176,6 +176,15 @@ public interface BaseEntity extends Identifiable { */ @NotNull TransformedItemStack offHand(); + /** + * Gets helmet item + * @return helmet + * @since 2.0.1 + */ + default @NotNull TransformedItemStack helmet() { + return TransformedItemStack.empty(); + } + /** * Gets tracker registry of this adapter * @return optional tracker registry diff --git a/api/src/main/java/kr/toxicity/model/api/util/TransformedItemStack.java b/api/src/main/java/kr/toxicity/model/api/util/TransformedItemStack.java index aad7fe967..465ada004 100644 --- a/api/src/main/java/kr/toxicity/model/api/util/TransformedItemStack.java +++ b/api/src/main/java/kr/toxicity/model/api/util/TransformedItemStack.java @@ -69,6 +69,15 @@ public record TransformedItemStack(@NotNull Vector3f position, @NotNull Vector3f return of(position, offset, scale, itemStack); } + /** + * Sets a uniform scale + * @param scale uniform scale factor + * @return new item with the given scale + */ + public @NotNull TransformedItemStack withScale(float scale) { + return of(position, offset, new Vector3f(scale), itemStack); + } + /** * Modify item * @param mapper mapper diff --git a/platform/fabric/src/main/kotlin/kr/toxicity/model/impl/fabric/entity/BaseFabricEntityImpl.kt b/platform/fabric/src/main/kotlin/kr/toxicity/model/impl/fabric/entity/BaseFabricEntityImpl.kt index e3f9eb8b2..390012ee7 100644 --- a/platform/fabric/src/main/kotlin/kr/toxicity/model/impl/fabric/entity/BaseFabricEntityImpl.kt +++ b/platform/fabric/src/main/kotlin/kr/toxicity/model/impl/fabric/entity/BaseFabricEntityImpl.kt @@ -16,6 +16,7 @@ import net.kyori.adventure.text.Component import net.minecraft.server.level.ServerPlayer import net.minecraft.world.effect.MobEffects import net.minecraft.world.entity.Entity +import net.minecraft.world.entity.EquipmentSlot import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.ai.attributes.Attributes import org.joml.Vector3f @@ -128,6 +129,15 @@ class BaseFabricEntityImpl(private var entity: Entity) : BaseFabricEntity { } } + override fun helmet(): TransformedItemStack { + val entity = entity + return if (entity is LivingEntity) { + TransformedItemStack.of(entity.getItemBySlot(EquipmentSlot.HEAD).wrap()) + } else { + TransformedItemStack.empty() + } + } + override fun modelData(): String? { return entity.modelData }