DB/ItemDisplayInfo/GeosRenderPrep

From wowdev
Jump to navigation Jump to search

WOD

// GeosetRenderPrep.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
 
int main()
{
    return 0;
}
 
struct CCharacterComponent
{
    uint32_t raceID;
    uint32_t classID;
    uint32_t skinIndex;
    uint32_t genderID;
    uint32_t faceIndex;
    void *modelPtr;
    uint32_t submeshIds[29];
    uint32_t itemids[10];
    uint32_t gap2[520];
    uint64_t shirtRelated[6];
    uint32_t flags;
 
    static void GeosRenderPrep(CCharacterComponent *pCharComponent);
};
 
struct CharSectionsRec
{
    uint32_t Flags;
};
 
struct CM2Model
{
    static void SetGeometryVisible(void *model, uint32_t start, uint32_t end, BOOL visible) {}
};
 
struct ItemDisplayInfoRec
{
    uint32_t Flags;
    uint32_t GeosetGroup[4];
};
 
CharSectionsRec *ComponentGetSectionsRecord(uint32_t raceID, uint32_t genderID, uint32_t sectionID, uint32_t faceIndex, uint32_t skinIndex, uint32_t unk1)
{
    return nullptr;
}
 
uint32_t GetConditionalGeoset(uint32_t raceID, uint32_t geosetGroup)
{
    return 0;
}
 
ItemDisplayInfoRec *GetItemDisplayInfoRec(uint32_t itemID)
{
    return nullptr;
}
 
