A simple, vanilla-friendly mod that gives you a second layer of defense. No more choosing between your enchanted diamond chestplate and that cool-looking chainmail. Now you can wear both.
Adds four new "underlayer" Curios slots, one for each armor type. This mod re-purposes vanilla chainmail to be worn underneath your primary armor instead of in the main armor slots. kinda like how you would in real life.
The chainmail provides its full armor and enchantment benefits, stacking with your main gear. More protection is always better.
The underlayer takes durability damage, but it's smart about it. If you have a primary armor piece equipped over it, the underlayer takes 60% less durability damage.
The best part. The chainmail realistically renders only in the gaps of your outer armor. No ugly clipping or Z-fighting. It just looks right.
mods folder.This mod is designed to be lightweight and client-focused. Here's a look under the hood:
Curios Integration (CapabilityAttacher.java & UnderlayerCurioProvider.java):
AttachCapabilitiesEvent<ItemStack>. When the event fires for a chainmail item, we attach our own ICapabilityProvider.UnderlayerCurioProvider, exposes the ICurio capability. The core logic resides in the ICurio implementation:canEquipFromUse: Returns true to enable right-click and shift-click equipping.canEquip: Checks the SlotContext identifier to ensure a chainmail piece can only be placed in its corresponding "underlayer_*" slot (e.g., Items.CHAINMAIL_HELMET in "underlayer_head").getAttributeModifiers: This is key for providing armor stats. It gets the item's default attribute modifiers for its corresponding EquipmentSlot and rebuilds them with a new UUID, effectively copying the armor and armor toughness attributes to the Curio.getEquipSound: Returns the vanilla SoundEvents.ARMOR_EQUIP_CHAIN.Damage & Durability Logic (ModForgeEvents.java):
LivingHurtEvent. This event is where all damage calculations happen.EnchantmentHelper.getDamageProtection() and accumulates the value. This total is then used to calculate the damage reduction factor (1.0f - Math.min(20.0f, totalEnchantmentProtection) / 25.0f), and the event's damage amount is updated.(int) Math.max(1.0f, finalDamage / 4.0f).durabilityDamage * 0.4f).ItemStack.hurtAndBreak() method is called on the curio's stack to apply the damage.The Rendering Magic (UnderlayerRenderer.java & ClientModEvents.java):
FMLClientSetupEvent, we register an instance of our UnderlayerRenderer for each of the four chainmail items using CuriosRendererRegistry.register().RenderSystem.colorMask(false, false, false, false)). This pass writes to the depth buffer (creating a 3D "mold") and, crucially, writes a value of 1 to the stencil buffer for every pixel the armor occupies. A custom RenderType (armorCutoutWithCull) is used to enable back-face culling, preventing the inside of the armor from creating a messy mold.RenderSystem to only draw where the stencil buffer's value is not equal to 1 (RenderSystem.stencilFunc(GL11.GL_NOTEQUAL, 1, 0xFF)). This confines the underlayer to the 2D silhouette of the outer armor. The standard depth test against the "mold" from Pass 1 then correctly clips the underlayer in 3D space, ensuring it only appears in the gaps and underneath the outer armor.AllTheTrimsCompat.tryRender() to provide explicit support for rendering trims from the All the Trims mod. If that fails or the mod is not present, it falls back to the vanilla trim rendering logic.