1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-20 17:23:53 +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) 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::InventoryStore &inventoryStore = MWWorld::Class::get(ptr).getInventoryStore(ptr);
MWWorld::ContainerStoreIterator heldIter = MWWorld::ContainerStoreIterator heldIter =
inventoryStore.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); 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) if(heldIter.getType() == MWWorld::ContainerStore::Type_Light)
{ {
// Use time from the player's light // Use time from the player's light
bool isPlayer = ptr.getRefData().getHandle()=="player";
if(isPlayer) if(isPlayer)
{ {
float timeRemaining = heldIter->getClass().getRemainingUsageTime(*heldIter); float timeRemaining = heldIter->getClass().getRemainingUsageTime(*heldIter);

View file

@ -25,14 +25,13 @@ namespace MWMechanics
{ {
class Actors class Actors
{ {
typedef std::map<MWWorld::Ptr,CharacterController*> PtrControllerMap; typedef std::map<MWWorld::Ptr,CharacterController*> PtrControllerMap;
PtrControllerMap mActors; PtrControllerMap mActors;
std::map<std::string, int> mDeathCount;
void updateNpc(const MWWorld::Ptr &ptr, float duration, bool paused);
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); 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()) mAnimation->play("torch", Priority_Torch, MWRender::Animation::Group_LeftArm,
{ false, 1.0f, "start", "stop", 0.0f, (~(size_t)0));
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);
}
}
}
} }
else if (mAnimation->isPlaying("torch"))
{
mAnimation->disable("torch");
}
return forcestateupdate; return forcestateupdate;
} }

View file

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

View file

@ -118,7 +118,6 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, int v
mViewMode(viewMode), mViewMode(viewMode),
mShowWeapons(false), mShowWeapons(false),
mShowShield(true), mShowShield(true),
mShowLights(false),
mFirstPersonOffset(0.f, 0.f, 0.f), mFirstPersonOffset(0.f, 0.f, 0.f),
mAlpha(1.f) mAlpha(1.f)
{ {
@ -321,7 +320,6 @@ void NpcAnimation::updateParts()
showWeapons(mShowWeapons); showWeapons(mShowWeapons);
showShield(mShowShield); showShield(mShowShield);
showLights(mShowLights);
// Remember body parts so we only have to search through the store once for each race/gender/viewmode combination // 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; 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::InventoryStore &inv = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
MWWorld::ContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); 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); Ogre::Vector3 glowColor = getEnchantmentColor(*shield);
std::string mesh = MWWorld::Class::get(*shield).getModel(*shield); std::string mesh = MWWorld::Class::get(*shield).getModel(*shield);
addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1, addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1,
mesh, !shield->getClass().getEnchantment(*shield).empty(), &glowColor); 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 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) void NpcAnimation::permanentEffectAdded(const ESM::MagicEffect *magicEffect, bool isNew, bool playSound)
{ {
// During first auto equip, we don't play any sounds. // During first auto equip, we don't play any sounds.

View file

@ -54,7 +54,6 @@ private:
ViewMode mViewMode; ViewMode mViewMode;
bool mShowWeapons; bool mShowWeapons;
bool mShowShield; bool mShowShield;
bool mShowLights;
int mVisibilityFlags; int mVisibilityFlags;
@ -102,7 +101,6 @@ public:
virtual void showWeapons(bool showWeapon); virtual void showWeapons(bool showWeapon);
virtual void showShield(bool showShield); virtual void showShield(bool showShield);
virtual void showLights(bool showLights);
void setViewMode(ViewMode viewMode); 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) for (ContainerStoreIterator iter (begin()); iter!=end(); ++iter)
{ {
Ptr test = *iter; Ptr test = *iter;
// Don't autoEquip lights
if (test.getTypeName() == typeid(ESM::Light).name())
{
continue;
}
int testSkill = MWWorld::Class::get (test).getEquipmentSkill (test); int testSkill = MWWorld::Class::get (test).getEquipmentSkill (test);
std::pair<std::vector<int>, bool> itemsSlots = std::pair<std::vector<int>, bool> itemsSlots =