void CCharacterComponent::GeosRenderPrep(CCharacterComponent *pCharComponent)
{
    BOOL eyeGlowFlag = 0;
 
    if (pCharComponent->classID == 6) // DK
    {
        eyeGlowFlag = 1;
    }
    else
    {
        // section Face
        auto pFaceSection = ComponentGetSectionsRecord(pCharComponent->raceID, pCharComponent->genderID, 1, pCharComponent->faceIndex, pCharComponent->skinIndex, 0);
 
        if (pFaceSection)
            eyeGlowFlag = pFaceSection->Flags & 4;// flags & 0x4
        else
            eyeGlowFlag = 0;
    }
 
    CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 0, 3000, 0); // disable all
    CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 0, 0, 1); // enable skin
 
    uint32_t i = 0;
    do
    {
        if (eyeGlowFlag && i == 17)
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1703, 1703, 1);
        else
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, pCharComponent->submeshIds[i], pCharComponent->submeshIds[i], 1);
        ++i;
    } while (i != 29);
 
    // Tail
    BOOL tailFlag = 0;
    // section Skin
    auto pSkinSection = ComponentGetSectionsRecord(pCharComponent->raceID, pCharComponent->genderID, 0, 0, pCharComponent->skinIndex, 0);
    if (pSkinSection)
        tailFlag = pSkinSection->Flags & 0x100; // flags & 0x100
 
    CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1900, 1999, 0);
 
    uint32_t tailGeoset = 1;
    if (!tailFlag)
        tailGeoset = GetConditionalGeoset(pCharComponent->raceID, 19);
    if (tailGeoset <= 0)
        tailGeoset = 1;

    CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1900 + tailGeoset, 1900 + tailGeoset, 1);

    // Item ID's
    // 0 Head?
    // 1 Shoulder?
    auto shirtID = pCharComponent->itemids[2];
    auto chestID = pCharComponent->itemids[3];
    auto beltID = pCharComponent->itemids[4];
    auto pantsID = pCharComponent->itemids[5];
    auto bootsID = pCharComponent->itemids[6];
    // 7 wrist?
    auto glovesID = pCharComponent->itemids[8];
    auto tabardID = pCharComponent->itemids[9];
    auto cloakID = pCharComponent->itemids[10];
    // 11 Weapon (Main Hand)?
    // 12 Weapon (Off Hand)?
    // 13 Shield?
    // 14 Ammo?

    // Gloves
    if (glovesID)
    {
        auto pGloves = GetItemDisplayInfoRec(glovesID);
        if (pGloves && pGloves->GeosetGroup[0])
        {
            auto glovesGeoset = 401 + pGloves->GeosetGroup[0];
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 401, 499, 0);
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, glovesGeoset, glovesGeoset, 1);
        }
    }
    else
    {
        // Chest
        if (chestID)
        {
            auto pChest = GetItemDisplayInfoRec(chestID);
            if (pChest && pChest->GeosetGroup[0])
            {
                auto chesetGeoset = 801 + pChest->GeosetGroup[0];
                CM2Model::SetGeometryVisible(pCharComponent->modelPtr, chesetGeoset, chesetGeoset, 1);
            }
        }
    }
 
    // unknown shirt pre-check
    // possibly !textureArmUpper && !textureArmLower && !textureTorsoUpper && !textureTorsoLower && !textureLegUpper && !textureLegLower ?
    if (!pCharComponent->shirtRelated[0] && !pCharComponent->shirtRelated[1] && !pCharComponent->shirtRelated[2] && !pCharComponent->shirtRelated[3] && !pCharComponent->shirtRelated[4] && !pCharComponent->shirtRelated[5])
    {
        // Shirt
        if (shirtID)
        {
            auto pShirt = GetItemDisplayInfoRec(shirtID);
            if (pShirt && pShirt->GeosetGroup[0])
            {
                auto shirtGeoset = 801 + pShirt->GeosetGroup[0];
                CM2Model::SetGeometryVisible(pCharComponent->modelPtr, shirtGeoset, shirtGeoset, 1);
            }
        }
    }
 
    // Tabard
    auto pTabard = GetItemDisplayInfoRec(tabardID);
    if (pTabard)
    {
        if (!(pTabard->Flags & 0x100000))
        {
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 2200, 2299, 0);
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 2202, 2202, 1);
        }
    }
    else
    {
        // Chest
        if (chestID)
        {
            auto pChest = GetItemDisplayInfoRec(chestID);
            if (pChest && pChest->GeosetGroup[3])
            {
                auto chestGeoset = 2201 + pChest->GeosetGroup[3];
                CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 2200, 2299, 0);
                CM2Model::SetGeometryVisible(pCharComponent->modelPtr, chestGeoset, chestGeoset, 1);
            }
        }
    }
 
    // Belt
    BOOL hasBulkyBeltFlag = 0;
    auto pBelt = GetItemDisplayInfoRec(beltID);
    if (pBelt)
        hasBulkyBeltFlag = pBelt->Flags & 0x200;
 
    BOOL dressPants, dressChestpiece;
 
    // Chest
    if (chestID)
    {
        auto pChest = GetItemDisplayInfoRec(chestID);
        if (pChest && pChest->GeosetGroup[2])
        {
            if (pChest->GeosetGroup[2])
            {
                dressPants = 0;
                dressChestpiece = 1;
                CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 501, 599, 0);
                CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 902, 999, 0);
                CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1100, 1199, 0);
                CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1300, 1399, 0);
                auto chestGeoset = 1301 + pChest->GeosetGroup[2];
                CM2Model::SetGeometryVisible(pCharComponent->modelPtr, chestGeoset, chestGeoset, 1);
            }
        }
    }
    else if (pantsID)// Pants
    {
        auto pPants = GetItemDisplayInfoRec(pantsID);
        if (pPants && pPants->GeosetGroup[2] && !HIWORD(pCharComponent->flags))
        {
            dressPants = 1;
            dressChestpiece = 0;
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 501, 599, 0);
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 902, 999, 0);
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1100, 1199, 0);
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1300, 1399, 0);
            auto pantsGeoset = 1301 + pPants->GeosetGroup[2];
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, pantsGeoset, pantsGeoset, 1);
        }
    }
    else
    {
        dressPants = 0;
        dressChestpiece = 0;
        // Boots
        auto pBoots = GetItemDisplayInfoRec(bootsID);
        if (pBoots && pBoots->GeosetGroup[0])
        {
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 501, 599, 0);
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 901, 901, 1);
            auto bootsGeoset = 501 + pBoots->GeosetGroup[0];
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, bootsGeoset, bootsGeoset, 1);
        }
        else
        {
            // Pants
            auto pPants = GetItemDisplayInfoRec(pantsID);
            uint32_t pantsGeoset;
            if (pPants && pPants->GeosetGroup[1] && !HIWORD(pCharComponent->flags))
            {
                pantsGeoset = 901 + pPants->GeosetGroup[1];
            }
            else
            {
                pantsGeoset = 901;
            }
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, pantsGeoset, pantsGeoset, 1);
        }
    }
 
    // Boots
    BOOL bootsFlag = 0;
    auto pBoots = GetItemDisplayInfoRec(bootsID);
    if (pBoots)
        bootsFlag = (pBoots->Flags & 0x100000) == 0;
 
    uint32_t bootsGeoset;
    if (pBoots && pBoots->GeosetGroup[1])
    {
        bootsGeoset = 2000 + pBoots->GeosetGroup[1];
    }
    else
    {
        if (bootsFlag)
        {
            bootsGeoset = 2002;
        }
        else
        {
            bootsGeoset = 2001;
        }
    }
    CM2Model::SetGeometryVisible(pCharComponent->modelPtr, bootsGeoset, bootsGeoset, 1);
 
    // Tabard
    BOOL showsTabard = 0;
    BOOL hasDress = dressChestpiece | dressPants;
    if (!hasDress && tabardID != 0 && pTabard && pTabard->GeosetGroup[0])
    {
        showsTabard = 0;
        uint32_t tabardGeoset;
        if (hasBulkyBeltFlag)
        {
            showsTabard = 1;
            tabardGeoset = 1203;
        }
        else
        {
            tabardGeoset = 1201 + pTabard->GeosetGroup[0];
            showsTabard = 1;
        }
        CM2Model::SetGeometryVisible(pCharComponent->modelPtr, tabardGeoset, tabardGeoset, 1);
    }
    else if (!(pCharComponent->flags & 0x10))
    {
        // nop
    }
    else
    {
        CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1201, 1201, 1);
 
        if (!hasDress)
        {
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1202, 1202, 1);
            showsTabard = 1;
        }
    }
 
    if (!(dressChestpiece | showsTabard))
    {
        // Chest
        if (chestID)
        {
            auto pChest = GetItemDisplayInfoRec(chestID);
            if (pChest && pChest->GeosetGroup[1])
            {
                auto chestGeoset = 1001 + pChest->GeosetGroup[1];
                CM2Model::SetGeometryVisible(pCharComponent->modelPtr, chestGeoset, chestGeoset, 1);
            }
        }
        else if (shirtID)
        {
            auto pShirt = GetItemDisplayInfoRec(shirtID);
            if (pShirt && pShirt->GeosetGroup[1])
            {
                auto shirtGeoset = 1001 + pShirt->GeosetGroup[1];
                CM2Model::SetGeometryVisible(pCharComponent->modelPtr, shirtGeoset, shirtGeoset, 1);
            }
        }
    }
 
    if (!dressChestpiece && !HIWORD(pCharComponent->flags))
    {
        if (pantsID)
        {
            auto pPants = GetItemDisplayInfoRec(pantsID);
            if (pPants && pPants->GeosetGroup[0])
            {
                auto geosetGroup = pPants->GeosetGroup[0];
                auto pantsGeoset = 1101 + geosetGroup;
                if (geosetGroup > 2)
                {
                    CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1300, 1399, 0);
                    CM2Model::SetGeometryVisible(pCharComponent->modelPtr, pantsGeoset, pantsGeoset, 1);
                }
                else if (!showsTabard)
                    CM2Model::SetGeometryVisible(pCharComponent->modelPtr, pantsGeoset, pantsGeoset, 1);
            }
        }
    }
 
    // Cloak
    if (cloakID)
    {
        auto pCloak = GetItemDisplayInfoRec(cloakID);
        if (pCloak && pCloak->GeosetGroup[0])
        {
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1500, 1599, 0);
            auto cloakGeoset = 1501 + pCloak->GeosetGroup[0];
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, cloakGeoset, cloakGeoset, 1);
        }
    }
 
    // Belt
    if (beltID)
    {
        auto pBelt = GetItemDisplayInfoRec(beltID);
        if (pBelt && pBelt->GeosetGroup[0])
        {
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1800, 1899, 0);
            auto beltGeoset = 1801 + pBelt->GeosetGroup[0];
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, beltGeoset, beltGeoset, 1);
        }
    }
 
    BOOL unkBool;
 
    if (pCharComponent->flags & 8)
    {
        unkBool = !pantsID && !dressChestpiece && !dressPants && !showsTabard && !tailFlag && !hasBulkyBeltFlag;
        //unkBool = ((pantsID | showsTabard | hasDress) == 0) & ((hasBulkyBeltFlag | tailFlag) ^ 1);
        if (unkBool)
        {
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1401, 1401, 1);
        }
        else
        {
            CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1400, 1499, 0);
        }
    }
    else
    {
        unkBool = 0;
    }
 
    // DH hands
    uint32_t v86 = GetConditionalGeoset(pCharComponent->raceID, 23);
    if (v86 <= 0)
        v86 = 1;
    CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 2300 + v86, 2300 + v86, 1);
 
    //sub_1401BCDC0(pCharComponent, unkBool);
    //auto v132 = sub_1401C53B0(pCharComponent->raceID, pCharComponent->genderID);
    //auto v133 = sub_14023D380(pCharComponent->raceID, pCharComponent->genderID, pCharComponent->faceIndex, v132 != 0);
    //uint32_t v2 = 0;
    //if (v133)
    //  v2 = *v133;
    //sub_1412EFA90(pCharComponent->modelPtr, v2);
    //sub_1412EE6B0(pCharComponent->modelPtr);
    //LOBYTE(pCharComponent->flags) &= 0xFDu;
}

