From 8902bb5b13bde2a465eca446e768f136ba6b593d Mon Sep 17 00:00:00 2001 From: NeveHanter Date: Tue, 20 Dec 2016 12:38:51 +0100 Subject: [PATCH] Player now pays for the following actors when travelling, with the exception of the first follower who travels for free, refactored getFollowers to getActorsFollowing/getActorsSidingWith --- apps/openmw/mwbase/mechanicsmanager.hpp | 5 ++++ apps/openmw/mwgui/travelwindow.cpp | 28 ++++++++++++++++--- apps/openmw/mwmechanics/actors.cpp | 14 ++++++++++ apps/openmw/mwmechanics/actors.hpp | 5 ++++ .../mwmechanics/mechanicsmanagerimp.cpp | 22 ++++++--------- .../mwmechanics/mechanicsmanagerimp.hpp | 5 ++++ apps/openmw/mwworld/actionteleport.cpp | 20 ++----------- 7 files changed, 64 insertions(+), 35 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 0f414972f..bd0d2ea4a 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include namespace osg @@ -200,6 +201,10 @@ namespace MWBase virtual std::list getEnemiesNearby(const MWWorld::Ptr& actor) = 0; + /// Recursive versions of above methods + virtual void getActorsFollowing(const MWWorld::Ptr& actor, std::set& out) = 0; + virtual void getActorsSidingWith(const MWWorld::Ptr& actor, std::set& out) = 0; + virtual void playerLoaded() = 0; virtual int countSavedGameRecords() const = 0; diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 8c55c3732..80a622803 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -55,7 +55,7 @@ namespace MWGui void TravelWindow::addDestination(const std::string& name,ESM::Position pos,bool interior) { - int price = 0; + int price; const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); @@ -70,14 +70,34 @@ namespace MWGui else { ESM::Position PlayerPos = player.getRefData().getPosition(); - float d = sqrt( pow(pos.pos[0] - PlayerPos.pos[0],2) + pow(pos.pos[1] - PlayerPos.pos[1],2) + pow(pos.pos[2] - PlayerPos.pos[2],2) ); + float d = sqrt(pow(pos.pos[0] - PlayerPos.pos[0], 2) + pow(pos.pos[1] - PlayerPos.pos[1], 2) + pow(pos.pos[2] - PlayerPos.pos[2], 2)); price = static_cast(d / gmst.find("fTravelMult")->getFloat()); } - price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true); + // Add price for the followers in range + std::set followers; + MWBase::Environment::get().getMechanicsManager()->getActorsFollowing(player, followers); + + unsigned int travellingFollowers = 0; + for(std::set::iterator it = followers.begin();it != followers.end();++it) + { + MWWorld::Ptr follower = *it; + + std::string script = follower.getClass().getScript(follower); + if (!script.empty() && follower.getRefData().getLocals().getIntVar(script, "stayoutside") == 1) + continue; + + if ((follower.getRefData().getPosition().asVec3() - player.getRefData().getPosition().asVec3()).length2() <= 800*800) + ++travellingFollowers; + } + + // Apply followers cost, in vanilla one follower travels for free + price *= travellingFollowers; + + price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true); MyGUI::Button* toAdd = mDestinationsView->createWidget("SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default); - toAdd->setEnabled(price<=playerGold); + toAdd->setEnabled(price <= playerGold); mCurrentY += sLineHeight; if(interior) toAdd->setUserString("interior","y"); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 23a6f497f..af8a47ccf 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1482,6 +1482,20 @@ namespace MWMechanics return list; } + void Actors::getActorsFollowing(const MWWorld::Ptr &actor, std::set& out) { + std::list followers = getActorsFollowing(actor); + for(std::list::iterator it = followers.begin();it != followers.end();++it) + if (out.insert(*it).second) + getActorsFollowing(*it, out); + } + + void Actors::getActorsSidingWith(const MWWorld::Ptr &actor, std::set& out) { + std::list followers = getActorsSidingWith(actor); + for(std::list::iterator it = followers.begin();it != followers.end();++it) + if (out.insert(*it).second) + getActorsSidingWith(*it, out); + } + std::list Actors::getActorsFollowingIndices(const MWWorld::Ptr &actor) { std::list list; diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 163995f6f..20aef4c17 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -123,6 +123,11 @@ namespace MWMechanics std::list getActorsSidingWith(const MWWorld::Ptr& actor); std::list getActorsFollowing(const MWWorld::Ptr& actor); + /// Recursive version of getActorsFollowing + void getActorsFollowing(const MWWorld::Ptr &actor, std::set& out); + /// Recursive version of getActorsSidingWith + void getActorsSidingWith(const MWWorld::Ptr &actor, std::set& out); + /// Get the list of AiFollow::mFollowIndex for all actors following this target std::list getActorsFollowingIndices(const MWWorld::Ptr& actor); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 97fa98b3b..e552f4683 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -978,18 +978,6 @@ namespace MWMechanics } - void getFollowers (const MWWorld::Ptr& actor, std::set& out) - { - std::list followers = MWBase::Environment::get().getMechanicsManager()->getActorsSidingWith(actor); - for(std::list::iterator it = followers.begin();it != followers.end();++it) - { - if (out.insert(*it).second) - { - getFollowers(*it, out); - } - } - } - bool MechanicsManager::commitCrime(const MWWorld::Ptr &player, const MWWorld::Ptr &victim, OffenseType type, int arg, bool victimAware) { // NOTE: victim may be empty @@ -1013,7 +1001,7 @@ namespace MWMechanics // get the player's followers / allies (works recursively) that will not report crimes std::set playerFollowers; - getFollowers(player, playerFollowers); + getActorsSidingWith(player, playerFollowers); // Did anyone see it? bool crimeSeen = false; @@ -1437,6 +1425,14 @@ namespace MWMechanics return mActors.getEnemiesNearby(actor); } + void MechanicsManager::getActorsFollowing(const MWWorld::Ptr& actor, std::set& out) { + mActors.getActorsFollowing(actor, out); + } + + void MechanicsManager::getActorsSidingWith(const MWWorld::Ptr& actor, std::set& out) { + mActors.getActorsSidingWith(actor, out); + } + int MechanicsManager::countSavedGameRecords() const { return 1 // Death counter diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 04c67fcb6..ed06f58c5 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -165,6 +165,11 @@ namespace MWMechanics virtual std::list getActorsFighting(const MWWorld::Ptr& actor); virtual std::list getEnemiesNearby(const MWWorld::Ptr& actor); + /// Recursive version of getActorsFollowing + virtual void getActorsFollowing(const MWWorld::Ptr& actor, std::set& out); + /// Recursive version of getActorsSidingWith + virtual void getActorsSidingWith(const MWWorld::Ptr& actor, std::set& out); + virtual bool toggleAI(); virtual bool isAIActive(); diff --git a/apps/openmw/mwworld/actionteleport.cpp b/apps/openmw/mwworld/actionteleport.cpp index c9315283d..ab1c0afc6 100644 --- a/apps/openmw/mwworld/actionteleport.cpp +++ b/apps/openmw/mwworld/actionteleport.cpp @@ -8,23 +8,6 @@ #include "player.hpp" -namespace -{ - - void getFollowers (const MWWorld::Ptr& actor, std::set& out) - { - std::list followers = MWBase::Environment::get().getMechanicsManager()->getActorsFollowing(actor); - for(std::list::iterator it = followers.begin();it != followers.end();++it) - { - if (out.insert(*it).second) - { - getFollowers(*it, out); - } - } - } - -} - namespace MWWorld { ActionTeleport::ActionTeleport (const std::string& cellName, @@ -39,7 +22,8 @@ namespace MWWorld { //find any NPC that is following the actor and teleport him too std::set followers; - getFollowers(actor, followers); + MWBase::Environment::get().getMechanicsManager()->getActorsFollowing(actor, followers); + for(std::set::iterator it = followers.begin();it != followers.end();++it) { MWWorld::Ptr follower = *it;