DB/ItemDisplayInfo/GeosRenderPrep: Difference between revisions

From wowdev
Jump to navigation Jump to search
(Created page with " void CCharacterComponent::GeosRenderPrep(CCharacterComponent *characterComponent) { // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND] // "characte...")
 
(Updated code for 8.0.1. It's also more clear.)
Line 1: Line 1:
  void CCharacterComponent::GeosRenderPrep(CCharacterComponent *characterComponent)
  // 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
  {
  {
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
uint32_t Flags;
 
uint32_t GeosetGroup[4];
  // "characterComponent->componentData.model2" simplified to "ourModel" for (vastly) shorter code
};
  // SHIRT = item_ids[2]
  // CHEST = item_ids[3]
CharSectionsRec *ComponentGetSectionsRecord(uint32_t raceID, uint32_t genderID, uint32_t sectionID, uint32_t faceIndex, uint32_t skinIndex, uint32_t unk1)
  // BELT = item_ids[4]
{
  // PANTS = item_ids[5]
return nullptr;
  // BOOTS = item_ids[6]
}
  // GLOVES = item_ids[8]
  // TABARD = item_ids[9]
uint32_t GetConditionalGeoset(uint32_t raceID, uint32_t geosetGroup)
  // CLOAK = field_6C0
{
return 0;
}
ItemDisplayInfoRec *GetItemDisplayInfoRec(uint32_t itemID)
{
return nullptr;
}
void CCharacterComponent::GeosRenderPrep(CCharacterComponent *pCharComponent)
{
BOOL eyeGlowFlag;
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
auto shirtID = pCharComponent->itemids[0];
auto chestID = pCharComponent->itemids[1];
auto beltID = pCharComponent->itemids[2];
auto pantsID = pCharComponent->itemids[3];
auto bootsID = pCharComponent->itemids[4];
// 5?
auto glovesID = pCharComponent->itemids[6];
auto tabardID = pCharComponent->itemids[7];
auto cloakID = pCharComponent->itemids[8];
// 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
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 = pChest->GeosetGroup[2] + 1301;
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 = pPants->GeosetGroup[2] + 1301;
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 = pPants->GeosetGroup[1] + 901;
}
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 = pBoots->GeosetGroup[1] + 2000;
}
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 = pTabard->GeosetGroup[0] + 1201;
showsTabard = 1;
}
CM2Model::SetGeometryVisible(pCharComponent->modelPtr, tabardGeoset, tabardGeoset, 1);
}
else if (!(pCharComponent->flags & 0x10))
{
}
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 v76;
if (pCharComponent->flags & 8)
{
v76 = ((pantsID | showsTabard | hasDress) == 0) & ((hasBulkyBeltFlag | tailFlag) ^ 1);
if (v76)
{
CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1401, 1401, 1);
}
else
{
CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1400, 1400, 0);
}
}
else
{
v76 = 0;
}
// DH hands
uint32_t v86 = GetConditionalGeoset(pCharComponent->raceID, 23);
if (v86 <= 0)
v86 = 1;
CM2Model::SetGeometryVisible(pCharComponent->modelPtr, (v86 + 2300), (v86 + 2300), 1);
   
   
  // Lookup something (if class is not DK)
//sub_1000990E0(pCharComponent, v76 != 0);
  booleanOfQuestionableUsefulness = false;
//v87 = pCharComponent->raceID;
  if ( characterComponent->componentData.class_ != 6 )
//v88 = *genderID;
  {
//if (!byte_101E3C7D0)
    booleanOfQuestionableUsefulness = true;
//{
    // ComponentGetSectionsRecord matches against CharSections.db2.
// byte_101E3C7D0 = 1;
    // parameters: UNKNOWN, raceID, genderID, baseSection, variationIndex, colorIndex
// v89 = qword_101E3C7C8;
    // since baseSection is 1, it is referring to the face, so variationIndex is really the 'type of face', and colorIndex is the skin color (so the face has matching skin color)'
// if (qword_101E3C7C8 || (v89 = sub_1000E0760("hdPlayerModels"), (qword_101E3C7C8 = v89) != 0))
    // what -exactly- v3 is is a bit of a mystery to me. Could be row ID from the DBC
// v90 = *(v89 + 92) != 0;
    v3 = ComponentGetSectionsRecord(
// else
            (__int64)&s_chrVarArray,
// v90 = 0;
            characterComponent->componentData.race,
// sub_100097210(v90, dword_101E3C15C);
            characterComponent->componentData.gender,
//}
            1,
//v91 = 0;
            characterComponent->componentData.face,
//if (v87 > 36)
            characterComponent->componentData.skinColor,
//{
            0);
// v92 = 0;
    if ( v3 )
//}
    {
//else
      booleanOfQuestionableUsefulness = (*(_BYTE *)(v3 + 28) & 4) == 0;
//{
    }
// v92 = 0;
  }