TBC (2.4.3.8606)

typedef struct item_display_info_line_s
{
	uint32_t id;
	char *model_name_left;
	char *model_name_right;
	char *model_texture_left;
	char *model_texture_right;
	char *icon1;
	char *icon2;
	uint32_t geoset1;
	uint32_t geoset2;
	uint32_t geoset3;
	/* ... */
} item_display_info_line_t;

typedef struct CCharacterComponent
{
	/* 0x00A */ uint8_t initialized;
	/* 0x00C */ uint8_t unk_C;
	/* 0x00D */ uint8_t unk_D;
	/* 0x034 */ CM2Model *model;
	/* 0x100 */ uint32_t submesh_ids[17];
	/* 0x2A8 */ uint32_t unk_bitmask;
	/* 0x4AC */ uint32_t helm_id;
	/* 0x4B0 */ uint32_t shoulder_id;
	/* 0x4B4 */ uint32_t shirt_id;
	/* 0x4B8 */ uint32_t chest_id;
	/* 0x4BC */ uint32_t belt_id;
	/* 0x4C0 */ uint32_t pants_id;
	/* 0x4C4 */ uint32_t boots_id;
	/* 0x4CC */ uint32_t gloves_id;
	/* 0x4D0 */ uint32_t tabard_id;
	/* 0x4D4 */ uint32_t cloak_id;
} CCharacterComponent;

