mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-25 11:26:37 +00:00 
			
		
		
		
	Move preload model list to MWClass, preload NPC head/hair
This commit is contained in:
		
							parent
							
								
									84f01b7527
								
							
						
					
					
						commit
						effe022bb2
					
				
					 7 changed files with 108 additions and 45 deletions
				
			
		|  | @ -182,6 +182,29 @@ namespace MWClass | ||||||
|         return ""; |         return ""; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     void Creature::getModelsToPreload(const MWWorld::Ptr &ptr, std::vector<std::string> &models) const | ||||||
|  |     { | ||||||
|  |         std::string model = getModel(ptr); | ||||||
|  |         if (!model.empty()) | ||||||
|  |             models.push_back(model); | ||||||
|  | 
 | ||||||
|  |         // FIXME: use const version of InventoryStore functions once they are available
 | ||||||
|  |         if (ptr.getClass().hasInventoryStore(ptr)) | ||||||
|  |         { | ||||||
|  |             MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr); | ||||||
|  |             for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot) | ||||||
|  |             { | ||||||
|  |                 MWWorld::ContainerStoreIterator equipped = invStore.getSlot(slot); | ||||||
|  |                 if (equipped != invStore.end()) | ||||||
|  |                 { | ||||||
|  |                     model = equipped->getClass().getModel(*equipped); | ||||||
|  |                     if (!model.empty()) | ||||||
|  |                         models.push_back(model); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     std::string Creature::getName (const MWWorld::ConstPtr& ptr) const |     std::string Creature::getName (const MWWorld::ConstPtr& ptr) const | ||||||
|     { |     { | ||||||
|         const MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>(); |         const MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>(); | ||||||
|  |  | ||||||
|  | @ -101,6 +101,9 @@ namespace MWClass | ||||||
| 
 | 
 | ||||||
|             virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; |             virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; | ||||||
| 
 | 
 | ||||||
|  |             virtual void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector<std::string>& models) const; | ||||||
|  |             ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: list getModel().
 | ||||||
|  | 
 | ||||||
|             virtual bool |             virtual bool | ||||||
|             isActor() const { |             isActor() const { | ||||||
|                 return true; |                 return true; | ||||||
|  |  | ||||||
|  | @ -429,6 +429,74 @@ namespace MWClass | ||||||
|         return model; |         return model; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     void Npc::getModelsToPreload(const MWWorld::Ptr &ptr, std::vector<std::string> &models) const | ||||||
|  |     { | ||||||
|  |         const MWWorld::LiveCellRef<ESM::NPC> *npc = ptr.get<ESM::NPC>(); | ||||||
|  |         const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().search(npc->mBase->mRace); | ||||||
|  |         if(race && race->mData.mFlags & ESM::Race::Beast) | ||||||
|  |             models.push_back("meshes\\base_animkna.nif"); | ||||||
|  | 
 | ||||||
|  |         // keep these always loaded just in case
 | ||||||
|  |         models.push_back("meshes/xargonian_swimkna.nif"); | ||||||
|  |         models.push_back("meshes/xbase_anim_female.nif"); | ||||||
|  |         models.push_back("meshes/xbase_anim.nif"); | ||||||
|  | 
 | ||||||
|  |         if (!npc->mBase->mModel.empty()) | ||||||
|  |             models.push_back("meshes/"+npc->mBase->mModel); | ||||||
|  | 
 | ||||||
|  |         if (!npc->mBase->mHead.empty()) | ||||||
|  |         { | ||||||
|  |             const ESM::BodyPart* head = MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>().search(npc->mBase->mHead); | ||||||
|  |             if (head) | ||||||
|  |                 models.push_back("meshes/"+head->mModel); | ||||||
|  |         } | ||||||
|  |         if (!npc->mBase->mHair.empty()) | ||||||
|  |         { | ||||||
|  |             const ESM::BodyPart* hair = MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>().search(npc->mBase->mHair); | ||||||
|  |             if (hair) | ||||||
|  |                 models.push_back("meshes/"+hair->mModel); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // FIXME: use const version of InventoryStore functions once they are available
 | ||||||
|  |         if (ptr.getClass().hasInventoryStore(ptr)) | ||||||
|  |         { | ||||||
|  |             MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr); | ||||||
|  |             for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot) | ||||||
|  |             { | ||||||
|  |                 MWWorld::ContainerStoreIterator equipped = invStore.getSlot(slot); | ||||||
|  |                 if (equipped != invStore.end()) | ||||||
|  |                 { | ||||||
|  |                     std::vector<ESM::PartReference> parts; | ||||||
|  |                     if(equipped->getTypeName() == typeid(ESM::Clothing).name()) | ||||||
|  |                     { | ||||||
|  |                         const ESM::Clothing *clothes = equipped->get<ESM::Clothing>()->mBase; | ||||||
|  |                         parts = clothes->mParts.mParts; | ||||||
|  |                     } | ||||||
|  |                     else if(equipped->getTypeName() == typeid(ESM::Armor).name()) | ||||||
|  |                     { | ||||||
|  |                         const ESM::Armor *armor = equipped->get<ESM::Armor>()->mBase; | ||||||
|  |                         parts = armor->mParts.mParts; | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                     { | ||||||
|  |                         std::string model = equipped->getClass().getModel(*equipped); | ||||||
|  |                         if (!model.empty()) | ||||||
|  |                             models.push_back(model); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     for (std::vector<ESM::PartReference>::const_iterator it = parts.begin(); it != parts.end(); ++it) | ||||||
|  |                     { | ||||||
|  |                         const std::string& partname = (npc->mBase->mFlags & ESM::NPC::Female) ? it->mFemale : it->mMale; | ||||||
|  |                         const ESM::BodyPart* part = MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>().search(partname); | ||||||
|  |                         if (part && !part->mModel.empty()) | ||||||
|  |                             models.push_back("meshes/"+part->mModel); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     std::string Npc::getName (const MWWorld::ConstPtr& ptr) const |     std::string Npc::getName (const MWWorld::ConstPtr& ptr) const | ||||||
|     { |     { | ||||||
|         if(ptr.getRefData().getCustomData() && ptr.getRefData().getCustomData()->asNpcCustomData().mNpcStats.isWerewolf()) |         if(ptr.getRefData().getCustomData() && ptr.getRefData().getCustomData()->asNpcCustomData().mNpcStats.isWerewolf()) | ||||||
|  |  | ||||||
|  | @ -75,6 +75,9 @@ namespace MWClass | ||||||
| 
 | 
 | ||||||
|             virtual void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, bool successful) const; |             virtual void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, bool successful) const; | ||||||
| 
 | 
 | ||||||
|  |             virtual void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector<std::string>& models) const; | ||||||
|  |             ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: list getModel().
 | ||||||
|  | 
 | ||||||
|             virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr, |             virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr, | ||||||
|                 const MWWorld::Ptr& actor) const; |                 const MWWorld::Ptr& actor) const; | ||||||
|             ///< Generate action for activation
 |             ///< Generate action for activation
 | ||||||
|  |  | ||||||
|  | @ -31,51 +31,7 @@ namespace MWWorld | ||||||
| 
 | 
 | ||||||
|         virtual bool operator()(const MWWorld::Ptr& ptr) |         virtual bool operator()(const MWWorld::Ptr& ptr) | ||||||
|         { |         { | ||||||
|             std::string model = ptr.getClass().getModel(ptr); |             ptr.getClass().getModelsToPreload(ptr, mOut); | ||||||
|             if (!model.empty()) |  | ||||||
|                 mOut.push_back(model); |  | ||||||
| 
 |  | ||||||
|             // TODO: preload NPC body parts (mHead / mHair)
 |  | ||||||
| 
 |  | ||||||
|             // FIXME: use const version of InventoryStore functions once they are available
 |  | ||||||
|             if (ptr.getClass().hasInventoryStore(ptr)) |  | ||||||
|             { |  | ||||||
|                 MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr); |  | ||||||
|                 for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot) |  | ||||||
|                 { |  | ||||||
|                     MWWorld::ContainerStoreIterator equipped = invStore.getSlot(slot); |  | ||||||
|                     if (equipped != invStore.end()) |  | ||||||
|                     { |  | ||||||
|                         std::vector<ESM::PartReference> parts; |  | ||||||
|                         if(equipped->getTypeName() == typeid(ESM::Clothing).name()) |  | ||||||
|                         { |  | ||||||
|                             const ESM::Clothing *clothes = equipped->get<ESM::Clothing>()->mBase; |  | ||||||
|                             parts = clothes->mParts.mParts; |  | ||||||
|                         } |  | ||||||
|                         else if(equipped->getTypeName() == typeid(ESM::Armor).name()) |  | ||||||
|                         { |  | ||||||
|                             const ESM::Armor *armor = equipped->get<ESM::Armor>()->mBase; |  | ||||||
|                             parts = armor->mParts.mParts; |  | ||||||
|                         } |  | ||||||
|                         else |  | ||||||
|                         { |  | ||||||
|                             model = equipped->getClass().getModel(*equipped); |  | ||||||
|                             if (!model.empty()) |  | ||||||
|                                 mOut.push_back(model); |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
|                         for (std::vector<ESM::PartReference>::const_iterator it = parts.begin(); it != parts.end(); ++it) |  | ||||||
|                         { |  | ||||||
|                             const ESM::BodyPart* part = MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>().search(it->mMale); |  | ||||||
|                             if (part && !part->mModel.empty()) |  | ||||||
|                                 mOut.push_back("meshes/"+part->mModel); |  | ||||||
|                             part = MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>().search(it->mFemale); |  | ||||||
|                             if (part && !part->mModel.empty()) |  | ||||||
|                                 mOut.push_back("meshes/"+part->mModel); |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -291,6 +291,13 @@ namespace MWWorld | ||||||
|         return ""; |         return ""; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     void Class::getModelsToPreload(const Ptr &ptr, std::vector<std::string> &models) const | ||||||
|  |     { | ||||||
|  |         std::string model = getModel(ptr); | ||||||
|  |         if (!model.empty()) | ||||||
|  |             models.push_back(model); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     std::string Class::applyEnchantment(const MWWorld::ConstPtr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const |     std::string Class::applyEnchantment(const MWWorld::ConstPtr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const | ||||||
|     { |     { | ||||||
|         throw std::runtime_error ("class can't be enchanted"); |         throw std::runtime_error ("class can't be enchanted"); | ||||||
|  |  | ||||||
|  | @ -262,6 +262,9 @@ namespace MWWorld | ||||||
| 
 | 
 | ||||||
|             virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; |             virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; | ||||||
| 
 | 
 | ||||||
|  |             virtual void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector<std::string>& models) const; | ||||||
|  |             ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: list getModel().
 | ||||||
|  | 
 | ||||||
|             virtual std::string applyEnchantment(const MWWorld::ConstPtr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const; |             virtual std::string applyEnchantment(const MWWorld::ConstPtr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const; | ||||||
|             ///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it.
 |             ///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it.
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue