diff --git a/Minecraft.Client/ArmorStandRenderer.cpp b/Minecraft.Client/ArmorStandRenderer.cpp index 1947830f..7fdf75bc 100644 --- a/Minecraft.Client/ArmorStandRenderer.cpp +++ b/Minecraft.Client/ArmorStandRenderer.cpp @@ -21,9 +21,11 @@ static const float DEG_TO_RAD = 3.14159265f / 180.0f; ResourceLocation ArmorStandRenderer::LOC_ARMOR_STAND = ResourceLocation(TN_MOB_ARMORSTAND); + ArmorStandRenderer::ArmorStandArmorLayer::ArmorStandArmorLayer(LivingEntityRenderer* renderer) : HumanoidArmorLayer(renderer) { + delete armorModel1; delete armorModel2; armorModel1 = new ArmorStandArmorModel(0.5f); @@ -42,17 +44,23 @@ ArmorStandRenderer::ArmorStandRenderer() : LivingEntityRenderer(new ArmorStandModel(0.0f), 0.0f) { armorLayer = new ArmorStandArmorLayer(this); + ArmorStandModel* m = static_cast(getModel()); - headLayer = m ? new CustomHeadLayer(m->head) : nullptr; + + + headLayer = m ? new CustomHeadLayer(m->head, this) : nullptr; } ArmorStandRenderer::~ArmorStandRenderer() {} + + ResourceLocation* ArmorStandRenderer::getTextureLocation(shared_ptr entity) { return &LOC_ARMOR_STAND; } + bool ArmorStandRenderer::shouldShowName(shared_ptr entity) { if (!entity) return false; @@ -77,6 +85,7 @@ void ArmorStandRenderer::setupRotations(shared_ptr mob, } } + void ArmorStandRenderer::render(shared_ptr entity, double x, double y, double z, float rot, float a) @@ -84,6 +93,7 @@ void ArmorStandRenderer::render(shared_ptr entity, LivingEntityRenderer::render(entity, x, y, z, rot, a); } + void ArmorStandRenderer::renderModel(shared_ptr mob, float wp, float ws, float bob, float headRotMinusBodyRot, @@ -110,44 +120,71 @@ void ArmorStandRenderer::renderModel(shared_ptr mob, ll.x * DEG_TO_RAD, ll.y * DEG_TO_RAD, ll.z * DEG_TO_RAD, rl.x * DEG_TO_RAD, rl.y * DEG_TO_RAD, rl.z * DEG_TO_RAD ); - if (armorLayer) { auto applyPose = [&](HumanoidModel* am) { if (!am) return; - am->head->xRot = h.x * DEG_TO_RAD; am->head->yRot = h.y * DEG_TO_RAD; am->head->zRot = h.z * DEG_TO_RAD; - if (am->hair) { am->hair->xRot = h.x * DEG_TO_RAD; am->hair->yRot = h.y * DEG_TO_RAD; am->hair->zRot = h.z * DEG_TO_RAD; } - am->body->xRot = b.x * DEG_TO_RAD; am->body->yRot = b.y * DEG_TO_RAD; am->body->zRot = b.z * DEG_TO_RAD; - am->arm1->xRot = la.x * DEG_TO_RAD; am->arm1->yRot = la.y * DEG_TO_RAD; am->arm1->zRot = la.z * DEG_TO_RAD; - am->arm0->xRot = ra.x * DEG_TO_RAD; am->arm0->yRot = ra.y * DEG_TO_RAD; am->arm0->zRot = ra.z * DEG_TO_RAD; - am->leg0->xRot = rl.x * DEG_TO_RAD; am->leg0->yRot = rl.y * DEG_TO_RAD; am->leg0->zRot = rl.z * DEG_TO_RAD; - am->leg1->xRot = ll.x * DEG_TO_RAD; am->leg1->yRot = ll.y * DEG_TO_RAD; am->leg1->zRot = ll.z * DEG_TO_RAD; + am->head->xRot = h.x * DEG_TO_RAD; + am->head->yRot = h.y * DEG_TO_RAD; + am->head->zRot = h.z * DEG_TO_RAD; + if (am->hair) + { + am->hair->xRot = h.x * DEG_TO_RAD; + am->hair->yRot = h.y * DEG_TO_RAD; + am->hair->zRot = h.z * DEG_TO_RAD; + } + am->body->xRot = b.x * DEG_TO_RAD; + am->body->yRot = b.y * DEG_TO_RAD; + am->body->zRot = b.z * DEG_TO_RAD; + am->arm1->xRot = la.x * DEG_TO_RAD; + am->arm1->yRot = la.y * DEG_TO_RAD; + am->arm1->zRot = la.z * DEG_TO_RAD; + am->arm0->xRot = ra.x * DEG_TO_RAD; + am->arm0->yRot = ra.y * DEG_TO_RAD; + am->arm0->zRot = ra.z * DEG_TO_RAD; + am->leg0->xRot = rl.x * DEG_TO_RAD; + am->leg0->yRot = rl.y * DEG_TO_RAD; + am->leg0->zRot = rl.z * DEG_TO_RAD; + am->leg1->xRot = ll.x * DEG_TO_RAD; + am->leg1->yRot = ll.y * DEG_TO_RAD; + am->leg1->zRot = ll.z * DEG_TO_RAD; }; + applyPose(static_cast(armorLayer->armorModel1)); applyPose(static_cast(armorLayer->armorModel2)); } LivingEntityRenderer::renderModel(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale); + if (headLayer) { float fScale = 1.0f / 16.0f; float bodyRot = mob->yBodyRotO + (mob->yBodyRot - mob->yBodyRotO) * 0.0f; float headRot = mob->yHeadRotO + (mob->yHeadRot - mob->yHeadRotO) * 0.0f; - float headRotX = mob->xRotO + (mob->xRot - mob->xRotO) * 0.0f; + float headRotX = mob->xRotO + (mob->xRot - mob->xRotO) * 0.0f; headLayer->render(mob, wp, ws, bob, headRot - bodyRot, headRotX, fScale, true); } } + void ArmorStandRenderer::additionalRendering(shared_ptr mob, float a) { shared_ptr headGear = mob->getArmor(3); if (!headGear) return; + if ((mob->getAnimOverrideBitmask() & (1 << HumanoidModel::eAnim_DontRenderArmour)) != 0) return; - if (headGear->getItem()->id >= 256) return; + Item* item = headGear->getItem(); + if (!item) return; + + + if (dynamic_cast(item)) return; + + + if (item->id >= 256) return; ArmorStandModel* m = static_cast(getModel()); if (!m || !m->head) return; @@ -155,17 +192,21 @@ void ArmorStandRenderer::additionalRendering(shared_ptr mob, float glPushMatrix(); m->head->translateTo(1.0f / 16.0f); - if (Tile::tiles[headGear->id] != nullptr && TileRenderer::canRender(Tile::tiles[headGear->id]->getRenderShape())) + if (Tile::tiles[headGear->id] != nullptr + && TileRenderer::canRender(Tile::tiles[headGear->id]->getRenderShape())) { float s = 10.0f / 16.0f; glTranslatef(0.0f, -4.0f / 16.0f, 0.0f); glRotatef(90.0f, 0.0f, 1.0f, 0.0f); glScalef(s, -s, s); } + this->entityRenderDispatcher->itemInHandRenderer->renderItem(mob, headGear, 0); glPopMatrix(); } + + int ArmorStandRenderer::prepareArmor(shared_ptr mob, int layer, float a) { if (!armorLayer) return -1; @@ -174,13 +215,26 @@ int ArmorStandRenderer::prepareArmor(shared_ptr mob, int layer, fl if (!itemInstance) return -1; Item* item = itemInstance->getItem(); + if (!item) return -1; + SkullItem* skullItem = dynamic_cast(item); if (skullItem && layer == 0) { HumanoidModel* am = armorLayer->getArmorModel(layer); + if (!am) return -1; - switch (itemInstance->getAuxValue()) + + am->head->visible = true; + if (am->hair) am->hair->visible = false; + am->body->visible = false; + am->arm0->visible = false; + am->arm1->visible = false; + am->leg0->visible = false; + am->leg1->visible = false; + + int skullType = itemInstance->getAuxValue() & 0xF; + switch (skullType) { case SkullTileEntity::TYPE_WITHER: bindTexture(&PlayerRenderer::WITHER_SKELETON_LOCATION); @@ -200,14 +254,6 @@ int ArmorStandRenderer::prepareArmor(shared_ptr mob, int layer, fl break; } - am->head->visible = true; - if (am->hair) am->hair->visible = false; - am->body->visible = false; - am->arm0->visible = false; - am->arm1->visible = false; - am->leg0->visible = false; - am->leg1->visible = false; - setArmor(am); am->attackTime = model->attackTime; am->riding = model->riding; @@ -221,13 +267,16 @@ int ArmorStandRenderer::prepareArmor(shared_ptr mob, int layer, fl bindTexture(HumanoidMobRenderer::getArmorLocation(armorItem, layer)); HumanoidModel* am = armorLayer->getArmorModel(layer); - am->head->visible = (layer == 0); + if (!am) return -1; + + + am->head->visible = (layer == 0); if (am->hair) am->hair->visible = (layer == 0); - am->body->visible = (layer == 1 || layer == 2); - am->arm0->visible = (layer == 1); - am->arm1->visible = (layer == 1); - am->leg0->visible = (layer == 2 || layer == 3); - am->leg1->visible = (layer == 2 || layer == 3); + am->body->visible = (layer == 1 || layer == 2); + am->arm0->visible = (layer == 1); + am->arm1->visible = (layer == 1); + am->leg0->visible = (layer == 2 || layer == 3); + am->leg1->visible = (layer == 2 || layer == 3); setArmor(am); am->attackTime = model->attackTime; @@ -236,17 +285,14 @@ int ArmorStandRenderer::prepareArmor(shared_ptr mob, int layer, fl if (armorItem->getMaterial() == ArmorItem::ArmorMaterial::CLOTH) { - int color = armorItem->getColor(itemInstance); + int color = armorItem->getColor(itemInstance); float red = static_cast((color >> 16) & 0xFF) / 255.0f; - float green = static_cast((color >> 8) & 0xFF) / 255.0f; - float blue = static_cast(color & 0xFF) / 255.0f; + float green = static_cast((color >> 8) & 0xFF) / 255.0f; + float blue = static_cast( color & 0xFF) / 255.0f; glColor3f(red, green, blue); - if (itemInstance->isEnchanted()) return 0x1f; - return 0x10; + return itemInstance->isEnchanted() ? 0x1f : 0x10; } glColor3f(1.0f, 1.0f, 1.0f); - if (itemInstance->isEnchanted()) return 15; - return 1; -} - + return itemInstance->isEnchanted() ? 15 : 1; +} \ No newline at end of file diff --git a/Minecraft.Client/CustomHeadLayer.cpp b/Minecraft.Client/CustomHeadLayer.cpp index ad522b70..408409ce 100644 --- a/Minecraft.Client/CustomHeadLayer.cpp +++ b/Minecraft.Client/CustomHeadLayer.cpp @@ -1,15 +1,19 @@ #include "stdafx.h" #include "CustomHeadLayer.h" +#include "LivingEntityRenderer.h" #include "ModelPart.h" #include "SkullTileRenderer.h" #include "TileRenderer.h" +#include "EntityRenderDispatcher.h" #include "../Minecraft.World/ItemInstance.h" #include "../Minecraft.World/Item.h" #include "../Minecraft.World/Tile.h" +#include "../Minecraft.World/SkullItem.h" +#include "../Minecraft.World/SkullTileEntity.h" #include "../Minecraft.World/LivingEntity.h" -CustomHeadLayer::CustomHeadLayer(ModelPart* headPart) - : headPart(headPart) +CustomHeadLayer::CustomHeadLayer(ModelPart* headPart, LivingEntityRenderer* parentRenderer) + : headPart(headPart), parentRenderer(parentRenderer) { } @@ -23,43 +27,52 @@ void CustomHeadLayer::render(shared_ptr mob, float headRot, float headRotX, float scale, bool useCompiled) { - ItemInstanceArray slots = mob->getEquipmentSlots(); - if (slots.length < 5) return; - shared_ptr helmet = slots[4]; + if (mob->instanceof(eTYPE_PLAYER)) return; + + if (!headPart) return; + + shared_ptr helmet = mob->getArmor(3); if (!helmet) return; + Item* item = helmet->getItem(); if (!item) return; - bool hasHatLayer = false; - if (mob->instanceof(eTYPE_PLAYER)) { - _SkinAdjustments adj; - mob->getSkinAdjustments(&adj); - hasHatLayer = (adj.data[0] & 0x100) != 0; - } + + if (dynamic_cast(item)) return; + + + if (item->id >= 256) return; + + + EntityRenderDispatcher* dispatcher = parentRenderer ? parentRenderer->entityRenderDispatcher : nullptr; glPushMatrix(); - headPart->translateTo(0.0625f); + headPart->translateTo(1.0f / 16.0f); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - int itemId = item->id; + + if (item->id > 0 + && item->id < Tile::TILE_NUM_COUNT + && Tile::tiles[item->id] != nullptr + && TileRenderer::canRender(Tile::tiles[item->id]->getRenderShape())) + { + float s = 10.0f / 16.0f; + glTranslatef(0.0f, -4.0f / 16.0f, 0.0f); + glRotatef(90.0f, 0.0f, 1.0f, 0.0f); + glScalef(s, -s, s); - if (itemId == Tile::skull_Id) { - if (!SkullTileRenderer::instance) { glPopMatrix(); return; } - glScalef(1.1875f, -1.1875f, -1.1875f); - glTranslatef(-0.5f, 0.0f, -0.5f); - int skullType = helmet->getAuxValue() & 0xF; - wstring extra = helmet->hasTag() ? helmet->getTag()->getString(L"SkullOwner") : L""; - SkullTileRenderer::instance->renderSkull(0.0f, 0.0f, 0.0f, -1, 180.0f, skullType, extra); - } else if (itemId < 0x100) { - glTranslatef(0.0f, -0.25f, 0.0f); - glRotatef(180.0f, 0.0f, 1.0f, 0.0f); - glScalef(0.625f, 0.625f, 0.625f); - glRotatef(90.0f, 0.0f, 1.0f, 0.0f); - if (itemId > 0 && itemId < Tile::TILE_NUM_COUNT && Tile::tiles[itemId]) { + TileRenderer tr; - tr.renderTile(Tile::tiles[itemId], helmet->getAuxValue(), 1.0f, 1.0f, useCompiled); + tr.renderTile(Tile::tiles[item->id], helmet->getAuxValue(), 1.0f, 1.0f, useCompiled); + glPopMatrix(); + return; + } + + + if (dispatcher && dispatcher->itemInHandRenderer) + { + dispatcher->itemInHandRenderer->renderItem(mob, helmet, 0); } -} glPopMatrix(); } \ No newline at end of file diff --git a/Minecraft.Client/CustomHeadLayer.h b/Minecraft.Client/CustomHeadLayer.h index f4b83301..da6814c6 100644 --- a/Minecraft.Client/CustomHeadLayer.h +++ b/Minecraft.Client/CustomHeadLayer.h @@ -3,16 +3,17 @@ class ModelPart; class LivingEntity; +class LivingEntityRenderer; class CustomHeadLayer : public RenderLayer { public: - - ModelPart* headPart; + ModelPart* headPart; + LivingEntityRenderer* parentRenderer; - explicit CustomHeadLayer(ModelPart* headPart); + CustomHeadLayer(ModelPart* headPart, LivingEntityRenderer* parentRenderer); virtual ~CustomHeadLayer() {} - virtual int colorsOnDamage() override; + virtual int colorsOnDamage() override; virtual void render(shared_ptr mob, float wp, float ws, float bob, float headRot, float headRotX, diff --git a/Minecraft.Client/EntityRenderer.h b/Minecraft.Client/EntityRenderer.h index 0445fe1e..6cdb1d86 100644 --- a/Minecraft.Client/EntityRenderer.h +++ b/Minecraft.Client/EntityRenderer.h @@ -21,6 +21,7 @@ class Font; // 4J - this was originally a generic of type EntityRenderer class EntityRenderer { + friend class CustomHeadLayer; friend class PlayerRenderer; // 4J Added to allow PlayerRenderer to call renderShadow protected: EntityRenderDispatcher *entityRenderDispatcher; diff --git a/Minecraft.Client/PlayerRenderer.cpp b/Minecraft.Client/PlayerRenderer.cpp index 458a3236..fd8ed380 100644 --- a/Minecraft.Client/PlayerRenderer.cpp +++ b/Minecraft.Client/PlayerRenderer.cpp @@ -422,7 +422,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); @@ -433,7 +433,7 @@ 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.Server/cmake/sources/Common.cmake b/Minecraft.Server/cmake/sources/Common.cmake index 9215df80..1db8331e 100644 --- a/Minecraft.Server/cmake/sources/Common.cmake +++ b/Minecraft.Server/cmake/sources/Common.cmake @@ -547,6 +547,17 @@ set(_MINECRAFT_SERVER_COMMON_ROOT "${_MS_SRC}/../include/lce_filesystem/lce_filesystem.cpp" "${_MS_SRC}/Console/ServerCliInput.cpp" "${_MS_SRC}/Console/ServerCliInput.h" + "${_MS_SRC}/../Minecraft.Client/AbstractArmorLayer.h" + "${_MS_SRC}/../Minecraft.Client/AbstractArmorLayer.cpp" + "${_MS_SRC}/../Minecraft.Client/HumanoidArmorLayer.h" + "${_MS_SRC}/../Minecraft.Client/HumanoidArmorLayer.cpp" + "${_MS_SRC}/../Minecraft.Client/ArmorStandArmorModel.h" + "${_MS_SRC}/../Minecraft.Client/ArmorStandArmorModel.cpp" + "${_MS_SRC}/../Minecraft.Client/ItemInHandLayer.h" + "${_MS_SRC}/../Minecraft.Client/ItemInHandLayer.cpp" + "${_MS_SRC}/../Minecraft.Client/CustomHeadLayer.h" + "${_MS_SRC}/../Minecraft.Client/CustomHeadLayer.cpp" + "${_MS_SRC}/../Minecraft.Client/RenderLayer.h" ) source_group("" FILES ${_MINECRAFT_SERVER_COMMON_ROOT})