From 27d0a8ffc35389963386156c8c3999e19ac7eb9f Mon Sep 17 00:00:00 2001 From: SevenToaster509 Date: Fri, 17 Apr 2026 20:50:32 +0100 Subject: [PATCH] feat: Skulls worn by mobs/players now display on the armor layer --- Minecraft.Client/PlayerRenderer.cpp | 63 ++++++++++++++++++++++++-- Minecraft.Client/PlayerRenderer.h | 6 +++ Minecraft.Client/SkeletonHeadModel.cpp | 8 ++-- Minecraft.Client/SkeletonHeadModel.h | 4 +- 4 files changed, 71 insertions(+), 10 deletions(-) diff --git a/Minecraft.Client/PlayerRenderer.cpp b/Minecraft.Client/PlayerRenderer.cpp index a0d965e2..d3dc4491 100644 --- a/Minecraft.Client/PlayerRenderer.cpp +++ b/Minecraft.Client/PlayerRenderer.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "PlayerRenderer.h" #include "SkullTileRenderer.h" +#include "../Minecraft.World/SkullTileEntity.h" #include "HumanoidMobRenderer.h" #include "HumanoidModel.h" #include "ModelPart.h" @@ -13,8 +14,15 @@ #include "../Minecraft.World/net.minecraft.world.level.tile.h" #include "../Minecraft.World/net.minecraft.h" #include "../Minecraft.World/StringHelpers.h" +#include "SkeletonHeadModel.h" +#include "Textures.h" #include "Skins.h" +ResourceLocation PlayerRenderer::SKELETON_LOCATION = ResourceLocation(TN_MOB_SKELETON); +ResourceLocation PlayerRenderer::WITHER_SKELETON_LOCATION = ResourceLocation(TN_MOB_WITHER_SKELETON); +ResourceLocation PlayerRenderer::ZOMBIE_LOCATION = ResourceLocation(TN_MOB_ZOMBIE); +ResourceLocation PlayerRenderer::CREEPER_LOCATION = ResourceLocation(TN_MOB_CREEPER); + static unsigned int nametagColorForIndex(int index) { static const unsigned int s_firstColors[] = { @@ -65,6 +73,7 @@ PlayerRenderer::PlayerRenderer() : LivingEntityRenderer( new HumanoidModel(0), 0 armorParts1 = new HumanoidModel(1.0f); armorParts2 = new HumanoidModel(0.5f); + armorParts3 = new HumanoidModel(0.5f); } unsigned int PlayerRenderer::getNametagColour(int index) @@ -93,8 +102,9 @@ int PlayerRenderer::prepareArmor(shared_ptr _player, int layer, fl if (dynamic_cast(item)) { ArmorItem *armorItem = dynamic_cast(item); - bindTexture(HumanoidMobRenderer::getArmorLocation(armorItem, layer)); + bindTexture(HumanoidMobRenderer::getArmorLocation(armorItem, layer)); + SkullItem* skullItem = dynamic_cast(item); HumanoidModel *armor = layer == 2 ? armorParts2 : armorParts1; armor->head->visible = layer == 0; @@ -131,6 +141,51 @@ int PlayerRenderer::prepareArmor(shared_ptr _player, int layer, fl return 1; } + else if (dynamic_cast(item)) { + SkullItem* skullItem = dynamic_cast(item); + HumanoidModel* armor = armorParts3; + auto t = new SkeletonHeadModel(0, 0, 64, 64, 1); + //armor->head->_init(); + armor->head = t->head; + //armor->head->addHumanoidBox(-4, -8, -4, 8, 8, 8, 0.5); // Head + + armor->head->visible = layer == 0; + + armor->hair->visible = false; + armor->body->visible = false; + armor->arm0->visible = false; + armor->arm1->visible = false; + armor->leg0->visible = false; + armor->leg1->visible = false; + + switch (itemInstance->getAuxValue()) + { + case SkullTileEntity::TYPE_WITHER: + bindTexture(&WITHER_SKELETON_LOCATION); + break; + case SkullTileEntity::TYPE_ZOMBIE: + bindTexture(&ZOMBIE_LOCATION); + break; + case SkullTileEntity::TYPE_CREEPER: + bindTexture(&CREEPER_LOCATION); + break; + case SkullTileEntity::TYPE_CHAR: + { + bindTexture(&PlayerRenderer::DEFAULT_LOCATION); + break; + } + case SkullTileEntity::TYPE_SKELETON: + default: + bindTexture(&SKELETON_LOCATION); + break; + } + setArmor(armor); + if (armor != nullptr) armor->attackTime = model->attackTime; + if (armor != nullptr) armor->riding = model->riding; + if (armor != nullptr) armor->young = model->young; + + return 1; + } } return -1; @@ -366,7 +421,7 @@ void PlayerRenderer::additionalRendering(shared_ptr _mob, float a) entityRenderDispatcher->itemInHandRenderer->renderItem(mob, headGear, 0); } - else if (headGear->getItem()->id == Item::skull_Id) + /*else if (headGear->getItem()->id == Item::skull_Id) { float s = 17 / 16.0f; glScalef(s, -s, -s); @@ -377,8 +432,8 @@ void PlayerRenderer::additionalRendering(shared_ptr _mob, float a) extra = headGear->getTag()->getString(L"SkullOwner"); } SkullTileRenderer::instance->renderSkull(-0.5f, 0, -0.5f, Facing::UP, 180, headGear->getAuxValue(), extra); - } - + }*/ + //SkullTileRenderer::instance->renderSkull(-0.5f, 0, -0.5f, Facing::UP, 180, headGear->getAuxValue(), extra); glPopMatrix(); } } diff --git a/Minecraft.Client/PlayerRenderer.h b/Minecraft.Client/PlayerRenderer.h index 9d559201..ce61abb3 100644 --- a/Minecraft.Client/PlayerRenderer.h +++ b/Minecraft.Client/PlayerRenderer.h @@ -20,8 +20,14 @@ private: HumanoidModel *armorParts1; HumanoidModel *armorParts2; + HumanoidModel *armorParts3; bool defaultSlimHands; + static ResourceLocation SKELETON_LOCATION; + static ResourceLocation WITHER_SKELETON_LOCATION; + static ResourceLocation ZOMBIE_LOCATION; + static ResourceLocation CREEPER_LOCATION; + public: PlayerRenderer(); diff --git a/Minecraft.Client/SkeletonHeadModel.cpp b/Minecraft.Client/SkeletonHeadModel.cpp index 8e126d66..7bbebc15 100644 --- a/Minecraft.Client/SkeletonHeadModel.cpp +++ b/Minecraft.Client/SkeletonHeadModel.cpp @@ -2,7 +2,7 @@ #include "ModelPart.h" #include "SkeletonHeadModel.h" -void SkeletonHeadModel::_init(int u, int v, int tw, int th) +void SkeletonHeadModel::_init(int u, int v, int tw, int th, int g) { texWidth = tw; texHeight = th; @@ -10,7 +10,7 @@ void SkeletonHeadModel::_init(int u, int v, int tw, int th) // 4J Stu - Set "g" param to 0.1 to fix z-fighting issues (hair has this set to 0.5, so need to be less that that) // Fix for #101501 - TU12: Content: Art: Z-Fighting occurs on the bottom side of a character's head when a Mob Head is equipped. - head->addBox(-4, -8, -4, 8, 8, 8, 0.1); // Head + head->addBox(-4, -8, -4, 8, 8, 8, g); // Head head->setPos(0, 0, 0); // 4J added - compile now to avoid random performance hit first time cubes are rendered @@ -22,9 +22,9 @@ SkeletonHeadModel::SkeletonHeadModel() _init(0, 35, 64, 64); } -SkeletonHeadModel::SkeletonHeadModel(int u, int v, int tw, int th) +SkeletonHeadModel::SkeletonHeadModel(int u, int v, int tw, int th, int g) { - _init(u,v,tw,th); + _init(u,v,tw,th,g); } void SkeletonHeadModel::render(shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) diff --git a/Minecraft.Client/SkeletonHeadModel.h b/Minecraft.Client/SkeletonHeadModel.h index f6911dc6..f6c1cb26 100644 --- a/Minecraft.Client/SkeletonHeadModel.h +++ b/Minecraft.Client/SkeletonHeadModel.h @@ -8,11 +8,11 @@ public: ModelPart *head; private: - void _init(int u, int v, int tw, int th); + void _init(int u, int v, int tw, int th, int g = 0.1); public: SkeletonHeadModel(); - SkeletonHeadModel(int u, int v, int tw, int th); + SkeletonHeadModel(int u, int v, int tw, int th, int g = 0.1); void render(shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled); void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, shared_ptr entity, unsigned int uiBitmaskOverrideAnim=0);