From 9e0d5dc28a8d8e9dd90ee4e16b1cf38b052f77b1 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Fri, 5 Sep 2014 01:58:57 +0200 Subject: [PATCH 1/5] Werewolf: can't sleep in beds anymore, actors will attack you on sight, and if you are seen transforming, you will be marked for death --- .../mwmechanics/mechanicsmanagerimp.cpp | 14 ++++++++++ apps/openmw/mwworld/worldimp.cpp | 26 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index b6b2c213d6..cb6e025dbc 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -874,6 +874,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; @@ -1301,6 +1307,14 @@ namespace MWMechanics + ((50 - disposition) * fFightDispMult)) + bias; + 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..bb76f2be95 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,31 @@ 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 (getLOS(*it, actor) && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor, *it)) + { + detected = true; + break; + } + } + + if (detected) + { + windowManager->messageBox("#{sWerewolfAlarmMessage}"); + setGlobalInt("pcknownwerewolf", 1); + } } } From c1cc66985dba67cad7dc7ec1004c28bd53311b0e Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sat, 6 Sep 2014 03:09:11 +0200 Subject: [PATCH 2/5] Werewolf: only NPCs should have modified fight and react to your transformation --- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 13 ++++++++----- apps/openmw/mwworld/worldimp.cpp | 3 +++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index cb6e025dbc..b21c0f6746 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1307,12 +1307,15 @@ namespace MWMechanics + ((50 - disposition) * fFightDispMult)) + bias; - if (target.getClass().getNpcStats(target).isWerewolf() || - (target == MWBase::Environment::get().getWorld()->getPlayerPtr() && - MWBase::Environment::get().getWorld()->getGlobalInt("pcknownwerewolf"))) + if (ptr.getClass().isNpc() && target.getClass().isNpc()) { - const ESM::GameSetting * iWerewolfFightMod = MWBase::Environment::get().getWorld()->getStore().get().search("iWerewolfFightMod"); - fight += iWerewolfFightMod->getInt(); + 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 bb76f2be95..44dc69ee8d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2344,6 +2344,9 @@ namespace MWWorld if (*it == actor) continue; + if (!it->getClass().isNpc()) + continue; + if (getLOS(*it, actor) && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor, *it)) { detected = true; From 57f7ef1db472d5fae2da34cd410c999476bbb290 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sat, 6 Sep 2014 03:13:35 +0200 Subject: [PATCH 3/5] GUI: update/clear force-hidden window status --- apps/openmw/mwgui/windowmanagerimp.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) 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(); From b1a449a0b9bd85e581366e3921f96d8cf8a37018 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sat, 6 Sep 2014 05:52:47 +0200 Subject: [PATCH 4/5] Fix wolfrun sound playing all the time when running is default --- apps/openmw/mwmechanics/character.cpp | 6 ++++-- apps/openmw/mwmechanics/character.hpp | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index bd3ff5cd52..6c8edf17ce 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -794,6 +794,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 +1250,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; From 931e778b4db69e91ca2b5f49335e2f4fbcf6a90c Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sat, 6 Sep 2014 21:31:48 +0200 Subject: [PATCH 5/5] Initialize mHasMovedInXY in CharacterController --- apps/openmw/mwmechanics/character.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 6c8edf17ce..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)