diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 780580e2a8..a750e266c8 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -23,6 +23,8 @@ #include "../mwworld/player.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwmechanics/npcstats.hpp" + #include "../mwsound/soundmanagerimp.hpp" #include "console.hpp" @@ -1442,6 +1444,10 @@ namespace MWGui void WindowManager::updatePlayer() { mInventoryWindow->updatePlayer(); + + const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + if (player.getClass().getNpcStats(player).isWerewolf()) + forceHide((GuiWindow)(MWGui::GW_Inventory | MWGui::GW_Magic)); } void WindowManager::setKeyFocusWidget(MyGUI::Widget *widget) @@ -1532,6 +1538,8 @@ namespace MWGui mCustomMarkers.clear(); + mForceHidden = GW_None; + mGuiModes.clear(); MWBase::Environment::get().getInputManager()->changeInputMode(false); updateVisible(); diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index bd3ff5cd52..c2a934d3a1 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -580,6 +580,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim , mIdleState(CharState_None) , mMovementState(CharState_None) , mMovementSpeed(0.0f) + , mHasMovedInXY(false) , mMovementAnimationControlled(true) , mDeathState(CharState_None) , mHitState(CharState_None) @@ -794,6 +795,7 @@ bool CharacterController::updateWeaponState() { MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); if(cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Run) + && mHasMovedInXY && !MWBase::Environment::get().getWorld()->isSwimming(mPtr) && mWeaponType == WeapType_None) { @@ -1249,11 +1251,12 @@ void CharacterController::update(float duration) CharacterState idlestate = CharState_SpecialIdle; bool forcestateupdate = false; - isrunning = isrunning && std::abs(vec[0])+std::abs(vec[1]) > 0.0f; + mHasMovedInXY = std::abs(vec[0])+std::abs(vec[1]) > 0.0f; + isrunning = isrunning && mHasMovedInXY; // advance athletics - if(std::abs(vec[0])+std::abs(vec[1]) > 0.0f && mPtr.getRefData().getHandle() == "player") + if(mHasMovedInXY && mPtr.getRefData().getHandle() == "player") { if(inwater) { diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index b1e1738bd9..8110c88cde 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -147,6 +147,7 @@ class CharacterController CharacterState mMovementState; std::string mCurrentMovement; float mMovementSpeed; + bool mHasMovedInXY; bool mMovementAnimationControlled; CharacterState mDeathState; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 8547188637..e4dda2db27 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -869,6 +869,12 @@ namespace MWMechanics bool MechanicsManager::sleepInBed(const MWWorld::Ptr &ptr, const MWWorld::Ptr &bed) { + if (ptr.getClass().getNpcStats(ptr).isWerewolf()) + { + MWBase::Environment::get().getWindowManager()->messageBox("#{sWerewolfRefusal}"); + return true; + } + if(MWBase::Environment::get().getWorld()->getPlayer().isInCombat()) { MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage2}"); return true; @@ -1296,6 +1302,17 @@ namespace MWMechanics + ((50 - disposition) * fFightDispMult)) + bias; + if (ptr.getClass().isNpc() && target.getClass().isNpc()) + { + if (target.getClass().getNpcStats(target).isWerewolf() || + (target == MWBase::Environment::get().getWorld()->getPlayerPtr() && + MWBase::Environment::get().getWorld()->getGlobalInt("pcknownwerewolf"))) + { + const ESM::GameSetting * iWerewolfFightMod = MWBase::Environment::get().getWorld()->getStore().get().search("iWerewolfFightMod"); + fight += iWerewolfFightMod->getInt(); + } + } + return (fight >= 100); } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index c1147fa035..44dc69ee8d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -390,6 +390,7 @@ namespace MWWorld // vanilla Morrowind does not define dayspassed. globals["dayspassed"] = ESM::Variant(1); // but the addons start counting at 1 :( globals["WerewolfClawMult"] = ESM::Variant(1.f); + globals["PCKnownWerewolf"] = ESM::Variant(0); for (std::map::iterator it = gmst.begin(); it != gmst.end(); ++it) { @@ -2330,6 +2331,34 @@ namespace MWWorld windowManager->unsetForceHide(MWGui::GW_Inventory); windowManager->unsetForceHide(MWGui::GW_Magic); } + + // Witnesses of the player's transformation will make them a globally known werewolf + std::vector closeActors; + MWBase::Environment::get().getMechanicsManager()->getActorsInRange(Ogre::Vector3(actor.getRefData().getPosition().pos), + getStore().get().search("fAlarmRadius")->getFloat(), + closeActors); + + bool detected = false; + for (std::vector::const_iterator it = closeActors.begin(); it != closeActors.end(); ++it) + { + if (*it == actor) + continue; + + if (!it->getClass().isNpc()) + continue; + + if (getLOS(*it, actor) && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor, *it)) + { + detected = true; + break; + } + } + + if (detected) + { + windowManager->messageBox("#{sWerewolfAlarmMessage}"); + setGlobalInt("pcknownwerewolf", 1); + } } }