void NpcAnimation::addPartGroup(int group, int priority, std::vector<ESM::PartReference> &parts) { for(std::size_t i = 0; i < parts.size(); i++) { ESM::PartReference &part = parts[i]; const ESM::BodyPart *bodypart = 0; if(isFemale) bodypart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search(part.mFemale); if(!bodypart) bodypart = MWBase::Environment::get().getWorld()->getStore().bodyParts.search(part.mMale); if(bodypart) addOrReplaceIndividualPart(part.mPart, group, priority,"meshes\\" + bodypart->mModel); else reserveIndividualPart(part.mPart, group, priority); } }
void NpcAnimation::updateParts() { bool apparelChanged = false; const struct { MWWorld::ContainerStoreIterator *iter; int slot; } slotlist[] = { { &robe, MWWorld::InventoryStore::Slot_Robe }, { &skirtiter, MWWorld::InventoryStore::Slot_Skirt }, { &helmet, MWWorld::InventoryStore::Slot_Helmet }, { &cuirass, MWWorld::InventoryStore::Slot_Cuirass }, { &greaves, MWWorld::InventoryStore::Slot_Greaves }, { &leftpauldron, MWWorld::InventoryStore::Slot_LeftPauldron }, { &rightpauldron, MWWorld::InventoryStore::Slot_RightPauldron }, { &boots, MWWorld::InventoryStore::Slot_Boots }, { &leftglove, MWWorld::InventoryStore::Slot_LeftGauntlet }, { &rightglove, MWWorld::InventoryStore::Slot_RightGauntlet }, { &shirt, MWWorld::InventoryStore::Slot_Shirt }, { &pants, MWWorld::InventoryStore::Slot_Pants }, }; for(size_t i = 0;i < sizeof(slotlist)/sizeof(slotlist[0]);i++) { MWWorld::ContainerStoreIterator iter = mInv.getSlot(slotlist[i].slot); if(*slotlist[i].iter != iter) { *slotlist[i].iter = iter; removePartGroup(slotlist[i].slot); apparelChanged = true; } } if(apparelChanged) { if(robe != mInv.end()) { MWWorld::Ptr ptr = *robe; const ESM::Clothing *clothes = (ptr.get<ESM::Clothing>())->base; std::vector<ESM::PartReference> parts = clothes->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Robe, 5, parts); reserveIndividualPart(ESM::PRT_Groin, MWWorld::InventoryStore::Slot_Robe, 5); reserveIndividualPart(ESM::PRT_Skirt, MWWorld::InventoryStore::Slot_Robe, 5); reserveIndividualPart(ESM::PRT_RLeg, MWWorld::InventoryStore::Slot_Robe, 5); reserveIndividualPart(ESM::PRT_LLeg, MWWorld::InventoryStore::Slot_Robe, 5); reserveIndividualPart(ESM::PRT_RUpperarm, MWWorld::InventoryStore::Slot_Robe, 5); reserveIndividualPart(ESM::PRT_LUpperarm, MWWorld::InventoryStore::Slot_Robe, 5); reserveIndividualPart(ESM::PRT_RKnee, MWWorld::InventoryStore::Slot_Robe, 5); reserveIndividualPart(ESM::PRT_LKnee, MWWorld::InventoryStore::Slot_Robe, 5); reserveIndividualPart(ESM::PRT_RForearm, MWWorld::InventoryStore::Slot_Robe, 5); reserveIndividualPart(ESM::PRT_LForearm, MWWorld::InventoryStore::Slot_Robe, 5); reserveIndividualPart(ESM::PRT_RPauldron, MWWorld::InventoryStore::Slot_Robe, 5); reserveIndividualPart(ESM::PRT_LPauldron, MWWorld::InventoryStore::Slot_Robe, 5); } if(skirtiter != mInv.end()) { MWWorld::Ptr ptr = *skirtiter; const ESM::Clothing *clothes = (ptr.get<ESM::Clothing>())->base; std::vector<ESM::PartReference> parts = clothes->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Skirt, 4, parts); reserveIndividualPart(ESM::PRT_Groin, MWWorld::InventoryStore::Slot_Skirt, 4); reserveIndividualPart(ESM::PRT_RLeg, MWWorld::InventoryStore::Slot_Skirt, 4); reserveIndividualPart(ESM::PRT_LLeg, MWWorld::InventoryStore::Slot_Skirt, 4); } if(helmet != mInv.end()) { removeIndividualPart(ESM::PRT_Hair); const ESM::Armor *armor = (helmet->get<ESM::Armor>())->base; std::vector<ESM::PartReference> parts = armor->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Helmet, 3, parts); } if(cuirass != mInv.end()) { const ESM::Armor *armor = (cuirass->get<ESM::Armor>())->base; std::vector<ESM::PartReference> parts = armor->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Cuirass, 3, parts); } if(greaves != mInv.end()) { const ESM::Armor *armor = (greaves->get<ESM::Armor>())->base; std::vector<ESM::PartReference> parts = armor->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Greaves, 3, parts); } if(leftpauldron != mInv.end()) { const ESM::Armor *armor = (leftpauldron->get<ESM::Armor>())->base; std::vector<ESM::PartReference> parts = armor->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_LeftPauldron, 3, parts); } if(rightpauldron != mInv.end()) { const ESM::Armor *armor = (rightpauldron->get<ESM::Armor>())->base; std::vector<ESM::PartReference> parts = armor->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_RightPauldron, 3, parts); } if(boots != mInv.end()) { if(boots->getTypeName() == typeid(ESM::Clothing).name()) { const ESM::Clothing *clothes = (boots->get<ESM::Clothing>())->base; std::vector<ESM::PartReference> parts = clothes->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Boots, 2, parts); } else if(boots->getTypeName() == typeid(ESM::Armor).name()) { const ESM::Armor *armor = (boots->get<ESM::Armor>())->base; std::vector<ESM::PartReference> parts = armor->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Boots, 3, parts); } } if(leftglove != mInv.end()) { if(leftglove->getTypeName() == typeid(ESM::Clothing).name()) { const ESM::Clothing *clothes = (leftglove->get<ESM::Clothing>())->base; std::vector<ESM::PartReference> parts = clothes->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_LeftGauntlet, 2, parts); } else { const ESM::Armor *armor = (leftglove->get<ESM::Armor>())->base; std::vector<ESM::PartReference> parts = armor->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_LeftGauntlet, 3, parts); } } if(rightglove != mInv.end()) { if(rightglove->getTypeName() == typeid(ESM::Clothing).name()) { const ESM::Clothing *clothes = (rightglove->get<ESM::Clothing>())->base; std::vector<ESM::PartReference> parts = clothes->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_RightGauntlet, 2, parts); } else { const ESM::Armor *armor = (rightglove->get<ESM::Armor>())->base; std::vector<ESM::PartReference> parts = armor->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_RightGauntlet, 3, parts); } } if(shirt != mInv.end()) { const ESM::Clothing *clothes = (shirt->get<ESM::Clothing>())->base; std::vector<ESM::PartReference> parts = clothes->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Shirt, 2, parts); } if(pants != mInv.end()) { const ESM::Clothing *clothes = (pants->get<ESM::Clothing>())->base; std::vector<ESM::PartReference> parts = clothes->mParts.mParts; addPartGroup(MWWorld::InventoryStore::Slot_Pants, 2, parts); } } if(mPartPriorities[ESM::PRT_Head] < 1) addOrReplaceIndividualPart(ESM::PRT_Head, -1,1, headModel); if(mPartPriorities[ESM::PRT_Hair] < 1 && mPartPriorities[ESM::PRT_Head] <= 1) addOrReplaceIndividualPart(ESM::PRT_Hair, -1,1, hairModel); static const struct { ESM::PartReferenceType type; const char name[2][12]; } PartTypeList[] = { { ESM::PRT_Neck, { "neck", "" } }, { ESM::PRT_Cuirass, { "chest", "" } }, { ESM::PRT_Groin, { "groin", "" } }, { ESM::PRT_RHand, { "hand", "hands" } }, { ESM::PRT_LHand, { "hand", "hands" } }, { ESM::PRT_RWrist, { "wrist", "" } }, { ESM::PRT_LWrist, { "wrist", "" } }, { ESM::PRT_RForearm, { "forearm", "" } }, { ESM::PRT_LForearm, { "forearm", "" } }, { ESM::PRT_RUpperarm, { "upper arm", "" } }, { ESM::PRT_LUpperarm, { "upper arm", "" } }, { ESM::PRT_RFoot, { "foot", "feet" } }, { ESM::PRT_LFoot, { "foot", "feet" } }, { ESM::PRT_RAnkle, { "ankle", "" } }, { ESM::PRT_LAnkle, { "ankle", "" } }, { ESM::PRT_RKnee, { "knee", "" } }, { ESM::PRT_LKnee, { "knee", "" } }, { ESM::PRT_RLeg, { "upper leg", "" } }, { ESM::PRT_LLeg, { "upper leg", "" } }, { ESM::PRT_Tail, { "tail", "" } } }; const ESMS::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); for(size_t i = 0;i < sizeof(PartTypeList)/sizeof(PartTypeList[0]);i++) { if(mPartPriorities[PartTypeList[i].type] < 1) { const ESM::BodyPart *part = NULL; bool tryfemale = isFemale; int ni = 0; do { part = store.bodyParts.search(bodyRaceID+(tryfemale?"_f_":"_m_")+PartTypeList[i].name[ni]); if(part) break; ni ^= 1; if(ni == 0) { if(!tryfemale) break; tryfemale = false; } } while(1); if(part) addOrReplaceIndividualPart(PartTypeList[i].type, -1,1, "meshes\\"+part->mModel); } } }
void NpcAnimation::updateParts(bool forceupdate) { static const struct { int numRemoveParts; // Max: 1 ESM::PartReferenceType removeParts[1]; MWWorld::ContainerStoreIterator NpcAnimation::*part; int slot; int numReserveParts; // Max: 12 ESM::PartReferenceType reserveParts[12]; } slotlist[] = { { 0, { }, &NpcAnimation::mRobe, MWWorld::InventoryStore::Slot_Robe, 12, { ESM::PRT_Groin, ESM::PRT_Skirt, ESM::PRT_RLeg, ESM::PRT_LLeg, ESM::PRT_RUpperarm, ESM::PRT_LUpperarm, ESM::PRT_RKnee, ESM::PRT_LKnee, ESM::PRT_RForearm, ESM::PRT_LForearm, ESM::PRT_RPauldron, ESM::PRT_LPauldron } }, { 0, { }, &NpcAnimation::mSkirtIter, MWWorld::InventoryStore::Slot_Skirt, 3, { ESM::PRT_Groin, ESM::PRT_RLeg, ESM::PRT_LLeg } }, { 1, { ESM::PRT_Hair }, &NpcAnimation::mHelmet, MWWorld::InventoryStore::Slot_Helmet, 0, { } }, { 0, { }, &NpcAnimation::mCuirass, MWWorld::InventoryStore::Slot_Cuirass, 0, { } }, { 0, { }, &NpcAnimation::mGreaves, MWWorld::InventoryStore::Slot_Greaves, 0, { } }, { 0, { }, &NpcAnimation::mPauldronL, MWWorld::InventoryStore::Slot_LeftPauldron, 0, { } }, { 0, { }, &NpcAnimation::mPauldronR, MWWorld::InventoryStore::Slot_RightPauldron, 0, { } }, { 0, { }, &NpcAnimation::mBoots, MWWorld::InventoryStore::Slot_Boots, 0, { } }, { 0, { }, &NpcAnimation::mGloveL, MWWorld::InventoryStore::Slot_LeftGauntlet, 0, { } }, { 0, { }, &NpcAnimation::mGloveR, MWWorld::InventoryStore::Slot_RightGauntlet, 0, { } }, { 0, { }, &NpcAnimation::mShirt, MWWorld::InventoryStore::Slot_Shirt, 0, { } }, { 0, { }, &NpcAnimation::mPants, MWWorld::InventoryStore::Slot_Pants, 0, { } }, }; static const size_t slotlistsize = sizeof(slotlist)/sizeof(slotlist[0]); MWWorld::InventoryStore &inv = MWWorld::Class::get(mPtr).getInventoryStore(mPtr); for(size_t i = 0;!forceupdate && i < slotlistsize;i++) { MWWorld::ContainerStoreIterator iter = inv.getSlot(slotlist[i].slot); if(this->*slotlist[i].part != iter) { forceupdate = true; break; } } if(!forceupdate) return; for(size_t i = 0;i < slotlistsize && !mHeadOnly;i++) { MWWorld::ContainerStoreIterator iter = inv.getSlot(slotlist[i].slot); this->*slotlist[i].part = iter; removePartGroup(slotlist[i].slot); if(this->*slotlist[i].part == inv.end()) continue; for(int rem = 0;rem < slotlist[i].numRemoveParts;rem++) removeIndividualPart(slotlist[i].removeParts[rem]); int prio = 1; MWWorld::ContainerStoreIterator &store = this->*slotlist[i].part; if(store->getTypeName() == typeid(ESM::Clothing).name()) { prio = ((slotlist[i].numReserveParts+1)<<1) + 0; const ESM::Clothing *clothes = store->get<ESM::Clothing>()->mBase; addPartGroup(slotlist[i].slot, prio, clothes->mParts.mParts); } else if(store->getTypeName() == typeid(ESM::Armor).name()) { prio = ((slotlist[i].numReserveParts+1)<<1) + 1; const ESM::Armor *armor = store->get<ESM::Armor>()->mBase; addPartGroup(slotlist[i].slot, prio, armor->mParts.mParts); } for(int res = 0;res < slotlist[i].numReserveParts;res++) reserveIndividualPart(slotlist[i].reserveParts[res], slotlist[i].slot, prio); } if(mPartPriorities[ESM::PRT_Head] < 1) addOrReplaceIndividualPart(ESM::PRT_Head, -1,1, mHeadModel); if(mPartPriorities[ESM::PRT_Hair] < 1 && mPartPriorities[ESM::PRT_Head] <= 1) addOrReplaceIndividualPart(ESM::PRT_Hair, -1,1, mHairModel); if (mHeadOnly) return; static const struct { ESM::PartReferenceType type; const char name[2][12]; } PartTypeList[] = { { ESM::PRT_Neck, { "neck", "" } }, { ESM::PRT_Cuirass, { "chest", "" } }, { ESM::PRT_Groin, { "groin", "" } }, { ESM::PRT_RHand, { "hand", "hands" } }, { ESM::PRT_LHand, { "hand", "hands" } }, { ESM::PRT_RWrist, { "wrist", "" } }, { ESM::PRT_LWrist, { "wrist", "" } }, { ESM::PRT_RForearm, { "forearm", "" } }, { ESM::PRT_LForearm, { "forearm", "" } }, { ESM::PRT_RUpperarm, { "upper arm", "" } }, { ESM::PRT_LUpperarm, { "upper arm", "" } }, { ESM::PRT_RFoot, { "foot", "feet" } }, { ESM::PRT_LFoot, { "foot", "feet" } }, { ESM::PRT_RAnkle, { "ankle", "" } }, { ESM::PRT_LAnkle, { "ankle", "" } }, { ESM::PRT_RKnee, { "knee", "" } }, { ESM::PRT_LKnee, { "knee", "" } }, { ESM::PRT_RLeg, { "upper leg", "" } }, { ESM::PRT_LLeg, { "upper leg", "" } }, { ESM::PRT_Tail, { "tail", "" } } }; const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); for(size_t i = 0;i < sizeof(PartTypeList)/sizeof(PartTypeList[0]);i++) { if(mPartPriorities[PartTypeList[i].type] < 1) { const ESM::BodyPart *part = NULL; const MWWorld::Store<ESM::BodyPart> &partStore = store.get<ESM::BodyPart>(); if(!mNpc->isMale()) { part = partStore.search(mBodyPrefix + "_f_" + PartTypeList[i].name[0]); if(part == 0) part = partStore.search(mBodyPrefix + "_f_" + PartTypeList[i].name[1]); } if(part == 0) part = partStore.search(mBodyPrefix + "_m_" + PartTypeList[i].name[0]); if(part == 0) part = partStore.search(mBodyPrefix + "_m_" + PartTypeList[i].name[1]); if(part) addOrReplaceIndividualPart(PartTypeList[i].type, -1,1, "meshes\\"+part->mModel); } } }