// if (v88 <= 1)
 
// v92 = dword_101E3C15C[4 * v87 + 2 * v88] == 1;
  // Disable all geosets from 0 to 2200
//}
  CM2Model::SetGeometryVisible(ourModel, 0, 2200, 0);
//v93 = sub_100148CA0(pCharComponent->raceID, *genderID, pCharComponent->faceIndex, v92);
 
//if (v93)
  // Enable geoset 0, the skin
// v91 = *v93;
  CM2Model::SetGeometryVisible(ourModel, 0, 0, 1);
//sub_101436B70(pCharComponent->modelPtr, v91);
 
//sub_1014387C0(pCharComponent->modelPtr);
  // Enable default geosets for that model (i.e. fill in all the holes that there would be on a model with no armor on)
//LOBYTE(pCharComponent->flags) &= 0xFDu;
  if ( booleanOfQuestionableUsefulness )
  {
    v4 = 0; // Counter variable
    do
    {
      CM2Model::SetGeometryVisible(ourModel, characterComponent->componentData.submeshIds[v4], characterComponent->componentData.submeshIds[v4], 1);
      ++v4;
    }
    while ( (_DWORD)v4 != 21 );
  }
  // If Class is DK (or Race has eye glow?), enable special eyes
  else
  {
    v5 = 0; // Counter variable
    do
    {
      if ( (_DWORD)v5 == 17 )
      {
        v6 = 1703;
        v7 = 1703;
      }
      else
      {
        v6 = characterComponent->componentData.submeshIds[v5];
        v7 = characterComponent->componentData.submeshIds[v5];
      }
      CM2Model::SetGeometryVisible(ourModel, v6, v7, 1);
      ++v5;
    }
    while ( (_DWORD)v5 != 21 );
  }
 
  // TAIL is checked here? 'GetConditionalGeoset' probably checks racial conditions or something.
  CM2Model::SetGeometryVisible(ourModel, 1900, 1999, 0);
  v8 = GetConditionalGeoset(&characterComponent->componentData, (COMP_GEOSET)19);
  v9 = v8 + 1900;
  if ( (signed int)v8 <= 0 )
  {
    v9 = 1901;
  }
  CM2Model::SetGeometryVisible(ourModel, v9, v9, 1);
 
  // GLOVES (8)
  v10 = characterComponent->item_ids[GLOVES];
  if ( v10 && g_itemDisplayInfoDB->GetRecord(v10) && g_itemDisplayInfoDB->GetRecord(v10)->m_geosetGroup[0] )
  {
    CM2Model::SetGeometryVisible(ourModel, 400, 499, 0);
    CM2Model::SetGeometryVisible(
      ourModel,
      g_itemDisplayInfoDB->GetRecord(v10)->m_geosetGroup[0] + 401,
      g_itemDisplayInfoDB->GetRecord(v10)->m_geosetGroup[0] + 401,
      1);
  }
  else
  {
    // if no glove geoset, CHEST (3) - m_geosetGroup[0] modifies 801
    v14 = characterComponent->item_ids[CHEST];
    if ( v14 )
    {
      v15 = g_itemDisplayInfoDB->GetRecord(v14);
      if ( v15 )
      {
        v16 = v15->m_geosetGroup[0];
        if ( v16 )
        {
          CM2Model::SetGeometryVisible(ourModel, v16 + 801, v16 + 801, 1);
        }
      }
    }
  }
 
  bool valid = true;
  for ( int v13 = 65; v13 <= 70; ++v13 )
  {
    if ( *(&characterComponent->field_0 + v13) != 0 )
    {
      valid = false;
    }
  }
  if (valid)
    // (CONDITIONALLY) SHIRT (2) - m_geosetGroup[0] modifies 801
    v18 = characterComponent->item_ids[SHIRT];
    if ( v18 )
    {
      v19 = g_itemDisplayInfoDB->GetRecord(v18);
      if ( v19 )
      {
        v20 = v19->m_geosetGroup[0];
        if ( v20 )
        {
          CM2Model::SetGeometryVisible(ourModel, v20 + 801, v20 + 801, 1);
        }
      }
    }
  }
 
  // BELT (4) - m_geosetGroup[0] modifies a truth value used later to test whether to apply the tabard geoset (only if m_flags & 0x200)
  hasBulkyBeltFlag = 0;
  v21 = characterComponent->item_ids[BELT];
  if ( v21 )
  {
    v23 = g_itemDisplayInfoDB->GetRecord(v21);
    if ( v23 )
    {
      if ( v23->m_geosetGroup[0] )
      {
        hasBulkyBeltFlag = ((unsigned int)v23->m_flags >> 9) & 1;
      }
    }
  }
 
  v24 = characterComponent->item_ids[CHEST];
  v29 = characterComponent->item_ids[PANTS];
  // CHEST (3) - m_geosetGroup[2] modifies 1301
  if ( v24 && g_itemDisplayInfoDB->GetRecord(v24) && g_itemDisplayInfoDB->GetRecord(v24)->m_geosetGroup[2] )
  {
    dressPants = false;
    dressChestpiece = true;
    CM2Model::SetGeometryVisible(ourModel, g_itemDisplayInfoDB->GetRecord(v24)->m_geosetGroup[2] + 1301, g_itemDisplayInfoDB->GetRecord(v24)->m_geosetGroup[2] + 1301, 1);
  }
  // (CONDITIONALLY) PANTS (5) - m_geosetGroup[2] modifies 1301 (only if CHEST's m_geosetGroup[2] is 0)
  // FIELD 20 CHECK (&0x08 == 0)
  else if ( v29 && g_itemDisplayInfoDB->GetRecord(v29) && g_itemDisplayInfoDB->GetRecord(v29)->m_geosetGroup[2]  && (characterComponent->field_20 & 8 == 0) )
  {
    dressPants = true;
    dressChestpiece = false;
    CM2Model::SetGeometryVisible(ourModel, g_itemDisplayInfoDB->GetRecord(v29)->m_geosetGroup[2] + 1301, g_itemDisplayInfoDB->GetRecord(v29)->m_geosetGroup[2] + 1301, 1);
  }
  else
  {
    dressPants = false;
    dressChestpiece = false;
    // (CONDITIONALLY) BOOTS (6) - m_geosetGroup[0] modifies 501 (only if CHEST's m_geosetGroup[2] is 0 and PANTS' m_geosetGroup[2] is 0)
    v31 = characterComponent->item_ids[BOOTS];
    if ( v31 && g_itemDisplayInfoDB->GetRecord(v31) && g_itemDisplayInfoDB->GetRecord(v31)->m_geosetGroup[0] )
    {
      CM2Model::SetGeometryVisible(ourModel, g_itemDisplayInfoDB->GetRecord(v31)->m_geosetGroup[0] + 501, g_itemDisplayInfoDB->GetRecord(v31)->m_geosetGroup[0] + 501, 1);
    }
    else
    {
      // (CONDITIONALLY) PANTS (5) - m_geosetGroup[1] modifies 901 (only if CHEST's m_geosetGroup[2] is 0 and PANTS' m_geosetGroup[2] is 0 and BOOTS' m_geosetGroup[0] is 0 and field_20 & 0x08 != 0)
      v34 = characterComponent->item_ids[PANTS];
      // FIELD 20 CHECK (&0x08 == 0)
      if ( v34 && g_itemDisplayInfoDB->GetRecord(v34) && g_itemDisplayInfoDB->GetRecord(v34)->m_geosetGroup[1] && (characterComponent->field_20 & 8 == 0) )
      {
        v38 = v36 + 901;
      }
      // else, else, else: 901 is set (901 is default set then)
      else
      {
        v38 = 901;
      }
      CM2Model::SetGeometryVisible(ourModel, v38, v38, 1);
    }
  }
 
  // BOOTS (6) - m_geosetGroup[1] modifies 2000 (yes, 2000) and has some fun conditionals
  v40 = characterComponent->item_ids[BOOTS];
  // If you are wearing BOOTS
  if ( v40 )
  {
    v41 = g_itemDisplayInfoDB->GetRecord(v40);
    // If your BOOTS' m_geosetGroup[1] is 0
    if ( !v41 || !v41->m_geosetGroup[1] )
    {
      v44 = 2002;
      v45 = 2002;
    }
    // If your BOOTS' m_geosetGroup[1] is non-zero
    else
    {
      v44 = v41->m_geosetGroup[1] + 2000;
      v45 = v41->m_geosetGroup[1] + 2000;
    }
  }
  // If you are not wearing BOOTS
  else
  {
    v44 = 2001;
    v45 = 2001;
  }
  CM2Model::SetGeometryVisible(ourModel, v44, v45, 1);
 
  // (CONDITIONALLY) TABARD (9) - m_geosetGroup[0] modifies 1201 (if not wearing a dress and m_flags & 0x200 is 0 for your BELT)
  showsTabard = false;
  hasDress = (dressChestpiece | dressPants);
  if ( !hasDress && !hasBulkyBeltFlag )
  {
    v49 = characterComponent->item_ids[TABARD];
    if ( v49 )
    {
      v50 = g_itemDisplayInfoDB->GetRecord(v49);
      if ( v50 )
      {
        v51 = v50->m_geosetGroup[0];
        if ( v51 )
        {
          showsTabard = true;
          CM2Model::SetGeometryVisible(ourModel, v51 + 1201, v51 + 1201, 1);
        }
      }
    }
  }
  // FIELD 20 CHECK (&0x20 == 0) - result is tabard geoset hidden
  if ( characterComponent->field_20 & 0x20 == 0 )
  {
    CM2Model::SetGeometryVisible(ourModel, 1201, 1201, 1)
  }
  // FIELD 20 CHECK (&0x20 == 0) - result is tabard geoset shown if hasDress is false
  if ( (characterComponent->field_20 & 0x20 == 0) && !hasDress )
  {
    CM2Model::SetGeometryVisible(ourModel, 1202, 1202, 1);
    showsTabard = true;
  }
  else
  {
    if ( !showsTabard && !dressChestpiece )
    {
      // (CONDITIONALLY) CHEST (3) - m_geosetGroup[1] modifies 1001
      if (characterComponent->item_ids[CHEST] && g_itemDisplayInfoDB->GetRecord(characterComponent->item_ids[CHEST]) && g_itemDisplayInfoDB->GetRecord(characterComponent->item_ids[CHEST])->m_geosetGroup[1])
      {
        CM2Model::SetGeometryVisible(ourModel, g_itemDisplayInfoDB->GetRecord(characterComponent->item_ids[CHEST])->m_geosetGroup[1] + 1001, g_itemDisplayInfoDB->GetRecord(characterComponent->item_ids[CHEST])->m_geosetGroup[1] + 1001, 1);
        showsTabard = false;
      }
      // (CONDITIONALLY) SHIRT (2) - m_geosetGroup[1] modifies 1001
      else if (characterComponent->item_ids[SHIRT] && g_itemDisplayInfoDB->GetRecord(characterComponent->item_ids[SHIRT]) && g_itemDisplayInfoDB->GetRecord(characterComponent->item_ids[SHIRT])->m_geosetGroup[1])
      {
        CM2Model::SetGeometryVisible(ourModel, g_itemDisplayInfoDB->GetRecord(characterComponent->item_ids[SHIRT])->m_geosetGroup[1] + 1001, g_itemDisplayInfoDB->GetRecord(characterComponent->item_ids[SHIRT])->m_geosetGroup[1] + 1001, 1);
        showsTabard = false;
      }
    }
  }
 
  // FIELD 20 CHECK (&0x08 == 0)
  if ( !dressChestpiece && (characterComponent->field_20 & 8 == 0) )
  {
    // (CONDITIONALLY) PANTS (5) - m_geosetGroup[0] modifies 1101 (if m_geosetGroup[0] > 2, it wipes all geosets from 1300 to 1399 and then sets 1101. if it is less than or equal to 2 and if a tabard is shown, it sets 1101.)
    v58 = characterComponent->item_ids[PANTS];
    if ( v58 )
    {
      v59 = g_itemDisplayInfoDB->GetRecord(v58);
      if ( v59 )
      {
        v60 = v59->m_geosetGroup[0];
        if ( v60 )
        {
          if ( v60 > 2 )
          {
            CM2Model::SetGeometryVisible(ourModel, 1300, 1399, 0);
            CM2Model::SetGeometryVisible(ourModel, v60 + 1101, v60 + 1101, 1);
          }
          else if ( showsTabard )
          {
            CM2Model::SetGeometryVisible(ourModel, v60 + 1101, v60 + 1101, 1);
          }
        }
      }
    }
  }
 
  // CLOAK (?) - m_geosetGroup[0] modifies 1501
  // FIELD 6C0 CHECK (it's an itemID?)
  v61 = characterComponent->field_6C0;
  if ( v61 )
  {
    v62 = g_itemDisplayInfoDB->GetRecord(v61);
    if ( v62 )
    {
      if ( v62->m_geosetGroup[0] )
      {
        CM2Model::SetGeometryVisible(ourModel, 1500, 1599, 0);
        CM2Model::SetGeometryVisible(ourModel, v62->m_geosetGroup[0] + 1501, v62->m_geosetGroup[0] + 1501, 1);
      }
    }
  }
  // BELT (4) - m_geosetGroup[0] modifies 1801
  v64 = characterComponent->item_ids[BELT];
  if ( v64 )
  {
    v65 = g_itemDisplayInfoDB->GetRecord(v64);
    if ( v65 )
    {
      if ( v65->m_geosetGroup[0] )
      {
        CM2Model::SetGeometryVisible(ourModel, 1800, 1899, 0);
        CM2Model::SetGeometryVisible(ourModel, v65->m_geosetGroup[0] + 1801, v65->m_geosetGroup[0] + 1801, 1);
      }
    }
  }
  // FIELD 20 CHECK (&0x10 != 0)
  if ( characterComponent->field_20 & 0x10 != )
  {
    // If you aren't wearing PANTS, you have a tabard, and you don't have a dress (a dress from CHEST presumably, since you aren't wearing PANTS), enable 1401
    if ( showsTabard && !characterComponent->item_ids[PANTS] && !hasDress )
    {
      v67 = 1401;
      v68 = 1401;
      v69 = 1;
    }
    else
    {
      v67 = 1400;
      v68 = 1499;
      v69 = 0;
    }
    CM2Model::SetGeometryVisible(ourModel, v67, v68, v69);
  }
 
  // Remove unneeded edges and vertices due to the enabled geosets
  CM2Model::OptimizeVisibleGeometry(ourModel);
 
  // FIELD 20 MODIFICATION (&=0xFD)
  characterComponent->field_20 &= 0xFD;
  }
  }

