Skip to content

Instantly share code, notes, and snippets.

@JTK222
Last active May 19, 2021 19:46
Show Gist options
  • Save JTK222/b8bfa91836d529f9bf3850683675bd7d to your computer and use it in GitHub Desktop.
Save JTK222/b8bfa91836d529f9bf3850683675bd7d to your computer and use it in GitHub Desktop.
package armor;
import net.minecraft.client.renderer.entity.model.BipedModel;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.IArmorMaterial;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
public class ArmorBaseItem extends ArmorItem {
private Supplier<Supplier<ArmorBaseModel>> armorModel;
public ArmorBaseItem(IArmorMaterial material, EquipmentSlotType equipmentSlot, Item.Properties properties, Supplier<Supplier<ArmorBaseModel>> armorModel) {
super(material, equipmentSlot, properties);
this.armorModel = armorModel;
}
@OnlyIn(Dist.CLIENT)
@Nullable
@Override
public final BipedModel getArmorModel(LivingEntity entity, ItemStack itemStack, EquipmentSlotType armorSlot, BipedModel defaultArmor) {
return armorModel.get().get().applyEntityStats(defaultArmor).applySlot(armorSlot);
}
@Nullable
@Override
public final String getArmorTexture(ItemStack stack, Entity entity, EquipmentSlotType slot, String type) {
return armorModel.get().get().getTexture();
}
}
package armor;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.client.renderer.entity.model.BipedModel;
import net.minecraft.client.renderer.model.ModelRenderer;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.util.ResourceLocation;
public abstract class ArmorBaseModel extends BipedModel<LivingEntity> {
protected final ModelRenderer armorHead;
protected final ModelRenderer armorBody;
protected final ModelRenderer armorRightArm;
protected final ModelRenderer armorLeftArm;
protected final ModelRenderer armorRightLeg;
protected final ModelRenderer armorLeftLeg;
protected final ModelRenderer armorRightBoot;
protected final ModelRenderer armorLeftBoot;
private String texture;
public ArmorBaseModel(int textureWidth, int textureHeight, ResourceLocation texture){
super(1F);
this.textureWidth = textureWidth;
this.textureHeight = textureHeight;
this.texture = texture.toString();
armorHead = new ModelRenderer(this);
armorHead.setRotationPoint(0.0F, 0.0F, 0.0F);
bipedHead.addChild(armorHead);
armorBody = new ModelRenderer(this);
armorBody.setRotationPoint(0.0F, 0.0F, 0.0F);
bipedBody.addChild(armorBody);
armorRightArm = new ModelRenderer(this);
armorRightArm.setRotationPoint(0.0F, 0.0F, 0.0F);
bipedRightArm.addChild(armorRightArm);
armorLeftArm = new ModelRenderer(this);
armorLeftArm.setRotationPoint(0.0F, 0.0F, 0.0F);
bipedLeftArm.addChild(armorLeftArm);
armorRightLeg = new ModelRenderer(this);
armorRightLeg.setRotationPoint(0.0F, 0.0F, 0.0F);
bipedRightLeg.addChild(armorRightLeg);
armorLeftLeg = new ModelRenderer(this);
armorLeftLeg.setRotationPoint(0.0F, 0.0F, 0.0F);
bipedLeftLeg.addChild(armorLeftLeg);
armorRightBoot = new ModelRenderer(this);
armorRightBoot.setRotationPoint(0.0F, 0.0F, 0.0F);
bipedRightLeg.addChild(armorRightBoot);
armorLeftBoot = new ModelRenderer(this);
armorLeftBoot.setRotationPoint(0.0F, 0.0F, 0.0F);
bipedLeftLeg.addChild(armorLeftBoot);
setupArmorParts();
}
public abstract void setupArmorParts();
public final String getTexture(){
return this.texture;
}
/**
* Feel free to override this method as needed.
* It's just required to hide armor parts depending on the equipment slot
*/
public BipedModel applySlot(EquipmentSlotType slot){
armorHead.showModel = false;
armorBody.showModel = false;
armorRightArm.showModel = false;
armorLeftArm.showModel = false;
armorRightLeg.showModel = false;
armorLeftLeg.showModel = false;
armorRightBoot.showModel = false;
armorLeftBoot.showModel = false;
switch(slot){
case HEAD:
armorHead.showModel = true;
break;
case CHEST:
armorBody.showModel = true;
armorRightArm.showModel = true;
armorLeftArm.showModel = true;
break;
case LEGS:
armorRightLeg.showModel = true;
armorLeftLeg.showModel = true;
break;
case FEET:
armorRightBoot.showModel = true;
armorLeftBoot.showModel = true;
break;
default:
break;
}
return this;
}
public final ArmorBaseModel applyEntityStats(BipedModel defaultArmor){
this.isChild = defaultArmor.isChild;
this.isSneak = defaultArmor.isSneak;
this.isSitting = defaultArmor.isSitting;
this.rightArmPose = defaultArmor.rightArmPose;
this.leftArmPose = defaultArmor.leftArmPose;
return this;
}
@Override
public void render(MatrixStack matrixStack, IVertexBuilder buffer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) {
copyModelAngles(this.bipedHead, this.armorHead);
copyModelAngles(this.bipedBody, this.armorBody);
copyModelAngles(this.bipedRightArm, this.armorRightArm);
copyModelAngles(this.bipedLeftArm, this.armorLeftArm);
copyModelAngles(this.bipedRightLeg, this.armorRightLeg);
copyModelAngles(this.bipedLeftLeg, this.armorLeftLeg);
copyModelAngles(this.bipedRightLeg, this.armorRightBoot);
copyModelAngles(this.bipedLeftLeg, this.armorLeftBoot);
matrixStack.push();
if(isSneak) matrixStack.translate(0, 0.2, 0);
renderChildrenOnly(this.bipedHead, matrixStack, buffer, packedLight, packedOverlay, red, green, blue, alpha);
renderChildrenOnly(this.bipedBody, matrixStack, buffer, packedLight, packedOverlay, red, green, blue, alpha);
renderChildrenOnly(this.bipedRightArm, matrixStack, buffer, packedLight, packedOverlay, red, green, blue, alpha);
renderChildrenOnly(this.bipedLeftArm, matrixStack, buffer, packedLight, packedOverlay, red, green, blue, alpha);
renderChildrenOnly(this.bipedRightLeg, matrixStack, buffer, packedLight, packedOverlay, red, green, blue, alpha);
renderChildrenOnly(this.bipedLeftLeg, matrixStack, buffer, packedLight, packedOverlay, red, green, blue, alpha);
matrixStack.pop();
}
public final void setRotationAngle(ModelRenderer modelRenderer, float x, float y, float z) {
modelRenderer.rotateAngleX = x;
modelRenderer.rotateAngleY = y;
modelRenderer.rotateAngleZ = z;
}
private final void copyModelAngles(ModelRenderer in, ModelRenderer out){
out.rotateAngleX = in.rotateAngleX;
out.rotateAngleY = in.rotateAngleY;
out.rotateAngleZ = in.rotateAngleZ;
}
private final void renderChildrenOnly(ModelRenderer bodyPart, MatrixStack matrixStack, IVertexBuilder buffer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha){
if(!bodyPart.childModels.isEmpty()){
matrixStack.push();
bodyPart.translateRotate(matrixStack);
for(ModelRenderer child : bodyPart.childModels)
child.render(matrixStack, buffer, packedLight, packedOverlay, red, green, blue, alpha);
matrixStack.pop();
}
}
}
public class ArmorModelImplementation extends ArmorBaseModel {
public ArmorModelImplementation() {
super(/*texture width*/, /*texture height*/, new ResourceLocation(/*Texture path*/));
}
@Override
public void setupArmorParts() {
//You need to cut out some parts from Blockbenchs exported model, and paste them here.
//You can see 2 examples of how this may look, adding a cube to the head
//and a rotated cube on the chest
//Export the unedited armor template to see which parts you should **not** copy over
armorHead.cubeList.add(new ModelBox(armorHead, 0, 18, -0.5F, -22.0F, -5.0F, 1, 22, 10, 0.0F, false));
ModelRenderer bone = new ModelRenderer(this);
bone.setRotationPoint(0.0F, 0.0F, 0.0F);
setRotationAngle(bone, 0.0F, 0.0F, -0.7854F);
armorBody.addChild(bone);
bone.cubeList.add(new ModelBox(bone, 18, 82, -4.0F, 1.0F, -3.0F, 3, 3, 1, 0.0F, false));
}
}
//This needs to be it's own class, I don't recommend doing anything else in here!
//Otherwise you risk being incompatible with servers.
public class ClientArmorHelper{
private final static ArmorBaseModel YOUR_FIRST_ARMOR = new ArmorModelImplementation();
private final static ArmorBaseModel YOUR_SECOND_ARMOR = new SomeOtherArmorModelImplementation();
public static ArmorBaseModel getFirstArmor(){
return YOUR_FIRST_ARMOR;
}
public static ArmorBaseModel getSecondArmor(){
return YOUR_SECOND_ARMOR;
}
}
//Creating an Armor Item now looks similar to this:
new ArmorBaseItem(material, slotType, properties, () -> ClientArmorHelper::getFirstArmor);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment