1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-20 08:53:52 +00:00

Move preload model list to MWClass, preload NPC head/hair

This commit is contained in:
scrawl 2016-02-08 20:52:32 +01:00
parent 84f01b7527
commit effe022bb2
7 changed files with 108 additions and 45 deletions

View file

@ -182,6 +182,29 @@ namespace MWClass
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
{
const MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();

View file

@ -101,6 +101,9 @@ namespace MWClass
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
isActor() const {
return true;

View file

@ -429,6 +429,74 @@ namespace MWClass
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
{
if(ptr.getRefData().getCustomData() && ptr.getRefData().getCustomData()->asNpcCustomData().mNpcStats.isWerewolf())

View file

@ -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 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,
const MWWorld::Ptr& actor) const;
///< Generate action for activation

View file

@ -31,51 +31,7 @@ namespace MWWorld
virtual bool operator()(const MWWorld::Ptr& ptr)
{
std::string model = ptr.getClass().getModel(ptr);
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);
}
}
}
}
ptr.getClass().getModelsToPreload(ptr, mOut);
return true;
}

View file

@ -291,6 +291,13 @@ namespace MWWorld
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
{
throw std::runtime_error ("class can't be enchanted");

View file

@ -262,6 +262,9 @@ namespace MWWorld
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;
///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it.