/* sub_717020 */
void CM2Model::SetGeometryVisible(uint32_t first, uint32_t last, uint32_t visible)
{
	/* XXX */
}

/* sub_47A180 */
void CCharacterComponent::HideGeometry(uint32_t first, uint32_t last)
{
	this->model->SetGeometryVisible(first, last, 0);
}

/* sub_47A1A0 */
void CCharacterComponent::ShowGeometry(uint32_t id)
{
	this->model->SetGeometryVisible(id, id, 1);
}

/* sub_47BE80 */
bool CCharacterComponent::GetObjectGeoset(uint32_t id, uint32_t geoset_id, item_display_info_line_t *line)
{
	if (!id)
		return false;
	if (!g_item_display_info->GetLine(id, line))
		return false;
	if (!*((&line->geoset1)[geoset_id]))
		return false;
	return true;
}

/* sub_47BEC0 */
void CCharacterComponent::GeosRenderPrep()
{
	/* loaded flag ? */
	if (!this->initialized)
		return;

	item_display_info_line_t tmp_line;

	/* disable everything */
	model->HideGeometry(0, 1900);
	/* display skin */
	model->ShowGeometry(0);

	uint32_t *submesh_ids = this->submesh_ids;
	uint32_t i = 18;
	do
	{
		/* loc_47BEF5 */
		this->model->SetGeometryVisible(*submesh_ids, *submesh_ids, 1);
		submesh_ids++;
	} while (--i);

	if (GetObjectGeoset(this->gloves_id, 0, &tmp_line))
	{
		/* disable gloves */
		HideGeometry(401, 499);
		/* enable glove */
		ShowGeometry(401 + tmp_line.geoset1);
	}
	else if (GetObjectGeoset(this->chest_id, 0, &tmp_line))
	{
		/* enable wrists */
		ShowGeometry(801 + tmp_line.geoset1);
	}

	/* loc_47BF6F */
	for (uint32_t i = 0; i < 7; ++i)
	{
		if (!(this->unk_bitmask & (1 << i)))
			goto found;
	}

	if (GetObjectGeoset(this->shirt_id, 0, &tmp_line))
	{
		/* enable wrists */
		ShowGeometry(801 + tmp_line.geoset1);
	}

	/* loc_47BFBC */
found:
	uint32_t displayed_tabard = false;
	uint32_t displayed_chestpiece = false;
	uint32_t displayed_pants = 0;
	if (GetObjectGeoset(this->chest_id, 2, &tmp_line))
	{
		/* hide boots */
		HideGeometry(501, 509);
		/* hide kneepads */
		HideGeometry(902, 999);
		/* hide pants */
		HideGeometry(1100, 1199);
		/* hide trousers */
		HideGeometry(1300, 1399);
		/* show trousers */
		ShowGeometry(1301 + tmp_line.geoset3);
		displayed_chestpiece = true;
	}
	else if (GetObjectGeoset(this->pants_id, 2, &tmp_line) && !this->unk_C)
	{
		/* hide boots */
		HideGeometry(501, 599);
		/* hide kneepads */
		HideGeometry(902, 999);
		/* hide pants */
		HideGeometry(1100, 1199);
		/* hide trousers */
		HideGeometry(1300, 1399);
		/* show trousers */
		ShowGeometry(1301 + tmp_line.geoset3);
		displayed_pants = 1;
	}
	else
	{
		/* loc_47C0B5 */
		if (GetObjectGeoset(this->boots_id, 0, &tmp_line))
		{
			/* hide boots */
			HideGeometry(501, 599);
			/* show kneepads */
			ShowGeometry(901);
			/* show boots */
			ShowGeometry(501 + tmp_line.geoset1);
		}
		else if (GetObjectGeoset(this->pants_id, 1, &tmp_line))
		{
			/* show kneepads */
			ShowGeometry(901 + tmp_line.geoset2);
		}
		else
		{
			/* show kneepads */
			ShowGeometry(901);
		}

		/* loc_47C11F */
		if (GetObjectGeoset(this->tabard_id, 0, &tmp_line))
		{
			/* show tabard */
			ShowGeometry(1201 + tmp_line.geoset1);
			displayed_tabard = true;
		}
	}

	if (this->unk_D)
	{
		/* show tabard */
		ShowGeometry(1201);
		if (displayed_chestpiece)
			goto end_robe;
		if (!displayed_pants)
			ShowGeometry(1202);
	}
	else if (displayed_chestpiece)
	{
		goto end_robe;
	}

	/* loc_47C182 */
	if (!displayed_tabard)
	{
		if (GetObjectGeoset(this->shirt_id, 1, &tmp_line))
		{
			/* show chest */
			ShowGeometry(1001 + tmp_line.geoset2);
		}
		if (GetObjectGeoset(this->pants_id, 0, &tmp_line))
		{
			/* show pants */
			ShowGeometry(1102 + tmp_line.geoset1);
		}
	}

	/* loc_47C1DA */
end_robe:

	if (GetObjectGeoset(this->cloak_id, 0, &tmp_line))
	{
		/* hide cloak */
		HideGeometry(1500, 1599);
		/* show cloak */
		ShowGeometry(1501 + tmp_line.geoset1);
	}

	this->sub_47A1C0();
}