From f052c05018455e938b27408115aded79151f90d0 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 26 Dec 2015 18:22:21 +0100 Subject: [PATCH] Move werewolf functions from World to MechanicsManager --- apps/openmw/mwbase/mechanicsmanager.hpp | 7 ++ apps/openmw/mwbase/world.hpp | 7 -- .../mwmechanics/mechanicsmanagerimp.cpp | 105 ++++++++++++++++++ .../mwmechanics/mechanicsmanagerimp.hpp | 3 + apps/openmw/mwscript/statsextensions.cpp | 4 +- apps/openmw/mwworld/worldimp.cpp | 105 ------------------ apps/openmw/mwworld/worldimp.hpp | 4 - 7 files changed, 117 insertions(+), 118 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 31afc126a..42da1a052 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -221,6 +221,13 @@ namespace MWBase virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid) = 0; virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::CellRef& cellref, MWWorld::Ptr& victim) = 0; + + /// Turn actor into werewolf or normal form. + virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) = 0; + + /// Sets the NPC's Acrobatics skill to match the fWerewolfAcrobatics GMST. + /// It only applies to the current form the NPC is in. + virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) = 0; }; } diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 5ae21022c..ebce2e1bf 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -456,13 +456,6 @@ namespace MWBase /// Returns true if levitation spell effect is allowed. virtual bool isLevitationEnabled() const = 0; - /// Turn actor into werewolf or normal form. - virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) = 0; - - /// Sets the NPC's Acrobatics skill to match the fWerewolfAcrobatics GMST. - /// It only applies to the current form the NPC is in. - virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) = 0; - virtual bool getGodModeState() = 0; virtual bool toggleGodMode() = 0; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 9dafebffa..f88d27fce 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1585,4 +1585,109 @@ namespace MWMechanics { return mActors.isReadyToBlock(ptr); } + + void MechanicsManager::setWerewolf(const MWWorld::Ptr& actor, bool werewolf) + { + MWMechanics::NpcStats& npcStats = actor.getClass().getNpcStats(actor); + + // The actor does not have to change state + if (npcStats.isWerewolf() == werewolf) + return; + + MWWorld::Player* player = &MWBase::Environment::get().getWorld()->getPlayer(); + + if (actor == player->getPlayer()) + { + if (werewolf) + { + player->saveSkillsAttributes(); + player->setWerewolfSkillsAttributes(); + } + else + player->restoreSkillsAttributes(); + } + + npcStats.setWerewolf(werewolf); + + // This is a bit dangerous. Equipped items other than WerewolfRobe may reference + // bones that do not even exist with the werewolf object root. + // Therefore, make sure to unequip everything at once, and only fire the change event + // (which will rebuild the animation parts) afterwards. unequipAll will do this for us. + MWWorld::InventoryStore& invStore = actor.getClass().getInventoryStore(actor); + invStore.unequipAll(actor); + + if(werewolf) + { + MWWorld::InventoryStore &inv = actor.getClass().getInventoryStore(actor); + + inv.equip(MWWorld::InventoryStore::Slot_Robe, inv.ContainerStore::add("werewolfrobe", 1, actor), actor); + } + else + { + actor.getClass().getContainerStore(actor).remove("werewolfrobe", 1, actor); + } + + if(actor == player->getPlayer()) + { + MWBase::Environment::get().getWorld()->reattachPlayerCamera(); + + // Update the GUI only when called on the player + MWBase::WindowManager* windowManager = MWBase::Environment::get().getWindowManager(); + + if (werewolf) + { + windowManager->forceHide(MWGui::GW_Inventory); + windowManager->forceHide(MWGui::GW_Magic); + } + else + { + windowManager->unsetForceHide(MWGui::GW_Inventory); + windowManager->unsetForceHide(MWGui::GW_Magic); + } + + windowManager->setWerewolfOverlay(werewolf); + + // Witnesses of the player's transformation will make them a globally known werewolf + std::vector closeActors; + const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + getActorsInRange(actor.getRefData().getPosition().asVec3(), gmst.find("fAlarmRadius")->getFloat(), closeActors); + + bool detected = false, reported = false; + for (std::vector::const_iterator it = closeActors.begin(); it != closeActors.end(); ++it) + { + if (*it == actor) + continue; + + if (!it->getClass().isNpc()) + continue; + + if (MWBase::Environment::get().getWorld()->getLOS(*it, actor) && awarenessCheck(actor, *it)) + detected = true; + if (it->getClass().getCreatureStats(*it).getAiSetting(MWMechanics::CreatureStats::AI_Alarm).getModified() > 0) + reported = true; + } + + if (detected) + { + windowManager->messageBox("#{sWerewolfAlarmMessage}"); + MWBase::Environment::get().getWorld()->setGlobalInt("pcknownwerewolf", 1); + + if (reported) + { + npcStats.setBounty(npcStats.getBounty()+ + gmst.find("iWereWolfBounty")->getInt()); + windowManager->messageBox("#{sCrimeMessage}"); + } + } + } + } + + void MechanicsManager::applyWerewolfAcrobatics(const MWWorld::Ptr &actor) + { + const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + MWMechanics::NpcStats &stats = actor.getClass().getNpcStats(actor); + + stats.getSkill(ESM::Skill::Acrobatics).setBase(gmst.find("fWerewolfAcrobatics")->getInt()); + } + } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 603888adc..fb29c07ea 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -187,6 +187,9 @@ namespace MWMechanics /// @return is \a ptr allowed to take/use \a cellref or is it a crime? virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::CellRef& cellref, MWWorld::Ptr& victim); + virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf); + virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor); + private: void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, OffenseType type, int arg=0); diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 2a504f2ab..cdf60d329 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -1096,7 +1096,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = R()(runtime); - MWBase::Environment::get().getWorld()->setWerewolf(ptr, set); + MWBase::Environment::get().getMechanicsManager()->setWerewolf(ptr, set); } }; @@ -1108,7 +1108,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = R()(runtime); - MWBase::Environment::get().getWorld()->applyWerewolfAcrobatics(ptr); + MWBase::Environment::get().getMechanicsManager()->applyWerewolfAcrobatics(ptr); } }; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index c2c8e5833..15826009d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2453,111 +2453,6 @@ namespace MWWorld mRendering->rebuildPtr(getPlayerPtr()); } - void World::setWerewolf(const MWWorld::Ptr& actor, bool werewolf) - { - MWMechanics::NpcStats& npcStats = actor.getClass().getNpcStats(actor); - - // The actor does not have to change state - if (npcStats.isWerewolf() == werewolf) - return; - - if (actor == getPlayerPtr()) - { - if (werewolf) - { - mPlayer->saveSkillsAttributes(); - mPlayer->setWerewolfSkillsAttributes(); - } - else - mPlayer->restoreSkillsAttributes(); - } - - npcStats.setWerewolf(werewolf); - - // This is a bit dangerous. Equipped items other than WerewolfRobe may reference - // bones that do not even exist with the werewolf object root. - // Therefore, make sure to unequip everything at once, and only fire the change event - // (which will rebuild the animation parts) afterwards. unequipAll will do this for us. - MWWorld::InventoryStore& invStore = actor.getClass().getInventoryStore(actor); - invStore.unequipAll(actor); - - if(werewolf) - { - InventoryStore &inv = actor.getClass().getInventoryStore(actor); - - inv.equip(InventoryStore::Slot_Robe, inv.ContainerStore::add("werewolfrobe", 1, actor), actor); - } - else - { - actor.getClass().getContainerStore(actor).remove("werewolfrobe", 1, actor); - } - - // NpcAnimation::updateParts will already rebuild the animation when it detects change of Npc type. - // the following is just for reattaching the camera properly. - mRendering->rebuildPtr(actor); - - if(actor == getPlayerPtr()) - { - // Update the GUI only when called on the player - MWBase::WindowManager* windowManager = MWBase::Environment::get().getWindowManager(); - - if (werewolf) - { - windowManager->forceHide(MWGui::GW_Inventory); - windowManager->forceHide(MWGui::GW_Magic); - } - else - { - windowManager->unsetForceHide(MWGui::GW_Inventory); - windowManager->unsetForceHide(MWGui::GW_Magic); - } - - windowManager->setWerewolfOverlay(werewolf); - - // Witnesses of the player's transformation will make them a globally known werewolf - std::vector closeActors; - MWBase::Environment::get().getMechanicsManager()->getActorsInRange(actor.getRefData().getPosition().asVec3(), - getStore().get().search("fAlarmRadius")->getFloat(), - closeActors); - - bool detected = false, reported = 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; - if (it->getClass().getCreatureStats(*it).getAiSetting(MWMechanics::CreatureStats::AI_Alarm).getModified() > 0) - reported = true; - } - - if (detected) - { - windowManager->messageBox("#{sWerewolfAlarmMessage}"); - setGlobalInt("pcknownwerewolf", 1); - - if (reported) - { - npcStats.setBounty(npcStats.getBounty()+ - mStore.get().find("iWereWolfBounty")->getInt()); - windowManager->messageBox("#{sCrimeMessage}"); - } - } - } - } - - void World::applyWerewolfAcrobatics(const Ptr &actor) - { - const Store &gmst = getStore().get(); - MWMechanics::NpcStats &stats = actor.getClass().getNpcStats(actor); - - stats.getSkill(ESM::Skill::Acrobatics).setBase(gmst.find("fWerewolfAcrobatics")->getInt()); - } - bool World::getGodModeState() { return mGodMode; diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index ceda1321a..4ed97759e 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -560,10 +560,6 @@ namespace MWWorld /// Returns true if levitation spell effect is allowed. virtual bool isLevitationEnabled() const; - virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf); - - virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor); - virtual bool getGodModeState(); virtual bool toggleGodMode();