Revision as of 19:40, 30 March 2018

// 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;

	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
	auto shirtID = pCharComponent->itemids[0];
	auto chestID = pCharComponent->itemids[1];
	auto beltID = pCharComponent->itemids[2];
	auto pantsID = pCharComponent->itemids[3];
	auto bootsID = pCharComponent->itemids[4];
	// 5?
	auto glovesID = pCharComponent->itemids[6];
	auto tabardID = pCharComponent->itemids[7];
	auto cloakID = pCharComponent->itemids[8];

	// 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
	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 = pChest->GeosetGroup[2] + 1301;
				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 = pPants->GeosetGroup[2] + 1301;
			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 = pPants->GeosetGroup[1] + 901;
			}
			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 = pBoots->GeosetGroup[1] + 2000;
	}
	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 = pTabard->GeosetGroup[0] + 1201;
			showsTabard = 1;
		}
		CM2Model::SetGeometryVisible(pCharComponent->modelPtr, tabardGeoset, tabardGeoset, 1);
	}
	else if (!(pCharComponent->flags & 0x10))
	{

	}
	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 v76;

	if (pCharComponent->flags & 8)
	{
		v76 = ((pantsID | showsTabard | hasDress) == 0) & ((hasBulkyBeltFlag | tailFlag) ^ 1);
		if (v76)
		{
			CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1401, 1401, 1);
		}
		else
		{
			CM2Model::SetGeometryVisible(pCharComponent->modelPtr, 1400, 1400, 0);
		}
	}
	else
	{
		v76 = 0;
	}

	// DH hands
	uint32_t v86 = GetConditionalGeoset(pCharComponent->raceID, 23);
	if (v86 <= 0)
		v86 = 1;
	CM2Model::SetGeometryVisible(pCharComponent->modelPtr, (v86 + 2300), (v86 + 2300), 1);

	//sub_1000990E0(pCharComponent, v76 != 0);
	//v87 = pCharComponent->raceID;
	//v88 = *genderID;
	//if (!byte_101E3C7D0)
	//{
	//	byte_101E3C7D0 = 1;
	//	v89 = qword_101E3C7C8;
	//	if (qword_101E3C7C8 || (v89 = sub_1000E0760("hdPlayerModels"), (qword_101E3C7C8 = v89) != 0))
	//		v90 = *(v89 + 92) != 0;
	//	else
	//		v90 = 0;
	//	sub_100097210(v90, dword_101E3C15C);
	//}
	//v91 = 0;
	//if (v87 > 36)
	//{
	//	v92 = 0;
	//}
	//else
	//{
	//	v92 = 0;
	//	if (v88 <= 1)
	//		v92 = dword_101E3C15C[4 * v87 + 2 * v88] == 1;
	//}
	//v93 = sub_100148CA0(pCharComponent->raceID, *genderID, pCharComponent->faceIndex, v92);
	//if (v93)
	//	v91 = *v93;
	//sub_101436B70(pCharComponent->modelPtr, v91);
	//sub_1014387C0(pCharComponent->modelPtr);
	//LOBYTE(pCharComponent->flags) &= 0xFDu;
}