1
0
Fork 0
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:
Lukasz Gromanowski 2013-12-20 22:38:23 +01:00
parent abc126e2af
commit 900bc06d2c
7 changed files with 66 additions and 77 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -275,7 +275,6 @@ public:
virtual void showWeapons(bool showWeapon);
virtual void showShield(bool show) {}
virtual void showLights(bool show) {}
void enableLights(bool enable);

View file

@ -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.

View file

@ -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);

View file

@ -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 =