minecraft-src/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java
2025-07-04 03:15:13 +03:00

112 lines
4.5 KiB
Java

package net.minecraft.client.renderer.entity.layers;
import com.mojang.blaze3d.vertex.PoseStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.model.HumanoidModel;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.RenderLayerParent;
import net.minecraft.client.renderer.entity.state.HumanoidRenderState;
import net.minecraft.client.resources.model.EquipmentClientInfo;
import net.minecraft.core.component.DataComponents;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.equipment.EquipmentAsset;
import net.minecraft.world.item.equipment.Equippable;
@Environment(EnvType.CLIENT)
public class HumanoidArmorLayer<S extends HumanoidRenderState, M extends HumanoidModel<S>, A extends HumanoidModel<S>> extends RenderLayer<S, M> {
private final A innerModel;
private final A outerModel;
private final A innerModelBaby;
private final A outerModelBaby;
private final EquipmentLayerRenderer equipmentRenderer;
public HumanoidArmorLayer(RenderLayerParent<S, M> renderer, A innerModel, A outerModel, EquipmentLayerRenderer equipmentRenderer) {
this(renderer, innerModel, outerModel, innerModel, outerModel, equipmentRenderer);
}
public HumanoidArmorLayer(
RenderLayerParent<S, M> renderer, A innerModel, A outerModel, A innerModelBaby, A outerModelBaby, EquipmentLayerRenderer equipmentRenderer
) {
super(renderer);
this.innerModel = innerModel;
this.outerModel = outerModel;
this.innerModelBaby = innerModelBaby;
this.outerModelBaby = outerModelBaby;
this.equipmentRenderer = equipmentRenderer;
}
public static boolean shouldRender(ItemStack stack, EquipmentSlot slot) {
Equippable equippable = stack.get(DataComponents.EQUIPPABLE);
return equippable != null && shouldRender(equippable, slot);
}
private static boolean shouldRender(Equippable equippable, EquipmentSlot slot) {
return equippable.assetId().isPresent() && equippable.slot() == slot;
}
public void render(PoseStack poseStack, MultiBufferSource multiBufferSource, int i, S humanoidRenderState, float f, float g) {
this.renderArmorPiece(
poseStack, multiBufferSource, humanoidRenderState.chestEquipment, EquipmentSlot.CHEST, i, this.getArmorModel(humanoidRenderState, EquipmentSlot.CHEST)
);
this.renderArmorPiece(
poseStack, multiBufferSource, humanoidRenderState.legsEquipment, EquipmentSlot.LEGS, i, this.getArmorModel(humanoidRenderState, EquipmentSlot.LEGS)
);
this.renderArmorPiece(
poseStack, multiBufferSource, humanoidRenderState.feetEquipment, EquipmentSlot.FEET, i, this.getArmorModel(humanoidRenderState, EquipmentSlot.FEET)
);
this.renderArmorPiece(
poseStack, multiBufferSource, humanoidRenderState.headEquipment, EquipmentSlot.HEAD, i, this.getArmorModel(humanoidRenderState, EquipmentSlot.HEAD)
);
}
private void renderArmorPiece(PoseStack poseStack, MultiBufferSource bufferSource, ItemStack armorItem, EquipmentSlot slot, int packedLight, A model) {
Equippable equippable = armorItem.get(DataComponents.EQUIPPABLE);
if (equippable != null && shouldRender(equippable, slot)) {
this.getParentModel().copyPropertiesTo(model);
this.setPartVisibility(model, slot);
EquipmentClientInfo.LayerType layerType = this.usesInnerModel(slot)
? EquipmentClientInfo.LayerType.HUMANOID_LEGGINGS
: EquipmentClientInfo.LayerType.HUMANOID;
this.equipmentRenderer
.renderLayers(layerType, (ResourceKey<EquipmentAsset>)equippable.assetId().orElseThrow(), model, armorItem, poseStack, bufferSource, packedLight);
}
}
protected void setPartVisibility(A model, EquipmentSlot slot) {
model.setAllVisible(false);
switch (slot) {
case HEAD:
model.head.visible = true;
model.hat.visible = true;
break;
case CHEST:
model.body.visible = true;
model.rightArm.visible = true;
model.leftArm.visible = true;
break;
case LEGS:
model.body.visible = true;
model.rightLeg.visible = true;
model.leftLeg.visible = true;
break;
case FEET:
model.rightLeg.visible = true;
model.leftLeg.visible = true;
}
}
private A getArmorModel(S renderState, EquipmentSlot slot) {
if (this.usesInnerModel(slot)) {
return renderState.isBaby ? this.innerModelBaby : this.innerModel;
} else {
return renderState.isBaby ? this.outerModelBaby : this.outerModel;
}
}
private boolean usesInnerModel(EquipmentSlot slot) {
return slot == EquipmentSlot.LEGS;
}
}