mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 21:49:55 +00:00
Merge pull request #1171 from NeveHanter/travel-followers-cost
Implemented "paying" for travelling followers
This commit is contained in:
commit
c9dd63af8d
8 changed files with 76 additions and 49 deletions
|
@ -4,6 +4,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <set>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
|
@ -200,6 +201,10 @@ namespace MWBase
|
||||||
|
|
||||||
virtual std::list<MWWorld::Ptr> getEnemiesNearby(const MWWorld::Ptr& actor) = 0;
|
virtual std::list<MWWorld::Ptr> getEnemiesNearby(const MWWorld::Ptr& actor) = 0;
|
||||||
|
|
||||||
|
/// Recursive versions of above methods
|
||||||
|
virtual void getActorsFollowing(const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out) = 0;
|
||||||
|
virtual void getActorsSidingWith(const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out) = 0;
|
||||||
|
|
||||||
virtual void playerLoaded() = 0;
|
virtual void playerLoaded() = 0;
|
||||||
|
|
||||||
virtual int countSavedGameRecords() const = 0;
|
virtual int countSavedGameRecords() const = 0;
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace MWGui
|
||||||
|
|
||||||
void TravelWindow::addDestination(const std::string& name,ESM::Position pos,bool interior)
|
void TravelWindow::addDestination(const std::string& name,ESM::Position pos,bool interior)
|
||||||
{
|
{
|
||||||
int price = 0;
|
int price;
|
||||||
|
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
@ -70,14 +70,21 @@ namespace MWGui
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ESM::Position PlayerPos = player.getRefData().getPosition();
|
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<int>(d / gmst.find("fTravelMult")->getFloat());
|
price = static_cast<int>(d / gmst.find("fTravelMult")->getFloat());
|
||||||
}
|
}
|
||||||
|
|
||||||
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true);
|
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true);
|
||||||
|
|
||||||
|
// Add price for the travelling followers
|
||||||
|
std::set<MWWorld::Ptr> followers;
|
||||||
|
MWWorld::ActionTeleport::getFollowersToTeleport(player, followers);
|
||||||
|
|
||||||
|
// Apply followers cost, in vanilla one follower travels for free
|
||||||
|
price *= std::max(1, static_cast<int>(followers.size()));
|
||||||
|
|
||||||
MyGUI::Button* toAdd = mDestinationsView->createWidget<MyGUI::Button>("SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default);
|
MyGUI::Button* toAdd = mDestinationsView->createWidget<MyGUI::Button>("SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default);
|
||||||
toAdd->setEnabled(price<=playerGold);
|
toAdd->setEnabled(price <= playerGold);
|
||||||
mCurrentY += sLineHeight;
|
mCurrentY += sLineHeight;
|
||||||
if(interior)
|
if(interior)
|
||||||
toAdd->setUserString("interior","y");
|
toAdd->setUserString("interior","y");
|
||||||
|
|
|
@ -1482,6 +1482,20 @@ namespace MWMechanics
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Actors::getActorsFollowing(const MWWorld::Ptr &actor, std::set<MWWorld::Ptr>& out) {
|
||||||
|
std::list<MWWorld::Ptr> followers = getActorsFollowing(actor);
|
||||||
|
for(std::list<MWWorld::Ptr>::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<MWWorld::Ptr>& out) {
|
||||||
|
std::list<MWWorld::Ptr> followers = getActorsSidingWith(actor);
|
||||||
|
for(std::list<MWWorld::Ptr>::iterator it = followers.begin();it != followers.end();++it)
|
||||||
|
if (out.insert(*it).second)
|
||||||
|
getActorsSidingWith(*it, out);
|
||||||
|
}
|
||||||
|
|
||||||
std::list<int> Actors::getActorsFollowingIndices(const MWWorld::Ptr &actor)
|
std::list<int> Actors::getActorsFollowingIndices(const MWWorld::Ptr &actor)
|
||||||
{
|
{
|
||||||
std::list<int> list;
|
std::list<int> list;
|
||||||
|
|
|
@ -123,6 +123,11 @@ namespace MWMechanics
|
||||||
std::list<MWWorld::Ptr> getActorsSidingWith(const MWWorld::Ptr& actor);
|
std::list<MWWorld::Ptr> getActorsSidingWith(const MWWorld::Ptr& actor);
|
||||||
std::list<MWWorld::Ptr> getActorsFollowing(const MWWorld::Ptr& actor);
|
std::list<MWWorld::Ptr> getActorsFollowing(const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
|
/// Recursive version of getActorsFollowing
|
||||||
|
void getActorsFollowing(const MWWorld::Ptr &actor, std::set<MWWorld::Ptr>& out);
|
||||||
|
/// Recursive version of getActorsSidingWith
|
||||||
|
void getActorsSidingWith(const MWWorld::Ptr &actor, std::set<MWWorld::Ptr>& out);
|
||||||
|
|
||||||
/// Get the list of AiFollow::mFollowIndex for all actors following this target
|
/// Get the list of AiFollow::mFollowIndex for all actors following this target
|
||||||
std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor);
|
std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
|
|
|
@ -978,18 +978,6 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void getFollowers (const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out)
|
|
||||||
{
|
|
||||||
std::list<MWWorld::Ptr> followers = MWBase::Environment::get().getMechanicsManager()->getActorsSidingWith(actor);
|
|
||||||
for(std::list<MWWorld::Ptr>::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)
|
bool MechanicsManager::commitCrime(const MWWorld::Ptr &player, const MWWorld::Ptr &victim, OffenseType type, int arg, bool victimAware)
|
||||||
{
|
{
|
||||||
// NOTE: victim may be empty
|
// NOTE: victim may be empty
|
||||||
|
@ -1013,7 +1001,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
// get the player's followers / allies (works recursively) that will not report crimes
|
// get the player's followers / allies (works recursively) that will not report crimes
|
||||||
std::set<MWWorld::Ptr> playerFollowers;
|
std::set<MWWorld::Ptr> playerFollowers;
|
||||||
getFollowers(player, playerFollowers);
|
getActorsSidingWith(player, playerFollowers);
|
||||||
|
|
||||||
// Did anyone see it?
|
// Did anyone see it?
|
||||||
bool crimeSeen = false;
|
bool crimeSeen = false;
|
||||||
|
@ -1437,6 +1425,14 @@ namespace MWMechanics
|
||||||
return mActors.getEnemiesNearby(actor);
|
return mActors.getEnemiesNearby(actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MechanicsManager::getActorsFollowing(const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out) {
|
||||||
|
mActors.getActorsFollowing(actor, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MechanicsManager::getActorsSidingWith(const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out) {
|
||||||
|
mActors.getActorsSidingWith(actor, out);
|
||||||
|
}
|
||||||
|
|
||||||
int MechanicsManager::countSavedGameRecords() const
|
int MechanicsManager::countSavedGameRecords() const
|
||||||
{
|
{
|
||||||
return 1 // Death counter
|
return 1 // Death counter
|
||||||
|
|
|
@ -165,6 +165,11 @@ namespace MWMechanics
|
||||||
virtual std::list<MWWorld::Ptr> getActorsFighting(const MWWorld::Ptr& actor);
|
virtual std::list<MWWorld::Ptr> getActorsFighting(const MWWorld::Ptr& actor);
|
||||||
virtual std::list<MWWorld::Ptr> getEnemiesNearby(const MWWorld::Ptr& actor);
|
virtual std::list<MWWorld::Ptr> getEnemiesNearby(const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
|
/// Recursive version of getActorsFollowing
|
||||||
|
virtual void getActorsFollowing(const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out);
|
||||||
|
/// Recursive version of getActorsSidingWith
|
||||||
|
virtual void getActorsSidingWith(const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out);
|
||||||
|
|
||||||
virtual bool toggleAI();
|
virtual bool toggleAI();
|
||||||
virtual bool isAIActive();
|
virtual bool isAIActive();
|
||||||
|
|
||||||
|
|
|
@ -8,23 +8,6 @@
|
||||||
|
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
void getFollowers (const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out)
|
|
||||||
{
|
|
||||||
std::list<MWWorld::Ptr> followers = MWBase::Environment::get().getMechanicsManager()->getActorsFollowing(actor);
|
|
||||||
for(std::list<MWWorld::Ptr>::iterator it = followers.begin();it != followers.end();++it)
|
|
||||||
{
|
|
||||||
if (out.insert(*it).second)
|
|
||||||
{
|
|
||||||
getFollowers(*it, out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
ActionTeleport::ActionTeleport (const std::string& cellName,
|
ActionTeleport::ActionTeleport (const std::string& cellName,
|
||||||
|
@ -37,21 +20,12 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
if (mTeleportFollowers)
|
if (mTeleportFollowers)
|
||||||
{
|
{
|
||||||
//find any NPC that is following the actor and teleport him too
|
// Find any NPCs that are following the actor and teleport them with him
|
||||||
std::set<MWWorld::Ptr> followers;
|
std::set<MWWorld::Ptr> followers;
|
||||||
getFollowers(actor, followers);
|
getFollowersToTeleport(actor, followers);
|
||||||
for(std::set<MWWorld::Ptr>::iterator it = followers.begin();it != followers.end();++it)
|
|
||||||
{
|
|
||||||
MWWorld::Ptr follower = *it;
|
|
||||||
|
|
||||||
std::string script = follower.getClass().getScript(follower);
|
for (std::set<MWWorld::Ptr>::iterator it = followers.begin(); it != followers.end(); ++it)
|
||||||
if (!script.empty() && follower.getRefData().getLocals().getIntVar(script, "stayoutside") == 1)
|
teleport(*it);
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((follower.getRefData().getPosition().asVec3() - actor.getRefData().getPosition().asVec3()).length2()
|
|
||||||
<= 800*800)
|
|
||||||
teleport(*it);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
teleport(actor);
|
teleport(actor);
|
||||||
|
@ -82,4 +56,21 @@ namespace MWWorld
|
||||||
world->moveObject(actor,world->getInterior(mCellName),mPosition.pos[0],mPosition.pos[1],mPosition.pos[2]);
|
world->moveObject(actor,world->getInterior(mCellName),mPosition.pos[0],mPosition.pos[1],mPosition.pos[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ActionTeleport::getFollowersToTeleport(const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out) {
|
||||||
|
std::set<MWWorld::Ptr> followers;
|
||||||
|
MWBase::Environment::get().getMechanicsManager()->getActorsFollowing(actor, followers);
|
||||||
|
|
||||||
|
for(std::set<MWWorld::Ptr>::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() - actor.getRefData().getPosition().asVec3()).length2() <= 800*800)
|
||||||
|
out.insert(follower);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef GAME_MWWORLD_ACTIONTELEPORT_H
|
#ifndef GAME_MWWORLD_ACTIONTELEPORT_H
|
||||||
#define GAME_MWWORLD_ACTIONTELEPORT_H
|
#define GAME_MWWORLD_ACTIONTELEPORT_H
|
||||||
|
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <components/esm/defs.hpp>
|
#include <components/esm/defs.hpp>
|
||||||
|
@ -23,9 +24,12 @@ namespace MWWorld
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ActionTeleport (const std::string& cellName, const ESM::Position& position, bool teleportFollowers);
|
/// If cellName is empty, an exterior cell is assumed.
|
||||||
///< If cellName is empty, an exterior cell is assumed.
|
|
||||||
/// @param teleportFollowers Whether to teleport any following actors of the target actor as well.
|
/// @param teleportFollowers Whether to teleport any following actors of the target actor as well.
|
||||||
|
ActionTeleport (const std::string& cellName, const ESM::Position& position, bool teleportFollowers);
|
||||||
|
|
||||||
|
/// Outputs every actor follower who is in teleport range and wasn't ordered to not enter interiors
|
||||||
|
static void getFollowersToTeleport(const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue