mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 17:59:56 +00:00
Fixes #845: NPCs hold torches during the day
Moved 'equipping torches at night and unequipping at day' code from Character to Actors class. Removed unneeded showLights method (introduced in previous commits) from animation/npcanimation classes. Since this commit autoEquip() method doesn't automatically equip lights. Signed-off-by: Lukasz Gromanowski <lgromanowski@gmail.com>
This commit is contained in:
parent
abc126e2af
commit
900bc06d2c
7 changed files with 66 additions and 77 deletions
|
@ -439,15 +439,48 @@ namespace MWMechanics
|
|||
|
||||
void Actors::updateEquippedLight (const MWWorld::Ptr& ptr, float duration)
|
||||
{
|
||||
//If holding a light...
|
||||
bool isPlayer = ptr.getRefData().getHandle()=="player";
|
||||
|
||||
MWWorld::InventoryStore &inventoryStore = MWWorld::Class::get(ptr).getInventoryStore(ptr);
|
||||
MWWorld::ContainerStoreIterator heldIter =
|
||||
inventoryStore.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
|
||||
/**
|
||||
* Automatically equip NPCs torches at night and unequip them at day
|
||||
*/
|
||||
if (!isPlayer && !MWWorld::Class::get (ptr).getCreatureStats (ptr).isHostile())
|
||||
{
|
||||
if (mTorchPtr.isEmpty())
|
||||
{
|
||||
mTorchPtr = inventoryStore.search("torch_infinite_time");
|
||||
}
|
||||
|
||||
if (MWBase::Environment::get().getWorld()->isNight())
|
||||
{
|
||||
if (heldIter != inventoryStore.end() && heldIter->getTypeName() != typeid(ESM::Light).name())
|
||||
{
|
||||
inventoryStore.unequipItem(*heldIter, ptr);
|
||||
}
|
||||
else if (heldIter == inventoryStore.end() && !mTorchPtr.isEmpty())
|
||||
{
|
||||
heldIter = inventoryStore.add(mTorchPtr, ptr);
|
||||
inventoryStore.equip(MWWorld::InventoryStore::Slot_CarriedLeft, heldIter, ptr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (heldIter != inventoryStore.end() && heldIter->getTypeName() == typeid(ESM::Light).name())
|
||||
{
|
||||
inventoryStore.unequipItem(*heldIter, ptr);
|
||||
inventoryStore.add(*heldIter, ptr);
|
||||
inventoryStore.autoEquip(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//If holding a light...
|
||||
if(heldIter.getType() == MWWorld::ContainerStore::Type_Light)
|
||||
{
|
||||
// Use time from the player's light
|
||||
bool isPlayer = ptr.getRefData().getHandle()=="player";
|
||||
if(isPlayer)
|
||||
{
|
||||
float timeRemaining = heldIter->getClass().getRemainingUsageTime(*heldIter);
|
||||
|
|
|
@ -25,14 +25,13 @@ namespace MWMechanics
|
|||
{
|
||||
class Actors
|
||||
{
|
||||
typedef std::map<MWWorld::Ptr,CharacterController*> PtrControllerMap;
|
||||
PtrControllerMap mActors;
|
||||
|
||||
std::map<std::string, int> mDeathCount;
|
||||
|
||||
void updateNpc(const MWWorld::Ptr &ptr, float duration, bool paused);
|
||||
typedef std::map<MWWorld::Ptr,CharacterController*> PtrControllerMap;
|
||||
PtrControllerMap mActors;
|
||||
|
||||
std::map<std::string, int> mDeathCount;
|
||||
MWWorld::Ptr mTorchPtr;
|
||||
|
||||
void updateNpc(const MWWorld::Ptr &ptr, float duration, bool paused);
|
||||
|
||||
void adjustMagicEffects (const MWWorld::Ptr& creature);
|
||||
|
||||
|
|
|
@ -709,50 +709,17 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun
|
|||
}
|
||||
}
|
||||
|
||||
if (mPtr.getRefData().getHandle() != "player")
|
||||
MWWorld::ContainerStoreIterator item = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
|
||||
if (item != inv.end() && item->getTypeName() == typeid(ESM::Light).name())
|
||||
{
|
||||
if (MWBase::Environment::get().getWorld()->isNight())
|
||||
{
|
||||
MWWorld::ContainerStoreIterator item = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
|
||||
if (item != inv.end() && item->getTypeName() != typeid(ESM::Light).name())
|
||||
{
|
||||
inv.unequipItem(*item, mPtr);
|
||||
}
|
||||
else if (item == inv.end())
|
||||
{
|
||||
MWWorld::Ptr itemPtr = inv.search("torch_infinite_time");
|
||||
if (!itemPtr.isEmpty())
|
||||
{
|
||||
item = inv.add(itemPtr, mPtr);
|
||||
inv.equip(MWWorld::InventoryStore::Slot_CarriedLeft, item, mPtr);
|
||||
}
|
||||
}
|
||||
|
||||
if (item != inv.end() && item->getTypeName() == typeid(ESM::Light).name())
|
||||
{
|
||||
mAnimation->showLights(true);
|
||||
if (!mAnimation->isPlaying("torch"))
|
||||
{
|
||||
mAnimation->play("torch", Priority_Torch, MWRender::Animation::Group_LeftArm,
|
||||
false, 1.0f, "start", "stop", 0.0f, (~(size_t)0));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mAnimation->isPlaying("torch"))
|
||||
{
|
||||
mAnimation->disable("torch");
|
||||
mAnimation->showLights(false);
|
||||
MWWorld::ContainerStoreIterator item = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
|
||||
if (item != inv.end() && item->getTypeName() == typeid(ESM::Light).name())
|
||||
{
|
||||
inv.unequipItem(*item, mPtr);
|
||||
inv.add(*item, mPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
mAnimation->play("torch", Priority_Torch, MWRender::Animation::Group_LeftArm,
|
||||
false, 1.0f, "start", "stop", 0.0f, (~(size_t)0));
|
||||
}
|
||||
else if (mAnimation->isPlaying("torch"))
|
||||
{
|
||||
mAnimation->disable("torch");
|
||||
}
|
||||
|
||||
return forcestateupdate;
|
||||
}
|
||||
|
||||
|
|
|
@ -275,7 +275,6 @@ public:
|
|||
|
||||
virtual void showWeapons(bool showWeapon);
|
||||
virtual void showShield(bool show) {}
|
||||
virtual void showLights(bool show) {}
|
||||
|
||||
void enableLights(bool enable);
|
||||
|
||||
|
|
|
@ -118,7 +118,6 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, int v
|
|||
mViewMode(viewMode),
|
||||
mShowWeapons(false),
|
||||
mShowShield(true),
|
||||
mShowLights(false),
|
||||
mFirstPersonOffset(0.f, 0.f, 0.f),
|
||||
mAlpha(1.f)
|
||||
{
|
||||
|
@ -321,7 +320,6 @@ void NpcAnimation::updateParts()
|
|||
|
||||
showWeapons(mShowWeapons);
|
||||
showShield(mShowShield);
|
||||
showLights(mShowLights);
|
||||
|
||||
// Remember body parts so we only have to search through the store once for each race/gender/viewmode combination
|
||||
static std::map< std::pair<std::string,int>,std::vector<const ESM::BodyPart*> > sRaceMapping;
|
||||
|
@ -662,12 +660,21 @@ void NpcAnimation::showShield(bool show)
|
|||
MWWorld::InventoryStore &inv = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
MWWorld::ContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
|
||||
|
||||
if(show && shield != inv.end() && shield->getTypeName() != typeid(ESM::Light).name())
|
||||
if (shield != inv.end() && shield->getTypeName() == typeid(ESM::Light).name())
|
||||
{
|
||||
// ... Except for lights, which are still shown during spellcasting since they
|
||||
// have their own (one-handed) casting animations
|
||||
show = true;
|
||||
}
|
||||
if(show && shield != inv.end())
|
||||
{
|
||||
Ogre::Vector3 glowColor = getEnchantmentColor(*shield);
|
||||
std::string mesh = MWWorld::Class::get(*shield).getModel(*shield);
|
||||
addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1,
|
||||
mesh, !shield->getClass().getEnchantment(*shield).empty(), &glowColor);
|
||||
|
||||
if (shield->getTypeName() == typeid(ESM::Light).name())
|
||||
addExtraLight(mInsert->getCreator(), mObjectParts[ESM::PRT_Shield], shield->get<ESM::Light>()->mBase);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -675,27 +682,6 @@ void NpcAnimation::showShield(bool show)
|
|||
}
|
||||
}
|
||||
|
||||
void NpcAnimation::showLights(bool show)
|
||||
{
|
||||
MWWorld::InventoryStore &inv = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
MWWorld::ContainerStoreIterator light = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
|
||||
|
||||
if(show && light != inv.end() && light->getTypeName() == typeid(ESM::Light).name())
|
||||
{
|
||||
mShowLights = show;
|
||||
Ogre::Vector3 glowColor = getEnchantmentColor(*light);
|
||||
std::string mesh = MWWorld::Class::get(*light).getModel(*light);
|
||||
addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1,
|
||||
mesh, !light->getClass().getEnchantment(*light).empty(), &glowColor);
|
||||
addExtraLight(mInsert->getCreator(), mObjectParts[ESM::PRT_Shield], light->get<ESM::Light>()->mBase);
|
||||
}
|
||||
else
|
||||
{
|
||||
removeIndividualPart(ESM::PRT_Shield);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NpcAnimation::permanentEffectAdded(const ESM::MagicEffect *magicEffect, bool isNew, bool playSound)
|
||||
{
|
||||
// During first auto equip, we don't play any sounds.
|
||||
|
|
|
@ -54,7 +54,6 @@ private:
|
|||
ViewMode mViewMode;
|
||||
bool mShowWeapons;
|
||||
bool mShowShield;
|
||||
bool mShowLights;
|
||||
|
||||
int mVisibilityFlags;
|
||||
|
||||
|
@ -102,7 +101,6 @@ public:
|
|||
|
||||
virtual void showWeapons(bool showWeapon);
|
||||
virtual void showShield(bool showShield);
|
||||
virtual void showLights(bool showLights);
|
||||
|
||||
void setViewMode(ViewMode viewMode);
|
||||
|
||||
|
|
|
@ -175,6 +175,13 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
|
|||
for (ContainerStoreIterator iter (begin()); iter!=end(); ++iter)
|
||||
{
|
||||
Ptr test = *iter;
|
||||
|
||||
// Don't autoEquip lights
|
||||
if (test.getTypeName() == typeid(ESM::Light).name())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int testSkill = MWWorld::Class::get (test).getEquipmentSkill (test);
|
||||
|
||||
std::pair<std::vector<int>, bool> itemsSlots =
|
||||
|
|
Loading…
Reference in a new issue