Cosmetics
Letting familiars wear hats and hold weapons, and drawing them.
On the entity
ItemStack getCosmetic(FamiliarCosmeticSlot slot); // HAT or WEAPON
void setCosmetic(FamiliarCosmeticSlot slot, ItemStack stack);
boolean canWearCosmeticHat(); // override: true if it has a hat slot
boolean canWearCosmeticHat(ItemStack stack); // default: in familiarslib:familiar_hats
boolean canHoldCosmeticWeapon(); // override: true if it has a weapon slot
boolean canHoldCosmeticWeapon(ItemStack stack); // default: in getCosmeticWeaponTag()
TagKey<Item> getCosmeticWeaponTag(); // default: <entity namespace>:familiar_weapons/<entity path>
void dropCosmetics(); // drops both items and empties the slotsUsually you only override the no-argument methods. Ship the familiar's weapon tag, and add it to familiarslib:familiar_weapons in data/familiarslib/tags/item/familiar_weapons.json with "replace": false. Call dropCosmetics() wherever a familiar is gone for good, or its items are lost.
Cosmetics are saved as "CosmeticHat" and "CosmeticWeapon". Shrunk items carry the familiarslib:familiar_cosmetic component; FamiliarCosmetics has helpers like isShrunkCosmetic, shrink, slotForEquip and weaponTagFor.
Hats: FamiliarHatLayer
Hats are drawn on an armor bone, the way GeckoLib draws helmets, so every hat lines up the same:
{ "name": "armorBipedHead", "parent": "body", "pivot": [0, 0.5, 0],
"cubes": [{ "origin": [-5, -0.5, -5], "size": [10, 10, 10], "uv": {} }] }- The pivot is where the head meets the neck; hats sit on it.
- The cube size is the hat size. A vanilla helmet is 10 wide, so hats are scaled by
cube size / 10. Keep the three dimensions equal. - At scale
s, a hat spans frompivot - stopivot + 9·svertically: when shrinking hats, move the pivot up to keep the top in place.
addRenderLayer(new FamiliarHatLayer<>(this)); // the "armorBipedHead" bone
addRenderLayer(new FamiliarHatLayer<>(this, "my_hat_bone")); // or your own boneGeckoLib armor (Iron's Spellbooks hats) and vanilla helmets are drawn as worn helmets, skulls like on a player, and other items the way vanilla draws them on a player's head. GeckoLib helmets may not show when a familiar is drawn in a screen.
Weapons: FamiliarCosmeticLayer
addRenderLayer(new FamiliarCosmeticLayer<>(this)
.weapon(FamiliarCosmeticLayer.Placement.on("bm_weapon")
.rotation(-90, 180, 0)
.scale(0.6F)
.context(ItemDisplayContext.THIRD_PERSON_LEFT_HAND)
.hideBone()));| Method | Meaning |
|---|---|
on(bone) | The bone to attach to |
offset(x, y, z) | Moves the item from the bone's pivot, in model pixels |
rotation(x, y, z) | Rotates the item in degrees, X then Y then Z |
scale(s) | Scales the item |
context(ctx) | The item model view to use (default THIRD_PERSON_RIGHT_HAND) |
hideBone() | Hides the bone and its children while a cosmetic weapon is equipped |
The placement is relative to the bone as it looks in Blockbench, including its animated rotation, so the item follows every animation. The offset needed grows with the scale, so fix the scale first.
The context picks the item model's view: Iron's Spellbooks spellbooks show their open 3D lectern book with ItemDisplayContext.HEAD.
