13 eyeGlowType(
EGT_NONE), showUnderwear(true), showEars(true), showHair(true),
14 showFacialHair(true), showFeet(true), autoHideGeosetsForHeadItems(true),
15 isNPC(true), model_(nullptr), isDemonHunter_(false)
26 pugi::xml_node
child =
node.append_child(
"customization");
27 child.append_attribute(
"id") =
opt.first;
28 child.append_attribute(
"value") =
opt.second;
31 node.append_child(
"eyeGlowType").append_attribute(
"value") =
static_cast<int>(
eyeGlowType);
32 node.append_child(
"showUnderwear").append_attribute(
"value") =
showUnderwear ? 1 : 0;
33 node.append_child(
"showEars").append_attribute(
"value") =
showEars ? 1 : 0;
34 node.append_child(
"showHair").append_attribute(
"value") =
showHair ? 1 : 0;
35 node.append_child(
"showFacialHair").append_attribute(
"value") =
showFacialHair ? 1 : 0;
36 node.append_child(
"showFeet").append_attribute(
"value") =
showFeet ? 1 : 0;
42 pugi::xml_document
doc;
43 pugi::xml_parse_result
result =
doc.load_file(f.c_str());
52 if (std::string(
charNode.name()) !=
"CharDetails")
60 LOG_ERROR <<
"CharDetails node not found in" << f.c_str();
66 const std::string name =
child.name();
68 if (name ==
"customization")
69 set(
child.attribute(
"id").as_uint(),
child.attribute(
"value").as_uint());
70 else if (name ==
"eyeGlowType")
72 else if (name ==
"showUnderwear")
74 else if (name ==
"showEars")
76 else if (name ==
"showHair")
78 else if (name ==
"showFacialHair")
80 else if (name ==
"showFeet")
82 else if (name ==
"isDemonHunter")
92 if ((model !=
nullptr) & (model !=
model_))
127 if (!c.second.empty())
130 event.setCustomizationOptionId(c.first);
154 if (infos.raceID == -1)
157 const auto options =
WOWDB.getTable(
"ChrCustomizationOption");
164 for (
const auto& row : *
options)
166 if (row.getUInt(
"ChrModelID") ==
static_cast<uint32_t>(infos.ChrModelID[0]))
168 matchingOptions.push_back({
static_cast<uint>(row.recordID()), row.getUInt(
"OrderIndex"), row.getUInt(
"Flags")});
179 if (!(
opt.flags & 0x20))
210 vals.push_back(c.id);
213 if (vals != originalVals)
215 LOG_INFO << __FUNCTION__ << chrCustomizationOption;
217 for (
const auto& v : vals)
218 info += std::to_string(v) +
" ";
222 event.setCustomizationOptionId(chrCustomizationOption);
233 if (infos.raceID == -1)
294 if (row.getUInt(
"ChrCustomizationChoiceID") !=
choiceId)
298 const uint geosetID = row.getUInt(
"ChrCustomizationGeosetID");
300 const uint materialID = row.getUInt(
"ChrCustomizationMaterialID");
310 geoRow.getUInt(
"GeosetType"),
geoRow.getUInt(
"GeosetID"));
322 skinRow.getUInt(
"CollectionsFileDataID"),
323 std::make_pair(
skinRow.getUInt(
"GeosetType"),
skinRow.getUInt(
"GeosetID")));
348 fileDataID =
tfdRow.getUInt(
"FileDataID");
366 blendMode =
layerRow.getUInt(
"BlendMode");
375 t.blendMode = blendMode;
376 t.fileId = fileDataID;
378 LOG_INFO <<
"texture ->" <<
"layer" <<
t.layer <<
"region" <<
t.region <<
"type" <<
t.type <<
379 "blendMode" <<
t.blendMode <<
"fileId" <<
t.fileId;
398 while (((
mask =
mask >> 1) & 0x01) == 0)
431 for (
auto geo :
elt.second.geosets)
474 for (
auto t :
elt.second.textures)
506 for (
const auto m :
elt.second.models)
Event fired when character detail customisation options change.
@ CHOICE_LIST_CHANGED
A customisation choice list was modified.
void rebuildAllCustomizationElements()
std::map< uint, CustomizationElements > customizationElementsPerOption_
void setDemonHunterMode(bool val)
void save(pugi::xml_node &parentNode)
void set(uint chrCustomizationOptionID, uint chrCustomizationChoiceID)
static int bitMaskToSectionType(int mask)
void reset(WoWModel *m=nullptr)
std::map< uint, std::vector< uint > > choicesPerOptionMap_
std::set< uint > defaultOptionIds_
void refreshSkinnedModels()
void fillCustomizationMap()
std::map< uint, uint > currentCustomization_
std::map< uint, uint > geosets
void fillCustomizationMapForOption(uint chrCustomizationOption)
uint get(uint chrCustomizationOptionID) const
std::vector< uint > getCustomizationChoices(const uint chrCustomizationOptionID)
std::vector< TextureCustomization > textures
std::vector< std::pair< uint, std::pair< uint, uint > > > models_
void load(const std::string &filepath)
Lightweight handle to a single row in a DB2Table.
uint32_t getUInt(const std::string &field, unsigned int arrayIndex=0) const
Provides typed, field-name-based access to records in a WDC DB2 file.
void notify(Event &)
Broadcast an event to all attached observers.
int sexID
0 = male, 1 = female.
int textureLayoutID
Texture layout ID for compositing.
int raceID
Race ID (-1 = invalid).
Core WoW .m2 model: geometry, animation, textures, and character data.
WoWModel * mergeModel(std::string name, int type=1, bool noRefresh=false)
int getItemId(CharSlots slot)
void unmergeModel(std::string name)
void setGeosetGroupDisplay(CharGeosets group, int val)
CharGeosets
Character geoset group identifiers (mesh IDs for body/armour regions).