1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-21 02:53:54 +00:00

Fixes #845: NPCs hold torches during the day

Added method in WeatherManger and World which returns true if it is night.
This method is used later in character controller to show torches
(or other sources of light) at night and hide them at day.

Signed-off-by: Lukasz Gromanowski <lgromanowski@gmail.com>
This commit is contained in:
Lukasz Gromanowski 2013-12-10 23:48:49 +01:00
parent 77a2179d1e
commit 91a4d9a2eb
9 changed files with 62 additions and 17 deletions

View file

@ -421,6 +421,8 @@ namespace MWBase
const MWWorld::Ptr& actor, const std::string& sourceName) = 0;
virtual void breakInvisibility (const MWWorld::Ptr& actor) = 0;
virtual bool isNight() const = 0;
};
}

View file

@ -707,17 +707,30 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun
}
}
MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
if(torch != inv.end() && torch->getTypeName() == typeid(ESM::Light).name())
if (MWBase::Environment::get().getWorld()->isNight())
{
MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
if(torch != inv.end() && torch->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));
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);
mAnimation->showShield(true);
}
}
else if(mAnimation->isPlaying("torch"))
else
{
mAnimation->disable("torch");
mAnimation->showLights(false);
mAnimation->showShield(true);
}
return forcestateupdate;
}

View file

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

View file

@ -118,6 +118,7 @@ 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)
{
@ -320,6 +321,7 @@ 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;
@ -660,21 +662,12 @@ void NpcAnimation::showShield(bool show)
MWWorld::InventoryStore &inv = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
MWWorld::ContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
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())
if(show && shield != inv.end() && shield->getTypeName() != typeid(ESM::Light).name())
{
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
{
@ -682,6 +675,27 @@ void NpcAnimation::showShield(bool show)
}
}
void NpcAnimation::showLights(bool show)
{
mShowLights = 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())
{
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);
addExtraLight(mInsert->getCreator(), mObjectParts[ESM::PRT_Shield], shield->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,6 +54,7 @@ private:
ViewMode mViewMode;
bool mShowWeapons;
bool mShowShield;
bool mShowLights;
int mVisibilityFlags;
@ -101,6 +102,7 @@ public:
virtual void showWeapons(bool showWeapon);
virtual void showShield(bool showShield);
virtual void showLights(bool showLights);
void setViewMode(ViewMode viewMode);

View file

@ -707,3 +707,8 @@ float WeatherManager::getWindSpeed() const
{
return mWindSpeed;
}
bool WeatherManager::isNight() const
{
return (mHour < mSunriseTime || mHour > mNightStart - 1);
}

View file

@ -152,6 +152,8 @@ namespace MWWorld
void modRegion(const std::string &regionid, const std::vector<char> &chances);
bool isNight() const;
private:
float mHour;
int mDay, mMonth;

View file

@ -2244,4 +2244,9 @@ namespace MWWorld
actor.getClass().getCreatureStats(actor).getActiveSpells().purgeEffect(ESM::MagicEffect::Invisibility);
actor.getClass().getInventoryStore(actor).purgeEffect(ESM::MagicEffect::Invisibility);
}
bool World::isNight() const
{
return mWeatherManager->isNight();
}
}

View file

@ -506,6 +506,7 @@ namespace MWWorld
const MWWorld::Ptr& actor, const std::string& sourceName);
virtual void breakInvisibility (const MWWorld::Ptr& actor);
virtual bool isNight() const;
};
}