104 lines
5.6 KiB
Java
104 lines
5.6 KiB
Java
package net.minecraft.client.renderer.entity.layers;
|
|
|
|
import com.mojang.blaze3d.vertex.PoseStack;
|
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
|
import java.io.IOException;
|
|
import java.util.Optional;
|
|
import java.util.function.UnaryOperator;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.Util;
|
|
import net.minecraft.client.model.EntityModel;
|
|
import net.minecraft.client.model.VillagerLikeModel;
|
|
import net.minecraft.client.renderer.MultiBufferSource;
|
|
import net.minecraft.client.renderer.entity.RenderLayerParent;
|
|
import net.minecraft.client.renderer.entity.state.LivingEntityRenderState;
|
|
import net.minecraft.client.renderer.entity.state.VillagerDataHolderRenderState;
|
|
import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite;
|
|
import net.minecraft.client.resources.metadata.animation.VillagerMetadataSection;
|
|
import net.minecraft.core.Holder;
|
|
import net.minecraft.resources.ResourceKey;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.server.packs.resources.ResourceManager;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.world.entity.npc.VillagerData;
|
|
import net.minecraft.world.entity.npc.VillagerProfession;
|
|
import net.minecraft.world.entity.npc.VillagerType;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class VillagerProfessionLayer<S extends LivingEntityRenderState & VillagerDataHolderRenderState, M extends EntityModel<S> & VillagerLikeModel>
|
|
extends RenderLayer<S, M> {
|
|
private static final Int2ObjectMap<ResourceLocation> LEVEL_LOCATIONS = Util.make(new Int2ObjectOpenHashMap<>(), int2ObjectOpenHashMap -> {
|
|
int2ObjectOpenHashMap.put(1, ResourceLocation.withDefaultNamespace("stone"));
|
|
int2ObjectOpenHashMap.put(2, ResourceLocation.withDefaultNamespace("iron"));
|
|
int2ObjectOpenHashMap.put(3, ResourceLocation.withDefaultNamespace("gold"));
|
|
int2ObjectOpenHashMap.put(4, ResourceLocation.withDefaultNamespace("emerald"));
|
|
int2ObjectOpenHashMap.put(5, ResourceLocation.withDefaultNamespace("diamond"));
|
|
});
|
|
private final Object2ObjectMap<ResourceKey<VillagerType>, VillagerMetadataSection.Hat> typeHatCache = new Object2ObjectOpenHashMap<>();
|
|
private final Object2ObjectMap<ResourceKey<VillagerProfession>, VillagerMetadataSection.Hat> professionHatCache = new Object2ObjectOpenHashMap<>();
|
|
private final ResourceManager resourceManager;
|
|
private final String path;
|
|
|
|
public VillagerProfessionLayer(RenderLayerParent<S, M> renderer, ResourceManager resourceManager, String path) {
|
|
super(renderer);
|
|
this.resourceManager = resourceManager;
|
|
this.path = path;
|
|
}
|
|
|
|
public void render(PoseStack poseStack, MultiBufferSource multiBufferSource, int i, S livingEntityRenderState, float f, float g) {
|
|
if (!livingEntityRenderState.isInvisible) {
|
|
VillagerData villagerData = livingEntityRenderState.getVillagerData();
|
|
if (villagerData != null) {
|
|
Holder<VillagerType> holder = villagerData.type();
|
|
Holder<VillagerProfession> holder2 = villagerData.profession();
|
|
VillagerMetadataSection.Hat hat = this.getHatData(this.typeHatCache, "type", holder);
|
|
VillagerMetadataSection.Hat hat2 = this.getHatData(this.professionHatCache, "profession", holder2);
|
|
M entityModel = this.getParentModel();
|
|
entityModel.hatVisible(hat2 == VillagerMetadataSection.Hat.NONE || hat2 == VillagerMetadataSection.Hat.PARTIAL && hat != VillagerMetadataSection.Hat.FULL);
|
|
ResourceLocation resourceLocation = this.getResourceLocation("type", holder);
|
|
renderColoredCutoutModel(entityModel, resourceLocation, poseStack, multiBufferSource, i, livingEntityRenderState, -1);
|
|
entityModel.hatVisible(true);
|
|
if (!holder2.is(VillagerProfession.NONE) && !livingEntityRenderState.isBaby) {
|
|
ResourceLocation resourceLocation2 = this.getResourceLocation("profession", holder2);
|
|
renderColoredCutoutModel(entityModel, resourceLocation2, poseStack, multiBufferSource, i, livingEntityRenderState, -1);
|
|
if (!holder2.is(VillagerProfession.NITWIT)) {
|
|
ResourceLocation resourceLocation3 = this.getResourceLocation(
|
|
"profession_level", LEVEL_LOCATIONS.get(Mth.clamp(villagerData.level(), 1, LEVEL_LOCATIONS.size()))
|
|
);
|
|
renderColoredCutoutModel(entityModel, resourceLocation3, poseStack, multiBufferSource, i, livingEntityRenderState, -1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private ResourceLocation getResourceLocation(String folder, ResourceLocation location) {
|
|
return location.withPath((UnaryOperator<String>)(string2 -> "textures/entity/" + this.path + "/" + folder + "/" + string2 + ".png"));
|
|
}
|
|
|
|
private ResourceLocation getResourceLocation(String folder, Holder<?> holder) {
|
|
return (ResourceLocation)holder.unwrapKey()
|
|
.map(resourceKey -> this.getResourceLocation(folder, resourceKey.location()))
|
|
.orElse(MissingTextureAtlasSprite.getLocation());
|
|
}
|
|
|
|
public <K> VillagerMetadataSection.Hat getHatData(Object2ObjectMap<ResourceKey<K>, VillagerMetadataSection.Hat> cache, String folder, Holder<K> key) {
|
|
ResourceKey<K> resourceKey = (ResourceKey<K>)key.unwrapKey().orElse(null);
|
|
return resourceKey == null
|
|
? VillagerMetadataSection.Hat.NONE
|
|
: cache.computeIfAbsent(
|
|
resourceKey,
|
|
object -> (VillagerMetadataSection.Hat)this.resourceManager.getResource(this.getResourceLocation(folder, resourceKey.location())).flatMap(resource -> {
|
|
try {
|
|
return resource.metadata().getSection(VillagerMetadataSection.TYPE).map(VillagerMetadataSection::hat);
|
|
} catch (IOException var2) {
|
|
return Optional.empty();
|
|
}
|
|
}).orElse(VillagerMetadataSection.Hat.NONE)
|
|
);
|
|
}
|
|
}
|