mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-26 03:52:01 +02:00
Merge branch 'develop' into feature/VCMIMapFormat1
Conflicts: lib/CArtHandler.cpp
This commit is contained in:
commit
37d0dad70a
@ -8,7 +8,7 @@
|
|||||||
#include "../../lib/VCMI_Lib.h"
|
#include "../../lib/VCMI_Lib.h"
|
||||||
|
|
||||||
using boost::optional;
|
using boost::optional;
|
||||||
static shared_ptr<CBattleCallback> cbc;
|
static std::shared_ptr<CBattleCallback> cbc;
|
||||||
|
|
||||||
#define LOGL(text) print(text)
|
#define LOGL(text) print(text)
|
||||||
#define LOGFL(text, formattingEl) print(boost::str(boost::format(text) % formattingEl))
|
#define LOGFL(text, formattingEl) print(boost::str(boost::format(text) % formattingEl))
|
||||||
@ -91,7 +91,7 @@ CBattleAI::~CBattleAI(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleAI::init(shared_ptr<CBattleCallback> CB)
|
void CBattleAI::init(std::shared_ptr<CBattleCallback> CB)
|
||||||
{
|
{
|
||||||
print("init called, saving ptr to IBattleCallback");
|
print("init called, saving ptr to IBattleCallback");
|
||||||
cbc = cb = CB;
|
cbc = cb = CB;
|
||||||
@ -610,7 +610,7 @@ ThreatMap::ThreatMap(const CStack *Endangered) : endangered(Endangered)
|
|||||||
|
|
||||||
const TBonusListPtr StackWithBonuses::getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= nullptr*/, const std::string &cachingStr /*= ""*/) const
|
const TBonusListPtr StackWithBonuses::getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= nullptr*/, const std::string &cachingStr /*= ""*/) const
|
||||||
{
|
{
|
||||||
TBonusListPtr ret = make_shared<BonusList>();
|
TBonusListPtr ret = std::make_shared<BonusList>();
|
||||||
const TBonusListPtr originalList = stack->getAllBonuses(selector, limit, root, cachingStr);
|
const TBonusListPtr originalList = stack->getAllBonuses(selector, limit, root, cachingStr);
|
||||||
range::copy(*originalList, std::back_inserter(*ret));
|
range::copy(*originalList, std::back_inserter(*ret));
|
||||||
for(auto &bonus : bonusesToAdd)
|
for(auto &bonus : bonusesToAdd)
|
||||||
|
@ -110,7 +110,7 @@ struct PotentialTargets
|
|||||||
class CBattleAI : public CBattleGameInterface
|
class CBattleAI : public CBattleGameInterface
|
||||||
{
|
{
|
||||||
int side;
|
int side;
|
||||||
shared_ptr<CBattleCallback> cb;
|
std::shared_ptr<CBattleCallback> cb;
|
||||||
|
|
||||||
//Previous setting of cb
|
//Previous setting of cb
|
||||||
bool wasWaitingForRealize, wasUnlockingGs;
|
bool wasWaitingForRealize, wasUnlockingGs;
|
||||||
@ -120,7 +120,7 @@ public:
|
|||||||
CBattleAI(void);
|
CBattleAI(void);
|
||||||
~CBattleAI(void);
|
~CBattleAI(void);
|
||||||
|
|
||||||
void init(shared_ptr<CBattleCallback> CB) override;
|
void init(std::shared_ptr<CBattleCallback> CB) override;
|
||||||
void actionFinished(const BattleAction &action) override;//occurs AFTER every action taken by any stack or by the hero
|
void actionFinished(const BattleAction &action) override;//occurs AFTER every action taken by any stack or by the hero
|
||||||
void actionStarted(const BattleAction &action) override;//occurs BEFORE every action taken by any stack or by the hero
|
void actionStarted(const BattleAction &action) override;//occurs BEFORE every action taken by any stack or by the hero
|
||||||
BattleAction activeStack(const CStack * stack) override; //called when it's turn of that stack
|
BattleAction activeStack(const CStack * stack) override; //called when it's turn of that stack
|
||||||
|
@ -25,7 +25,7 @@ extern "C" DLL_EXPORT void GetAiName(char* name)
|
|||||||
strcpy_s(name, strlen(g_cszAiName) + 1, g_cszAiName);
|
strcpy_s(name, strlen(g_cszAiName) + 1, g_cszAiName);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DLL_EXPORT void GetNewBattleAI(shared_ptr<CBattleGameInterface> &out)
|
extern "C" DLL_EXPORT void GetNewBattleAI(std::shared_ptr<CBattleGameInterface> &out)
|
||||||
{
|
{
|
||||||
out = make_shared<CBattleAI>();
|
out = std::make_shared<CBattleAI>();
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "../../lib/CRandomGenerator.h"
|
#include "../../lib/CRandomGenerator.h"
|
||||||
|
|
||||||
void CEmptyAI::init(shared_ptr<CCallback> CB)
|
void CEmptyAI::init(std::shared_ptr<CCallback> CB)
|
||||||
{
|
{
|
||||||
cb = CB;
|
cb = CB;
|
||||||
human=false;
|
human=false;
|
||||||
|
@ -7,10 +7,10 @@ struct HeroMoveDetails;
|
|||||||
|
|
||||||
class CEmptyAI : public CGlobalAI
|
class CEmptyAI : public CGlobalAI
|
||||||
{
|
{
|
||||||
shared_ptr<CCallback> cb;
|
std::shared_ptr<CCallback> cb;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void init(shared_ptr<CCallback> CB) override;
|
void init(std::shared_ptr<CCallback> CB) override;
|
||||||
void yourTurn() override;
|
void yourTurn() override;
|
||||||
void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID) override;
|
void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID) override;
|
||||||
void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID) override;
|
void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID) override;
|
||||||
|
@ -13,7 +13,7 @@ extern "C" DLL_EXPORT void GetAiName(char* name)
|
|||||||
strcpy(name,NAME);
|
strcpy(name,NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DLL_EXPORT void GetNewAI(shared_ptr<CGlobalAI> &out)
|
extern "C" DLL_EXPORT void GetNewAI(std::shared_ptr<CGlobalAI> &out)
|
||||||
{
|
{
|
||||||
out = make_shared<CEmptyAI>();
|
out = std::make_shared<CEmptyAI>();
|
||||||
}
|
}
|
@ -5,7 +5,7 @@
|
|||||||
#include "../../CCallback.h"
|
#include "../../CCallback.h"
|
||||||
#include "../../lib/CCreatureHandler.h"
|
#include "../../lib/CCreatureHandler.h"
|
||||||
|
|
||||||
static shared_ptr<CBattleCallback> cbc;
|
static std::shared_ptr<CBattleCallback> cbc;
|
||||||
|
|
||||||
CStupidAI::CStupidAI(void)
|
CStupidAI::CStupidAI(void)
|
||||||
: side(-1)
|
: side(-1)
|
||||||
@ -19,7 +19,7 @@ CStupidAI::~CStupidAI(void)
|
|||||||
print("destroyed");
|
print("destroyed");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStupidAI::init(shared_ptr<CBattleCallback> CB)
|
void CStupidAI::init(std::shared_ptr<CBattleCallback> CB)
|
||||||
{
|
{
|
||||||
print("init called, saving ptr to IBattleCallback");
|
print("init called, saving ptr to IBattleCallback");
|
||||||
cbc = cb = CB;
|
cbc = cb = CB;
|
||||||
|
@ -5,14 +5,14 @@
|
|||||||
class CStupidAI : public CBattleGameInterface
|
class CStupidAI : public CBattleGameInterface
|
||||||
{
|
{
|
||||||
int side;
|
int side;
|
||||||
shared_ptr<CBattleCallback> cb;
|
std::shared_ptr<CBattleCallback> cb;
|
||||||
|
|
||||||
void print(const std::string &text) const;
|
void print(const std::string &text) const;
|
||||||
public:
|
public:
|
||||||
CStupidAI(void);
|
CStupidAI(void);
|
||||||
~CStupidAI(void);
|
~CStupidAI(void);
|
||||||
|
|
||||||
void init(shared_ptr<CBattleCallback> CB) override;
|
void init(std::shared_ptr<CBattleCallback> CB) override;
|
||||||
void actionFinished(const BattleAction &action) override;//occurs AFTER every action taken by any stack or by the hero
|
void actionFinished(const BattleAction &action) override;//occurs AFTER every action taken by any stack or by the hero
|
||||||
void actionStarted(const BattleAction &action) override;//occurs BEFORE every action taken by any stack or by the hero
|
void actionStarted(const BattleAction &action) override;//occurs BEFORE every action taken by any stack or by the hero
|
||||||
BattleAction activeStack(const CStack * stack) override; //called when it's turn of that stack
|
BattleAction activeStack(const CStack * stack) override; //called when it's turn of that stack
|
||||||
|
@ -25,7 +25,7 @@ extern "C" DLL_EXPORT void GetAiName(char* name)
|
|||||||
strcpy_s(name, strlen(g_cszAiName) + 1, g_cszAiName);
|
strcpy_s(name, strlen(g_cszAiName) + 1, g_cszAiName);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DLL_EXPORT void GetNewBattleAI(shared_ptr<CBattleGameInterface> &out)
|
extern "C" DLL_EXPORT void GetNewBattleAI(std::shared_ptr<CBattleGameInterface> &out)
|
||||||
{
|
{
|
||||||
out = make_shared<CStupidAI>();
|
out = std::make_shared<CStupidAI>();
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ class CCallback;
|
|||||||
typedef const int3& crint3;
|
typedef const int3& crint3;
|
||||||
typedef const std::string& crstring;
|
typedef const std::string& crstring;
|
||||||
|
|
||||||
const int HERO_GOLD_COST = 2500;
|
|
||||||
const int GOLD_MINE_PRODUCTION = 1000, WOOD_ORE_MINE_PRODUCTION = 2, RESOURCE_MINE_PRODUCTION = 1;
|
const int GOLD_MINE_PRODUCTION = 1000, WOOD_ORE_MINE_PRODUCTION = 2, RESOURCE_MINE_PRODUCTION = 1;
|
||||||
const int ACTUAL_RESOURCE_COUNT = 7;
|
const int ACTUAL_RESOURCE_COUNT = 7;
|
||||||
const int ALLOWED_ROAMING_HEROES = 8;
|
const int ALLOWED_ROAMING_HEROES = 8;
|
||||||
|
@ -31,7 +31,6 @@ class Engine;
|
|||||||
class InputVariable;
|
class InputVariable;
|
||||||
class CGTownInstance;
|
class CGTownInstance;
|
||||||
|
|
||||||
using namespace vstd;
|
|
||||||
//using namespace Goals;
|
//using namespace Goals;
|
||||||
|
|
||||||
FuzzyHelper *fh;
|
FuzzyHelper *fh;
|
||||||
@ -85,7 +84,7 @@ armyStructure evaluateArmyStructure (const CArmedInstance * army)
|
|||||||
if (walker)
|
if (walker)
|
||||||
walkersStrenght += s.second->getPower();
|
walkersStrenght += s.second->getPower();
|
||||||
|
|
||||||
amax (maxSpeed, s.second->type->valOfBonuses(Bonus::STACKS_SPEED));
|
vstd::amax(maxSpeed, s.second->type->valOfBonuses(Bonus::STACKS_SPEED));
|
||||||
}
|
}
|
||||||
armyStructure as;
|
armyStructure as;
|
||||||
as.walkers = walkersStrenght / totalStrenght;
|
as.walkers = walkersStrenght / totalStrenght;
|
||||||
@ -297,7 +296,7 @@ FuzzyHelper::TacticalAdvantage::~TacticalAdvantage()
|
|||||||
delete threat;
|
delete threat;
|
||||||
}
|
}
|
||||||
|
|
||||||
//shared_ptr<AbstractGoal> chooseSolution (std::vector<shared_ptr<AbstractGoal>> & vec)
|
//std::shared_ptr<AbstractGoal> chooseSolution (std::vector<std::shared_ptr<AbstractGoal>> & vec)
|
||||||
|
|
||||||
Goals::TSubgoal FuzzyHelper::chooseSolution (Goals::TGoalVec vec)
|
Goals::TSubgoal FuzzyHelper::chooseSolution (Goals::TGoalVec vec)
|
||||||
{
|
{
|
||||||
|
@ -83,5 +83,5 @@ public:
|
|||||||
float getTacticalAdvantage (const CArmedInstance *we, const CArmedInstance *enemy); //returns factor how many times enemy is stronger than us
|
float getTacticalAdvantage (const CArmedInstance *we, const CArmedInstance *enemy); //returns factor how many times enemy is stronger than us
|
||||||
|
|
||||||
Goals::TSubgoal chooseSolution (Goals::TGoalVec vec);
|
Goals::TSubgoal chooseSolution (Goals::TGoalVec vec);
|
||||||
//shared_ptr<AbstractGoal> chooseSolution (std::vector<shared_ptr<AbstractGoal>> & vec);
|
//std::shared_ptr<AbstractGoal> chooseSolution (std::vector<std::shared_ptr<AbstractGoal>> & vec);
|
||||||
};
|
};
|
||||||
|
@ -19,12 +19,11 @@ extern boost::thread_specific_ptr<CCallback> cb;
|
|||||||
extern boost::thread_specific_ptr<VCAI> ai;
|
extern boost::thread_specific_ptr<VCAI> ai;
|
||||||
extern FuzzyHelper * fh; //TODO: this logic should be moved inside VCAI
|
extern FuzzyHelper * fh; //TODO: this logic should be moved inside VCAI
|
||||||
|
|
||||||
using namespace vstd;
|
|
||||||
using namespace Goals;
|
using namespace Goals;
|
||||||
|
|
||||||
TSubgoal Goals::sptr(const AbstractGoal & tmp)
|
TSubgoal Goals::sptr(const AbstractGoal & tmp)
|
||||||
{
|
{
|
||||||
shared_ptr<AbstractGoal> ptr;
|
std::shared_ptr<AbstractGoal> ptr;
|
||||||
ptr.reset(tmp.clone());
|
ptr.reset(tmp.clone());
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
@ -575,7 +574,7 @@ TGoalVec Explore::getAllPossibleSubgoals()
|
|||||||
{
|
{
|
||||||
//heroes = ai->getUnblockedHeroes();
|
//heroes = ai->getUnblockedHeroes();
|
||||||
heroes = cb->getHeroesInfo();
|
heroes = cb->getHeroesInfo();
|
||||||
erase_if (heroes, [](const HeroPtr h)
|
vstd::erase_if(heroes, [](const HeroPtr h)
|
||||||
{
|
{
|
||||||
if (ai->getGoal(h)->goalType == Goals::EXPLORE) //do not reassign hero who is already explorer
|
if (ai->getGoal(h)->goalType == Goals::EXPLORE) //do not reassign hero who is already explorer
|
||||||
return true;
|
return true;
|
||||||
@ -693,8 +692,8 @@ TSubgoal RecruitHero::whatToDoToAchieve()
|
|||||||
if(!t)
|
if(!t)
|
||||||
return sptr (Goals::BuildThis(BuildingID::TAVERN));
|
return sptr (Goals::BuildThis(BuildingID::TAVERN));
|
||||||
|
|
||||||
if(cb->getResourceAmount(Res::GOLD) < HERO_GOLD_COST)
|
if(cb->getResourceAmount(Res::GOLD) < GameConstants::HERO_GOLD_COST)
|
||||||
return sptr (Goals::CollectRes(Res::GOLD, HERO_GOLD_COST));
|
return sptr (Goals::CollectRes(Res::GOLD, GameConstants::HERO_GOLD_COST));
|
||||||
|
|
||||||
return iAmElementar();
|
return iAmElementar();
|
||||||
}
|
}
|
||||||
@ -749,7 +748,7 @@ TGoalVec VisitTile::getAllPossibleSubgoals()
|
|||||||
}
|
}
|
||||||
if(ret.empty())
|
if(ret.empty())
|
||||||
{
|
{
|
||||||
auto obj = frontOrNull(cb->getVisitableObjs(tile));
|
auto obj = vstd::frontOrNull(cb->getVisitableObjs(tile));
|
||||||
if(obj && obj->ID == Obj::HERO && obj->tempOwner == ai->playerID) //our own hero stands on that tile
|
if(obj && obj->ID == Obj::HERO && obj->tempOwner == ai->playerID) //our own hero stands on that tile
|
||||||
{
|
{
|
||||||
if (hero.get(true) && hero->id == obj->id) //if it's assigned hero, visit tile. If it's different hero, we can't visit tile now
|
if (hero.get(true) && hero->id == obj->id) //if it's assigned hero, visit tile. If it's different hero, we can't visit tile now
|
||||||
@ -767,7 +766,7 @@ TGoalVec VisitTile::getAllPossibleSubgoals()
|
|||||||
|
|
||||||
TSubgoal DigAtTile::whatToDoToAchieve()
|
TSubgoal DigAtTile::whatToDoToAchieve()
|
||||||
{
|
{
|
||||||
const CGObjectInstance *firstObj = frontOrNull(cb->getVisitableObjs(tile));
|
const CGObjectInstance *firstObj = vstd::frontOrNull(cb->getVisitableObjs(tile));
|
||||||
if(firstObj && firstObj->ID == Obj::HERO && firstObj->tempOwner == ai->playerID) //we have hero at dest
|
if(firstObj && firstObj->ID == Obj::HERO && firstObj->tempOwner == ai->playerID) //we have hero at dest
|
||||||
{
|
{
|
||||||
const CGHeroInstance *h = dynamic_cast<const CGHeroInstance *>(firstObj);
|
const CGHeroInstance *h = dynamic_cast<const CGHeroInstance *>(firstObj);
|
||||||
@ -1057,7 +1056,7 @@ TGoalVec GatherArmy::getAllPossibleSubgoals()
|
|||||||
|
|
||||||
auto otherHeroes = cb->getHeroesInfo();
|
auto otherHeroes = cb->getHeroesInfo();
|
||||||
auto heroDummy = hero;
|
auto heroDummy = hero;
|
||||||
erase_if(otherHeroes, [heroDummy](const CGHeroInstance * h)
|
vstd::erase_if(otherHeroes, [heroDummy](const CGHeroInstance * h)
|
||||||
{
|
{
|
||||||
return (h == heroDummy.h || !ai->isAccessibleForHero(heroDummy->visitablePos(), h, true)
|
return (h == heroDummy.h || !ai->isAccessibleForHero(heroDummy->visitablePos(), h, true)
|
||||||
|| !ai->canGetArmy(heroDummy.h, h) || ai->getGoal(h)->goalType == Goals::GATHER_ARMY);
|
|| !ai->canGetArmy(heroDummy.h, h) || ai->getGoal(h)->goalType == Goals::GATHER_ARMY);
|
||||||
|
@ -107,7 +107,7 @@ public:
|
|||||||
static TSubgoal tryRecruitHero();
|
static TSubgoal tryRecruitHero();
|
||||||
|
|
||||||
///Visitor pattern
|
///Visitor pattern
|
||||||
//TODO: make accept work for shared_ptr... somehow
|
//TODO: make accept work for std::shared_ptr... somehow
|
||||||
virtual void accept (VCAI * ai); //unhandled goal will report standard error
|
virtual void accept (VCAI * ai); //unhandled goal will report standard error
|
||||||
virtual float accept (FuzzyHelper * f);
|
virtual float accept (FuzzyHelper * f);
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ public:
|
|||||||
TSubgoal iAmElementar()
|
TSubgoal iAmElementar()
|
||||||
{
|
{
|
||||||
setisElementar(true);
|
setisElementar(true);
|
||||||
shared_ptr<AbstractGoal> ptr;
|
std::shared_ptr<AbstractGoal> ptr;
|
||||||
ptr.reset(clone());
|
ptr.reset(clone());
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
184
AI/VCAI/VCAI.cpp
184
AI/VCAI/VCAI.cpp
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CCreatureHandler.h, part of VCMI engine
|
* VCAI.cpp, part of VCMI engine
|
||||||
*
|
*
|
||||||
* Authors: listed in file AUTHORS in main folder
|
* Authors: listed in file AUTHORS in main folder
|
||||||
*
|
*
|
||||||
@ -29,8 +29,6 @@ class CGVisitableOPW;
|
|||||||
const double SAFE_ATTACK_CONSTANT = 1.5;
|
const double SAFE_ATTACK_CONSTANT = 1.5;
|
||||||
const int GOLD_RESERVE = 10000; //when buying creatures we want to keep at least this much gold (10000 so at least we'll be able to reach capitol)
|
const int GOLD_RESERVE = 10000; //when buying creatures we want to keep at least this much gold (10000 so at least we'll be able to reach capitol)
|
||||||
|
|
||||||
using namespace vstd;
|
|
||||||
|
|
||||||
//one thread may be turn of AI and another will be handling a side effect for AI2
|
//one thread may be turn of AI and another will be handling a side effect for AI2
|
||||||
boost::thread_specific_ptr<CCallback> cb;
|
boost::thread_specific_ptr<CCallback> cb;
|
||||||
boost::thread_specific_ptr<VCAI> ai;
|
boost::thread_specific_ptr<VCAI> ai;
|
||||||
@ -124,8 +122,8 @@ void VCAI::heroMoved(const TryMoveHero & details)
|
|||||||
{
|
{
|
||||||
const int3 from = CGHeroInstance::convertPosition(details.start, false),
|
const int3 from = CGHeroInstance::convertPosition(details.start, false),
|
||||||
to = CGHeroInstance::convertPosition(details.end, false);
|
to = CGHeroInstance::convertPosition(details.end, false);
|
||||||
const CGObjectInstance *o1 = frontOrNull(cb->getVisitableObjs(from)),
|
const CGObjectInstance *o1 = vstd::frontOrNull(cb->getVisitableObjs(from)),
|
||||||
*o2 = frontOrNull(cb->getVisitableObjs(to));
|
*o2 = vstd::frontOrNull(cb->getVisitableObjs(to));
|
||||||
|
|
||||||
auto t1 = dynamic_cast<const CGTeleport *>(o1);
|
auto t1 = dynamic_cast<const CGTeleport *>(o1);
|
||||||
auto t2 = dynamic_cast<const CGTeleport *>(o2);
|
auto t2 = dynamic_cast<const CGTeleport *>(o2);
|
||||||
@ -394,8 +392,8 @@ void VCAI::objectRemoved(const CGObjectInstance *obj)
|
|||||||
LOG_TRACE(logAi);
|
LOG_TRACE(logAi);
|
||||||
NET_EVENT_HANDLER;
|
NET_EVENT_HANDLER;
|
||||||
|
|
||||||
erase_if_present(visitableObjs, obj);
|
vstd::erase_if_present(visitableObjs, obj);
|
||||||
erase_if_present(alreadyVisited, obj);
|
vstd::erase_if_present(alreadyVisited, obj);
|
||||||
|
|
||||||
for (auto h : cb->getHeroesInfo())
|
for (auto h : cb->getHeroesInfo())
|
||||||
unreserveObject(h, obj);
|
unreserveObject(h, obj);
|
||||||
@ -518,7 +516,7 @@ void VCAI::objectPropertyChanged(const SetObjectProperty * sop)
|
|||||||
{
|
{
|
||||||
//we don't want to visit know object twice (do we really?)
|
//we don't want to visit know object twice (do we really?)
|
||||||
if(sop->val == playerID.getNum())
|
if(sop->val == playerID.getNum())
|
||||||
erase_if_present(visitableObjs, myCb->getObj(sop->id));
|
vstd::erase_if_present(visitableObjs, myCb->getObj(sop->id));
|
||||||
else if(myCb->getPlayerRelations(playerID, (PlayerColor)sop->val) == PlayerRelations::ENEMIES)
|
else if(myCb->getPlayerRelations(playerID, (PlayerColor)sop->val) == PlayerRelations::ENEMIES)
|
||||||
{
|
{
|
||||||
//we want to visit objects owned by oppponents
|
//we want to visit objects owned by oppponents
|
||||||
@ -526,7 +524,7 @@ void VCAI::objectPropertyChanged(const SetObjectProperty * sop)
|
|||||||
if (obj)
|
if (obj)
|
||||||
{
|
{
|
||||||
addVisitableObj(obj);
|
addVisitableObj(obj);
|
||||||
erase_if_present(alreadyVisited, obj);
|
vstd::erase_if_present(alreadyVisited, obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -557,7 +555,7 @@ void VCAI::showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions)
|
|||||||
NET_EVENT_HANDLER;
|
NET_EVENT_HANDLER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCAI::init(shared_ptr<CCallback> CB)
|
void VCAI::init(std::shared_ptr<CCallback> CB)
|
||||||
{
|
{
|
||||||
LOG_TRACE(logAi);
|
LOG_TRACE(logAi);
|
||||||
myCb = CB;
|
myCb = CB;
|
||||||
@ -738,7 +736,7 @@ void VCAI::makeTurn()
|
|||||||
if (isWeeklyRevisitable(obj))
|
if (isWeeklyRevisitable(obj))
|
||||||
{
|
{
|
||||||
addVisitableObj(obj);
|
addVisitableObj(obj);
|
||||||
erase_if_present (alreadyVisited, obj);
|
vstd::erase_if_present(alreadyVisited, obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -945,7 +943,7 @@ bool VCAI::canGetArmy (const CGHeroInstance * army, const CGHeroInstance * sourc
|
|||||||
if(armyPtr->getCreature(SlotID(j)) == bestArmy[i] && armyPtr != army) //it's a searched creature not in dst ARMY
|
if(armyPtr->getCreature(SlotID(j)) == bestArmy[i] && armyPtr != army) //it's a searched creature not in dst ARMY
|
||||||
{
|
{
|
||||||
//FIXME: line below is useless when simulating exchange between two non-singular armies
|
//FIXME: line below is useless when simulating exchange between two non-singular armies
|
||||||
if (!(armyPtr->needsLastStack() && armyPtr->Slots().size() == 1)) //can't take away last creature
|
if(!(armyPtr->needsLastStack() && armyPtr->stacksCount() == 1)) //can't take away last creature
|
||||||
return true; //at least one exchange will be performed
|
return true; //at least one exchange will be performed
|
||||||
else
|
else
|
||||||
return false; //no further exchange possible
|
return false; //no further exchange possible
|
||||||
@ -992,7 +990,7 @@ void VCAI::pickBestCreatures(const CArmedInstance * army, const CArmedInstance *
|
|||||||
for (int j = 0; j < GameConstants::ARMY_SIZE; j++)
|
for (int j = 0; j < GameConstants::ARMY_SIZE; j++)
|
||||||
{
|
{
|
||||||
if(armyPtr->getCreature(SlotID(j)) == bestArmy[i] && (i != j || armyPtr != army)) //it's a searched creature not in dst SLOT
|
if(armyPtr->getCreature(SlotID(j)) == bestArmy[i] && (i != j || armyPtr != army)) //it's a searched creature not in dst SLOT
|
||||||
if (!(armyPtr->needsLastStack() && armyPtr->Slots().size() == 1)) //can't take away last creature
|
if(!(armyPtr->needsLastStack() && armyPtr->stacksCount() == 1)) //can't take away last creature
|
||||||
cb->mergeOrSwapStacks(armyPtr, army, SlotID(j), SlotID(i));
|
cb->mergeOrSwapStacks(armyPtr, army, SlotID(j), SlotID(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1052,6 +1050,9 @@ void VCAI::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance * ot
|
|||||||
if (location.relatedObj() == target && location.slot < ArtifactPosition::AFTER_LAST)
|
if (location.relatedObj() == target && location.slot < ArtifactPosition::AFTER_LAST)
|
||||||
continue; //don't reequip artifact we already wear
|
continue; //don't reequip artifact we already wear
|
||||||
|
|
||||||
|
if(location.slot == ArtifactPosition::MACH4) // don't attempt to move catapult
|
||||||
|
continue;
|
||||||
|
|
||||||
auto s = location.getSlot();
|
auto s = location.getSlot();
|
||||||
if (!s || s->locked) //we can't move locks
|
if (!s || s->locked) //we can't move locks
|
||||||
continue;
|
continue;
|
||||||
@ -1118,7 +1119,7 @@ void VCAI::recruitCreatures(const CGDwelling * d, const CArmedInstance * recruit
|
|||||||
// if(containsSavedRes(c->cost))
|
// if(containsSavedRes(c->cost))
|
||||||
// continue;
|
// continue;
|
||||||
|
|
||||||
amin(count, freeResources() / VLC->creh->creatures[creID]->cost);
|
vstd::amin(count, freeResources() / VLC->creh->creatures[creID]->cost);
|
||||||
if(count > 0)
|
if(count > 0)
|
||||||
cb->recruitCreatures(d, recruiter, creID, count, i);
|
cb->recruitCreatures(d, recruiter, creID, count, i);
|
||||||
}
|
}
|
||||||
@ -1445,7 +1446,7 @@ bool VCAI::canRecruitAnyHero (const CGTownInstance * t) const
|
|||||||
if (!t)
|
if (!t)
|
||||||
t = findTownWithTavern();
|
t = findTownWithTavern();
|
||||||
if (t)
|
if (t)
|
||||||
return cb->getResourceAmount(Res::GOLD) >= HERO_GOLD_COST &&
|
return cb->getResourceAmount(Res::GOLD) >= GameConstants::HERO_GOLD_COST &&
|
||||||
cb->getHeroesInfo().size() < ALLOWED_ROAMING_HEROES &&
|
cb->getHeroesInfo().size() < ALLOWED_ROAMING_HEROES &&
|
||||||
cb->getAvailableHeroes(t).size();
|
cb->getAvailableHeroes(t).size();
|
||||||
else
|
else
|
||||||
@ -1481,7 +1482,7 @@ void VCAI::wander(HeroPtr h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
range::copy(getPossibleDestinations(h), std::back_inserter(dests));
|
range::copy(getPossibleDestinations(h), std::back_inserter(dests));
|
||||||
erase_if(dests, [&](ObjectIdRef obj) -> bool
|
vstd::erase_if(dests, [&](ObjectIdRef obj) -> bool
|
||||||
{
|
{
|
||||||
return !isSafeToVisit(h, sm->firstTileToGet(h, obj->visitablePos()));
|
return !isSafeToVisit(h, sm->firstTileToGet(h, obj->visitablePos()));
|
||||||
});
|
});
|
||||||
@ -1530,10 +1531,10 @@ void VCAI::wander(HeroPtr h)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if(cb->getResourceAmount(Res::GOLD) >= HERO_GOLD_COST)
|
else if(cb->getResourceAmount(Res::GOLD) >= GameConstants::HERO_GOLD_COST)
|
||||||
{
|
{
|
||||||
std::vector<const CGTownInstance *> towns = cb->getTownsInfo();
|
std::vector<const CGTownInstance *> towns = cb->getTownsInfo();
|
||||||
erase_if(towns, [](const CGTownInstance *t) -> bool
|
vstd::erase_if(towns, [](const CGTownInstance *t) -> bool
|
||||||
{
|
{
|
||||||
for(const CGHeroInstance *h : cb->getHeroesInfo())
|
for(const CGHeroInstance *h : cb->getHeroesInfo())
|
||||||
if(!t->getArmyStrength() || howManyReinforcementsCanGet(h, t))
|
if(!t->getArmyStrength() || howManyReinforcementsCanGet(h, t))
|
||||||
@ -1585,7 +1586,7 @@ void VCAI::wander(HeroPtr h)
|
|||||||
void VCAI::setGoal(HeroPtr h, Goals::TSubgoal goal)
|
void VCAI::setGoal(HeroPtr h, Goals::TSubgoal goal)
|
||||||
{ //TODO: check for presence?
|
{ //TODO: check for presence?
|
||||||
if(goal->invalid())
|
if(goal->invalid())
|
||||||
erase_if_present(lockedHeroes, h);
|
vstd::erase_if_present(lockedHeroes, h);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lockedHeroes[h] = goal;
|
lockedHeroes[h] = goal;
|
||||||
@ -1626,7 +1627,7 @@ void VCAI::battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int
|
|||||||
NET_EVENT_HANDLER;
|
NET_EVENT_HANDLER;
|
||||||
assert(playerID > PlayerColor::PLAYER_LIMIT || status.getBattle() == UPCOMING_BATTLE);
|
assert(playerID > PlayerColor::PLAYER_LIMIT || status.getBattle() == UPCOMING_BATTLE);
|
||||||
status.setBattle(ONGOING_BATTLE);
|
status.setBattle(ONGOING_BATTLE);
|
||||||
const CGObjectInstance *presumedEnemy = backOrNull(cb->getVisitableObjs(tile)); //may be nullptr in some very are cases -> eg. visited monolith and fighting with an enemy at the FoW covered exit
|
const CGObjectInstance *presumedEnemy = vstd::backOrNull(cb->getVisitableObjs(tile)); //may be nullptr in some very are cases -> eg. visited monolith and fighting with an enemy at the FoW covered exit
|
||||||
battlename = boost::str(boost::format("Starting battle of %s attacking %s at %s") % (hero1 ? hero1->name : "a army") % (presumedEnemy ? presumedEnemy->getObjectName() : "unknown enemy") % tile);
|
battlename = boost::str(boost::format("Starting battle of %s attacking %s at %s") % (hero1 ? hero1->name : "a army") % (presumedEnemy ? presumedEnemy->getObjectName() : "unknown enemy") % tile);
|
||||||
CAdventureAI::battleStart(army1, army2, tile, hero1, hero2, side);
|
CAdventureAI::battleStart(army1, army2, tile, hero1, hero2, side);
|
||||||
}
|
}
|
||||||
@ -1666,8 +1667,8 @@ void VCAI::reserveObject(HeroPtr h, const CGObjectInstance *obj)
|
|||||||
|
|
||||||
void VCAI::unreserveObject(HeroPtr h, const CGObjectInstance *obj)
|
void VCAI::unreserveObject(HeroPtr h, const CGObjectInstance *obj)
|
||||||
{
|
{
|
||||||
erase_if_present(reservedObjs, obj); //unreserve objects
|
vstd::erase_if_present(reservedObjs, obj); //unreserve objects
|
||||||
erase_if_present(reservedHeroesMap[h], obj);
|
vstd::erase_if_present(reservedHeroesMap[h], obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCAI::markHeroUnableToExplore (HeroPtr h)
|
void VCAI::markHeroUnableToExplore (HeroPtr h)
|
||||||
@ -1676,7 +1677,7 @@ void VCAI::markHeroUnableToExplore (HeroPtr h)
|
|||||||
}
|
}
|
||||||
void VCAI::markHeroAbleToExplore (HeroPtr h)
|
void VCAI::markHeroAbleToExplore (HeroPtr h)
|
||||||
{
|
{
|
||||||
erase_if_present(heroesUnableToExplore, h);
|
vstd::erase_if_present(heroesUnableToExplore, h);
|
||||||
}
|
}
|
||||||
bool VCAI::isAbleToExplore (HeroPtr h)
|
bool VCAI::isAbleToExplore (HeroPtr h)
|
||||||
{
|
{
|
||||||
@ -1697,7 +1698,7 @@ void VCAI::validateVisitableObjs()
|
|||||||
auto shouldBeErased = [&](const CGObjectInstance *obj) -> bool
|
auto shouldBeErased = [&](const CGObjectInstance *obj) -> bool
|
||||||
{
|
{
|
||||||
if (obj)
|
if (obj)
|
||||||
return !cb->getObj(obj->id);
|
return !cb->getObj(obj->id, false); // no verbose output needed as we check object visibility
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -1713,25 +1714,25 @@ void VCAI::validateVisitableObjs()
|
|||||||
|
|
||||||
//errorMsg is captured by ref so lambda will take the new text
|
//errorMsg is captured by ref so lambda will take the new text
|
||||||
errorMsg = " shouldn't be on the visitable objects list!";
|
errorMsg = " shouldn't be on the visitable objects list!";
|
||||||
erase_if(visitableObjs, shouldBeErased);
|
vstd::erase_if(visitableObjs, shouldBeErased);
|
||||||
|
|
||||||
//FIXME: how comes our own heroes become inaccessible?
|
//FIXME: how comes our own heroes become inaccessible?
|
||||||
erase_if(reservedHeroesMap, [](std::pair<HeroPtr, std::set<const CGObjectInstance *>> hp) -> bool
|
vstd::erase_if(reservedHeroesMap, [](std::pair<HeroPtr, std::set<const CGObjectInstance *>> hp) -> bool
|
||||||
{
|
{
|
||||||
return !hp.first.get(true);
|
return !hp.first.get(true);
|
||||||
});
|
});
|
||||||
for(auto &p : reservedHeroesMap)
|
for(auto &p : reservedHeroesMap)
|
||||||
{
|
{
|
||||||
errorMsg = " shouldn't be on list for hero " + p.first->name + "!";
|
errorMsg = " shouldn't be on list for hero " + p.first->name + "!";
|
||||||
erase_if(p.second, shouldBeErased);
|
vstd::erase_if(p.second, shouldBeErased);
|
||||||
}
|
}
|
||||||
|
|
||||||
errorMsg = " shouldn't be on the reserved objs list!";
|
errorMsg = " shouldn't be on the reserved objs list!";
|
||||||
erase_if(reservedObjs, shouldBeErased);
|
vstd::erase_if(reservedObjs, shouldBeErased);
|
||||||
|
|
||||||
//TODO overkill, hidden object should not be removed. However, we can't know if hidden object is erased from game.
|
//TODO overkill, hidden object should not be removed. However, we can't know if hidden object is erased from game.
|
||||||
errorMsg = " shouldn't be on the already visited objs list!";
|
errorMsg = " shouldn't be on the already visited objs list!";
|
||||||
erase_if(alreadyVisited, shouldBeErased);
|
vstd::erase_if(alreadyVisited, shouldBeErased);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCAI::retreiveVisitableObjs(std::vector<const CGObjectInstance *> &out, bool includeOwned /*= false*/) const
|
void VCAI::retreiveVisitableObjs(std::vector<const CGObjectInstance *> &out, bool includeOwned /*= false*/) const
|
||||||
@ -1762,7 +1763,7 @@ std::vector<const CGObjectInstance *> VCAI::getFlaggedObjects() const
|
|||||||
{
|
{
|
||||||
std::vector<const CGObjectInstance *> ret;
|
std::vector<const CGObjectInstance *> ret;
|
||||||
retreiveVisitableObjs(ret, true);
|
retreiveVisitableObjs(ret, true);
|
||||||
erase_if(ret, [](const CGObjectInstance *obj)
|
vstd::erase_if(ret, [](const CGObjectInstance *obj)
|
||||||
{
|
{
|
||||||
return obj->tempOwner != ai->playerID;
|
return obj->tempOwner != ai->playerID;
|
||||||
});
|
});
|
||||||
@ -1784,7 +1785,7 @@ const CGObjectInstance * VCAI::lookForArt(int aid) const
|
|||||||
{
|
{
|
||||||
for(const CGObjectInstance *obj : ai->visitableObjs)
|
for(const CGObjectInstance *obj : ai->visitableObjs)
|
||||||
{
|
{
|
||||||
if(obj->ID == 5 && obj->subID == aid)
|
if(obj->ID == Obj::ARTIFACT && obj->subID == aid)
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1876,6 +1877,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
|||||||
logAi->errorStream() << "Hero " << h->name << " cannot reach " << dst;
|
logAi->errorStream() << "Hero " << h->name << " cannot reach " << dst;
|
||||||
throw goalFulfilledException (sptr(Goals::VisitTile(dst).sethero(h)));
|
throw goalFulfilledException (sptr(Goals::VisitTile(dst).sethero(h)));
|
||||||
}
|
}
|
||||||
|
int i = path.nodes.size()-1;
|
||||||
|
|
||||||
auto getObj = [&](int3 coord, bool ignoreHero)
|
auto getObj = [&](int3 coord, bool ignoreHero)
|
||||||
{
|
{
|
||||||
@ -1885,6 +1887,31 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
|||||||
//return cb->getTile(coord,false)->topVisitableObj(ignoreHero);
|
//return cb->getTile(coord,false)->topVisitableObj(ignoreHero);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto isTeleportAction = [&](CGPathNode::ENodeAction action) -> bool
|
||||||
|
{
|
||||||
|
if(action != CGPathNode::TELEPORT_NORMAL &&
|
||||||
|
action != CGPathNode::TELEPORT_BLOCKING_VISIT &&
|
||||||
|
action != CGPathNode::TELEPORT_BATTLE)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto getDestTeleportObj = [&](const CGObjectInstance * currentObject, const CGObjectInstance * nextObjectTop, const CGObjectInstance * nextObject) -> const CGObjectInstance *
|
||||||
|
{
|
||||||
|
if(CGTeleport::isConnected(currentObject, nextObjectTop))
|
||||||
|
return nextObjectTop;
|
||||||
|
if(nextObjectTop && nextObjectTop->ID == Obj::HERO &&
|
||||||
|
CGTeleport::isConnected(currentObject, nextObject))
|
||||||
|
{
|
||||||
|
return nextObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
auto doMovement = [&](int3 dst, bool transit)
|
auto doMovement = [&](int3 dst, bool transit)
|
||||||
{
|
{
|
||||||
cb->moveHero(*h, CGHeroInstance::convertPosition(dst, true), transit);
|
cb->moveHero(*h, CGHeroInstance::convertPosition(dst, true), transit);
|
||||||
@ -1915,17 +1942,18 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
|||||||
doTeleportMovement(currentExit, currentPos);
|
doTeleportMovement(currentExit, currentPos);
|
||||||
};
|
};
|
||||||
|
|
||||||
int i=path.nodes.size()-1;
|
|
||||||
for(; i>0; i--)
|
for(; i>0; i--)
|
||||||
{
|
{
|
||||||
int3 currentCoord = path.nodes[i].coord;
|
int3 currentCoord = path.nodes[i].coord;
|
||||||
int3 nextCoord = path.nodes[i-1].coord;
|
int3 nextCoord = path.nodes[i-1].coord;
|
||||||
|
|
||||||
auto currentObject = getObj(currentCoord, currentCoord == CGHeroInstance::convertPosition(h->pos,false));
|
auto currentObject = getObj(currentCoord, currentCoord == CGHeroInstance::convertPosition(h->pos,false));
|
||||||
auto nextObject = getObj(nextCoord, false);
|
auto nextObjectTop = getObj(nextCoord, false);
|
||||||
if(CGTeleport::isConnected(currentObject, nextObject))
|
auto nextObject = getObj(nextCoord, true);
|
||||||
|
auto destTeleportObj = getDestTeleportObj(currentObject, nextObjectTop, nextObject);
|
||||||
|
if(isTeleportAction(path.nodes[i-1].action) && destTeleportObj != nullptr)
|
||||||
{ //we use special login if hero standing on teleporter it's mean we need
|
{ //we use special login if hero standing on teleporter it's mean we need
|
||||||
doTeleportMovement(nextObject->id, nextCoord);
|
doTeleportMovement(destTeleportObj->id, nextCoord);
|
||||||
if(teleportChannelProbingList.size())
|
if(teleportChannelProbingList.size())
|
||||||
doChannelProbing();
|
doChannelProbing();
|
||||||
|
|
||||||
@ -1944,8 +1972,8 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if((i-2 >= 0) // Check there is node after next one; otherwise transit is pointless
|
if((i-2 >= 0) // Check there is node after next one; otherwise transit is pointless
|
||||||
&& (CGTeleport::isConnected(nextObject, getObj(path.nodes[i-2].coord, false))
|
&& (CGTeleport::isConnected(nextObjectTop, getObj(path.nodes[i-2].coord, false))
|
||||||
|| CGTeleport::isTeleport(nextObject)))
|
|| CGTeleport::isTeleport(nextObjectTop)))
|
||||||
{ // Hero should be able to go through object if it's allow transit
|
{ // Hero should be able to go through object if it's allow transit
|
||||||
doMovement(endpos, true);
|
doMovement(endpos, true);
|
||||||
}
|
}
|
||||||
@ -1963,7 +1991,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
|||||||
}
|
}
|
||||||
if (h)
|
if (h)
|
||||||
{
|
{
|
||||||
if (auto visitedObject = frontOrNull(cb->getVisitableObjs(h->visitablePos()))) //we stand on something interesting
|
if(auto visitedObject = vstd::frontOrNull(cb->getVisitableObjs(h->visitablePos()))) //we stand on something interesting
|
||||||
{
|
{
|
||||||
if (visitedObject != *h)
|
if (visitedObject != *h)
|
||||||
performObjectInteraction (visitedObject, h);
|
performObjectInteraction (visitedObject, h);
|
||||||
@ -1976,14 +2004,14 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
|||||||
|
|
||||||
if(!ret) //reserve object we are heading towards
|
if(!ret) //reserve object we are heading towards
|
||||||
{
|
{
|
||||||
auto obj = frontOrNull(cb->getVisitableObjs(dst));
|
auto obj = vstd::frontOrNull(cb->getVisitableObjs(dst));
|
||||||
if(obj && obj != *h)
|
if(obj && obj != *h)
|
||||||
reserveObject(h, obj);
|
reserveObject(h, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(startHpos == h->visitablePos() && !ret) //we didn't move and didn't reach the target
|
if(startHpos == h->visitablePos() && !ret) //we didn't move and didn't reach the target
|
||||||
{
|
{
|
||||||
erase_if_present (lockedHeroes, h); //hero seemingly is confused
|
vstd::erase_if_present(lockedHeroes, h); //hero seemingly is confused
|
||||||
throw cannotFulfillGoalException("Invalid path found!"); //FIXME: should never happen
|
throw cannotFulfillGoalException("Invalid path found!"); //FIXME: should never happen
|
||||||
}
|
}
|
||||||
logAi->debugStream() << boost::format("Hero %s moved from %s to %s. Returning %d.") % h->name % startHpos % h->visitablePos() % ret;
|
logAi->debugStream() << boost::format("Hero %s moved from %s to %s. Returning %d.") % h->name % startHpos % h->visitablePos() % ret;
|
||||||
@ -2290,7 +2318,7 @@ Goals::TSubgoal VCAI::striveToGoalInternal(Goals::TSubgoal ultimateGoal, bool on
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
erase_if_present (lockedHeroes, goal->hero); // we seemingly don't know what to do with hero
|
vstd::erase_if_present (lockedHeroes, goal->hero); // we seemingly don't know what to do with hero
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2545,7 +2573,7 @@ int3 VCAI::explorationNewPoint(HeroPtr h)
|
|||||||
for (int i = 1; i < radius; i++)
|
for (int i = 1; i < radius; i++)
|
||||||
{
|
{
|
||||||
getVisibleNeighbours(tiles[i-1], tiles[i]);
|
getVisibleNeighbours(tiles[i-1], tiles[i]);
|
||||||
removeDuplicates(tiles[i]);
|
vstd::removeDuplicates(tiles[i]);
|
||||||
|
|
||||||
for(const int3 &tile : tiles[i])
|
for(const int3 &tile : tiles[i])
|
||||||
{
|
{
|
||||||
@ -2593,7 +2621,7 @@ int3 VCAI::explorationDesperate(HeroPtr h)
|
|||||||
for(int i = 1; i < radius; i++)
|
for(int i = 1; i < radius; i++)
|
||||||
{
|
{
|
||||||
getVisibleNeighbours(tiles[i-1], tiles[i]);
|
getVisibleNeighbours(tiles[i-1], tiles[i]);
|
||||||
removeDuplicates(tiles[i]);
|
vstd::removeDuplicates(tiles[i]);
|
||||||
|
|
||||||
for(const int3 &tile : tiles[i])
|
for(const int3 &tile : tiles[i])
|
||||||
{
|
{
|
||||||
@ -2705,37 +2733,26 @@ void VCAI::finish()
|
|||||||
|
|
||||||
void VCAI::requestActionASAP(std::function<void()> whatToDo)
|
void VCAI::requestActionASAP(std::function<void()> whatToDo)
|
||||||
{
|
{
|
||||||
boost::mutex mutex;
|
boost::thread newThread([this,whatToDo]()
|
||||||
mutex.lock();
|
|
||||||
|
|
||||||
boost::thread newThread([&mutex,this,whatToDo]()
|
|
||||||
{
|
{
|
||||||
setThreadName("VCAI::requestActionASAP::helper");
|
setThreadName("VCAI::requestActionASAP::whatToDo");
|
||||||
SET_GLOBAL_STATE(this);
|
SET_GLOBAL_STATE(this);
|
||||||
boost::shared_lock<boost::shared_mutex> gsLock(cb->getGsMutex());
|
boost::shared_lock<boost::shared_mutex> gsLock(cb->getGsMutex());
|
||||||
// unlock mutex and allow parent function to exit
|
|
||||||
mutex.unlock();
|
|
||||||
whatToDo();
|
whatToDo();
|
||||||
});
|
});
|
||||||
|
|
||||||
// wait for mutex to unlock and for thread to initialize properly
|
|
||||||
mutex.lock();
|
|
||||||
|
|
||||||
// unlock mutex - boost dislikes destruction of locked mutexes
|
|
||||||
mutex.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCAI::lostHero(HeroPtr h)
|
void VCAI::lostHero(HeroPtr h)
|
||||||
{
|
{
|
||||||
logAi->debugStream() << boost::format("I lost my hero %s. It's best to forget and move on.") % h.name;
|
logAi->debugStream() << boost::format("I lost my hero %s. It's best to forget and move on.") % h.name;
|
||||||
|
|
||||||
erase_if_present(lockedHeroes, h);
|
vstd::erase_if_present(lockedHeroes, h);
|
||||||
for(auto obj : reservedHeroesMap[h])
|
for(auto obj : reservedHeroesMap[h])
|
||||||
{
|
{
|
||||||
erase_if_present(reservedObjs, obj); //unreserve all objects for that hero
|
vstd::erase_if_present(reservedObjs, obj); //unreserve all objects for that hero
|
||||||
}
|
}
|
||||||
erase_if_present(reservedHeroesMap, h);
|
vstd::erase_if_present(reservedHeroesMap, h);
|
||||||
erase_if_present(cachedSectorMaps, h);
|
vstd::erase_if_present(cachedSectorMaps, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCAI::answerQuery(QueryID queryID, int selection)
|
void VCAI::answerQuery(QueryID queryID, int selection)
|
||||||
@ -2779,12 +2796,12 @@ void VCAI::validateObject(ObjectIdRef obj)
|
|||||||
auto matchesId = [&](const CGObjectInstance *hlpObj) -> bool { return hlpObj->id == obj.id; };
|
auto matchesId = [&](const CGObjectInstance *hlpObj) -> bool { return hlpObj->id == obj.id; };
|
||||||
if(!obj)
|
if(!obj)
|
||||||
{
|
{
|
||||||
erase_if(visitableObjs, matchesId);
|
vstd::erase_if(visitableObjs, matchesId);
|
||||||
|
|
||||||
for(auto &p : reservedHeroesMap)
|
for(auto &p : reservedHeroesMap)
|
||||||
erase_if(p.second, matchesId);
|
vstd::erase_if(p.second, matchesId);
|
||||||
|
|
||||||
erase_if(reservedObjs, matchesId);
|
vstd::erase_if(reservedObjs, matchesId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3062,7 +3079,7 @@ void SectorMap::exploreNewSector(crint3 pos, int num, CCallback * cbp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removeDuplicates(s.embarkmentPoints);
|
vstd::removeDuplicates(s.embarkmentPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SectorMap::write(crstring fname)
|
void SectorMap::write(crstring fname)
|
||||||
@ -3241,21 +3258,6 @@ For ship construction etc, another function (goal?) is needed
|
|||||||
sectorQueue.push(neigh);
|
sectorQueue.push(neigh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto gate : s->subterraneanGates)
|
|
||||||
{
|
|
||||||
auto gatePair = ai->knownSubterraneanGates.find(gate);
|
|
||||||
if (gatePair != ai->knownSubterraneanGates.end())
|
|
||||||
{
|
|
||||||
//check the other side of gate
|
|
||||||
Sector *neigh = &infoOnSectors[retreiveTile(gatePair->second->visitablePos())];
|
|
||||||
if(!preds[neigh]) //if we didn't come into this sector yet
|
|
||||||
{
|
|
||||||
preds[neigh] = s; //it becomes our new target sector
|
|
||||||
sectorQueue.push(neigh);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!preds[dest])
|
if(!preds[dest])
|
||||||
@ -3361,30 +3363,8 @@ For ship construction etc, another function (goal?) is needed
|
|||||||
//disembark
|
//disembark
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
else //use subterranean gates
|
else //use subterranean gates - not needed since gates are now handled via Pathfinder
|
||||||
{
|
{
|
||||||
//auto t = findFirstVisitableTile (h, dst);
|
|
||||||
//if (t.valid())
|
|
||||||
// return t;
|
|
||||||
|
|
||||||
//TODO: pop sectors linked by Subterranean Gate in loop
|
|
||||||
|
|
||||||
auto firstGate = boost::find_if(src->subterraneanGates, [=](const CGObjectInstance * gate) -> bool
|
|
||||||
{
|
|
||||||
//make sure no hero block the way
|
|
||||||
auto pos = ai->knownSubterraneanGates[gate]->visitablePos();
|
|
||||||
const TerrainTile *t = getTile(pos);
|
|
||||||
return t && t->visitableObjects.size() == 1 && t->topVisitableId() == Obj::SUBTERRANEAN_GATE
|
|
||||||
&& retreiveTile(pos) == sectorToReach->id;
|
|
||||||
});
|
|
||||||
|
|
||||||
if(firstGate != src->subterraneanGates.end())
|
|
||||||
{
|
|
||||||
//TODO: pahtfinder can find path through subterranean gates, but this function only reaches closest gate
|
|
||||||
return (*firstGate)->visitablePos();
|
|
||||||
}
|
|
||||||
//TODO
|
|
||||||
//Monolith? Whirlpool? ...
|
|
||||||
return ret;
|
return ret;
|
||||||
//throw cannotFulfillGoalException("Land-land and water-water inter-sector transitions are not implemented!");
|
//throw cannotFulfillGoalException("Land-land and water-water inter-sector transitions are not implemented!");
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ struct SectorMap
|
|||||||
//std::vector<std::vector<std::vector<unsigned char>>> pathfinderSector;
|
//std::vector<std::vector<std::vector<unsigned char>>> pathfinderSector;
|
||||||
|
|
||||||
std::map<int, Sector> infoOnSectors;
|
std::map<int, Sector> infoOnSectors;
|
||||||
shared_ptr<boost::multi_array<TerrainTile*, 3>> visibleTiles;
|
std::shared_ptr<boost::multi_array<TerrainTile*, 3>> visibleTiles;
|
||||||
|
|
||||||
SectorMap();
|
SectorMap();
|
||||||
SectorMap(HeroPtr h);
|
SectorMap(HeroPtr h);
|
||||||
@ -129,7 +129,7 @@ public:
|
|||||||
|
|
||||||
friend class FuzzyHelper;
|
friend class FuzzyHelper;
|
||||||
|
|
||||||
std::map<TeleportChannelID, shared_ptr<TeleportChannel> > knownTeleportChannels;
|
std::map<TeleportChannelID, std::shared_ptr<TeleportChannel> > knownTeleportChannels;
|
||||||
std::map<const CGObjectInstance *, const CGObjectInstance *> knownSubterraneanGates;
|
std::map<const CGObjectInstance *, const CGObjectInstance *> knownSubterraneanGates;
|
||||||
ObjectInstanceID destinationTeleport;
|
ObjectInstanceID destinationTeleport;
|
||||||
int3 destinationTeleportPos;
|
int3 destinationTeleportPos;
|
||||||
@ -153,9 +153,9 @@ public:
|
|||||||
AIStatus status;
|
AIStatus status;
|
||||||
std::string battlename;
|
std::string battlename;
|
||||||
|
|
||||||
shared_ptr<CCallback> myCb;
|
std::shared_ptr<CCallback> myCb;
|
||||||
|
|
||||||
unique_ptr<boost::thread> makingTurn;
|
std::unique_ptr<boost::thread> makingTurn;
|
||||||
|
|
||||||
VCAI(void);
|
VCAI(void);
|
||||||
~VCAI(void);
|
~VCAI(void);
|
||||||
@ -180,7 +180,7 @@ public:
|
|||||||
|
|
||||||
virtual std::string getBattleAIName() const override;
|
virtual std::string getBattleAIName() const override;
|
||||||
|
|
||||||
virtual void init(shared_ptr<CCallback> CB) override;
|
virtual void init(std::shared_ptr<CCallback> CB) override;
|
||||||
virtual void yourTurn() override;
|
virtual void yourTurn() override;
|
||||||
|
|
||||||
virtual void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID) override; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
|
virtual void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID) override; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
|
||||||
|
@ -23,7 +23,7 @@ extern "C" DLL_EXPORT void GetAiName(char* name)
|
|||||||
strcpy_s(name, strlen(g_cszAiName) + 1, g_cszAiName);
|
strcpy_s(name, strlen(g_cszAiName) + 1, g_cszAiName);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" DLL_EXPORT void GetNewAI(shared_ptr<CGlobalAI> &out)
|
extern "C" DLL_EXPORT void GetNewAI(std::shared_ptr<CGlobalAI> &out)
|
||||||
{
|
{
|
||||||
out = make_shared<VCAI>();
|
out = std::make_shared<VCAI>();
|
||||||
}
|
}
|
||||||
|
2
AUTHORS
2
AUTHORS
@ -52,5 +52,5 @@ Alexey aka Macron1Robot, <>
|
|||||||
Alexander Shishkin aka alexvins,
|
Alexander Shishkin aka alexvins,
|
||||||
* MinGW platform support, modding related programming
|
* MinGW platform support, modding related programming
|
||||||
|
|
||||||
Arseniy Shestakov aka SXX,
|
Arseniy Shestakov aka SXX, <me@arseniyshestakov.com>
|
||||||
* pathfinding improvements, programming
|
* pathfinding improvements, programming
|
||||||
|
@ -333,22 +333,22 @@ int CCallback::mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance
|
|||||||
return swapCreatures(s1, s2, p1, p2);
|
return swapCreatures(s1, s2, p1, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCallback::registerGameInterface(shared_ptr<IGameEventsReceiver> gameEvents)
|
void CCallback::registerGameInterface(std::shared_ptr<IGameEventsReceiver> gameEvents)
|
||||||
{
|
{
|
||||||
cl->additionalPlayerInts[*player].push_back(gameEvents);
|
cl->additionalPlayerInts[*player].push_back(gameEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCallback::registerBattleInterface(shared_ptr<IBattleEventsReceiver> battleEvents)
|
void CCallback::registerBattleInterface(std::shared_ptr<IBattleEventsReceiver> battleEvents)
|
||||||
{
|
{
|
||||||
cl->additionalBattleInts[*player].push_back(battleEvents);
|
cl->additionalBattleInts[*player].push_back(battleEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCallback::unregisterGameInterface(shared_ptr<IGameEventsReceiver> gameEvents)
|
void CCallback::unregisterGameInterface(std::shared_ptr<IGameEventsReceiver> gameEvents)
|
||||||
{
|
{
|
||||||
cl->additionalPlayerInts[*player] -= gameEvents;
|
cl->additionalPlayerInts[*player] -= gameEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCallback::unregisterBattleInterface(shared_ptr<IBattleEventsReceiver> battleEvents)
|
void CCallback::unregisterBattleInterface(std::shared_ptr<IBattleEventsReceiver> battleEvents)
|
||||||
{
|
{
|
||||||
cl->additionalBattleInts[*player] -= battleEvents;
|
cl->additionalBattleInts[*player] -= battleEvents;
|
||||||
}
|
}
|
||||||
|
@ -110,10 +110,10 @@ public:
|
|||||||
virtual void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out);
|
virtual void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out);
|
||||||
|
|
||||||
//Set of metrhods that allows adding more interfaces for this player that'll receive game event call-ins.
|
//Set of metrhods that allows adding more interfaces for this player that'll receive game event call-ins.
|
||||||
void registerGameInterface(shared_ptr<IGameEventsReceiver> gameEvents);
|
void registerGameInterface(std::shared_ptr<IGameEventsReceiver> gameEvents);
|
||||||
void registerBattleInterface(shared_ptr<IBattleEventsReceiver> battleEvents);
|
void registerBattleInterface(std::shared_ptr<IBattleEventsReceiver> battleEvents);
|
||||||
void unregisterGameInterface(shared_ptr<IGameEventsReceiver> gameEvents);
|
void unregisterGameInterface(std::shared_ptr<IGameEventsReceiver> gameEvents);
|
||||||
void unregisterBattleInterface(shared_ptr<IBattleEventsReceiver> battleEvents);
|
void unregisterBattleInterface(std::shared_ptr<IBattleEventsReceiver> battleEvents);
|
||||||
|
|
||||||
void unregisterAllInterfaces(); //stops delivering information about game events to player interfaces -> can be called ONLY after victory/loss
|
void unregisterAllInterfaces(); //stops delivering information about game events to player interfaces -> can be called ONLY after victory/loss
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ endif()
|
|||||||
if (WIN32)
|
if (WIN32)
|
||||||
add_definitions(-DBOOST_THREAD_USE_LIB)
|
add_definitions(-DBOOST_THREAD_USE_LIB)
|
||||||
add_definitions(-D_WIN32_WINNT=0x0501)
|
add_definitions(-D_WIN32_WINNT=0x0501)
|
||||||
set(SYSTEM_LIBS ${SYSTEM_LIBS} ole32 oleaut32 ws2_32 mswsock)
|
set(SYSTEM_LIBS ${SYSTEM_LIBS} ole32 oleaut32 ws2_32 mswsock dbghelp)
|
||||||
|
|
||||||
#delete lib prefix for dlls (libvcmi -> vcmi)
|
#delete lib prefix for dlls (libvcmi -> vcmi)
|
||||||
set(CMAKE_SHARED_LIBRARY_PREFIX "")
|
set(CMAKE_SHARED_LIBRARY_PREFIX "")
|
||||||
|
4
Global.h
4
Global.h
@ -93,6 +93,7 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
|
|||||||
#ifdef VCMI_WINDOWS
|
#ifdef VCMI_WINDOWS
|
||||||
# define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers - delete this line if something is missing.
|
# define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers - delete this line if something is missing.
|
||||||
# define NOMINMAX // Exclude min/max macros from <Windows.h>. Use std::[min/max] from <algorithm> instead.
|
# define NOMINMAX // Exclude min/max macros from <Windows.h>. Use std::[min/max] from <algorithm> instead.
|
||||||
|
# define _NO_W32_PSEUDO_MODIFIERS // Exclude more macros for compiling with MinGW on Linux.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------- */
|
||||||
@ -179,9 +180,6 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
|
|||||||
/* ---------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------- */
|
||||||
/* Usings */
|
/* Usings */
|
||||||
/* ---------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------- */
|
||||||
using std::shared_ptr;
|
|
||||||
using std::unique_ptr;
|
|
||||||
using std::make_shared;
|
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
namespace range = boost::range;
|
namespace range = boost::range;
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ static void prog_version(void)
|
|||||||
static void prog_help(const po::options_description &opts)
|
static void prog_help(const po::options_description &opts)
|
||||||
{
|
{
|
||||||
printf("%s - A Heroes of Might and Magic 3 clone\n", GameConstants::VCMI_VERSION.c_str());
|
printf("%s - A Heroes of Might and Magic 3 clone\n", GameConstants::VCMI_VERSION.c_str());
|
||||||
printf("Copyright (C) 2007-2014 VCMI dev team - see AUTHORS file\n");
|
printf("Copyright (C) 2007-2016 VCMI dev team - see AUTHORS file\n");
|
||||||
printf("This is free software; see the source for copying conditions. There is NO\n");
|
printf("This is free software; see the source for copying conditions. There is NO\n");
|
||||||
printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
|
printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@ -244,7 +244,9 @@ int main(int argc, char** argv)
|
|||||||
("loadhumanplayerindices",po::value<std::vector<int>>(),"Indexes of human players (0=Red, etc.)")
|
("loadhumanplayerindices",po::value<std::vector<int>>(),"Indexes of human players (0=Red, etc.)")
|
||||||
("loadplayer", po::value<int>(),"specifies which player we are in multiplayer loaded games (0=Red, etc.)")
|
("loadplayer", po::value<int>(),"specifies which player we are in multiplayer loaded games (0=Red, etc.)")
|
||||||
("loadserverip",po::value<std::string>(),"IP for loaded game server")
|
("loadserverip",po::value<std::string>(),"IP for loaded game server")
|
||||||
("loadserverport",po::value<std::string>(),"port for loaded game server");
|
("loadserverport",po::value<std::string>(),"port for loaded game server")
|
||||||
|
("testingport",po::value<std::string>(),"port for testing, override specified in config file")
|
||||||
|
("testingfileprefix",po::value<std::string>(),"prefix for auto save files");
|
||||||
|
|
||||||
if(argc > 1)
|
if(argc > 1)
|
||||||
{
|
{
|
||||||
@ -299,6 +301,15 @@ int main(int argc, char** argv)
|
|||||||
preinitDLL(::console);
|
preinitDLL(::console);
|
||||||
settings.init();
|
settings.init();
|
||||||
|
|
||||||
|
// Init special testing settings
|
||||||
|
Settings testingSettings = settings.write["testing"];
|
||||||
|
if(vm.count("testingport") && vm.count("testingfileprefix"))
|
||||||
|
{
|
||||||
|
testingSettings["enabled"].Bool() = true;
|
||||||
|
testingSettings["port"].String() = vm["testingport"].as<std::string>();
|
||||||
|
testingSettings["prefix"].String() = vm["testingfileprefix"].as<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize logging based on settings
|
// Initialize logging based on settings
|
||||||
logConfig.configure();
|
logConfig.configure();
|
||||||
|
|
||||||
@ -314,7 +325,9 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
if (!testFile("DATA/HELP.TXT", "Heroes III data") ||
|
if (!testFile("DATA/HELP.TXT", "Heroes III data") ||
|
||||||
!testFile("MODS/VCMI/MOD.JSON", "VCMI data"))
|
!testFile("MODS/VCMI/MOD.JSON", "VCMI data"))
|
||||||
|
{
|
||||||
exit(1); // These are unrecoverable errors
|
exit(1); // These are unrecoverable errors
|
||||||
|
}
|
||||||
|
|
||||||
// these two are optional + some installs have them on CD and not in data directory
|
// these two are optional + some installs have them on CD and not in data directory
|
||||||
testFile("VIDEO/GOOD1A.SMK", "campaign movies");
|
testFile("VIDEO/GOOD1A.SMK", "campaign movies");
|
||||||
|
@ -349,7 +349,7 @@ void CMusicHandler::playMusicFromSet(std::string whichSet, int entryID, bool loo
|
|||||||
queueNext(this, "", selectedEntry->second, loop);
|
queueNext(this, "", selectedEntry->second, loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMusicHandler::queueNext(unique_ptr<MusicEntry> queued)
|
void CMusicHandler::queueNext(std::unique_ptr<MusicEntry> queued)
|
||||||
{
|
{
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
return;
|
return;
|
||||||
|
@ -114,11 +114,11 @@ private:
|
|||||||
SettingsListener listener;
|
SettingsListener listener;
|
||||||
void onVolumeChange(const JsonNode &volumeNode);
|
void onVolumeChange(const JsonNode &volumeNode);
|
||||||
|
|
||||||
unique_ptr<MusicEntry> current;
|
std::unique_ptr<MusicEntry> current;
|
||||||
unique_ptr<MusicEntry> next;
|
std::unique_ptr<MusicEntry> next;
|
||||||
|
|
||||||
void queueNext(CMusicHandler *owner, std::string setName, std::string musicURI, bool looped);
|
void queueNext(CMusicHandler *owner, std::string setName, std::string musicURI, bool looped);
|
||||||
void queueNext(unique_ptr<MusicEntry> queued);
|
void queueNext(std::unique_ptr<MusicEntry> queued);
|
||||||
|
|
||||||
std::map<std::string, std::map<int, std::string> > musicsSet;
|
std::map<std::string, std::map<int, std::string> > musicsSet;
|
||||||
public:
|
public:
|
||||||
|
@ -133,7 +133,7 @@ CPlayerInterface::~CPlayerInterface()
|
|||||||
if(LOCPLINT == this)
|
if(LOCPLINT == this)
|
||||||
LOCPLINT = nullptr;
|
LOCPLINT = nullptr;
|
||||||
}
|
}
|
||||||
void CPlayerInterface::init(shared_ptr<CCallback> CB)
|
void CPlayerInterface::init(std::shared_ptr<CCallback> CB)
|
||||||
{
|
{
|
||||||
cb = CB;
|
cb = CB;
|
||||||
if(observerInDuelMode)
|
if(observerInDuelMode)
|
||||||
@ -157,24 +157,30 @@ void CPlayerInterface::yourTurn()
|
|||||||
GH.curInt = this;
|
GH.curInt = this;
|
||||||
adventureInt->selection = nullptr;
|
adventureInt->selection = nullptr;
|
||||||
|
|
||||||
|
std::string prefix = "";
|
||||||
|
if(settings["testing"]["enabled"].Bool())
|
||||||
|
{
|
||||||
|
prefix = settings["testing"]["prefix"].String();
|
||||||
|
}
|
||||||
|
|
||||||
if(firstCall)
|
if(firstCall)
|
||||||
{
|
{
|
||||||
if(howManyPeople == 1)
|
if(howManyPeople == 1)
|
||||||
adventureInt->setPlayer(playerID);
|
adventureInt->setPlayer(playerID);
|
||||||
|
|
||||||
autosaveCount = getLastIndex("Autosave_");
|
autosaveCount = getLastIndex(prefix + "Autosave_");
|
||||||
|
|
||||||
if(firstCall > 0) //new game, not loaded
|
if(firstCall > 0) //new game, not loaded
|
||||||
{
|
{
|
||||||
int index = getLastIndex("Newgame_Autosave_");
|
int index = getLastIndex(prefix + "Newgame_");
|
||||||
index %= SAVES_COUNT;
|
index %= SAVES_COUNT;
|
||||||
cb->save("Saves/Newgame_Autosave_" + boost::lexical_cast<std::string>(index + 1));
|
cb->save("Saves/" + prefix + "Newgame_Autosave_" + boost::lexical_cast<std::string>(index + 1));
|
||||||
}
|
}
|
||||||
firstCall = 0;
|
firstCall = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOCPLINT->cb->save("Saves/Autosave_" + boost::lexical_cast<std::string>(autosaveCount++ + 1));
|
LOCPLINT->cb->save("Saves/" + prefix + "Autosave_" + boost::lexical_cast<std::string>(autosaveCount++ + 1));
|
||||||
autosaveCount %= 5;
|
autosaveCount %= 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2242,8 +2248,10 @@ CGPath * CPlayerInterface::getAndVerifyPath(const CGHeroInstance * h)
|
|||||||
|
|
||||||
void CPlayerInterface::acceptTurn()
|
void CPlayerInterface::acceptTurn()
|
||||||
{
|
{
|
||||||
|
bool centerView = true;
|
||||||
if(settings["session"]["autoSkip"].Bool())
|
if(settings["session"]["autoSkip"].Bool())
|
||||||
{
|
{
|
||||||
|
centerView = false;
|
||||||
while(CInfoWindow *iw = dynamic_cast<CInfoWindow *>(GH.topInt()))
|
while(CInfoWindow *iw = dynamic_cast<CInfoWindow *>(GH.topInt()))
|
||||||
iw->close();
|
iw->close();
|
||||||
}
|
}
|
||||||
@ -2270,10 +2278,10 @@ void CPlayerInterface::acceptTurn()
|
|||||||
//select first hero if available.
|
//select first hero if available.
|
||||||
if(heroToSelect != nullptr)
|
if(heroToSelect != nullptr)
|
||||||
{
|
{
|
||||||
adventureInt->select(heroToSelect);
|
adventureInt->select(heroToSelect, centerView);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
adventureInt->select(towns.front());
|
adventureInt->select(towns.front(), centerView);
|
||||||
|
|
||||||
//show new day animation and sound on infobar
|
//show new day animation and sound on infobar
|
||||||
adventureInt->infoBar.showDate();
|
adventureInt->infoBar.showDate();
|
||||||
@ -2629,6 +2637,31 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path)
|
|||||||
return cb->getTile(CGHeroInstance::convertPosition(coord,false))->topVisitableObj(ignoreHero);
|
return cb->getTile(CGHeroInstance::convertPosition(coord,false))->topVisitableObj(ignoreHero);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto isTeleportAction = [&](CGPathNode::ENodeAction action) -> bool
|
||||||
|
{
|
||||||
|
if(action != CGPathNode::TELEPORT_NORMAL &&
|
||||||
|
action != CGPathNode::TELEPORT_BLOCKING_VISIT &&
|
||||||
|
action != CGPathNode::TELEPORT_BATTLE)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto getDestTeleportObj = [&](const CGObjectInstance * currentObject, const CGObjectInstance * nextObjectTop, const CGObjectInstance * nextObject) -> const CGObjectInstance *
|
||||||
|
{
|
||||||
|
if(CGTeleport::isConnected(currentObject, nextObjectTop))
|
||||||
|
return nextObjectTop;
|
||||||
|
if(nextObjectTop && nextObjectTop->ID == Obj::HERO &&
|
||||||
|
CGTeleport::isConnected(currentObject, nextObject))
|
||||||
|
{
|
||||||
|
return nextObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
boost::unique_lock<boost::mutex> un(stillMoveHero.mx);
|
boost::unique_lock<boost::mutex> un(stillMoveHero.mx);
|
||||||
stillMoveHero.data = CONTINUE_MOVE;
|
stillMoveHero.data = CONTINUE_MOVE;
|
||||||
auto doMovement = [&](int3 dst, bool transit)
|
auto doMovement = [&](int3 dst, bool transit)
|
||||||
@ -2661,13 +2694,21 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path)
|
|||||||
int3 currentCoord = path.nodes[i].coord;
|
int3 currentCoord = path.nodes[i].coord;
|
||||||
int3 nextCoord = path.nodes[i-1].coord;
|
int3 nextCoord = path.nodes[i-1].coord;
|
||||||
|
|
||||||
auto nextObject = getObj(nextCoord, nextCoord == h->pos);
|
auto currentObject = getObj(currentCoord, currentCoord == h->pos);
|
||||||
if(CGTeleport::isConnected(getObj(currentCoord, currentCoord == h->pos), nextObject))
|
auto nextObjectTop = getObj(nextCoord, false);
|
||||||
|
auto nextObject = getObj(nextCoord, true);
|
||||||
|
auto destTeleportObj = getDestTeleportObj(currentObject, nextObjectTop, nextObject);
|
||||||
|
if(isTeleportAction(path.nodes[i-1].action) && destTeleportObj != nullptr)
|
||||||
{
|
{
|
||||||
CCS->soundh->stopSound(sh);
|
CCS->soundh->stopSound(sh);
|
||||||
destinationTeleport = nextObject->id;
|
destinationTeleport = destTeleportObj->id;
|
||||||
destinationTeleportPos = nextCoord;
|
destinationTeleportPos = nextCoord;
|
||||||
doMovement(h->pos, false);
|
doMovement(h->pos, false);
|
||||||
|
if(path.nodes[i-1].action == CGPathNode::TELEPORT_BLOCKING_VISIT)
|
||||||
|
{
|
||||||
|
destinationTeleport = ObjectInstanceID();
|
||||||
|
destinationTeleportPos = int3(-1);
|
||||||
|
}
|
||||||
sh = CCS->soundh->playSound(CCS->soundh->horseSounds[currentTerrain], -1);
|
sh = CCS->soundh->playSound(CCS->soundh->horseSounds[currentTerrain], -1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2700,8 +2741,8 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path)
|
|||||||
|
|
||||||
bool useTransit = false;
|
bool useTransit = false;
|
||||||
if((i-2 >= 0) // Check there is node after next one; otherwise transit is pointless
|
if((i-2 >= 0) // Check there is node after next one; otherwise transit is pointless
|
||||||
&& (CGTeleport::isConnected(nextObject, getObj(path.nodes[i-2].coord, false))
|
&& (CGTeleport::isConnected(nextObjectTop, getObj(path.nodes[i-2].coord, false))
|
||||||
|| CGTeleport::isTeleport(nextObject)))
|
|| CGTeleport::isTeleport(nextObjectTop)))
|
||||||
{ // Hero should be able to go through object if it's allow transit
|
{ // Hero should be able to go through object if it's allow transit
|
||||||
useTransit = true;
|
useTransit = true;
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ public:
|
|||||||
static CBattleInterface * battleInt; //nullptr if no battle
|
static CBattleInterface * battleInt; //nullptr if no battle
|
||||||
CInGameConsole * cingconsole;
|
CInGameConsole * cingconsole;
|
||||||
|
|
||||||
shared_ptr<CCallback> cb; //to communicate with engine
|
std::shared_ptr<CCallback> cb; //to communicate with engine
|
||||||
const BattleAction *curAction; //during the battle - action currently performed by active stack (or nullptr)
|
const BattleAction *curAction; //during the battle - action currently performed by active stack (or nullptr)
|
||||||
|
|
||||||
std::list<CInfoWindow *> dialogs; //queue of dialogs awaiting to be shown (not currently shown!)
|
std::list<CInfoWindow *> dialogs; //queue of dialogs awaiting to be shown (not currently shown!)
|
||||||
@ -116,7 +116,7 @@ public:
|
|||||||
std::vector<const CGHeroInstance *> sleepingHeroes; //if hero is in here, he's sleeping
|
std::vector<const CGHeroInstance *> sleepingHeroes; //if hero is in here, he's sleeping
|
||||||
|
|
||||||
//During battle is quick combat mode is used
|
//During battle is quick combat mode is used
|
||||||
shared_ptr<CBattleGameInterface> autofightingAI; //AI that makes decisions
|
std::shared_ptr<CBattleGameInterface> autofightingAI; //AI that makes decisions
|
||||||
bool isAutoFightOn; //Flag, switch it to stop quick combat. Don't touch if there is no battle interface.
|
bool isAutoFightOn; //Flag, switch it to stop quick combat. Don't touch if there is no battle interface.
|
||||||
|
|
||||||
const CArmedInstance * getSelection();
|
const CArmedInstance * getSelection();
|
||||||
@ -236,7 +236,7 @@ public:
|
|||||||
void openTownWindow(const CGTownInstance * town); //shows townscreen
|
void openTownWindow(const CGTownInstance * town); //shows townscreen
|
||||||
void openHeroWindow(const CGHeroInstance * hero); //shows hero window with given hero
|
void openHeroWindow(const CGHeroInstance * hero); //shows hero window with given hero
|
||||||
void updateInfo(const CGObjectInstance * specific);
|
void updateInfo(const CGObjectInstance * specific);
|
||||||
void init(shared_ptr<CCallback> CB) override;
|
void init(std::shared_ptr<CCallback> CB) override;
|
||||||
int3 repairScreenPos(int3 pos); //returns position closest to pos we can center screen on
|
int3 repairScreenPos(int3 pos); //returns position closest to pos we can center screen on
|
||||||
|
|
||||||
// show dialogs
|
// show dialogs
|
||||||
|
@ -1918,7 +1918,7 @@ const CMapGenOptions & CRandomMapTab::getMapGenOptions() const
|
|||||||
return mapGenOptions;
|
return mapGenOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRandomMapTab::setMapGenOptions(shared_ptr<CMapGenOptions> opts)
|
void CRandomMapTab::setMapGenOptions(std::shared_ptr<CMapGenOptions> opts)
|
||||||
{
|
{
|
||||||
mapSizeBtnGroup->setSelected(vstd::find_pos(getPossibleMapSizes(), opts->getWidth()));
|
mapSizeBtnGroup->setSelected(vstd::find_pos(getPossibleMapSizes(), opts->getWidth()));
|
||||||
twoLevelsBtn->setSelected(opts->getHasTwoLevels());
|
twoLevelsBtn->setSelected(opts->getHasTwoLevels());
|
||||||
@ -3291,14 +3291,14 @@ void CBonusSelection::init()
|
|||||||
sFlags = CDefHandler::giveDef("ITGFLAGS.DEF");
|
sFlags = CDefHandler::giveDef("ITGFLAGS.DEF");
|
||||||
}
|
}
|
||||||
|
|
||||||
CBonusSelection::CBonusSelection(shared_ptr<CCampaignState> _ourCampaign) : ourCampaign(_ourCampaign)
|
CBonusSelection::CBonusSelection(std::shared_ptr<CCampaignState> _ourCampaign) : ourCampaign(_ourCampaign)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
CBonusSelection::CBonusSelection(const std::string & campaignFName)
|
CBonusSelection::CBonusSelection(const std::string & campaignFName)
|
||||||
{
|
{
|
||||||
ourCampaign = make_shared<CCampaignState>(CCampaignHandler::getCampaign(campaignFName));
|
ourCampaign = std::make_shared<CCampaignState>(CCampaignHandler::getCampaign(campaignFName));
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ public:
|
|||||||
CFunctionList<void (const CMapInfo *)> & getMapInfoChanged();
|
CFunctionList<void (const CMapInfo *)> & getMapInfoChanged();
|
||||||
const CMapInfo * getMapInfo() const;
|
const CMapInfo * getMapInfo() const;
|
||||||
const CMapGenOptions & getMapGenOptions() const;
|
const CMapGenOptions & getMapGenOptions() const;
|
||||||
void setMapGenOptions(shared_ptr<CMapGenOptions> opts);
|
void setMapGenOptions(std::shared_ptr<CMapGenOptions> opts);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addButtonsToGroup(CToggleGroup * group, const std::vector<std::string> & defs, int startIndex, int endIndex, int btnWidth, int helpStartIndex) const;
|
void addButtonsToGroup(CToggleGroup * group, const std::vector<std::string> & defs, int startIndex, int endIndex, int btnWidth, int helpStartIndex) const;
|
||||||
@ -316,7 +316,7 @@ private:
|
|||||||
* compOnlyTeamsCntGroup, * waterContentGroup, * monsterStrengthGroup;
|
* compOnlyTeamsCntGroup, * waterContentGroup, * monsterStrengthGroup;
|
||||||
CButton * showRandMaps;
|
CButton * showRandMaps;
|
||||||
CMapGenOptions mapGenOptions;
|
CMapGenOptions mapGenOptions;
|
||||||
unique_ptr<CMapInfo> mapInfo;
|
std::unique_ptr<CMapInfo> mapInfo;
|
||||||
CFunctionList<void(const CMapInfo *)> mapInfoChanged;
|
CFunctionList<void(const CMapInfo *)> mapInfoChanged;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -463,7 +463,7 @@ class CBonusSelection : public CIntObject
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CBonusSelection(const std::string & campaignFName);
|
CBonusSelection(const std::string & campaignFName);
|
||||||
CBonusSelection(shared_ptr<CCampaignState> _ourCampaign);
|
CBonusSelection(std::shared_ptr<CCampaignState> _ourCampaign);
|
||||||
~CBonusSelection();
|
~CBonusSelection();
|
||||||
|
|
||||||
void showAll(SDL_Surface * to) override;
|
void showAll(SDL_Surface * to) override;
|
||||||
@ -532,7 +532,7 @@ private:
|
|||||||
CDefHandler * sFlags;
|
CDefHandler * sFlags;
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
shared_ptr<CCampaignState> ourCampaign;
|
std::shared_ptr<CCampaignState> ourCampaign;
|
||||||
int selectedMap;
|
int selectedMap;
|
||||||
boost::optional<int> selectedBonus;
|
boost::optional<int> selectedBonus;
|
||||||
StartInfo startInfo;
|
StartInfo startInfo;
|
||||||
|
@ -247,17 +247,24 @@ void CClient::endGame( bool closeConnection /*= true*/ )
|
|||||||
void CClient::loadGame(const std::string & fname, const bool server, const std::vector<int>& humanplayerindices, const int loadNumPlayers, int player_, const std::string & ipaddr, const std::string & port)
|
void CClient::loadGame(const std::string & fname, const bool server, const std::vector<int>& humanplayerindices, const int loadNumPlayers, int player_, const std::string & ipaddr, const std::string & port)
|
||||||
{
|
{
|
||||||
PlayerColor player(player_); //intentional shadowing
|
PlayerColor player(player_); //intentional shadowing
|
||||||
|
|
||||||
logNetwork->infoStream() << "Loading procedure started!";
|
logNetwork->infoStream() << "Loading procedure started!";
|
||||||
|
|
||||||
|
std::string realPort;
|
||||||
|
if(settings["testing"]["enabled"].Bool())
|
||||||
|
realPort = settings["testing"]["port"].String();
|
||||||
|
else if(port.size())
|
||||||
|
realPort = port;
|
||||||
|
else
|
||||||
|
realPort = boost::lexical_cast<std::string>(settings["server"]["port"].Float());
|
||||||
|
|
||||||
CServerHandler sh;
|
CServerHandler sh;
|
||||||
if(server)
|
if(server)
|
||||||
sh.startServer();
|
sh.startServer();
|
||||||
else
|
else
|
||||||
serv = sh.justConnectToServer(ipaddr,port=="" ? "3030" : port);
|
serv = sh.justConnectToServer(ipaddr, realPort);
|
||||||
|
|
||||||
CStopWatch tmh;
|
CStopWatch tmh;
|
||||||
unique_ptr<CLoadFile> loader;
|
std::unique_ptr<CLoadFile> loader;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::string clientSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::CLIENT_SAVEGAME));
|
std::string clientSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::CLIENT_SAVEGAME));
|
||||||
@ -454,7 +461,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
installNewPlayerInterface(make_shared<CPlayerInterface>(color), color);
|
installNewPlayerInterface(std::make_shared<CPlayerInterface>(color), color);
|
||||||
humanPlayers++;
|
humanPlayers++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -470,7 +477,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
|||||||
if(!gNoGUI)
|
if(!gNoGUI)
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
|
boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
|
||||||
auto p = make_shared<CPlayerInterface>(PlayerColor::NEUTRAL);
|
auto p = std::make_shared<CPlayerInterface>(PlayerColor::NEUTRAL);
|
||||||
p->observerInDuelMode = true;
|
p->observerInDuelMode = true;
|
||||||
installNewPlayerInterface(p, boost::none);
|
installNewPlayerInterface(p, boost::none);
|
||||||
GH.curInt = p.get();
|
GH.curInt = p.get();
|
||||||
@ -535,7 +542,7 @@ void CClient::serialize(CISer & h, const int version)
|
|||||||
h & pid & dllname & isHuman;
|
h & pid & dllname & isHuman;
|
||||||
LOG_TRACE_PARAMS(logGlobal, "Loading player %s interface", pid);
|
LOG_TRACE_PARAMS(logGlobal, "Loading player %s interface", pid);
|
||||||
|
|
||||||
shared_ptr<CGameInterface> nInt;
|
std::shared_ptr<CGameInterface> nInt;
|
||||||
if(dllname.length())
|
if(dllname.length())
|
||||||
{
|
{
|
||||||
if(pid == PlayerColor::NEUTRAL)
|
if(pid == PlayerColor::NEUTRAL)
|
||||||
@ -553,7 +560,7 @@ void CClient::serialize(CISer & h, const int version)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert(isHuman);
|
assert(isHuman);
|
||||||
nInt = make_shared<CPlayerInterface>(pid);
|
nInt = std::make_shared<CPlayerInterface>(pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
nInt->dllName = dllname;
|
nInt->dllName = dllname;
|
||||||
@ -604,7 +611,7 @@ void CClient::serialize(CISer & h, const int version, const std::set<PlayerColor
|
|||||||
h & pid & dllname & isHuman;
|
h & pid & dllname & isHuman;
|
||||||
LOG_TRACE_PARAMS(logGlobal, "Loading player %s interface", pid);
|
LOG_TRACE_PARAMS(logGlobal, "Loading player %s interface", pid);
|
||||||
|
|
||||||
shared_ptr<CGameInterface> nInt;
|
std::shared_ptr<CGameInterface> nInt;
|
||||||
if(dllname.length())
|
if(dllname.length())
|
||||||
{
|
{
|
||||||
if(pid == PlayerColor::NEUTRAL)
|
if(pid == PlayerColor::NEUTRAL)
|
||||||
@ -623,7 +630,7 @@ void CClient::serialize(CISer & h, const int version, const std::set<PlayerColor
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert(isHuman);
|
assert(isHuman);
|
||||||
nInt = make_shared<CPlayerInterface>(pid);
|
nInt = std::make_shared<CPlayerInterface>(pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
nInt->dllName = dllname;
|
nInt->dllName = dllname;
|
||||||
@ -661,11 +668,11 @@ void CClient::handlePack( CPack * pack )
|
|||||||
delete pack;
|
delete pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::finishCampaign( shared_ptr<CCampaignState> camp )
|
void CClient::finishCampaign( std::shared_ptr<CCampaignState> camp )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::proposeNextMission(shared_ptr<CCampaignState> camp)
|
void CClient::proposeNextMission(std::shared_ptr<CCampaignState> camp)
|
||||||
{
|
{
|
||||||
GH.pushInt(new CBonusSelection(camp));
|
GH.pushInt(new CBonusSelection(camp));
|
||||||
}
|
}
|
||||||
@ -717,7 +724,7 @@ void CClient::battleStarted(const BattleInfo * info)
|
|||||||
// if(battleCallbacks.count(side))
|
// if(battleCallbacks.count(side))
|
||||||
// battleCallbacks[side]->setBattle(info);
|
// battleCallbacks[side]->setBattle(info);
|
||||||
|
|
||||||
shared_ptr<CPlayerInterface> att, def;
|
std::shared_ptr<CPlayerInterface> att, def;
|
||||||
auto &leftSide = info->sides[0], &rightSide = info->sides[1];
|
auto &leftSide = info->sides[0], &rightSide = info->sides[1];
|
||||||
|
|
||||||
|
|
||||||
@ -783,7 +790,7 @@ PlayerColor CClient::getLocalPlayer() const
|
|||||||
return getCurrentPlayer();
|
return getCurrentPlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::commenceTacticPhaseForInt(shared_ptr<CBattleGameInterface> battleInt)
|
void CClient::commenceTacticPhaseForInt(std::shared_ptr<CBattleGameInterface> battleInt)
|
||||||
{
|
{
|
||||||
setThreadName("CClient::commenceTacticPhaseForInt");
|
setThreadName("CClient::commenceTacticPhaseForInt");
|
||||||
try
|
try
|
||||||
@ -835,7 +842,7 @@ int CClient::sendRequest(const CPack *request, PlayerColor player)
|
|||||||
return requestID;
|
return requestID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::campaignMapFinished( shared_ptr<CCampaignState> camp )
|
void CClient::campaignMapFinished( std::shared_ptr<CCampaignState> camp )
|
||||||
{
|
{
|
||||||
endGame(false);
|
endGame(false);
|
||||||
|
|
||||||
@ -858,7 +865,7 @@ void CClient::campaignMapFinished( shared_ptr<CCampaignState> camp )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::installNewPlayerInterface(shared_ptr<CGameInterface> gameInterface, boost::optional<PlayerColor> color)
|
void CClient::installNewPlayerInterface(std::shared_ptr<CGameInterface> gameInterface, boost::optional<PlayerColor> color)
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
|
boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
|
||||||
PlayerColor colorUsed = color.get_value_or(PlayerColor::UNFLAGGABLE);
|
PlayerColor colorUsed = color.get_value_or(PlayerColor::UNFLAGGABLE);
|
||||||
@ -869,7 +876,7 @@ void CClient::installNewPlayerInterface(shared_ptr<CGameInterface> gameInterface
|
|||||||
playerint[colorUsed] = gameInterface;
|
playerint[colorUsed] = gameInterface;
|
||||||
|
|
||||||
logGlobal->traceStream() << boost::format("\tInitializing the interface for player %s") % colorUsed;
|
logGlobal->traceStream() << boost::format("\tInitializing the interface for player %s") % colorUsed;
|
||||||
auto cb = make_shared<CCallback>(gs, color, this);
|
auto cb = std::make_shared<CCallback>(gs, color, this);
|
||||||
callbacks[colorUsed] = cb;
|
callbacks[colorUsed] = cb;
|
||||||
battleCallbacks[colorUsed] = cb;
|
battleCallbacks[colorUsed] = cb;
|
||||||
gameInterface->init(cb);
|
gameInterface->init(cb);
|
||||||
@ -877,7 +884,7 @@ void CClient::installNewPlayerInterface(shared_ptr<CGameInterface> gameInterface
|
|||||||
installNewBattleInterface(gameInterface, color, false);
|
installNewBattleInterface(gameInterface, color, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::installNewBattleInterface(shared_ptr<CBattleGameInterface> battleInterface, boost::optional<PlayerColor> color, bool needCallback /*= true*/)
|
void CClient::installNewBattleInterface(std::shared_ptr<CBattleGameInterface> battleInterface, boost::optional<PlayerColor> color, bool needCallback /*= true*/)
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
|
boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
|
||||||
PlayerColor colorUsed = color.get_value_or(PlayerColor::UNFLAGGABLE);
|
PlayerColor colorUsed = color.get_value_or(PlayerColor::UNFLAGGABLE);
|
||||||
@ -890,7 +897,7 @@ void CClient::installNewBattleInterface(shared_ptr<CBattleGameInterface> battleI
|
|||||||
if(needCallback)
|
if(needCallback)
|
||||||
{
|
{
|
||||||
logGlobal->traceStream() << boost::format("\tInitializing the battle interface for player %s") % *color;
|
logGlobal->traceStream() << boost::format("\tInitializing the battle interface for player %s") % *color;
|
||||||
auto cbc = make_shared<CBattleCallback>(gs, color, this);
|
auto cbc = std::make_shared<CBattleCallback>(gs, color, this);
|
||||||
battleCallbacks[colorUsed] = cbc;
|
battleCallbacks[colorUsed] = cbc;
|
||||||
battleInterface->init(cbc);
|
battleInterface->init(cbc);
|
||||||
}
|
}
|
||||||
@ -967,6 +974,9 @@ CServerHandler::CServerHandler(bool runServer /*= false*/)
|
|||||||
{
|
{
|
||||||
serverThread = nullptr;
|
serverThread = nullptr;
|
||||||
shared = nullptr;
|
shared = nullptr;
|
||||||
|
if(settings["testing"]["enabled"].Bool())
|
||||||
|
port = settings["testing"]["port"].String();
|
||||||
|
else
|
||||||
port = boost::lexical_cast<std::string>(settings["server"]["port"].Float());
|
port = boost::lexical_cast<std::string>(settings["server"]["port"].Float());
|
||||||
verbose = true;
|
verbose = true;
|
||||||
|
|
||||||
@ -1009,6 +1019,14 @@ void CServerHandler::callServer()
|
|||||||
|
|
||||||
CConnection * CServerHandler::justConnectToServer(const std::string &host, const std::string &port)
|
CConnection * CServerHandler::justConnectToServer(const std::string &host, const std::string &port)
|
||||||
{
|
{
|
||||||
|
std::string realPort;
|
||||||
|
if(settings["testing"]["enabled"].Bool())
|
||||||
|
realPort = settings["testing"]["port"].String();
|
||||||
|
else if(port.size())
|
||||||
|
realPort = port;
|
||||||
|
else
|
||||||
|
realPort = boost::lexical_cast<std::string>(settings["server"]["port"].Float());
|
||||||
|
|
||||||
CConnection *ret = nullptr;
|
CConnection *ret = nullptr;
|
||||||
while(!ret)
|
while(!ret)
|
||||||
{
|
{
|
||||||
@ -1016,7 +1034,7 @@ CConnection * CServerHandler::justConnectToServer(const std::string &host, const
|
|||||||
{
|
{
|
||||||
logNetwork->infoStream() << "Establishing connection...";
|
logNetwork->infoStream() << "Establishing connection...";
|
||||||
ret = new CConnection( host.size() ? host : settings["server"]["server"].String(),
|
ret = new CConnection( host.size() ? host : settings["server"]["server"].String(),
|
||||||
port.size() ? port : boost::lexical_cast<std::string>(settings["server"]["port"].Float()),
|
realPort,
|
||||||
NAME);
|
NAME);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -115,17 +115,17 @@ public:
|
|||||||
/// Class which handles client - server logic
|
/// Class which handles client - server logic
|
||||||
class CClient : public IGameCallback
|
class CClient : public IGameCallback
|
||||||
{
|
{
|
||||||
unique_ptr<CPathsInfo> pathInfo;
|
std::unique_ptr<CPathsInfo> pathInfo;
|
||||||
public:
|
public:
|
||||||
std::map<PlayerColor,shared_ptr<CCallback> > callbacks; //callbacks given to player interfaces
|
std::map<PlayerColor,std::shared_ptr<CCallback> > callbacks; //callbacks given to player interfaces
|
||||||
std::map<PlayerColor,shared_ptr<CBattleCallback> > battleCallbacks; //callbacks given to player interfaces
|
std::map<PlayerColor,std::shared_ptr<CBattleCallback> > battleCallbacks; //callbacks given to player interfaces
|
||||||
std::vector<shared_ptr<IGameEventsReceiver>> privilagedGameEventReceivers; //scripting modules, spectator interfaces
|
std::vector<std::shared_ptr<IGameEventsReceiver>> privilagedGameEventReceivers; //scripting modules, spectator interfaces
|
||||||
std::vector<shared_ptr<IBattleEventsReceiver>> privilagedBattleEventReceivers; //scripting modules, spectator interfaces
|
std::vector<std::shared_ptr<IBattleEventsReceiver>> privilagedBattleEventReceivers; //scripting modules, spectator interfaces
|
||||||
std::map<PlayerColor, shared_ptr<CGameInterface>> playerint;
|
std::map<PlayerColor, std::shared_ptr<CGameInterface>> playerint;
|
||||||
std::map<PlayerColor, shared_ptr<CBattleGameInterface>> battleints;
|
std::map<PlayerColor, std::shared_ptr<CBattleGameInterface>> battleints;
|
||||||
|
|
||||||
std::map<PlayerColor,std::vector<shared_ptr<IGameEventsReceiver>>> additionalPlayerInts;
|
std::map<PlayerColor,std::vector<std::shared_ptr<IGameEventsReceiver>>> additionalPlayerInts;
|
||||||
std::map<PlayerColor,std::vector<shared_ptr<IBattleEventsReceiver>>> additionalBattleInts;
|
std::map<PlayerColor,std::vector<std::shared_ptr<IBattleEventsReceiver>>> additionalBattleInts;
|
||||||
|
|
||||||
bool hotSeat;
|
bool hotSeat;
|
||||||
CConnection *serv;
|
CConnection *serv;
|
||||||
@ -146,8 +146,8 @@ public:
|
|||||||
void newGame(CConnection *con, StartInfo *si); //con - connection to server
|
void newGame(CConnection *con, StartInfo *si); //con - connection to server
|
||||||
|
|
||||||
void loadNeutralBattleAI();
|
void loadNeutralBattleAI();
|
||||||
void installNewPlayerInterface(shared_ptr<CGameInterface> gameInterface, boost::optional<PlayerColor> color);
|
void installNewPlayerInterface(std::shared_ptr<CGameInterface> gameInterface, boost::optional<PlayerColor> color);
|
||||||
void installNewBattleInterface(shared_ptr<CBattleGameInterface> battleInterface, boost::optional<PlayerColor> color, bool needCallback = true);
|
void installNewBattleInterface(std::shared_ptr<CBattleGameInterface> battleInterface, boost::optional<PlayerColor> color, bool needCallback = true);
|
||||||
std::string aiNameForPlayer(const PlayerSettings &ps, bool battleAI); //empty means no AI -> human
|
std::string aiNameForPlayer(const PlayerSettings &ps, bool battleAI); //empty means no AI -> human
|
||||||
|
|
||||||
void endGame(bool closeConnection = true);
|
void endGame(bool closeConnection = true);
|
||||||
@ -155,9 +155,9 @@ public:
|
|||||||
void save(const std::string & fname);
|
void save(const std::string & fname);
|
||||||
void loadGame(const std::string & fname, const bool server = true, const std::vector<int>& humanplayerindices = std::vector<int>(), const int loadnumplayers = 1, int player_ = -1, const std::string & ipaddr = "", const std::string & port = "");
|
void loadGame(const std::string & fname, const bool server = true, const std::vector<int>& humanplayerindices = std::vector<int>(), const int loadnumplayers = 1, int player_ = -1, const std::string & ipaddr = "", const std::string & port = "");
|
||||||
void run();
|
void run();
|
||||||
void campaignMapFinished( shared_ptr<CCampaignState> camp );
|
void campaignMapFinished( std::shared_ptr<CCampaignState> camp );
|
||||||
void finishCampaign( shared_ptr<CCampaignState> camp );
|
void finishCampaign( std::shared_ptr<CCampaignState> camp );
|
||||||
void proposeNextMission(shared_ptr<CCampaignState> camp);
|
void proposeNextMission(std::shared_ptr<CCampaignState> camp);
|
||||||
|
|
||||||
void invalidatePaths();
|
void invalidatePaths();
|
||||||
const CPathsInfo * getPathsInfo(const CGHeroInstance *h);
|
const CPathsInfo * getPathsInfo(const CGHeroInstance *h);
|
||||||
@ -233,7 +233,7 @@ public:
|
|||||||
|
|
||||||
void handlePack( CPack * pack ); //applies the given pack and deletes it
|
void handlePack( CPack * pack ); //applies the given pack and deletes it
|
||||||
void battleStarted(const BattleInfo * info);
|
void battleStarted(const BattleInfo * info);
|
||||||
void commenceTacticPhaseForInt(shared_ptr<CBattleGameInterface> battleInt); //will be called as separate thread
|
void commenceTacticPhaseForInt(std::shared_ptr<CBattleGameInterface> battleInt); //will be called as separate thread
|
||||||
|
|
||||||
void commitPackage(CPackForClient *pack) override;
|
void commitPackage(CPackForClient *pack) override;
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ void CBattleInterface::addNewAnim(CBattleAnimation * anim)
|
|||||||
CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSet * army2,
|
CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSet * army2,
|
||||||
const CGHeroInstance *hero1, const CGHeroInstance *hero2,
|
const CGHeroInstance *hero1, const CGHeroInstance *hero2,
|
||||||
const SDL_Rect & myRect,
|
const SDL_Rect & myRect,
|
||||||
shared_ptr<CPlayerInterface> att, shared_ptr<CPlayerInterface> defen)
|
std::shared_ptr<CPlayerInterface> att, std::shared_ptr<CPlayerInterface> defen)
|
||||||
: background(nullptr), queue(nullptr), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0),
|
: background(nullptr), queue(nullptr), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0),
|
||||||
activeStack(nullptr), mouseHoveredStack(nullptr), stackToActivate(nullptr), selectedStack(nullptr), previouslyHoveredHex(-1),
|
activeStack(nullptr), mouseHoveredStack(nullptr), stackToActivate(nullptr), selectedStack(nullptr), previouslyHoveredHex(-1),
|
||||||
currentlyHoveredHex(-1), attackingHex(-1), stackCanCastSpell(false), creatureCasting(false), spellDestSelectMode(false), spellSelMode(NO_LOCATION), spellToCast(nullptr), sp(nullptr),
|
currentlyHoveredHex(-1), attackingHex(-1), stackCanCastSpell(false), creatureCasting(false), spellDestSelectMode(false), spellSelMode(NO_LOCATION), spellToCast(nullptr), sp(nullptr),
|
||||||
@ -3260,7 +3260,7 @@ void CBattleInterface::showStacks(SDL_Surface * to, std::vector<const CStack *>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleInterface::showObstacles(SDL_Surface *to, std::vector<shared_ptr<const CObstacleInstance> > &obstacles)
|
void CBattleInterface::showObstacles(SDL_Surface *to, std::vector<std::shared_ptr<const CObstacleInstance> > &obstacles)
|
||||||
{
|
{
|
||||||
for (auto & obstacle : obstacles)
|
for (auto & obstacle : obstacles)
|
||||||
{
|
{
|
||||||
|
@ -79,7 +79,7 @@ struct BattleObjectsByHex
|
|||||||
typedef std::vector<int> TWallList;
|
typedef std::vector<int> TWallList;
|
||||||
typedef std::vector<const CStack * > TStackList;
|
typedef std::vector<const CStack * > TStackList;
|
||||||
typedef std::vector<const BattleEffect *> TEffectList;
|
typedef std::vector<const BattleEffect *> TEffectList;
|
||||||
typedef std::vector<shared_ptr<const CObstacleInstance> > TObstacleList;
|
typedef std::vector<std::shared_ptr<const CObstacleInstance> > TObstacleList;
|
||||||
|
|
||||||
struct HexData
|
struct HexData
|
||||||
{
|
{
|
||||||
@ -153,7 +153,7 @@ private:
|
|||||||
BattleHex currentlyHoveredHex; //number of hex that is supposed to be hovered (for a while it may be inappropriately set, but will be renewed soon)
|
BattleHex currentlyHoveredHex; //number of hex that is supposed to be hovered (for a while it may be inappropriately set, but will be renewed soon)
|
||||||
int attackingHex; //hex from which the stack would perform attack with current cursor
|
int attackingHex; //hex from which the stack would perform attack with current cursor
|
||||||
|
|
||||||
shared_ptr<CPlayerInterface> tacticianInterface; //used during tactics mode, points to the interface of player with higher tactics (can be either attacker or defender in hot-seat), valid onloy for human players
|
std::shared_ptr<CPlayerInterface> tacticianInterface; //used during tactics mode, points to the interface of player with higher tactics (can be either attacker or defender in hot-seat), valid onloy for human players
|
||||||
bool tacticsMode;
|
bool tacticsMode;
|
||||||
bool stackCanCastSpell; //if true, active stack could possibly cast some target spell
|
bool stackCanCastSpell; //if true, active stack could possibly cast some target spell
|
||||||
bool creatureCasting; //if true, stack currently aims to cats a spell
|
bool creatureCasting; //if true, stack currently aims to cats a spell
|
||||||
@ -212,8 +212,8 @@ private:
|
|||||||
friend class CBattleInterface;
|
friend class CBattleInterface;
|
||||||
} * siegeH;
|
} * siegeH;
|
||||||
|
|
||||||
shared_ptr<CPlayerInterface> attackerInt, defenderInt; //because LOCPLINT is not enough in hotSeat
|
std::shared_ptr<CPlayerInterface> attackerInt, defenderInt; //because LOCPLINT is not enough in hotSeat
|
||||||
shared_ptr<CPlayerInterface> curInt; //current player interface
|
std::shared_ptr<CPlayerInterface> curInt; //current player interface
|
||||||
const CGHeroInstance * getActiveHero(); //returns hero that can currently cast a spell
|
const CGHeroInstance * getActiveHero(); //returns hero that can currently cast a spell
|
||||||
|
|
||||||
/** Methods for displaying battle screen */
|
/** Methods for displaying battle screen */
|
||||||
@ -229,7 +229,7 @@ private:
|
|||||||
|
|
||||||
void showAliveStacks(SDL_Surface * to, std::vector<const CStack *> stacks);
|
void showAliveStacks(SDL_Surface * to, std::vector<const CStack *> stacks);
|
||||||
void showStacks(SDL_Surface * to, std::vector<const CStack *> stacks);
|
void showStacks(SDL_Surface * to, std::vector<const CStack *> stacks);
|
||||||
void showObstacles(SDL_Surface *to, std::vector<shared_ptr<const CObstacleInstance> > &obstacles);
|
void showObstacles(SDL_Surface *to, std::vector<std::shared_ptr<const CObstacleInstance> > &obstacles);
|
||||||
void showPiecesOfWall(SDL_Surface * to, std::vector<int> pieces);
|
void showPiecesOfWall(SDL_Surface * to, std::vector<int> pieces);
|
||||||
|
|
||||||
void showBattleEffects(SDL_Surface *to, const std::vector<const BattleEffect *> &battleEffects);
|
void showBattleEffects(SDL_Surface *to, const std::vector<const BattleEffect *> &battleEffects);
|
||||||
@ -249,7 +249,7 @@ public:
|
|||||||
ui32 animIDhelper; //for giving IDs for animations
|
ui32 animIDhelper; //for giving IDs for animations
|
||||||
static CondSh<bool> animsAreDisplayed; //for waiting with the end of battle for end of anims
|
static CondSh<bool> animsAreDisplayed; //for waiting with the end of battle for end of anims
|
||||||
|
|
||||||
CBattleInterface(const CCreatureSet * army1, const CCreatureSet * army2, const CGHeroInstance *hero1, const CGHeroInstance *hero2, const SDL_Rect & myRect, shared_ptr<CPlayerInterface> att, shared_ptr<CPlayerInterface> defen); //c-tor
|
CBattleInterface(const CCreatureSet * army1, const CCreatureSet * army2, const CGHeroInstance *hero1, const CGHeroInstance *hero2, const SDL_Rect & myRect, std::shared_ptr<CPlayerInterface> att, std::shared_ptr<CPlayerInterface> defen); //c-tor
|
||||||
~CBattleInterface(); //d-tor
|
~CBattleInterface(); //d-tor
|
||||||
|
|
||||||
//std::vector<TimeInterested*> timeinterested; //animation handling
|
//std::vector<TimeInterested*> timeinterested; //animation handling
|
||||||
|
@ -66,7 +66,7 @@ private:
|
|||||||
|
|
||||||
//animation raw data
|
//animation raw data
|
||||||
//TODO: use vector instead?
|
//TODO: use vector instead?
|
||||||
unique_ptr<ui8[]> pixelData;
|
std::unique_ptr<ui8[]> pixelData;
|
||||||
size_t pixelDataSize;
|
size_t pixelDataSize;
|
||||||
|
|
||||||
// speed of animation, measure in frames per second
|
// speed of animation, measure in frames per second
|
||||||
|
@ -1576,7 +1576,7 @@ void CMapHandler::getTerrainDescr( const int3 &pos, std::string & out, bool terN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(t.hasFavourableWinds())
|
if(t.hasFavorableWinds())
|
||||||
out = CGI->objtypeh->getObjectName(Obj::FAVORABLE_WINDS);
|
out = CGI->objtypeh->getObjectName(Obj::FAVORABLE_WINDS);
|
||||||
else if(terName)
|
else if(terName)
|
||||||
{
|
{
|
||||||
|
@ -380,7 +380,16 @@ void MoraleLuckBox::set(const IBonusBearer *node)
|
|||||||
if (morale && node && (node->hasBonusOfType(Bonus::UNDEAD)
|
if (morale && node && (node->hasBonusOfType(Bonus::UNDEAD)
|
||||||
|| node->hasBonusOfType(Bonus::BLOCK_MORALE)
|
|| node->hasBonusOfType(Bonus::BLOCK_MORALE)
|
||||||
|| node->hasBonusOfType(Bonus::NON_LIVING)))
|
|| node->hasBonusOfType(Bonus::NON_LIVING)))
|
||||||
|
{
|
||||||
text += CGI->generaltexth->arraytxt[113]; //unaffected by morale
|
text += CGI->generaltexth->arraytxt[113]; //unaffected by morale
|
||||||
|
bonusValue = 0;
|
||||||
|
}
|
||||||
|
else if(!morale && node && node->hasBonusOfType(Bonus::BLOCK_LUCK))
|
||||||
|
{
|
||||||
|
// TODO: there is no text like "Unaffected by luck" so probably we need own text
|
||||||
|
text += CGI->generaltexth->arraytxt[noneTxtId];
|
||||||
|
bonusValue = 0;
|
||||||
|
}
|
||||||
else if(modifierList->empty())
|
else if(modifierList->empty())
|
||||||
text += CGI->generaltexth->arraytxt[noneTxtId];//no modifiers
|
text += CGI->generaltexth->arraytxt[noneTxtId];//no modifiers
|
||||||
else
|
else
|
||||||
|
@ -55,7 +55,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define ADVOPT (conf.go()->ac)
|
#define ADVOPT (conf.go()->ac)
|
||||||
using namespace boost::logic;
|
|
||||||
using namespace CSDL_Ext;
|
using namespace CSDL_Ext;
|
||||||
|
|
||||||
CAdvMapInt *adventureInt;
|
CAdvMapInt *adventureInt;
|
||||||
@ -767,6 +766,11 @@ void CAdvMapInt::updateMoveHero(const CGHeroInstance *h, tribool hasPath)
|
|||||||
moveHero->block(!hasPath || (h->movement == 0));
|
moveHero->block(!hasPath || (h->movement == 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CAdvMapInt::updateSpellbook(const CGHeroInstance *h)
|
||||||
|
{
|
||||||
|
spellbook->block(!h);
|
||||||
|
}
|
||||||
|
|
||||||
int CAdvMapInt::getNextHeroIndex(int startIndex)
|
int CAdvMapInt::getNextHeroIndex(int startIndex)
|
||||||
{
|
{
|
||||||
if (LOCPLINT->wanderingHeroes.size() == 0)
|
if (LOCPLINT->wanderingHeroes.size() == 0)
|
||||||
@ -1262,6 +1266,7 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView /*= true*/)
|
|||||||
|
|
||||||
updateSleepWake(nullptr);
|
updateSleepWake(nullptr);
|
||||||
updateMoveHero(nullptr);
|
updateMoveHero(nullptr);
|
||||||
|
updateSpellbook(nullptr);
|
||||||
}
|
}
|
||||||
else //hero selected
|
else //hero selected
|
||||||
{
|
{
|
||||||
@ -1275,6 +1280,7 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView /*= true*/)
|
|||||||
|
|
||||||
updateSleepWake(hero);
|
updateSleepWake(hero);
|
||||||
updateMoveHero(hero);
|
updateMoveHero(hero);
|
||||||
|
updateSpellbook(hero);
|
||||||
}
|
}
|
||||||
townList.redraw();
|
townList.redraw();
|
||||||
heroList.redraw();
|
heroList.redraw();
|
||||||
@ -1531,12 +1537,16 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
|
|||||||
}
|
}
|
||||||
else if(const CGHeroInstance * h = curHero())
|
else if(const CGHeroInstance * h = curHero())
|
||||||
{
|
{
|
||||||
const CGPathNode * pnode = LOCPLINT->cb->getPathsInfo(h)->getPathInfo(mapPos);
|
int3 mapPosCopy = mapPos;
|
||||||
|
const CGPathNode * pnode = LOCPLINT->cb->getPathsInfo(h)->getPathInfo(mapPosCopy);
|
||||||
|
assert(pnode);
|
||||||
|
|
||||||
int turns = pnode->turns;
|
int turns = pnode->turns;
|
||||||
vstd::amin(turns, 3);
|
vstd::amin(turns, 3);
|
||||||
switch(pnode->action)
|
switch(pnode->action)
|
||||||
{
|
{
|
||||||
case CGPathNode::NORMAL:
|
case CGPathNode::NORMAL:
|
||||||
|
case CGPathNode::TELEPORT_NORMAL:
|
||||||
if(pnode->layer == EPathfindingLayer::LAND)
|
if(pnode->layer == EPathfindingLayer::LAND)
|
||||||
CCS->curh->changeGraphic(ECursor::ADVENTURE, 4 + turns*6);
|
CCS->curh->changeGraphic(ECursor::ADVENTURE, 4 + turns*6);
|
||||||
else
|
else
|
||||||
@ -1545,6 +1555,7 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
|
|||||||
|
|
||||||
case CGPathNode::VISIT:
|
case CGPathNode::VISIT:
|
||||||
case CGPathNode::BLOCKING_VISIT:
|
case CGPathNode::BLOCKING_VISIT:
|
||||||
|
case CGPathNode::TELEPORT_BLOCKING_VISIT:
|
||||||
if(objAtTile && objAtTile->ID == Obj::HERO)
|
if(objAtTile && objAtTile->ID == Obj::HERO)
|
||||||
{
|
{
|
||||||
if(selection == objAtTile)
|
if(selection == objAtTile)
|
||||||
@ -1559,6 +1570,7 @@ void CAdvMapInt::tileHovered(const int3 &mapPos)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CGPathNode::BATTLE:
|
case CGPathNode::BATTLE:
|
||||||
|
case CGPathNode::TELEPORT_BATTLE:
|
||||||
CCS->curh->changeGraphic(ECursor::ADVENTURE, 5 + turns*6);
|
CCS->curh->changeGraphic(ECursor::ADVENTURE, 5 + turns*6);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1790,4 +1802,3 @@ void CAdvMapInt::WorldViewOptions::adjustDrawingInfo(MapDrawingInfo& info)
|
|||||||
|
|
||||||
info.additionalIcons = &iconPositions;
|
info.additionalIcons = &iconPositions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,6 +235,7 @@ public:
|
|||||||
//button updates
|
//button updates
|
||||||
void updateSleepWake(const CGHeroInstance *h);
|
void updateSleepWake(const CGHeroInstance *h);
|
||||||
void updateMoveHero(const CGHeroInstance *h, tribool hasPath = boost::logic::indeterminate);
|
void updateMoveHero(const CGHeroInstance *h, tribool hasPath = boost::logic::indeterminate);
|
||||||
|
void updateSpellbook(const CGHeroInstance *h);
|
||||||
void updateNextHero(const CGHeroInstance *h);
|
void updateNextHero(const CGHeroInstance *h);
|
||||||
|
|
||||||
/// changes current adventure map mode; used to switch between default view and world view; scale is ignored if EAdvMapMode == NORMAL
|
/// changes current adventure map mode; used to switch between default view and world view; scale is ignored if EAdvMapMode == NORMAL
|
||||||
|
@ -501,7 +501,10 @@ void CCastleBuildings::recreate()
|
|||||||
|
|
||||||
if(vstd::contains(town->builtBuildings, BuildingID::SHIPYARD))
|
if(vstd::contains(town->builtBuildings, BuildingID::SHIPYARD))
|
||||||
{
|
{
|
||||||
std::vector <const CGObjectInstance *> vobjs = LOCPLINT->cb->getVisitableObjs(town->bestLocation());
|
auto bayPos = town->bestLocation();
|
||||||
|
if(!bayPos.valid())
|
||||||
|
logGlobal->warnStream() << "Shipyard in non-coastal town!";
|
||||||
|
std::vector <const CGObjectInstance *> vobjs = LOCPLINT->cb->getVisitableObjs(bayPos, false);
|
||||||
//there is visitable obj at shipyard output tile and it's a boat or hero (on boat)
|
//there is visitable obj at shipyard output tile and it's a boat or hero (on boat)
|
||||||
if(!vobjs.empty() && (vobjs.front()->ID == Obj::BOAT || vobjs.front()->ID == Obj::HERO))
|
if(!vobjs.empty() && (vobjs.front()->ID == Obj::BOAT || vobjs.front()->ID == Obj::HERO))
|
||||||
{
|
{
|
||||||
|
@ -86,7 +86,7 @@ void CQuestMinimap::addQuestMarks (const QuestInfo * q)
|
|||||||
if (level != tile.z)
|
if (level != tile.z)
|
||||||
setLevel(tile.z);
|
setLevel(tile.z);
|
||||||
|
|
||||||
auto pic = make_shared<CQuestIcon>("VwSymbol.def", 3, x, y);
|
auto pic = std::make_shared<CQuestIcon>("VwSymbol.def", 3, x, y);
|
||||||
|
|
||||||
pic->moveBy (Point ( -pic->pos.w/2, -pic->pos.h/2));
|
pic->moveBy (Point ( -pic->pos.w/2, -pic->pos.h/2));
|
||||||
pic->callback = std::bind (&CQuestMinimap::iconClicked, this);
|
pic->callback = std::bind (&CQuestMinimap::iconClicked, this);
|
||||||
@ -179,7 +179,7 @@ void CQuestLog::recreateLabelList()
|
|||||||
else
|
else
|
||||||
text.addReplacement(quests[i].obj->getObjectName()); //get name of the object
|
text.addReplacement(quests[i].obj->getObjectName()); //get name of the object
|
||||||
}
|
}
|
||||||
auto label = make_shared<CQuestLabel>(Rect(13, 195, 149,31), FONT_SMALL, TOPLEFT, Colors::WHITE, text.toString());
|
auto label = std::make_shared<CQuestLabel>(Rect(13, 195, 149,31), FONT_SMALL, TOPLEFT, Colors::WHITE, text.toString());
|
||||||
label->disable();
|
label->disable();
|
||||||
|
|
||||||
label->callback = std::bind(&CQuestLog::selectQuest, this, i, currentLabel);
|
label->callback = std::bind(&CQuestLog::selectQuest, this, i, currentLabel);
|
||||||
|
@ -58,7 +58,7 @@ public:
|
|||||||
|
|
||||||
class CQuestMinimap : public CMinimap
|
class CQuestMinimap : public CMinimap
|
||||||
{
|
{
|
||||||
std::vector <shared_ptr<CQuestIcon>> icons;
|
std::vector <std::shared_ptr<CQuestIcon>> icons;
|
||||||
|
|
||||||
void clickLeft(tribool down, bool previousState) override{}; //minimap ignores clicking on its surface
|
void clickLeft(tribool down, bool previousState) override{}; //minimap ignores clicking on its surface
|
||||||
void iconClicked();
|
void iconClicked();
|
||||||
@ -86,7 +86,7 @@ class CQuestLog : public CWindowObject
|
|||||||
CLabel * hideCompleteLabel;
|
CLabel * hideCompleteLabel;
|
||||||
|
|
||||||
const std::vector<QuestInfo> quests;
|
const std::vector<QuestInfo> quests;
|
||||||
std::vector <shared_ptr<CQuestLabel>> labels;
|
std::vector <std::shared_ptr<CQuestLabel>> labels;
|
||||||
CTextBox * description;
|
CTextBox * description;
|
||||||
CQuestMinimap * minimap;
|
CQuestMinimap * minimap;
|
||||||
CSlider * slider; //scrolls quests
|
CSlider * slider; //scrolls quests
|
||||||
|
@ -861,7 +861,7 @@ void CMarketplaceWindow::selectionChanged(bool side)
|
|||||||
if(itemsType[1] == RESOURCE)
|
if(itemsType[1] == RESOURCE)
|
||||||
newAmount = LOCPLINT->cb->getResourceAmount(static_cast<Res::ERes>(soldItemId));
|
newAmount = LOCPLINT->cb->getResourceAmount(static_cast<Res::ERes>(soldItemId));
|
||||||
else if(itemsType[1] == CREATURE)
|
else if(itemsType[1] == CREATURE)
|
||||||
newAmount = hero->getStackCount(SlotID(hLeft->serial)) - (hero->Slots().size() == 1 && hero->needsLastStack());
|
newAmount = hero->getStackCount(SlotID(hLeft->serial)) - (hero->stacksCount() == 1 && hero->needsLastStack());
|
||||||
else
|
else
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
||||||
|
@ -704,7 +704,7 @@ CTavernWindow::CTavernWindow(const CGObjectInstance *TavernObj):
|
|||||||
oldSelected = -1;
|
oldSelected = -1;
|
||||||
|
|
||||||
new CLabel(200, 35, FONT_BIG, CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[37]);
|
new CLabel(200, 35, FONT_BIG, CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[37]);
|
||||||
new CLabel(320, 328, FONT_SMALL, CENTER, Colors::WHITE, "2500");
|
new CLabel(320, 328, FONT_SMALL, CENTER, Colors::WHITE, boost::lexical_cast<std::string>(GameConstants::HERO_GOLD_COST));
|
||||||
|
|
||||||
auto rumorText = boost::str(boost::format(CGI->generaltexth->allTexts[216]) % LOCPLINT->cb->getTavernRumor(tavernObj));
|
auto rumorText = boost::str(boost::format(CGI->generaltexth->allTexts[216]) % LOCPLINT->cb->getTavernRumor(tavernObj));
|
||||||
new CTextBox(rumorText, Rect(32, 190, 330, 68), 0, FONT_SMALL, CENTER, Colors::WHITE);
|
new CTextBox(rumorText, Rect(32, 190, 330, 68), 0, FONT_SMALL, CENTER, Colors::WHITE);
|
||||||
@ -714,7 +714,7 @@ CTavernWindow::CTavernWindow(const CGObjectInstance *TavernObj):
|
|||||||
recruit = new CButton(Point(272, 355), "TPTAV01.DEF", CButton::tooltip(), std::bind(&CTavernWindow::recruitb, this), SDLK_RETURN);
|
recruit = new CButton(Point(272, 355), "TPTAV01.DEF", CButton::tooltip(), std::bind(&CTavernWindow::recruitb, this), SDLK_RETURN);
|
||||||
thiefGuild = new CButton(Point(22, 428), "TPTAV02.DEF", CButton::tooltip(CGI->generaltexth->tavernInfo[5]), std::bind(&CTavernWindow::thievesguildb, this), SDLK_t);
|
thiefGuild = new CButton(Point(22, 428), "TPTAV02.DEF", CButton::tooltip(CGI->generaltexth->tavernInfo[5]), std::bind(&CTavernWindow::thievesguildb, this), SDLK_t);
|
||||||
|
|
||||||
if(LOCPLINT->cb->getResourceAmount(Res::GOLD) < 2500) //not enough gold
|
if(LOCPLINT->cb->getResourceAmount(Res::GOLD) < GameConstants::HERO_GOLD_COST) //not enough gold
|
||||||
{
|
{
|
||||||
recruit->addHoverText(CButton::NORMAL, CGI->generaltexth->tavernInfo[0]); //Cannot afford a Hero
|
recruit->addHoverText(CButton::NORMAL, CGI->generaltexth->tavernInfo[0]); //Cannot afford a Hero
|
||||||
recruit->block(true);
|
recruit->block(true);
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "BattleState.h"
|
#include "BattleState.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BattleAction.h, part of VCMI engine
|
* BattleAction.cpp, part of VCMI engine
|
||||||
*
|
*
|
||||||
* Authors: listed in file AUTHORS in main folder
|
* Authors: listed in file AUTHORS in main folder
|
||||||
*
|
*
|
||||||
|
@ -201,9 +201,7 @@ void BattleInfo::localInitStack(CStack * s)
|
|||||||
|
|
||||||
namespace CGH
|
namespace CGH
|
||||||
{
|
{
|
||||||
using namespace std;
|
static void readBattlePositions(const JsonNode &node, std::vector< std::vector<int> > & dest)
|
||||||
|
|
||||||
static void readBattlePositions(const JsonNode &node, vector< vector<int> > & dest)
|
|
||||||
{
|
{
|
||||||
for(const JsonNode &level : node.Vector())
|
for(const JsonNode &level : node.Vector())
|
||||||
{
|
{
|
||||||
@ -375,7 +373,7 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto obstPtr = make_shared<CObstacleInstance>();
|
auto obstPtr = std::make_shared<CObstacleInstance>();
|
||||||
obstPtr->obstacleType = CObstacleInstance::ABSOLUTE_OBSTACLE;
|
obstPtr->obstacleType = CObstacleInstance::ABSOLUTE_OBSTACLE;
|
||||||
obstPtr->ID = obidgen.getSuchNumber(appropriateAbsoluteObstacle);
|
obstPtr->ID = obidgen.getSuchNumber(appropriateAbsoluteObstacle);
|
||||||
obstPtr->uniqueID = curB->obstacles.size();
|
obstPtr->uniqueID = curB->obstacles.size();
|
||||||
@ -424,7 +422,7 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp
|
|||||||
|
|
||||||
RangeGenerator posgenerator(18, 168, ourRand);
|
RangeGenerator posgenerator(18, 168, ourRand);
|
||||||
|
|
||||||
auto obstPtr = make_shared<CObstacleInstance>();
|
auto obstPtr = std::make_shared<CObstacleInstance>();
|
||||||
obstPtr->ID = obid;
|
obstPtr->ID = obid;
|
||||||
obstPtr->pos = posgenerator.getSuchNumber(validPosition);
|
obstPtr->pos = posgenerator.getSuchNumber(validPosition);
|
||||||
obstPtr->uniqueID = curB->obstacles.size();
|
obstPtr->uniqueID = curB->obstacles.size();
|
||||||
@ -541,7 +539,7 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp
|
|||||||
}
|
}
|
||||||
|
|
||||||
//moat
|
//moat
|
||||||
auto moat = make_shared<MoatObstacle>();
|
auto moat = std::make_shared<MoatObstacle>();
|
||||||
moat->ID = curB->town->subID;
|
moat->ID = curB->town->subID;
|
||||||
moat->obstacleType = CObstacleInstance::MOAT;
|
moat->obstacleType = CObstacleInstance::MOAT;
|
||||||
moat->uniqueID = curB->obstacles.size();
|
moat->uniqueID = curB->obstacles.size();
|
||||||
@ -586,19 +584,19 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp
|
|||||||
|
|
||||||
case BFieldType::HOLY_GROUND:
|
case BFieldType::HOLY_GROUND:
|
||||||
{
|
{
|
||||||
curB->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, +1, Bonus::TERRAIN_OVERLAY)->addLimiter(make_shared<CreatureAlignmentLimiter>(EAlignment::GOOD)));
|
curB->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, +1, Bonus::TERRAIN_OVERLAY)->addLimiter(std::make_shared<CreatureAlignmentLimiter>(EAlignment::GOOD)));
|
||||||
curB->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, -1, Bonus::TERRAIN_OVERLAY)->addLimiter(make_shared<CreatureAlignmentLimiter>(EAlignment::EVIL)));
|
curB->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, -1, Bonus::TERRAIN_OVERLAY)->addLimiter(std::make_shared<CreatureAlignmentLimiter>(EAlignment::EVIL)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BFieldType::CLOVER_FIELD:
|
case BFieldType::CLOVER_FIELD:
|
||||||
{ //+2 luck bonus for neutral creatures
|
{ //+2 luck bonus for neutral creatures
|
||||||
curB->addNewBonus(makeFeature(Bonus::LUCK, Bonus::ONE_BATTLE, 0, +2, Bonus::TERRAIN_OVERLAY)->addLimiter(make_shared<CreatureAlignmentLimiter>(EAlignment::NEUTRAL)));
|
curB->addNewBonus(makeFeature(Bonus::LUCK, Bonus::ONE_BATTLE, 0, +2, Bonus::TERRAIN_OVERLAY)->addLimiter(std::make_shared<CreatureAlignmentLimiter>(EAlignment::NEUTRAL)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BFieldType::EVIL_FOG:
|
case BFieldType::EVIL_FOG:
|
||||||
{
|
{
|
||||||
curB->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, -1, Bonus::TERRAIN_OVERLAY)->addLimiter(make_shared<CreatureAlignmentLimiter>(EAlignment::GOOD)));
|
curB->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, -1, Bonus::TERRAIN_OVERLAY)->addLimiter(std::make_shared<CreatureAlignmentLimiter>(EAlignment::GOOD)));
|
||||||
curB->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, +1, Bonus::TERRAIN_OVERLAY)->addLimiter(make_shared<CreatureAlignmentLimiter>(EAlignment::EVIL)));
|
curB->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, +1, Bonus::TERRAIN_OVERLAY)->addLimiter(std::make_shared<CreatureAlignmentLimiter>(EAlignment::EVIL)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BFieldType::CURSED_GROUND:
|
case BFieldType::CURSED_GROUND:
|
||||||
@ -614,7 +612,7 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp
|
|||||||
//overlay premies given
|
//overlay premies given
|
||||||
|
|
||||||
//native terrain bonuses
|
//native terrain bonuses
|
||||||
auto nativeTerrain = make_shared<CreatureNativeTerrainLimiter>(curB->terrainType);
|
auto nativeTerrain = std::make_shared<CreatureNativeTerrainLimiter>(curB->terrainType);
|
||||||
curB->addNewBonus(makeFeature(Bonus::STACKS_SPEED, Bonus::ONE_BATTLE, 0, 1, Bonus::TERRAIN_NATIVE)->addLimiter(nativeTerrain));
|
curB->addNewBonus(makeFeature(Bonus::STACKS_SPEED, Bonus::ONE_BATTLE, 0, 1, Bonus::TERRAIN_NATIVE)->addLimiter(nativeTerrain));
|
||||||
curB->addNewBonus(makeFeature(Bonus::PRIMARY_SKILL, Bonus::ONE_BATTLE, PrimarySkill::ATTACK, 1, Bonus::TERRAIN_NATIVE)->addLimiter(nativeTerrain));
|
curB->addNewBonus(makeFeature(Bonus::PRIMARY_SKILL, Bonus::ONE_BATTLE, PrimarySkill::ATTACK, 1, Bonus::TERRAIN_NATIVE)->addLimiter(nativeTerrain));
|
||||||
curB->addNewBonus(makeFeature(Bonus::PRIMARY_SKILL, Bonus::ONE_BATTLE, PrimarySkill::DEFENSE, 1, Bonus::TERRAIN_NATIVE)->addLimiter(nativeTerrain));
|
curB->addNewBonus(makeFeature(Bonus::PRIMARY_SKILL, Bonus::ONE_BATTLE, PrimarySkill::DEFENSE, 1, Bonus::TERRAIN_NATIVE)->addLimiter(nativeTerrain));
|
||||||
@ -703,13 +701,13 @@ int BattleInfo::getIdForNewStack() const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<CObstacleInstance> BattleInfo::getObstacleOnTile(BattleHex tile) const
|
std::shared_ptr<CObstacleInstance> BattleInfo::getObstacleOnTile(BattleHex tile) const
|
||||||
{
|
{
|
||||||
for(auto &obs : obstacles)
|
for(auto &obs : obstacles)
|
||||||
if(vstd::contains(obs->getAffectedTiles(), tile))
|
if(vstd::contains(obs->getAffectedTiles(), tile))
|
||||||
return obs;
|
return obs;
|
||||||
|
|
||||||
return shared_ptr<CObstacleInstance>();
|
return std::shared_ptr<CObstacleInstance>();
|
||||||
}
|
}
|
||||||
|
|
||||||
BattlefieldBI::BattlefieldBI BattleInfo::battlefieldTypeToBI(BFieldType bfieldType)
|
BattlefieldBI::BattlefieldBI BattleInfo::battlefieldTypeToBI(BFieldType bfieldType)
|
||||||
@ -719,7 +717,7 @@ BattlefieldBI::BattlefieldBI BattleInfo::battlefieldTypeToBI(BFieldType bfieldTy
|
|||||||
{BFieldType::CLOVER_FIELD, BattlefieldBI::CLOVER_FIELD},
|
{BFieldType::CLOVER_FIELD, BattlefieldBI::CLOVER_FIELD},
|
||||||
{BFieldType::CURSED_GROUND, BattlefieldBI::CURSED_GROUND},
|
{BFieldType::CURSED_GROUND, BattlefieldBI::CURSED_GROUND},
|
||||||
{BFieldType::EVIL_FOG, BattlefieldBI::EVIL_FOG},
|
{BFieldType::EVIL_FOG, BattlefieldBI::EVIL_FOG},
|
||||||
{BFieldType::FAVOURABLE_WINDS, BattlefieldBI::NONE},
|
{BFieldType::FAVORABLE_WINDS, BattlefieldBI::NONE},
|
||||||
{BFieldType::FIERY_FIELDS, BattlefieldBI::FIERY_FIELDS},
|
{BFieldType::FIERY_FIELDS, BattlefieldBI::FIERY_FIELDS},
|
||||||
{BFieldType::HOLY_GROUND, BattlefieldBI::HOLY_GROUND},
|
{BFieldType::HOLY_GROUND, BattlefieldBI::HOLY_GROUND},
|
||||||
{BFieldType::LUCID_POOLS, BattlefieldBI::LUCID_POOLS},
|
{BFieldType::LUCID_POOLS, BattlefieldBI::LUCID_POOLS},
|
||||||
|
@ -83,7 +83,7 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb
|
|||||||
const CGTownInstance * town; //used during town siege, nullptr if this is not a siege (note that fortless town IS also a siege)
|
const CGTownInstance * town; //used during town siege, nullptr if this is not a siege (note that fortless town IS also a siege)
|
||||||
int3 tile; //for background and bonuses
|
int3 tile; //for background and bonuses
|
||||||
std::vector<CStack*> stacks;
|
std::vector<CStack*> stacks;
|
||||||
std::vector<shared_ptr<CObstacleInstance> > obstacles;
|
std::vector<std::shared_ptr<CObstacleInstance> > obstacles;
|
||||||
SiegeInfo si;
|
SiegeInfo si;
|
||||||
|
|
||||||
BFieldType battlefieldType; //like !!BA:B
|
BFieldType battlefieldType; //like !!BA:B
|
||||||
@ -124,7 +124,7 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb
|
|||||||
//std::vector<BattleHex> getAccessibility(const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable = nullptr, bool forPassingBy = false) const; //returns vector of accessible tiles (taking into account the creature range)
|
//std::vector<BattleHex> getAccessibility(const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable = nullptr, bool forPassingBy = false) const; //returns vector of accessible tiles (taking into account the creature range)
|
||||||
|
|
||||||
//bool isObstacleVisibleForSide(const CObstacleInstance &obstacle, ui8 side) const;
|
//bool isObstacleVisibleForSide(const CObstacleInstance &obstacle, ui8 side) const;
|
||||||
shared_ptr<CObstacleInstance> getObstacleOnTile(BattleHex tile) const;
|
std::shared_ptr<CObstacleInstance> getObstacleOnTile(BattleHex tile) const;
|
||||||
std::set<BattleHex> getStoppers(bool whichSidePerspective) const;
|
std::set<BattleHex> getStoppers(bool whichSidePerspective) const;
|
||||||
|
|
||||||
ui32 calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool unlucky, bool deathBlow, bool ballistaDoubleDmg, CRandomGenerator & rand); //charge - number of hexes travelled before attack (for champion's jousting)
|
ui32 calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool unlucky, bool deathBlow, bool ballistaDoubleDmg, CRandomGenerator & rand); //charge - number of hexes travelled before attack (for champion's jousting)
|
||||||
|
@ -545,7 +545,7 @@ ArtifactID CArtHandler::pickRandomArtifact(CRandomGenerator & rand, int flags)
|
|||||||
return pickRandomArtifact(rand, flags, [](ArtifactID){ return true;});
|
return pickRandomArtifact(rand, flags, [](ArtifactID){ return true;});
|
||||||
}
|
}
|
||||||
|
|
||||||
Bonus *createBonus(Bonus::BonusType type, int val, int subtype, Bonus::ValueType valType, shared_ptr<ILimiter> limiter = shared_ptr<ILimiter>(), int additionalInfo = 0)
|
Bonus *createBonus(Bonus::BonusType type, int val, int subtype, Bonus::ValueType valType, std::shared_ptr<ILimiter> limiter = std::shared_ptr<ILimiter>(), int additionalInfo = 0)
|
||||||
{
|
{
|
||||||
auto added = new Bonus(Bonus::PERMANENT,type,Bonus::ARTIFACT,val,-1,subtype);
|
auto added = new Bonus(Bonus::PERMANENT,type,Bonus::ARTIFACT,val,-1,subtype);
|
||||||
added->additionalInfo = additionalInfo;
|
added->additionalInfo = additionalInfo;
|
||||||
@ -554,7 +554,7 @@ Bonus *createBonus(Bonus::BonusType type, int val, int subtype, Bonus::ValueType
|
|||||||
return added;
|
return added;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bonus *createBonus(Bonus::BonusType type, int val, int subtype, shared_ptr<IPropagator> propagator = shared_ptr<IPropagator>(), int additionalInfo = 0)
|
Bonus *createBonus(Bonus::BonusType type, int val, int subtype, std::shared_ptr<IPropagator> propagator = std::shared_ptr<IPropagator>(), int additionalInfo = 0)
|
||||||
{
|
{
|
||||||
auto added = new Bonus(Bonus::PERMANENT,type,Bonus::ARTIFACT,val,-1,subtype);
|
auto added = new Bonus(Bonus::PERMANENT,type,Bonus::ARTIFACT,val,-1,subtype);
|
||||||
added->additionalInfo = additionalInfo;
|
added->additionalInfo = additionalInfo;
|
||||||
@ -563,12 +563,12 @@ Bonus *createBonus(Bonus::BonusType type, int val, int subtype, shared_ptr<IProp
|
|||||||
return added;
|
return added;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CArtHandler::giveArtBonus( ArtifactID aid, Bonus::BonusType type, int val, int subtype, Bonus::ValueType valType, shared_ptr<ILimiter> limiter, int additionalInfo)
|
void CArtHandler::giveArtBonus( ArtifactID aid, Bonus::BonusType type, int val, int subtype, Bonus::ValueType valType, std::shared_ptr<ILimiter> limiter, int additionalInfo)
|
||||||
{
|
{
|
||||||
giveArtBonus(aid, createBonus(type, val, subtype, valType, limiter, additionalInfo));
|
giveArtBonus(aid, createBonus(type, val, subtype, valType, limiter, additionalInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CArtHandler::giveArtBonus(ArtifactID aid, Bonus::BonusType type, int val, int subtype, shared_ptr<IPropagator> propagator /*= nullptr*/, int additionalInfo)
|
void CArtHandler::giveArtBonus(ArtifactID aid, Bonus::BonusType type, int val, int subtype, std::shared_ptr<IPropagator> propagator /*= nullptr*/, int additionalInfo)
|
||||||
{
|
{
|
||||||
giveArtBonus(aid, createBonus(type, val, subtype, propagator, additionalInfo));
|
giveArtBonus(aid, createBonus(type, val, subtype, propagator, additionalInfo));
|
||||||
}
|
}
|
||||||
@ -737,6 +737,7 @@ void CArtHandler::afterLoadFinalization()
|
|||||||
bonus->sid = art->id;
|
bonus->sid = art->id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CBonusSystemNode::treeHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
CArtifactInstance::CArtifactInstance()
|
CArtifactInstance::CArtifactInstance()
|
||||||
|
@ -258,8 +258,8 @@ private:
|
|||||||
void loadComponents(CArtifact * art, const JsonNode & node);
|
void loadComponents(CArtifact * art, const JsonNode & node);
|
||||||
void loadGrowingArt(CGrowingArtifact * art, const JsonNode & node);
|
void loadGrowingArt(CGrowingArtifact * art, const JsonNode & node);
|
||||||
|
|
||||||
void giveArtBonus(ArtifactID aid, Bonus::BonusType type, int val, int subtype = -1, Bonus::ValueType valType = Bonus::BASE_NUMBER, shared_ptr<ILimiter> limiter = shared_ptr<ILimiter>(), int additionalinfo = 0);
|
void giveArtBonus(ArtifactID aid, Bonus::BonusType type, int val, int subtype = -1, Bonus::ValueType valType = Bonus::BASE_NUMBER, std::shared_ptr<ILimiter> limiter = std::shared_ptr<ILimiter>(), int additionalinfo = 0);
|
||||||
void giveArtBonus(ArtifactID aid, Bonus::BonusType type, int val, int subtype, shared_ptr<IPropagator> propagator, int additionalinfo = 0);
|
void giveArtBonus(ArtifactID aid, Bonus::BonusType type, int val, int subtype, std::shared_ptr<IPropagator> propagator, int additionalinfo = 0);
|
||||||
void giveArtBonus(ArtifactID aid, Bonus *bonus);
|
void giveArtBonus(ArtifactID aid, Bonus *bonus);
|
||||||
|
|
||||||
void erasePickedArt(ArtifactID id);
|
void erasePickedArt(ArtifactID id);
|
||||||
|
@ -130,9 +130,9 @@ BFieldType CBattleInfoEssentials::battleGetBattlefieldType() const
|
|||||||
return getBattle()->battlefieldType;
|
return getBattle()->battlefieldType;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<shared_ptr<const CObstacleInstance> > CBattleInfoEssentials::battleGetAllObstacles(boost::optional<BattlePerspective::BattlePerspective> perspective /*= boost::none*/) const
|
std::vector<std::shared_ptr<const CObstacleInstance> > CBattleInfoEssentials::battleGetAllObstacles(boost::optional<BattlePerspective::BattlePerspective> perspective /*= boost::none*/) const
|
||||||
{
|
{
|
||||||
std::vector<shared_ptr<const CObstacleInstance> > ret;
|
std::vector<std::shared_ptr<const CObstacleInstance> > ret;
|
||||||
RETURN_IF_NOT_BATTLE(ret);
|
RETURN_IF_NOT_BATTLE(ret);
|
||||||
|
|
||||||
if(!perspective)
|
if(!perspective)
|
||||||
@ -1100,9 +1100,9 @@ std::pair<ui32, ui32> CBattleInfoCallback::battleEstimateDamage(const BattleAtta
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<const CObstacleInstance> CBattleInfoCallback::battleGetObstacleOnPos(BattleHex tile, bool onlyBlocking /*= true*/) const
|
std::shared_ptr<const CObstacleInstance> CBattleInfoCallback::battleGetObstacleOnPos(BattleHex tile, bool onlyBlocking /*= true*/) const
|
||||||
{
|
{
|
||||||
RETURN_IF_NOT_BATTLE(shared_ptr<const CObstacleInstance>());
|
RETURN_IF_NOT_BATTLE(std::shared_ptr<const CObstacleInstance>());
|
||||||
|
|
||||||
for(auto &obs : battleGetAllObstacles())
|
for(auto &obs : battleGetAllObstacles())
|
||||||
{
|
{
|
||||||
@ -1113,7 +1113,7 @@ shared_ptr<const CObstacleInstance> CBattleInfoCallback::battleGetObstacleOnPos(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return shared_ptr<const CObstacleInstance>();
|
return std::shared_ptr<const CObstacleInstance>();
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessibilityInfo CBattleInfoCallback::getAccesibility() const
|
AccessibilityInfo CBattleInfoCallback::getAccesibility() const
|
||||||
|
@ -170,7 +170,7 @@ public:
|
|||||||
|
|
||||||
ETerrainType battleTerrainType() const;
|
ETerrainType battleTerrainType() const;
|
||||||
BFieldType battleGetBattlefieldType() const;
|
BFieldType battleGetBattlefieldType() const;
|
||||||
std::vector<shared_ptr<const CObstacleInstance> > battleGetAllObstacles(boost::optional<BattlePerspective::BattlePerspective> perspective = boost::none) const; //returns all obstacles on the battlefield
|
std::vector<std::shared_ptr<const CObstacleInstance> > battleGetAllObstacles(boost::optional<BattlePerspective::BattlePerspective> perspective = boost::none) const; //returns all obstacles on the battlefield
|
||||||
|
|
||||||
/** @brief Main method for getting battle stacks
|
/** @brief Main method for getting battle stacks
|
||||||
*
|
*
|
||||||
@ -243,7 +243,7 @@ public:
|
|||||||
//battle
|
//battle
|
||||||
boost::optional<int> battleIsFinished() const; //return none if battle is ongoing; otherwise the victorious side (0/1) or 2 if it is a draw
|
boost::optional<int> battleIsFinished() const; //return none if battle is ongoing; otherwise the victorious side (0/1) or 2 if it is a draw
|
||||||
|
|
||||||
shared_ptr<const CObstacleInstance> battleGetObstacleOnPos(BattleHex tile, bool onlyBlocking = true) const; //blocking obstacles makes tile inaccessible, others cause special effects (like Land Mines, Moat, Quicksands)
|
std::shared_ptr<const CObstacleInstance> battleGetObstacleOnPos(BattleHex tile, bool onlyBlocking = true) const; //blocking obstacles makes tile inaccessible, others cause special effects (like Land Mines, Moat, Quicksands)
|
||||||
const CStack * battleGetStackByPos(BattleHex pos, bool onlyAlive = true) const; //returns stack info by given pos
|
const CStack * battleGetStackByPos(BattleHex pos, bool onlyAlive = true) const; //returns stack info by given pos
|
||||||
void battleGetStackQueue(std::vector<const CStack *> &out, const int howMany, const int turn = 0, int lastMoved = -1) const;
|
void battleGetStackQueue(std::vector<const CStack *> &out, const int howMany, const int turn = 0, int lastMoved = -1) const;
|
||||||
void battleGetStackCountOutsideHexes(bool *ac) const; // returns hexes which when in front of a stack cause us to move the amount box back
|
void battleGetStackCountOutsideHexes(bool *ac) const; // returns hexes which when in front of a stack cause us to move the amount box back
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "../lib/JsonNode.h"
|
#include "../lib/JsonNode.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CConfighandler.h, part of VCMI engine
|
* CConfigHandler.h, part of VCMI engine
|
||||||
*
|
*
|
||||||
* Authors: listed in file AUTHORS in main folder
|
* Authors: listed in file AUTHORS in main folder
|
||||||
*
|
*
|
||||||
|
@ -140,6 +140,7 @@ void CCreature::setId(CreatureID ID)
|
|||||||
if(bonus->source == Bonus::CREATURE_ABILITY)
|
if(bonus->source == Bonus::CREATURE_ABILITY)
|
||||||
bonus->sid = ID;
|
bonus->sid = ID;
|
||||||
}
|
}
|
||||||
|
CBonusSystemNode::treeHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddAbility(CCreature *cre, const JsonVector &ability_vec)
|
static void AddAbility(CCreature *cre, const JsonVector &ability_vec)
|
||||||
@ -488,8 +489,14 @@ void CCreatureHandler::loadCrExpBon()
|
|||||||
}
|
}
|
||||||
do //parse everything that's left
|
do //parse everything that's left
|
||||||
{
|
{
|
||||||
b.sid = parser.readNumber(); //id = this particular creature ID
|
auto sid = parser.readNumber(); //id = this particular creature ID
|
||||||
loadStackExp(b, creatures[b.sid]->getBonusList(), parser); //add directly to CCreature Node
|
b.sid = sid;
|
||||||
|
bl.clear();
|
||||||
|
loadStackExp(b, bl, parser);
|
||||||
|
for(Bonus * b : bl)
|
||||||
|
{
|
||||||
|
creatures[sid]->addNewBonus(b); //add directly to CCreature Node
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (parser.endLine());
|
while (parser.endLine());
|
||||||
|
|
||||||
@ -753,7 +760,7 @@ void CCreatureHandler::loadStackExperience(CCreature * creature, const JsonNode
|
|||||||
{
|
{
|
||||||
if (val.Bool() == true)
|
if (val.Bool() == true)
|
||||||
{
|
{
|
||||||
bonus->limiter = make_shared<RankRangeLimiter>(RankRangeLimiter(lowerLimit));
|
bonus->limiter = std::make_shared<RankRangeLimiter>(RankRangeLimiter(lowerLimit));
|
||||||
creature->addNewBonus (new Bonus(*bonus)); //bonuses must be unique objects
|
creature->addNewBonus (new Bonus(*bonus)); //bonuses must be unique objects
|
||||||
break; //TODO: allow bonuses to turn off?
|
break; //TODO: allow bonuses to turn off?
|
||||||
}
|
}
|
||||||
|
@ -225,14 +225,39 @@ ui64 CCreatureSet::getPower (SlotID slot) const
|
|||||||
return getStack(slot).getPower();
|
return getStack(slot).getPower();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CCreatureSet::getRoughAmount (SlotID slot) const
|
std::string CCreatureSet::getRoughAmount(SlotID slot, int mode) const
|
||||||
{
|
{
|
||||||
|
/// Mode represent return string format
|
||||||
|
/// "Pack" - 0, "A pack of" - 1, "a pack of" - 2
|
||||||
int quantity = CCreature::getQuantityID(getStackCount(slot));
|
int quantity = CCreature::getQuantityID(getStackCount(slot));
|
||||||
if(quantity)
|
if(quantity)
|
||||||
return VLC->generaltexth->arraytxt[174 + 3*CCreature::getQuantityID(getStackCount(slot))];
|
return VLC->generaltexth->arraytxt[(174 + mode) + 3*CCreature::getQuantityID(getStackCount(slot))];
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CCreatureSet::getArmyDescription() const
|
||||||
|
{
|
||||||
|
std::string text;
|
||||||
|
std::vector<std::string> guards;
|
||||||
|
for(auto & elem : stacks)
|
||||||
|
{
|
||||||
|
auto str = boost::str(boost::format("%s %s") % getRoughAmount(elem.first, 2) % getCreature(elem.first)->namePl);
|
||||||
|
guards.push_back(str);
|
||||||
|
}
|
||||||
|
if(guards.size())
|
||||||
|
{
|
||||||
|
for(int i = 0; i < guards.size(); i++)
|
||||||
|
{
|
||||||
|
text += guards[i];
|
||||||
|
if(i + 2 < guards.size())
|
||||||
|
text += ", ";
|
||||||
|
else if(i + 2 == guards.size())
|
||||||
|
text += VLC->generaltexth->allTexts[237];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
int CCreatureSet::stacksCount() const
|
int CCreatureSet::stacksCount() const
|
||||||
{
|
{
|
||||||
return stacks.size();
|
return stacks.size();
|
||||||
|
@ -200,7 +200,8 @@ public:
|
|||||||
virtual bool needsLastStack() const; //true if last stack cannot be taken
|
virtual bool needsLastStack() const; //true if last stack cannot be taken
|
||||||
ui64 getArmyStrength() const; //sum of AI values of creatures
|
ui64 getArmyStrength() const; //sum of AI values of creatures
|
||||||
ui64 getPower (SlotID slot) const; //value of specific stack
|
ui64 getPower (SlotID slot) const; //value of specific stack
|
||||||
std::string getRoughAmount (SlotID slot) const; //rough size of specific stack
|
std::string getRoughAmount(SlotID slot, int mode = 0) const; //rough size of specific stack
|
||||||
|
std::string getArmyDescription() const;
|
||||||
bool hasStackAtSlot(SlotID slot) const;
|
bool hasStackAtSlot(SlotID slot) const;
|
||||||
|
|
||||||
bool contains(const CStackInstance *stack) const;
|
bool contains(const CStackInstance *stack) const;
|
||||||
|
@ -475,7 +475,7 @@ const TerrainTile * CGameInfoCallback::getTile( int3 tile, bool verbose) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO: typedef?
|
//TODO: typedef?
|
||||||
shared_ptr<boost::multi_array<TerrainTile*, 3>> CGameInfoCallback::getAllVisibleTiles() const
|
std::shared_ptr<boost::multi_array<TerrainTile*, 3>> CGameInfoCallback::getAllVisibleTiles() const
|
||||||
{
|
{
|
||||||
assert(player.is_initialized());
|
assert(player.is_initialized());
|
||||||
auto team = getPlayerTeam(player.get());
|
auto team = getPlayerTeam(player.get());
|
||||||
@ -496,7 +496,7 @@ shared_ptr<boost::multi_array<TerrainTile*, 3>> CGameInfoCallback::getAllVisible
|
|||||||
else
|
else
|
||||||
tileArray[x][y][z] = nullptr;
|
tileArray[x][y][z] = nullptr;
|
||||||
}
|
}
|
||||||
return make_shared<boost::multi_array<TerrainTile*, 3>>(tileArray);
|
return std::make_shared<boost::multi_array<TerrainTile*, 3>>(tileArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
EBuildingState::EBuildingState CGameInfoCallback::canBuildStructure( const CGTownInstance *t, BuildingID ID )
|
EBuildingState::EBuildingState CGameInfoCallback::canBuildStructure( const CGTownInstance *t, BuildingID ID )
|
||||||
@ -577,7 +577,7 @@ EPlayerStatus::EStatus CGameInfoCallback::getPlayerStatus(PlayerColor player, bo
|
|||||||
std::string CGameInfoCallback::getTavernRumor(const CGObjectInstance * townOrTavern) const
|
std::string CGameInfoCallback::getTavernRumor(const CGObjectInstance * townOrTavern) const
|
||||||
{
|
{
|
||||||
std::string text = "", extraText = "";
|
std::string text = "", extraText = "";
|
||||||
if(gs->rumor.type == RumorState::TYPE_NONE) // (version < 755 backward compatability
|
if(gs->rumor.type == RumorState::TYPE_NONE)
|
||||||
return text;
|
return text;
|
||||||
|
|
||||||
auto rumor = gs->rumor.last[gs->rumor.type];
|
auto rumor = gs->rumor.last[gs->rumor.type];
|
||||||
|
@ -91,7 +91,7 @@ public:
|
|||||||
const CMapHeader * getMapHeader()const;
|
const CMapHeader * getMapHeader()const;
|
||||||
int3 getMapSize() const; //returns size of map - z is 1 for one - level map and 2 for two level map
|
int3 getMapSize() const; //returns size of map - z is 1 for one - level map and 2 for two level map
|
||||||
const TerrainTile * getTile(int3 tile, bool verbose = true) const;
|
const TerrainTile * getTile(int3 tile, bool verbose = true) const;
|
||||||
shared_ptr<boost::multi_array<TerrainTile*, 3>> getAllVisibleTiles() const;
|
std::shared_ptr<boost::multi_array<TerrainTile*, 3>> getAllVisibleTiles() const;
|
||||||
bool isInTheMap(const int3 &pos) const;
|
bool isInTheMap(const int3 &pos) const;
|
||||||
|
|
||||||
//town
|
//town
|
||||||
|
@ -24,19 +24,19 @@
|
|||||||
#ifdef VCMI_ANDROID
|
#ifdef VCMI_ANDROID
|
||||||
// we can't use shared libraries on Android so here's a hack
|
// we can't use shared libraries on Android so here's a hack
|
||||||
extern "C" DLL_EXPORT void VCAI_GetAiName(char* name);
|
extern "C" DLL_EXPORT void VCAI_GetAiName(char* name);
|
||||||
extern "C" DLL_EXPORT void VCAI_GetNewAI(shared_ptr<CGlobalAI> &out);
|
extern "C" DLL_EXPORT void VCAI_GetNewAI(std::shared_ptr<CGlobalAI> &out);
|
||||||
|
|
||||||
extern "C" DLL_EXPORT void StupidAI_GetAiName(char* name);
|
extern "C" DLL_EXPORT void StupidAI_GetAiName(char* name);
|
||||||
extern "C" DLL_EXPORT void StupidAI_GetNewBattleAI(shared_ptr<CGlobalAI> &out);
|
extern "C" DLL_EXPORT void StupidAI_GetNewBattleAI(std::shared_ptr<CGlobalAI> &out);
|
||||||
|
|
||||||
extern "C" DLL_EXPORT void BattleAI_GetAiName(char* name);
|
extern "C" DLL_EXPORT void BattleAI_GetAiName(char* name);
|
||||||
extern "C" DLL_EXPORT void BattleAI_GetNewBattleAI(shared_ptr<CBattleGameInterface> &out);
|
extern "C" DLL_EXPORT void BattleAI_GetNewBattleAI(std::shared_ptr<CBattleGameInterface> &out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename rett>
|
template<typename rett>
|
||||||
shared_ptr<rett> createAny(const boost::filesystem::path& libpath, const std::string& methodName)
|
std::shared_ptr<rett> createAny(const boost::filesystem::path& libpath, const std::string& methodName)
|
||||||
{
|
{
|
||||||
typedef void(*TGetAIFun)(shared_ptr<rett>&);
|
typedef void(*TGetAIFun)(std::shared_ptr<rett>&);
|
||||||
typedef void(*TGetNameFun)(char*);
|
typedef void(*TGetNameFun)(char*);
|
||||||
|
|
||||||
char temp[150];
|
char temp[150];
|
||||||
@ -102,7 +102,7 @@ shared_ptr<rett> createAny(const boost::filesystem::path& libpath, const std::st
|
|||||||
getName(temp);
|
getName(temp);
|
||||||
logGlobal->infoStream() << "Loaded " << temp;
|
logGlobal->infoStream() << "Loaded " << temp;
|
||||||
|
|
||||||
shared_ptr<rett> ret;
|
std::shared_ptr<rett> ret;
|
||||||
getAI(ret);
|
getAI(ret);
|
||||||
if(!ret)
|
if(!ret)
|
||||||
logGlobal->errorStream() << "Cannot get AI!";
|
logGlobal->errorStream() << "Cannot get AI!";
|
||||||
@ -111,7 +111,7 @@ shared_ptr<rett> createAny(const boost::filesystem::path& libpath, const std::st
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename rett>
|
template<typename rett>
|
||||||
shared_ptr<rett> createAnyAI(std::string dllname, const std::string& methodName)
|
std::shared_ptr<rett> createAnyAI(std::string dllname, const std::string& methodName)
|
||||||
{
|
{
|
||||||
logGlobal->infoStream() << "Opening " << dllname;
|
logGlobal->infoStream() << "Opening " << dllname;
|
||||||
const boost::filesystem::path filePath =
|
const boost::filesystem::path filePath =
|
||||||
@ -121,17 +121,17 @@ shared_ptr<rett> createAnyAI(std::string dllname, const std::string& methodName)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<CGlobalAI> CDynLibHandler::getNewAI(std::string dllname)
|
std::shared_ptr<CGlobalAI> CDynLibHandler::getNewAI(std::string dllname)
|
||||||
{
|
{
|
||||||
return createAnyAI<CGlobalAI>(dllname, "GetNewAI");
|
return createAnyAI<CGlobalAI>(dllname, "GetNewAI");
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<CBattleGameInterface> CDynLibHandler::getNewBattleAI(std::string dllname )
|
std::shared_ptr<CBattleGameInterface> CDynLibHandler::getNewBattleAI(std::string dllname )
|
||||||
{
|
{
|
||||||
return createAnyAI<CBattleGameInterface>(dllname, "GetNewBattleAI");
|
return createAnyAI<CBattleGameInterface>(dllname, "GetNewBattleAI");
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<CScriptingModule> CDynLibHandler::getNewScriptingModule(std::string dllname)
|
std::shared_ptr<CScriptingModule> CDynLibHandler::getNewScriptingModule(std::string dllname)
|
||||||
{
|
{
|
||||||
return createAny<CScriptingModule>(dllname, "GetNewModule");
|
return createAny<CScriptingModule>(dllname, "GetNewModule");
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ public:
|
|||||||
std::string dllName;
|
std::string dllName;
|
||||||
|
|
||||||
virtual ~CBattleGameInterface() {};
|
virtual ~CBattleGameInterface() {};
|
||||||
virtual void init(shared_ptr<CBattleCallback> CB){};
|
virtual void init(std::shared_ptr<CBattleCallback> CB){};
|
||||||
|
|
||||||
//battle call-ins
|
//battle call-ins
|
||||||
virtual BattleAction activeStack(const CStack * stack)=0; //called when it's turn of that stack
|
virtual BattleAction activeStack(const CStack * stack)=0; //called when it's turn of that stack
|
||||||
@ -82,7 +82,7 @@ public:
|
|||||||
class DLL_LINKAGE CGameInterface : public CBattleGameInterface, public IGameEventsReceiver
|
class DLL_LINKAGE CGameInterface : public CBattleGameInterface, public IGameEventsReceiver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void init(shared_ptr<CCallback> CB){};
|
virtual void init(std::shared_ptr<CCallback> CB){};
|
||||||
virtual void yourTurn(){}; //called AFTER playerStartsTurn(player)
|
virtual void yourTurn(){}; //called AFTER playerStartsTurn(player)
|
||||||
|
|
||||||
//pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
|
//pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
|
||||||
@ -105,9 +105,9 @@ public:
|
|||||||
class DLL_LINKAGE CDynLibHandler
|
class DLL_LINKAGE CDynLibHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static shared_ptr<CGlobalAI> getNewAI(std::string dllname);
|
static std::shared_ptr<CGlobalAI> getNewAI(std::string dllname);
|
||||||
static shared_ptr<CBattleGameInterface> getNewBattleAI(std::string dllname);
|
static std::shared_ptr<CBattleGameInterface> getNewBattleAI(std::string dllname);
|
||||||
static shared_ptr<CScriptingModule> getNewScriptingModule(std::string dllname);
|
static std::shared_ptr<CScriptingModule> getNewScriptingModule(std::string dllname);
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CGlobalAI : public CGameInterface // AI class (to derivate)
|
class DLL_LINKAGE CGlobalAI : public CGameInterface // AI class (to derivate)
|
||||||
@ -123,8 +123,8 @@ class DLL_LINKAGE CAdventureAI : public CGlobalAI
|
|||||||
public:
|
public:
|
||||||
CAdventureAI() {};
|
CAdventureAI() {};
|
||||||
|
|
||||||
shared_ptr<CBattleGameInterface> battleAI;
|
std::shared_ptr<CBattleGameInterface> battleAI;
|
||||||
shared_ptr<CBattleCallback> cbc;
|
std::shared_ptr<CBattleCallback> cbc;
|
||||||
|
|
||||||
virtual std::string getBattleAIName() const = 0; //has to return name of the battle AI to be used
|
virtual std::string getBattleAIName() const = 0; //has to return name of the battle AI to be used
|
||||||
|
|
||||||
|
@ -1939,7 +1939,7 @@ BFieldType CGameState::battleGetBattlefieldType(int3 tile)
|
|||||||
case Obj::EVIL_FOG:
|
case Obj::EVIL_FOG:
|
||||||
return BFieldType::EVIL_FOG;
|
return BFieldType::EVIL_FOG;
|
||||||
case Obj::FAVORABLE_WINDS:
|
case Obj::FAVORABLE_WINDS:
|
||||||
return BFieldType::FAVOURABLE_WINDS;
|
return BFieldType::FAVORABLE_WINDS;
|
||||||
case Obj::FIERY_FIELDS:
|
case Obj::FIERY_FIELDS:
|
||||||
return BFieldType::FIERY_FIELDS;
|
return BFieldType::FIERY_FIELDS;
|
||||||
case Obj::HOLY_GROUNDS:
|
case Obj::HOLY_GROUNDS:
|
||||||
@ -3177,7 +3177,7 @@ DuelParameters DuelParameters::fromJSON(const std::string &fname)
|
|||||||
|
|
||||||
for(const JsonNode &n : duelData["obstacles"].Vector())
|
for(const JsonNode &n : duelData["obstacles"].Vector())
|
||||||
{
|
{
|
||||||
auto oi = make_shared<CObstacleInstance>();
|
auto oi = std::make_shared<CObstacleInstance>();
|
||||||
if(n.getType() == JsonNode::DATA_VECTOR)
|
if(n.getType() == JsonNode::DATA_VECTOR)
|
||||||
{
|
{
|
||||||
oi->ID = n.Vector()[0].Float();
|
oi->ID = n.Vector()[0].Float();
|
||||||
|
@ -100,7 +100,7 @@ struct DLL_LINKAGE RumorState
|
|||||||
ERumorType type;
|
ERumorType type;
|
||||||
std::map<ERumorType, std::pair<int, int>> last;
|
std::map<ERumorType, std::pair<int, int>> last;
|
||||||
|
|
||||||
RumorState(){type = TYPE_NONE; last = {};};
|
RumorState(){type = TYPE_NONE;};
|
||||||
bool update(int id, int extra);
|
bool update(int id, int extra);
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
@ -149,7 +149,7 @@ struct DLL_EXPORT DuelParameters
|
|||||||
}
|
}
|
||||||
} sides[2];
|
} sides[2];
|
||||||
|
|
||||||
std::vector<shared_ptr<CObstacleInstance> > obstacles;
|
std::vector<std::shared_ptr<CObstacleInstance> > obstacles;
|
||||||
|
|
||||||
static DuelParameters fromJSON(const std::string &fname);
|
static DuelParameters fromJSON(const std::string &fname);
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & scenarioOps & initialOpts & currentPlayer & day & map & players & teams & hpool & globalEffects & rand;
|
h & scenarioOps & initialOpts & currentPlayer & day & map & players & teams & hpool & globalEffects & rand;
|
||||||
if(version >= 755)
|
if(version >= 755) //save format backward compatibility
|
||||||
{
|
{
|
||||||
h & rumor;
|
h & rumor;
|
||||||
}
|
}
|
||||||
|
@ -150,22 +150,24 @@ void CPathfinder::calculatePaths()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
destAction = getDestAction();
|
destAction = getDestAction();
|
||||||
int cost = CPathfinderHelper::getMovementCost(hero, cp->coord, dp->coord, ct, dt, movement, hlp->getTurnInfo());
|
int turnAtNextTile = turn, moveAtNextTile = movement;
|
||||||
int remains = movement - cost;
|
int cost = CPathfinderHelper::getMovementCost(hero, cp->coord, dp->coord, ct, dt, moveAtNextTile, hlp->getTurnInfo());
|
||||||
if(destAction == CGPathNode::EMBARK || destAction == CGPathNode::DISEMBARK)
|
int remains = moveAtNextTile - cost;
|
||||||
{
|
|
||||||
remains = hero->movementPointsAfterEmbark(movement, cost, destAction - 1, hlp->getTurnInfo());
|
|
||||||
cost = movement - remains;
|
|
||||||
}
|
|
||||||
int turnAtNextTile = turn;
|
|
||||||
if(remains < 0)
|
if(remains < 0)
|
||||||
{
|
{
|
||||||
//occurs rarely, when hero with low movepoints tries to leave the road
|
//occurs rarely, when hero with low movepoints tries to leave the road
|
||||||
hlp->updateTurnInfo(++turnAtNextTile);
|
hlp->updateTurnInfo(++turnAtNextTile);
|
||||||
int moveAtNextTile = hlp->getMaxMovePoints(i);
|
moveAtNextTile = hlp->getMaxMovePoints(i);
|
||||||
cost = CPathfinderHelper::getMovementCost(hero, cp->coord, dp->coord, ct, dt, moveAtNextTile, hlp->getTurnInfo()); //cost must be updated, movement points changed :(
|
cost = CPathfinderHelper::getMovementCost(hero, cp->coord, dp->coord, ct, dt, moveAtNextTile, hlp->getTurnInfo()); //cost must be updated, movement points changed :(
|
||||||
remains = moveAtNextTile - cost;
|
remains = moveAtNextTile - cost;
|
||||||
}
|
}
|
||||||
|
if(destAction == CGPathNode::EMBARK || destAction == CGPathNode::DISEMBARK)
|
||||||
|
{
|
||||||
|
/// FREE_SHIP_BOARDING bonus only remove additional penalty
|
||||||
|
/// land <-> sail transition still cost movement points as normal movement
|
||||||
|
remains = hero->movementPointsAfterEmbark(moveAtNextTile, cost, destAction - 1, hlp->getTurnInfo());
|
||||||
|
cost = moveAtNextTile - remains;
|
||||||
|
}
|
||||||
|
|
||||||
if(isBetterWay(remains, turnAtNextTile) &&
|
if(isBetterWay(remains, turnAtNextTile) &&
|
||||||
((cp->turns == turnAtNextTile && remains) || passOneTurnLimitCheck()))
|
((cp->turns == turnAtNextTile && remains) || passOneTurnLimitCheck()))
|
||||||
@ -189,13 +191,23 @@ void CPathfinder::calculatePaths()
|
|||||||
dp = out.getNode(neighbour, cp->layer);
|
dp = out.getNode(neighbour, cp->layer);
|
||||||
if(dp->locked)
|
if(dp->locked)
|
||||||
continue;
|
continue;
|
||||||
|
/// TODO: We may consider use invisible exits on FoW border in future
|
||||||
|
/// Useful for AI when at least one tile around exit is visible and passable
|
||||||
|
/// Objects are usually visible on FoW border anyway so it's not cheating.
|
||||||
|
///
|
||||||
|
/// For now it's disabled as it's will cause crashes in movement code.
|
||||||
|
if(dp->accessible == CGPathNode::BLOCKED)
|
||||||
|
continue;
|
||||||
|
|
||||||
if(isBetterWay(movement, turn))
|
if(isBetterWay(movement, turn))
|
||||||
{
|
{
|
||||||
|
dtObj = gs->map->getTile(neighbour).topVisitableObj();
|
||||||
|
|
||||||
dp->moveRemains = movement;
|
dp->moveRemains = movement;
|
||||||
dp->turns = turn;
|
dp->turns = turn;
|
||||||
dp->theNodeBefore = cp;
|
dp->theNodeBefore = cp;
|
||||||
dp->action = CGPathNode::NORMAL;
|
dp->action = getTeleportDestAction();
|
||||||
|
if(dp->action == CGPathNode::TELEPORT_NORMAL)
|
||||||
pq.push(dp);
|
pq.push(dp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -361,6 +373,16 @@ bool CPathfinder::isLayerTransitionPossible() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ELayer::WATER:
|
||||||
|
if(dp->accessible != CGPathNode::ACCESSIBLE && dp->accessible != CGPathNode::VISITABLE)
|
||||||
|
{
|
||||||
|
/// Hero that walking on water can transit to accessible and visitable tiles
|
||||||
|
/// Though hero can't interact with blocking visit objects while standing on water
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,7 +465,7 @@ bool CPathfinder::isMovementAfterDestPossible() const
|
|||||||
/// Transit over whirlpools only allowed when hero protected
|
/// Transit over whirlpools only allowed when hero protected
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if(dtObj->ID == Obj::GARRISON || dtObj->ID == Obj::GARRISON2)
|
else if(dtObj->ID == Obj::GARRISON || dtObj->ID == Obj::GARRISON2 || dtObj->ID == Obj::BORDER_GATE)
|
||||||
{
|
{
|
||||||
/// Transit via unguarded garrisons is always possible
|
/// Transit via unguarded garrisons is always possible
|
||||||
return true;
|
return true;
|
||||||
@ -507,18 +529,33 @@ CGPathNode::ENodeAction CPathfinder::getDestAction() const
|
|||||||
else
|
else
|
||||||
action = CGPathNode::BLOCKING_VISIT;
|
action = CGPathNode::BLOCKING_VISIT;
|
||||||
}
|
}
|
||||||
else if(dtObj->ID == Obj::TOWN && objRel == PlayerRelations::ENEMIES)
|
else if(dtObj->ID == Obj::TOWN)
|
||||||
{
|
{
|
||||||
const CGTownInstance * townObj = dynamic_cast<const CGTownInstance *>(dtObj);
|
if(dtObj->passableFor(hero->tempOwner))
|
||||||
if(townObj->armedGarrison())
|
action = CGPathNode::VISIT;
|
||||||
|
else if(objRel == PlayerRelations::ENEMIES)
|
||||||
action = CGPathNode::BATTLE;
|
action = CGPathNode::BATTLE;
|
||||||
}
|
}
|
||||||
else if(dtObj->ID == Obj::GARRISON || dtObj->ID == Obj::GARRISON2)
|
else if(dtObj->ID == Obj::GARRISON || dtObj->ID == Obj::GARRISON2)
|
||||||
{
|
{
|
||||||
const CGGarrison * garrisonObj = dynamic_cast<const CGGarrison *>(dtObj);
|
if(dtObj->passableFor(hero->tempOwner))
|
||||||
if((garrisonObj->stacksCount() && objRel == PlayerRelations::ENEMIES) || isDestinationGuarded(true))
|
{
|
||||||
|
if(isDestinationGuarded(true))
|
||||||
action = CGPathNode::BATTLE;
|
action = CGPathNode::BATTLE;
|
||||||
}
|
}
|
||||||
|
else if(objRel == PlayerRelations::ENEMIES)
|
||||||
|
action = CGPathNode::BATTLE;
|
||||||
|
}
|
||||||
|
else if(dtObj->ID == Obj::BORDER_GATE)
|
||||||
|
{
|
||||||
|
if(dtObj->passableFor(hero->tempOwner))
|
||||||
|
{
|
||||||
|
if(isDestinationGuarded(true))
|
||||||
|
action = CGPathNode::BATTLE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
action = CGPathNode::BLOCKING_VISIT;
|
||||||
|
}
|
||||||
else if(isDestinationGuardian())
|
else if(isDestinationGuardian())
|
||||||
action = CGPathNode::BATTLE;
|
action = CGPathNode::BATTLE;
|
||||||
else if(dtObj->blockVisit && !(options.useCastleGate && dtObj->ID == Obj::TOWN))
|
else if(dtObj->blockVisit && !(options.useCastleGate && dtObj->ID == Obj::TOWN))
|
||||||
@ -541,6 +578,21 @@ CGPathNode::ENodeAction CPathfinder::getDestAction() const
|
|||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CGPathNode::ENodeAction CPathfinder::getTeleportDestAction() const
|
||||||
|
{
|
||||||
|
CGPathNode::ENodeAction action = CGPathNode::TELEPORT_NORMAL;
|
||||||
|
if(isDestVisitableObj() && dtObj->ID == Obj::HERO)
|
||||||
|
{
|
||||||
|
auto objRel = getPlayerRelations(dtObj->tempOwner, hero->tempOwner);
|
||||||
|
if(objRel == PlayerRelations::ENEMIES)
|
||||||
|
action = CGPathNode::TELEPORT_BATTLE;
|
||||||
|
else
|
||||||
|
action = CGPathNode::TELEPORT_BLOCKING_VISIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
bool CPathfinder::isSourceInitialPosition() const
|
bool CPathfinder::isSourceInitialPosition() const
|
||||||
{
|
{
|
||||||
return cp->coord == out.hpos;
|
return cp->coord == out.hpos;
|
||||||
@ -987,7 +1039,7 @@ int CPathfinderHelper::getMovementCost(const CGHeroInstance * h, const int3 & sr
|
|||||||
}
|
}
|
||||||
else if(dt->terType == ETerrainType::WATER)
|
else if(dt->terType == ETerrainType::WATER)
|
||||||
{
|
{
|
||||||
if(h->boat && ct->hasFavourableWinds() && dt->hasFavourableWinds()) //Favourable Winds
|
if(h->boat && ct->hasFavorableWinds() && dt->hasFavorableWinds())
|
||||||
ret *= 0.666;
|
ret *= 0.666;
|
||||||
else if(!h->boat && ti->hasBonusOfType(Bonus::WATER_WALKING))
|
else if(!h->boat && ti->hasBonusOfType(Bonus::WATER_WALKING))
|
||||||
{
|
{
|
||||||
|
@ -36,7 +36,10 @@ struct DLL_LINKAGE CGPathNode
|
|||||||
NORMAL,
|
NORMAL,
|
||||||
BATTLE,
|
BATTLE,
|
||||||
VISIT,
|
VISIT,
|
||||||
BLOCKING_VISIT
|
BLOCKING_VISIT,
|
||||||
|
TELEPORT_NORMAL,
|
||||||
|
TELEPORT_BLOCKING_VISIT,
|
||||||
|
TELEPORT_BATTLE
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EAccessibility : ui8
|
enum EAccessibility : ui8
|
||||||
@ -159,7 +162,7 @@ private:
|
|||||||
CPathsInfo & out;
|
CPathsInfo & out;
|
||||||
const CGHeroInstance * hero;
|
const CGHeroInstance * hero;
|
||||||
const std::vector<std::vector<std::vector<ui8> > > &FoW;
|
const std::vector<std::vector<std::vector<ui8> > > &FoW;
|
||||||
unique_ptr<CPathfinderHelper> hlp;
|
std::unique_ptr<CPathfinderHelper> hlp;
|
||||||
|
|
||||||
enum EPatrolState {
|
enum EPatrolState {
|
||||||
PATROL_NONE = 0,
|
PATROL_NONE = 0,
|
||||||
@ -202,6 +205,7 @@ private:
|
|||||||
bool isMovementToDestPossible() const;
|
bool isMovementToDestPossible() const;
|
||||||
bool isMovementAfterDestPossible() const;
|
bool isMovementAfterDestPossible() const;
|
||||||
CGPathNode::ENodeAction getDestAction() const;
|
CGPathNode::ENodeAction getDestAction() const;
|
||||||
|
CGPathNode::ENodeAction getTeleportDestAction() const;
|
||||||
|
|
||||||
bool isSourceInitialPosition() const;
|
bool isSourceInitialPosition() const;
|
||||||
bool isSourceVisitableObj() const;
|
bool isSourceVisitableObj() const;
|
||||||
@ -240,7 +244,7 @@ struct DLL_LINKAGE TurnInfo
|
|||||||
|
|
||||||
BonusCache(TBonusListPtr bonusList);
|
BonusCache(TBonusListPtr bonusList);
|
||||||
};
|
};
|
||||||
unique_ptr<BonusCache> bonusCache;
|
std::unique_ptr<BonusCache> bonusCache;
|
||||||
|
|
||||||
const CGHeroInstance * hero;
|
const CGHeroInstance * hero;
|
||||||
TBonusListPtr bonuses;
|
TBonusListPtr bonuses;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* timeHandler.h, part of VCMI engine
|
* CStopWatch.h, part of VCMI engine
|
||||||
*
|
*
|
||||||
* Authors: listed in file AUTHORS in main folder
|
* Authors: listed in file AUTHORS in main folder
|
||||||
*
|
*
|
||||||
|
@ -17,9 +17,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using namespace boost;
|
|
||||||
using namespace boost::asio::ip;
|
|
||||||
|
|
||||||
extern template void registerTypes<CISer>(CISer & s);
|
extern template void registerTypes<CISer>(CISer & s);
|
||||||
extern template void registerTypes<COSer>(COSer & s);
|
extern template void registerTypes<COSer>(COSer & s);
|
||||||
extern template void registerTypes<CTypeList>(CTypeList & s);
|
extern template void registerTypes<CTypeList>(CTypeList & s);
|
||||||
@ -70,13 +67,13 @@ void CConnection::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
CConnection::CConnection(std::string host, std::string port, std::string Name)
|
CConnection::CConnection(std::string host, std::string port, std::string Name)
|
||||||
:iser(this), oser(this), io_service(new asio::io_service), name(Name)
|
:iser(this), oser(this), io_service(new boost::asio::io_service), name(Name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
boost::system::error_code error = asio::error::host_not_found;
|
boost::system::error_code error = boost::asio::error::host_not_found;
|
||||||
socket = new tcp::socket(*io_service);
|
socket = new boost::asio::ip::tcp::socket(*io_service);
|
||||||
tcp::resolver resolver(*io_service);
|
boost::asio::ip::tcp::resolver resolver(*io_service);
|
||||||
tcp::resolver::iterator end, pom, endpoint_iterator = resolver.resolve(tcp::resolver::query(host,port),error);
|
boost::asio::ip::tcp::resolver::iterator end, pom, endpoint_iterator = resolver.resolve(boost::asio::ip::tcp::resolver::query(host,port),error);
|
||||||
if(error)
|
if(error)
|
||||||
{
|
{
|
||||||
logNetwork->errorStream() << "Problem with resolving: \n" << error;
|
logNetwork->errorStream() << "Problem with resolving: \n" << error;
|
||||||
@ -132,8 +129,8 @@ CConnection::CConnection(TSocket * Socket, std::string Name )
|
|||||||
CConnection::CConnection(TAcceptor * acceptor, boost::asio::io_service *Io_service, std::string Name)
|
CConnection::CConnection(TAcceptor * acceptor, boost::asio::io_service *Io_service, std::string Name)
|
||||||
: iser(this), oser(this), name(Name)//, send(this), rec(this)
|
: iser(this), oser(this), name(Name)//, send(this), rec(this)
|
||||||
{
|
{
|
||||||
boost::system::error_code error = asio::error::host_not_found;
|
boost::system::error_code error = boost::asio::error::host_not_found;
|
||||||
socket = new tcp::socket(*io_service);
|
socket = new boost::asio::ip::tcp::socket(*io_service);
|
||||||
acceptor->accept(*socket,error);
|
acceptor->accept(*socket,error);
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
@ -149,7 +146,7 @@ int CConnection::write(const void * data, unsigned size)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
ret = asio::write(*socket,asio::const_buffers_1(asio::const_buffer(data,size)));
|
ret = boost::asio::write(*socket,boost::asio::const_buffers_1(boost::asio::const_buffer(data,size)));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
@ -164,7 +161,7 @@ int CConnection::read(void * data, unsigned size)
|
|||||||
//LOG("Receiving " << size << " byte(s) of data" <<std::endl);
|
//LOG("Receiving " << size << " byte(s) of data" <<std::endl);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int ret = asio::read(*socket,asio::mutable_buffers_1(asio::mutable_buffer(data,size)));
|
int ret = boost::asio::read(*socket,boost::asio::mutable_buffers_1(boost::asio::mutable_buffer(data,size)));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
@ -442,7 +439,7 @@ CTypeList::TypeInfoPtr CTypeList::registerType( const std::type_info *type )
|
|||||||
return typeDescr; //type found, return ptr to structure
|
return typeDescr; //type found, return ptr to structure
|
||||||
|
|
||||||
//type not found - add it to the list and return given ID
|
//type not found - add it to the list and return given ID
|
||||||
auto newType = make_shared<TypeDescriptor>();
|
auto newType = std::make_shared<TypeDescriptor>();
|
||||||
newType->typeID = typeInfos.size() + 1;
|
newType->typeID = typeInfos.size() + 1;
|
||||||
newType->name = type->name();
|
newType->name = type->name();
|
||||||
typeInfos[type] = newType;
|
typeInfos[type] = newType;
|
||||||
@ -450,18 +447,19 @@ CTypeList::TypeInfoPtr CTypeList::registerType( const std::type_info *type )
|
|||||||
return newType;
|
return newType;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui16 CTypeList::getTypeID( const std::type_info *type )
|
ui16 CTypeList::getTypeID( const std::type_info *type, bool throws ) const
|
||||||
|
{
|
||||||
|
auto descriptor = getTypeDescriptor(type, throws);
|
||||||
|
if (descriptor == nullptr)
|
||||||
{
|
{
|
||||||
auto i = typeInfos.find(type);
|
|
||||||
if(i != typeInfos.end())
|
|
||||||
return i->second->typeID;
|
|
||||||
else
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
return descriptor->typeID;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(TypeInfoPtr from, TypeInfoPtr to)
|
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(TypeInfoPtr from, TypeInfoPtr to) const
|
||||||
{
|
{
|
||||||
if(from == to)
|
if(!strcmp(from->name, to->name))
|
||||||
return std::vector<CTypeList::TypeInfoPtr>();
|
return std::vector<CTypeList::TypeInfoPtr>();
|
||||||
|
|
||||||
// Perform a simple BFS in the class hierarchy.
|
// Perform a simple BFS in the class hierarchy.
|
||||||
@ -512,17 +510,17 @@ std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(TypeInfoPtr from, Ty
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(const std::type_info *from, const std::type_info *to)
|
std::vector<CTypeList::TypeInfoPtr> CTypeList::castSequence(const std::type_info *from, const std::type_info *to) const
|
||||||
{
|
{
|
||||||
//This additional if is needed because getTypeDescriptor might fail if type is not registered
|
//This additional if is needed because getTypeDescriptor might fail if type is not registered
|
||||||
// (and if casting is not needed, then registereing should no be required)
|
// (and if casting is not needed, then registereing should no be required)
|
||||||
if(*from == *to)
|
if(!strcmp(from->name(), to->name()))
|
||||||
return std::vector<CTypeList::TypeInfoPtr>();
|
return std::vector<CTypeList::TypeInfoPtr>();
|
||||||
|
|
||||||
return castSequence(getTypeDescriptor(from), getTypeDescriptor(to));
|
return castSequence(getTypeDescriptor(from), getTypeDescriptor(to));
|
||||||
}
|
}
|
||||||
|
|
||||||
CTypeList::TypeInfoPtr CTypeList::getTypeDescriptor(const std::type_info *type, bool throws)
|
CTypeList::TypeInfoPtr CTypeList::getTypeDescriptor(const std::type_info *type, bool throws) const
|
||||||
{
|
{
|
||||||
auto i = typeInfos.find(type);
|
auto i = typeInfos.find(type);
|
||||||
if(i != typeInfos.end())
|
if(i != typeInfos.end())
|
||||||
@ -606,7 +604,7 @@ int CLoadIntegrityValidator::read( void * data, unsigned size )
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<CLoadFile> CLoadIntegrityValidator::decay()
|
std::unique_ptr<CLoadFile> CLoadIntegrityValidator::decay()
|
||||||
{
|
{
|
||||||
primaryFile->serializer.loadedPointers = this->serializer.loadedPointers;
|
primaryFile->serializer.loadedPointers = this->serializer.loadedPointers;
|
||||||
primaryFile->serializer.loadedPointersTypes = this->serializer.loadedPointersTypes;
|
primaryFile->serializer.loadedPointersTypes = this->serializer.loadedPointersTypes;
|
||||||
@ -646,4 +644,3 @@ CMemorySerializer::CMemorySerializer(): iser(this), oser(this)
|
|||||||
registerTypes(iser);
|
registerTypes(iser);
|
||||||
registerTypes(oser);
|
registerTypes(oser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
148
lib/Connection.h
148
lib/Connection.h
@ -83,7 +83,11 @@ struct TypeComparer
|
|||||||
{
|
{
|
||||||
bool operator()(const std::type_info *a, const std::type_info *b) const
|
bool operator()(const std::type_info *a, const std::type_info *b) const
|
||||||
{
|
{
|
||||||
|
#ifndef __APPLE__
|
||||||
return a->before(*b);
|
return a->before(*b);
|
||||||
|
#else
|
||||||
|
return strcmp(a->name(), b->name()) < 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -102,6 +106,11 @@ struct PointerCaster : IPointerCaster
|
|||||||
{
|
{
|
||||||
From * from = (From*)boost::any_cast<void*>(ptr);
|
From * from = (From*)boost::any_cast<void*>(ptr);
|
||||||
To * ret = dynamic_cast<To*>(from);
|
To * ret = dynamic_cast<To*>(from);
|
||||||
|
if (ret == nullptr)
|
||||||
|
{
|
||||||
|
// Last resort when RTTI goes mad
|
||||||
|
ret = static_cast<To*>(from);
|
||||||
|
}
|
||||||
return (void*)ret;
|
return (void*)ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +122,11 @@ struct PointerCaster : IPointerCaster
|
|||||||
{
|
{
|
||||||
auto from = boost::any_cast<SmartPt>(ptr);
|
auto from = boost::any_cast<SmartPt>(ptr);
|
||||||
auto ret = std::dynamic_pointer_cast<To>(from);
|
auto ret = std::dynamic_pointer_cast<To>(from);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
// Last resort when RTTI goes mad
|
||||||
|
ret = std::static_pointer_cast<To>(from);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
@ -136,7 +150,7 @@ struct PointerCaster : IPointerCaster
|
|||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CTypeList
|
class DLL_LINKAGE CTypeList: public boost::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct TypeDescriptor;
|
struct TypeDescriptor;
|
||||||
@ -147,33 +161,53 @@ public:
|
|||||||
const char *name;
|
const char *name;
|
||||||
std::vector<TypeInfoPtr> children, parents;
|
std::vector<TypeInfoPtr> children, parents;
|
||||||
};
|
};
|
||||||
|
typedef boost::shared_mutex TMutex;
|
||||||
|
typedef boost::unique_lock<TMutex> TUniqueLock;
|
||||||
|
typedef boost::shared_lock<TMutex> TSharedLock;
|
||||||
private:
|
private:
|
||||||
|
mutable TMutex mx;
|
||||||
|
|
||||||
std::map<const std::type_info *, TypeInfoPtr, TypeComparer> typeInfos;
|
std::map<const std::type_info *, TypeInfoPtr, TypeComparer> typeInfos;
|
||||||
std::map<std::pair<TypeInfoPtr, TypeInfoPtr>, std::unique_ptr<const IPointerCaster>> casters; //for each pair <Base, Der> we provide a caster (each registered relations creates a single entry here)
|
std::map<std::pair<TypeInfoPtr, TypeInfoPtr>, std::unique_ptr<const IPointerCaster>> casters; //for each pair <Base, Der> we provide a caster (each registered relations creates a single entry here)
|
||||||
|
|
||||||
CTypeList(CTypeList &)
|
/// Returns sequence of types starting from "from" and ending on "to". Every next type is derived from the previous.
|
||||||
{
|
/// Throws if there is no link registered.
|
||||||
// This type is non-copyable.
|
std::vector<TypeInfoPtr> castSequence(TypeInfoPtr from, TypeInfoPtr to) const;
|
||||||
// Unfortunately on Windows it is required for DLL_EXPORT-ed type to provide copy c-tor, so we can't =delete it.
|
std::vector<TypeInfoPtr> castSequence(const std::type_info *from, const std::type_info *to) const;
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
CTypeList &operator=(CTypeList &)
|
|
||||||
{
|
|
||||||
// As above.
|
|
||||||
assert(0);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
|
|
||||||
CTypeList();
|
|
||||||
|
template<boost::any(IPointerCaster::*CastingFunction)(const boost::any &) const>
|
||||||
|
boost::any castHelper(boost::any inputPtr, const std::type_info *fromArg, const std::type_info *toArg) const
|
||||||
|
{
|
||||||
|
TSharedLock lock(mx);
|
||||||
|
auto typesSequence = castSequence(fromArg, toArg);
|
||||||
|
|
||||||
|
boost::any ptr = inputPtr;
|
||||||
|
for(int i = 0; i < static_cast<int>(typesSequence.size()) - 1; i++)
|
||||||
|
{
|
||||||
|
auto &from = typesSequence[i];
|
||||||
|
auto &to = typesSequence[i + 1];
|
||||||
|
auto castingPair = std::make_pair(from, to);
|
||||||
|
if(!casters.count(castingPair))
|
||||||
|
THROW_FORMAT("Cannot find caster for conversion %s -> %s which is needed to cast %s -> %s", from->name % to->name % fromArg->name() % toArg->name());
|
||||||
|
|
||||||
|
auto &caster = casters.at(castingPair);
|
||||||
|
ptr = (*caster.*CastingFunction)(ptr); //Why does std::unique_ptr not have operator->* ..?
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeInfoPtr getTypeDescriptor(const std::type_info *type, bool throws = true) const; //if not throws, failure returns nullptr
|
||||||
|
|
||||||
TypeInfoPtr registerType(const std::type_info *type);
|
TypeInfoPtr registerType(const std::type_info *type);
|
||||||
|
public:
|
||||||
|
CTypeList();
|
||||||
|
|
||||||
template <typename Base, typename Derived>
|
template <typename Base, typename Derived>
|
||||||
void registerType(const Base * b = nullptr, const Derived * d = nullptr)
|
void registerType(const Base * b = nullptr, const Derived * d = nullptr)
|
||||||
{
|
{
|
||||||
|
TUniqueLock lock(mx);
|
||||||
static_assert(std::is_base_of<Base, Derived>::value, "First registerType template parameter needs to ba a base class of the second one.");
|
static_assert(std::is_base_of<Base, Derived>::value, "First registerType template parameter needs to ba a base class of the second one.");
|
||||||
static_assert(std::has_virtual_destructor<Base>::value, "Base class needs to have a virtual destructor.");
|
static_assert(std::has_virtual_destructor<Base>::value, "Base class needs to have a virtual destructor.");
|
||||||
static_assert(!std::is_same<Base, Derived>::value, "Parameters of registerTypes should be two diffrenet types.");
|
static_assert(!std::is_same<Base, Derived>::value, "Parameters of registerTypes should be two diffrenet types.");
|
||||||
@ -187,77 +221,52 @@ public:
|
|||||||
casters[std::make_pair(dti, bti)] = make_unique<const PointerCaster<Derived, Base>>();
|
casters[std::make_pair(dti, bti)] = make_unique<const PointerCaster<Derived, Base>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
ui16 getTypeID(const std::type_info *type);
|
ui16 getTypeID(const std::type_info *type, bool throws = false) const;
|
||||||
TypeInfoPtr getTypeDescriptor(const std::type_info *type, bool throws = true); //if not throws, failure returns nullptr
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
ui16 getTypeID(const T * t = nullptr)
|
ui16 getTypeID(const T * t = nullptr, bool throws = false) const
|
||||||
{
|
{
|
||||||
return getTypeID(getTypeInfo(t));
|
return getTypeID(getTypeInfo(t), throws);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Returns sequence of types starting from "from" and ending on "to". Every next type is derived from the previous.
|
|
||||||
// Throws if there is no link registered.
|
|
||||||
std::vector<TypeInfoPtr> castSequence(TypeInfoPtr from, TypeInfoPtr to);
|
|
||||||
std::vector<TypeInfoPtr> castSequence(const std::type_info *from, const std::type_info *to);
|
|
||||||
|
|
||||||
template<boost::any(IPointerCaster::*CastingFunction)(const boost::any &) const>
|
|
||||||
boost::any castHelper(boost::any inputPtr, const std::type_info *fromArg, const std::type_info *toArg)
|
|
||||||
{
|
|
||||||
auto typesSequence = castSequence(fromArg, toArg);
|
|
||||||
|
|
||||||
boost::any ptr = inputPtr;
|
|
||||||
for(int i = 0; i < (int)typesSequence.size() - 1; i++)
|
|
||||||
{
|
|
||||||
auto &from = typesSequence[i];
|
|
||||||
auto &to = typesSequence[i + 1];
|
|
||||||
auto castingPair = std::make_pair(from, to);
|
|
||||||
if(!casters.count(castingPair))
|
|
||||||
THROW_FORMAT("Cannot find caster for conversion %s -> %s which is needed to cast %s -> %s", from->name % to->name % fromArg->name() % toArg->name());
|
|
||||||
|
|
||||||
auto &caster = casters.at(castingPair);
|
|
||||||
ptr = (*caster.*CastingFunction)(ptr); //Why does unique_ptr does not have operator->* ..?
|
|
||||||
}
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TInput>
|
template<typename TInput>
|
||||||
void *castToMostDerived(const TInput *inputPtr)
|
void * castToMostDerived(const TInput * inputPtr) const
|
||||||
{
|
{
|
||||||
auto &baseType = typeid(typename std::remove_cv<TInput>::type);
|
auto &baseType = typeid(typename std::remove_cv<TInput>::type);
|
||||||
auto derivedType = getTypeInfo(inputPtr);
|
auto derivedType = getTypeInfo(inputPtr);
|
||||||
|
|
||||||
if(baseType == *derivedType)
|
if (!strcmp(baseType.name(), derivedType->name()))
|
||||||
return (void*)inputPtr;
|
{
|
||||||
|
return const_cast<void*>(reinterpret_cast<const void*>(inputPtr));
|
||||||
|
}
|
||||||
|
|
||||||
return boost::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>((void*)inputPtr, &baseType, derivedType));
|
return boost::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>(
|
||||||
|
const_cast<void*>(reinterpret_cast<const void*>(inputPtr)), &baseType,
|
||||||
|
derivedType));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TInput>
|
template<typename TInput>
|
||||||
boost::any castSharedToMostDerived(const std::shared_ptr<TInput> inputPtr)
|
boost::any castSharedToMostDerived(const std::shared_ptr<TInput> inputPtr) const
|
||||||
{
|
{
|
||||||
auto &baseType = typeid(typename std::remove_cv<TInput>::type);
|
auto &baseType = typeid(typename std::remove_cv<TInput>::type);
|
||||||
auto derivedType = getTypeInfo(inputPtr.get());
|
auto derivedType = getTypeInfo(inputPtr.get());
|
||||||
|
|
||||||
if(baseType == *derivedType)
|
if (!strcmp(baseType.name(), derivedType->name()))
|
||||||
return inputPtr;
|
return inputPtr;
|
||||||
|
|
||||||
return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, &baseType, derivedType);
|
return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, &baseType, derivedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* castRaw(void *inputPtr, const std::type_info *from, const std::type_info *to)
|
void * castRaw(void *inputPtr, const std::type_info *from, const std::type_info *to) const
|
||||||
{
|
{
|
||||||
return boost::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>(inputPtr, from, to));
|
return boost::any_cast<void*>(castHelper<&IPointerCaster::castRawPtr>(inputPtr, from, to));
|
||||||
}
|
}
|
||||||
boost::any castShared(boost::any inputPtr, const std::type_info *from, const std::type_info *to)
|
boost::any castShared(boost::any inputPtr, const std::type_info *from, const std::type_info *to) const
|
||||||
{
|
{
|
||||||
return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, from, to);
|
return castHelper<&IPointerCaster::castSharedPtr>(inputPtr, from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T> const std::type_info * getTypeInfo(const T * t = nullptr) const
|
||||||
template <typename T> const std::type_info * getTypeInfo(const T * t = nullptr)
|
|
||||||
{
|
{
|
||||||
if(t)
|
if(t)
|
||||||
return &typeid(*t);
|
return &typeid(*t);
|
||||||
@ -665,9 +674,8 @@ public:
|
|||||||
{
|
{
|
||||||
COSer &s = static_cast<COSer&>(ar);
|
COSer &s = static_cast<COSer&>(ar);
|
||||||
const T *ptr = static_cast<const T*>(data);
|
const T *ptr = static_cast<const T*>(data);
|
||||||
|
|
||||||
//T is most derived known type, it's time to call actual serialize
|
//T is most derived known type, it's time to call actual serialize
|
||||||
const_cast<T&>(*ptr).serialize(s,version);
|
const_cast<T*>(ptr)->serialize(s,version);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -841,13 +849,13 @@ public:
|
|||||||
const_cast<T&>(data).serialize(*this,version);
|
const_cast<T&>(data).serialize(*this,version);
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void saveSerializable(const shared_ptr<T> &data)
|
void saveSerializable(const std::shared_ptr<T> &data)
|
||||||
{
|
{
|
||||||
T *internalPtr = data.get();
|
T *internalPtr = data.get();
|
||||||
*this << internalPtr;
|
*this << internalPtr;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void saveSerializable(const unique_ptr<T> &data)
|
void saveSerializable(const std::unique_ptr<T> &data)
|
||||||
{
|
{
|
||||||
T *internalPtr = data.get();
|
T *internalPtr = data.get();
|
||||||
*this << internalPtr;
|
*this << internalPtr;
|
||||||
@ -1324,7 +1332,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void loadSerializable(shared_ptr<T> &data)
|
void loadSerializable(std::shared_ptr<T> &data)
|
||||||
{
|
{
|
||||||
typedef typename boost::remove_const<T>::type NonConstT;
|
typedef typename boost::remove_const<T>::type NonConstT;
|
||||||
NonConstT *internalPtr;
|
NonConstT *internalPtr;
|
||||||
@ -1345,7 +1353,7 @@ public:
|
|||||||
auto typeWeNeedToReturn = typeList.getTypeInfo<T>();
|
auto typeWeNeedToReturn = typeList.getTypeInfo<T>();
|
||||||
if(*actualType == *typeWeNeedToReturn)
|
if(*actualType == *typeWeNeedToReturn)
|
||||||
{
|
{
|
||||||
// No casting needed, just unpack already stored shared_ptr and return it
|
// No casting needed, just unpack already stored std::shared_ptr and return it
|
||||||
data = boost::any_cast<std::shared_ptr<T>>(itr->second);
|
data = boost::any_cast<std::shared_ptr<T>>(itr->second);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1375,7 +1383,7 @@ public:
|
|||||||
data.reset();
|
data.reset();
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void loadSerializable(unique_ptr<T> &data)
|
void loadSerializable(std::unique_ptr<T> &data)
|
||||||
{
|
{
|
||||||
T *internalPtr;
|
T *internalPtr;
|
||||||
*this >> internalPtr;
|
*this >> internalPtr;
|
||||||
@ -1543,7 +1551,7 @@ public:
|
|||||||
COSer serializer;
|
COSer serializer;
|
||||||
|
|
||||||
std::string fName;
|
std::string fName;
|
||||||
unique_ptr<std::ofstream> sfile;
|
std::unique_ptr<std::ofstream> sfile;
|
||||||
|
|
||||||
CSaveFile(const std::string &fname); //throws!
|
CSaveFile(const std::string &fname); //throws!
|
||||||
~CSaveFile();
|
~CSaveFile();
|
||||||
@ -1570,7 +1578,7 @@ public:
|
|||||||
CISer serializer;
|
CISer serializer;
|
||||||
|
|
||||||
std::string fName;
|
std::string fName;
|
||||||
unique_ptr<boost::filesystem::ifstream> sfile;
|
std::unique_ptr<boost::filesystem::ifstream> sfile;
|
||||||
|
|
||||||
CLoadFile(const boost::filesystem::path & fname, int minimalVersion = version); //throws!
|
CLoadFile(const boost::filesystem::path & fname, int minimalVersion = version); //throws!
|
||||||
~CLoadFile();
|
~CLoadFile();
|
||||||
@ -1595,7 +1603,7 @@ class DLL_LINKAGE CLoadIntegrityValidator
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CISer serializer;
|
CISer serializer;
|
||||||
unique_ptr<CLoadFile> primaryFile, controlFile;
|
std::unique_ptr<CLoadFile> primaryFile, controlFile;
|
||||||
bool foundDesync;
|
bool foundDesync;
|
||||||
|
|
||||||
CLoadIntegrityValidator(const std::string &primaryFileName, const std::string &controlFileName, int minimalVersion = version); //throws!
|
CLoadIntegrityValidator(const std::string &primaryFileName, const std::string &controlFileName, int minimalVersion = version); //throws!
|
||||||
@ -1603,7 +1611,7 @@ public:
|
|||||||
int read( void * data, unsigned size) override; //throws!
|
int read( void * data, unsigned size) override; //throws!
|
||||||
void checkMagicBytes(const std::string &text);
|
void checkMagicBytes(const std::string &text);
|
||||||
|
|
||||||
unique_ptr<CLoadFile> decay(); //returns primary file. CLoadIntegrityValidator stops being usable anymore
|
std::unique_ptr<CLoadFile> decay(); //returns primary file. CLoadIntegrityValidator stops being usable anymore
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service<boost::asio::ip::tcp> > TSocket;
|
typedef boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service<boost::asio::ip::tcp> > TSocket;
|
||||||
@ -1694,12 +1702,12 @@ public:
|
|||||||
CMemorySerializer();
|
CMemorySerializer();
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static unique_ptr<T> deepCopy(const T &data)
|
static std::unique_ptr<T> deepCopy(const T &data)
|
||||||
{
|
{
|
||||||
CMemorySerializer mem;
|
CMemorySerializer mem;
|
||||||
mem.oser << &data;
|
mem.oser << &data;
|
||||||
|
|
||||||
unique_ptr<T> ret;
|
std::unique_ptr<T> ret;
|
||||||
mem.iser >> ret;
|
mem.iser >> ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ namespace GameConstants
|
|||||||
const int SPELL_SCHOOL_LEVELS = 4;
|
const int SPELL_SCHOOL_LEVELS = 4;
|
||||||
const int CRE_LEVELS = 10; // number of creature experience levels
|
const int CRE_LEVELS = 10; // number of creature experience levels
|
||||||
|
|
||||||
|
const int HERO_GOLD_COST = 2500;
|
||||||
const int SPELLBOOK_GOLD_COST = 500;
|
const int SPELLBOOK_GOLD_COST = 500;
|
||||||
const int BATTLE_PENALTY_DISTANCE = 10; //if the distance is > than this, then shooting stack has distance penalty
|
const int BATTLE_PENALTY_DISTANCE = 10; //if the distance is > than this, then shooting stack has distance penalty
|
||||||
const int ARMY_SIZE = 7;
|
const int ARMY_SIZE = 7;
|
||||||
@ -837,10 +838,10 @@ public:
|
|||||||
// 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines
|
// 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines
|
||||||
//8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields
|
//8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields
|
||||||
//15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog
|
//15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog
|
||||||
//21. "favourable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship
|
//21. "favorable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship
|
||||||
enum EBFieldType {NONE = -1, NONE2, SAND_SHORE, SAND_MESAS, DIRT_BIRCHES, DIRT_HILLS, DIRT_PINES, GRASS_HILLS,
|
enum EBFieldType {NONE = -1, NONE2, SAND_SHORE, SAND_MESAS, DIRT_BIRCHES, DIRT_HILLS, DIRT_PINES, GRASS_HILLS,
|
||||||
GRASS_PINES, LAVA, MAGIC_PLAINS, SNOW_MOUNTAINS, SNOW_TREES, SUBTERRANEAN, SWAMP_TREES, FIERY_FIELDS,
|
GRASS_PINES, LAVA, MAGIC_PLAINS, SNOW_MOUNTAINS, SNOW_TREES, SUBTERRANEAN, SWAMP_TREES, FIERY_FIELDS,
|
||||||
ROCKLANDS, MAGIC_CLOUDS, LUCID_POOLS, HOLY_GROUND, CLOVER_FIELD, EVIL_FOG, FAVOURABLE_WINDS, CURSED_GROUND,
|
ROCKLANDS, MAGIC_CLOUDS, LUCID_POOLS, HOLY_GROUND, CLOVER_FIELD, EVIL_FOG, FAVORABLE_WINDS, CURSED_GROUND,
|
||||||
ROUGH, SHIP_TO_SHIP, SHIP
|
ROUGH, SHIP_TO_SHIP, SHIP
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -64,19 +64,19 @@ const std::map<std::string, Bonus::LimitEffect> bonusLimitEffect =
|
|||||||
|
|
||||||
const std::map<std::string, TLimiterPtr> bonusLimiterMap =
|
const std::map<std::string, TLimiterPtr> bonusLimiterMap =
|
||||||
{
|
{
|
||||||
{"SHOOTER_ONLY", make_shared<HasAnotherBonusLimiter>(Bonus::SHOOTER)},
|
{"SHOOTER_ONLY", std::make_shared<HasAnotherBonusLimiter>(Bonus::SHOOTER)},
|
||||||
{"DRAGON_NATURE", make_shared<HasAnotherBonusLimiter>(Bonus::DRAGON_NATURE)},
|
{"DRAGON_NATURE", std::make_shared<HasAnotherBonusLimiter>(Bonus::DRAGON_NATURE)},
|
||||||
{"IS_UNDEAD", make_shared<HasAnotherBonusLimiter>(Bonus::UNDEAD)}
|
{"IS_UNDEAD", std::make_shared<HasAnotherBonusLimiter>(Bonus::UNDEAD)}
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::map<std::string, TPropagatorPtr> bonusPropagatorMap =
|
const std::map<std::string, TPropagatorPtr> bonusPropagatorMap =
|
||||||
{
|
{
|
||||||
{"BATTLE_WIDE", make_shared<CPropagatorNodeType>(CBonusSystemNode::BATTLE)},
|
{"BATTLE_WIDE", std::make_shared<CPropagatorNodeType>(CBonusSystemNode::BATTLE)},
|
||||||
{"VISITED_TOWN_AND_VISITOR", make_shared<CPropagatorNodeType>(CBonusSystemNode::TOWN_AND_VISITOR)},
|
{"VISITED_TOWN_AND_VISITOR", std::make_shared<CPropagatorNodeType>(CBonusSystemNode::TOWN_AND_VISITOR)},
|
||||||
{"PLAYER_PROPAGATOR", make_shared<CPropagatorNodeType>(CBonusSystemNode::PLAYER)},
|
{"PLAYER_PROPAGATOR", std::make_shared<CPropagatorNodeType>(CBonusSystemNode::PLAYER)},
|
||||||
{"HERO", make_shared<CPropagatorNodeType>(CBonusSystemNode::HERO)},
|
{"HERO", std::make_shared<CPropagatorNodeType>(CBonusSystemNode::HERO)},
|
||||||
{"TEAM_PROPAGATOR", make_shared<CPropagatorNodeType>(CBonusSystemNode::TEAM)}, //untested
|
{"TEAM_PROPAGATOR", std::make_shared<CPropagatorNodeType>(CBonusSystemNode::TEAM)}, //untested
|
||||||
{"GLOBAL_EFFECT", make_shared<CPropagatorNodeType>(CBonusSystemNode::GLOBAL_EFFECTS)}
|
{"GLOBAL_EFFECT", std::make_shared<CPropagatorNodeType>(CBonusSystemNode::GLOBAL_EFFECTS)}
|
||||||
}; //untested
|
}; //untested
|
||||||
|
|
||||||
|
|
||||||
@ -651,7 +651,7 @@ const TBonusListPtr CBonusSystemNode::getAllBonuses(const CSelector &selector, c
|
|||||||
|
|
||||||
//We still don't have the bonuses (didn't returned them from cache)
|
//We still don't have the bonuses (didn't returned them from cache)
|
||||||
//Perform bonus selection
|
//Perform bonus selection
|
||||||
auto ret = make_shared<BonusList>();
|
auto ret = std::make_shared<BonusList>();
|
||||||
cachedBonuses.getBonuses(*ret, selector, limit);
|
cachedBonuses.getBonuses(*ret, selector, limit);
|
||||||
|
|
||||||
// Save the results in the cache
|
// Save the results in the cache
|
||||||
@ -668,7 +668,7 @@ const TBonusListPtr CBonusSystemNode::getAllBonuses(const CSelector &selector, c
|
|||||||
|
|
||||||
const TBonusListPtr CBonusSystemNode::getAllBonusesWithoutCaching(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= nullptr*/) const
|
const TBonusListPtr CBonusSystemNode::getAllBonusesWithoutCaching(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= nullptr*/) const
|
||||||
{
|
{
|
||||||
auto ret = make_shared<BonusList>();
|
auto ret = std::make_shared<BonusList>();
|
||||||
|
|
||||||
// Get bonus results without caching enabled.
|
// Get bonus results without caching enabled.
|
||||||
BonusList beforeLimiting, afterLimiting;
|
BonusList beforeLimiting, afterLimiting;
|
||||||
@ -995,11 +995,6 @@ CBonusSystemNode::ENodeTypes CBonusSystemNode::getNodeType() const
|
|||||||
return nodeType;
|
return nodeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
BonusList& CBonusSystemNode::getBonusList()
|
|
||||||
{
|
|
||||||
return bonuses;
|
|
||||||
}
|
|
||||||
|
|
||||||
const BonusList& CBonusSystemNode::getBonusList() const
|
const BonusList& CBonusSystemNode::getBonusList() const
|
||||||
{
|
{
|
||||||
return bonuses;
|
return bonuses;
|
||||||
@ -1072,7 +1067,7 @@ void CBonusSystemNode::limitBonuses(const BonusList &allBonuses, BonusList &out)
|
|||||||
|
|
||||||
TBonusListPtr CBonusSystemNode::limitBonuses(const BonusList &allBonuses) const
|
TBonusListPtr CBonusSystemNode::limitBonuses(const BonusList &allBonuses) const
|
||||||
{
|
{
|
||||||
auto ret = make_shared<BonusList>();
|
auto ret = std::make_shared<BonusList>();
|
||||||
limitBonuses(allBonuses, *ret);
|
limitBonuses(allBonuses, *ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1323,7 +1318,7 @@ Bonus * Bonus::addLimiter(TLimiterPtr Limiter)
|
|||||||
if(!limiterList)
|
if(!limiterList)
|
||||||
{
|
{
|
||||||
//Create a new limiter list with old limiter and the new one will be pushed later
|
//Create a new limiter list with old limiter and the new one will be pushed later
|
||||||
limiterList = make_shared<LimiterList>();
|
limiterList = std::make_shared<LimiterList>();
|
||||||
limiterList->add(limiter);
|
limiterList->add(limiter);
|
||||||
limiter = limiterList;
|
limiter = limiterList;
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@ class ILimiter;
|
|||||||
class IPropagator;
|
class IPropagator;
|
||||||
class BonusList;
|
class BonusList;
|
||||||
|
|
||||||
typedef shared_ptr<BonusList> TBonusListPtr;
|
typedef std::shared_ptr<BonusList> TBonusListPtr;
|
||||||
typedef shared_ptr<ILimiter> TLimiterPtr;
|
typedef std::shared_ptr<ILimiter> TLimiterPtr;
|
||||||
typedef shared_ptr<IPropagator> TPropagatorPtr;
|
typedef std::shared_ptr<IPropagator> TPropagatorPtr;
|
||||||
typedef std::set<CBonusSystemNode*> TNodes;
|
typedef std::set<CBonusSystemNode*> TNodes;
|
||||||
typedef std::set<const CBonusSystemNode*> TCNodes;
|
typedef std::set<const CBonusSystemNode*> TCNodes;
|
||||||
typedef std::vector<CBonusSystemNode *> TNodesVector;
|
typedef std::vector<CBonusSystemNode *> TNodesVector;
|
||||||
@ -694,7 +694,6 @@ public:
|
|||||||
void exportBonus(Bonus * b);
|
void exportBonus(Bonus * b);
|
||||||
void exportBonuses();
|
void exportBonuses();
|
||||||
|
|
||||||
BonusList &getBonusList();
|
|
||||||
const BonusList &getBonusList() const;
|
const BonusList &getBonusList() const;
|
||||||
BonusList &getExportedBonusList();
|
BonusList &getExportedBonusList();
|
||||||
CBonusSystemNode::ENodeTypes getNodeType() const;
|
CBonusSystemNode::ENodeTypes getNodeType() const;
|
||||||
|
@ -483,10 +483,10 @@ Bonus * JsonUtils::parseBonus (const JsonNode &ability)
|
|||||||
break;
|
break;
|
||||||
case JsonNode::DATA_STRUCT: //customizable limiters
|
case JsonNode::DATA_STRUCT: //customizable limiters
|
||||||
{
|
{
|
||||||
shared_ptr<ILimiter> l;
|
std::shared_ptr<ILimiter> l;
|
||||||
if (limiter["type"].String() == "CREATURE_TYPE_LIMITER")
|
if (limiter["type"].String() == "CREATURE_TYPE_LIMITER")
|
||||||
{
|
{
|
||||||
shared_ptr<CCreatureTypeLimiter> l2 = make_shared<CCreatureTypeLimiter>(); //TODO: How the hell resolve pointer to creature?
|
std::shared_ptr<CCreatureTypeLimiter> l2 = std::make_shared<CCreatureTypeLimiter>(); //TODO: How the hell resolve pointer to creature?
|
||||||
const JsonVector vec = limiter["parameters"].Vector();
|
const JsonVector vec = limiter["parameters"].Vector();
|
||||||
VLC->modh->identifiers.requestIdentifier("creature", vec[0], [=](si32 creature)
|
VLC->modh->identifiers.requestIdentifier("creature", vec[0], [=](si32 creature)
|
||||||
{
|
{
|
||||||
@ -503,7 +503,7 @@ Bonus * JsonUtils::parseBonus (const JsonNode &ability)
|
|||||||
}
|
}
|
||||||
if (limiter["type"].String() == "HAS_ANOTHER_BONUS_LIMITER")
|
if (limiter["type"].String() == "HAS_ANOTHER_BONUS_LIMITER")
|
||||||
{
|
{
|
||||||
shared_ptr<HasAnotherBonusLimiter> l2 = make_shared<HasAnotherBonusLimiter>();
|
std::shared_ptr<HasAnotherBonusLimiter> l2 = std::make_shared<HasAnotherBonusLimiter>();
|
||||||
const JsonVector vec = limiter["parameters"].Vector();
|
const JsonVector vec = limiter["parameters"].Vector();
|
||||||
std::string anotherBonusType = vec[0].String();
|
std::string anotherBonusType = vec[0].String();
|
||||||
|
|
||||||
|
@ -331,9 +331,6 @@ struct SetAvailableHeroes : public CPackForClient //113
|
|||||||
for (int i = 0; i < GameConstants::AVAILABLE_HEROES_PER_PLAYER; i++)
|
for (int i = 0; i < GameConstants::AVAILABLE_HEROES_PER_PLAYER; i++)
|
||||||
army[i].clear();
|
army[i].clear();
|
||||||
}
|
}
|
||||||
~SetAvailableHeroes()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void applyCl(CClient *cl);
|
void applyCl(CClient *cl);
|
||||||
DLL_LINKAGE void applyGs(CGameState *gs);
|
DLL_LINKAGE void applyGs(CGameState *gs);
|
||||||
|
|
||||||
@ -446,7 +443,7 @@ struct UpdateCampaignState : public CPackForClient //119
|
|||||||
type = 119;
|
type = 119;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<CCampaignState> camp;
|
std::shared_ptr<CCampaignState> camp;
|
||||||
void applyCl(CClient *cl);
|
void applyCl(CClient *cl);
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
@ -1684,7 +1681,7 @@ struct BattleObstaclePlaced : public CPackForClient //3020
|
|||||||
DLL_LINKAGE void applyGs(CGameState *gs); //effect
|
DLL_LINKAGE void applyGs(CGameState *gs); //effect
|
||||||
void applyCl(CClient *cl); //play animations & stuff
|
void applyCl(CClient *cl); //play animations & stuff
|
||||||
|
|
||||||
shared_ptr<CObstacleInstance> obstacle;
|
std::shared_ptr<CObstacleInstance> obstacle;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
|
@ -223,7 +223,7 @@ DLL_LINKAGE void FoWChange::applyGs( CGameState *gs )
|
|||||||
case Obj::TOWN:
|
case Obj::TOWN:
|
||||||
case Obj::ABANDONED_MINE:
|
case Obj::ABANDONED_MINE:
|
||||||
if(vstd::contains(team->players, o->tempOwner)) //check owned observators
|
if(vstd::contains(team->players, o->tempOwner)) //check owned observators
|
||||||
gs->getTilesInRange(tiles, o->getSightCenter(), o->getSightRadious(), o->tempOwner, 1);
|
gs->getTilesInRange(tilesRevealed, o->getSightCenter(), o->getSightRadious(), o->tempOwner, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1010,6 +1010,13 @@ DLL_LINKAGE void SetAvailableArtifacts::applyGs( CGameState *gs )
|
|||||||
DLL_LINKAGE void NewTurn::applyGs( CGameState *gs )
|
DLL_LINKAGE void NewTurn::applyGs( CGameState *gs )
|
||||||
{
|
{
|
||||||
gs->day = day;
|
gs->day = day;
|
||||||
|
|
||||||
|
// Update bonuses before doing anything else so hero don't get more MP than needed
|
||||||
|
gs->globalEffects.popBonuses(Bonus::OneDay); //works for children -> all game objs
|
||||||
|
gs->globalEffects.updateBonuses(Bonus::NDays);
|
||||||
|
gs->globalEffects.updateBonuses(Bonus::OneWeek);
|
||||||
|
//TODO not really a single root hierarchy, what about bonuses placed elsewhere? [not an issue with H3 mechanics but in the future...]
|
||||||
|
|
||||||
for(NewTurn::Hero h : heroes) //give mana/movement point
|
for(NewTurn::Hero h : heroes) //give mana/movement point
|
||||||
{
|
{
|
||||||
CGHeroInstance *hero = gs->getHero(h.id);
|
CGHeroInstance *hero = gs->getHero(h.id);
|
||||||
@ -1026,11 +1033,6 @@ DLL_LINKAGE void NewTurn::applyGs( CGameState *gs )
|
|||||||
for(auto creatureSet : cres) //set available creatures in towns
|
for(auto creatureSet : cres) //set available creatures in towns
|
||||||
creatureSet.second.applyGs(gs);
|
creatureSet.second.applyGs(gs);
|
||||||
|
|
||||||
gs->globalEffects.popBonuses(Bonus::OneDay); //works for children -> all game objs
|
|
||||||
gs->globalEffects.updateBonuses(Bonus::NDays);
|
|
||||||
gs->globalEffects.updateBonuses(Bonus::OneWeek);
|
|
||||||
//TODO not really a single root hierarchy, what about bonuses placed elsewhere? [not an issue with H3 mechanics but in the future...]
|
|
||||||
|
|
||||||
for(CGTownInstance* t : gs->map->towns)
|
for(CGTownInstance* t : gs->map->towns)
|
||||||
t->builded = 0;
|
t->builded = 0;
|
||||||
|
|
||||||
|
@ -82,9 +82,9 @@ struct StartInfo
|
|||||||
ui8 turnTime; //in minutes, 0=unlimited
|
ui8 turnTime; //in minutes, 0=unlimited
|
||||||
std::string mapname; // empty for random map, otherwise name of the map or savegame
|
std::string mapname; // empty for random map, otherwise name of the map or savegame
|
||||||
bool createRandomMap() const { return mapGenOptions.get() != nullptr; }
|
bool createRandomMap() const { return mapGenOptions.get() != nullptr; }
|
||||||
shared_ptr<CMapGenOptions> mapGenOptions;
|
std::shared_ptr<CMapGenOptions> mapGenOptions;
|
||||||
|
|
||||||
shared_ptr<CCampaignState> campState;
|
std::shared_ptr<CCampaignState> campState;
|
||||||
|
|
||||||
PlayerSettings & getIthPlayersSettings(PlayerColor no)
|
PlayerSettings & getIthPlayersSettings(PlayerColor no)
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "GameConstants.h"
|
#include "GameConstants.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GameConstants.h, part of VCMI engine
|
* StringConstants.h, part of VCMI engine
|
||||||
*
|
*
|
||||||
* Authors: listed in file AUTHORS in main folder
|
* Authors: listed in file AUTHORS in main folder
|
||||||
*
|
*
|
||||||
|
@ -293,8 +293,10 @@
|
|||||||
<ClInclude Include="Connection.h" />
|
<ClInclude Include="Connection.h" />
|
||||||
<ClInclude Include="ConstTransitivePtr.h" />
|
<ClInclude Include="ConstTransitivePtr.h" />
|
||||||
<ClInclude Include="CPathfinder.h" />
|
<ClInclude Include="CPathfinder.h" />
|
||||||
|
<ClInclude Include="CPlayerState.h" />
|
||||||
<ClInclude Include="CRandomGenerator.h" />
|
<ClInclude Include="CRandomGenerator.h" />
|
||||||
<ClInclude Include="CScriptingModule.h" />
|
<ClInclude Include="CScriptingModule.h" />
|
||||||
|
<ClInclude Include="CSoundBase.h" />
|
||||||
<ClInclude Include="CStopWatch.h" />
|
<ClInclude Include="CStopWatch.h" />
|
||||||
<ClInclude Include="CThreadHelper.h" />
|
<ClInclude Include="CThreadHelper.h" />
|
||||||
<ClInclude Include="CTownHandler.h" />
|
<ClInclude Include="CTownHandler.h" />
|
||||||
@ -313,6 +315,7 @@
|
|||||||
<ClInclude Include="filesystem\ResourceID.h" />
|
<ClInclude Include="filesystem\ResourceID.h" />
|
||||||
<ClInclude Include="FunctionList.h" />
|
<ClInclude Include="FunctionList.h" />
|
||||||
<ClInclude Include="IBonusTypeHandler.h" />
|
<ClInclude Include="IBonusTypeHandler.h" />
|
||||||
|
<ClInclude Include="IHandlerBase.h" />
|
||||||
<ClInclude Include="JsonDetail.h" />
|
<ClInclude Include="JsonDetail.h" />
|
||||||
<ClInclude Include="LogicalExpression.h" />
|
<ClInclude Include="LogicalExpression.h" />
|
||||||
<ClInclude Include="mapObjects\CArmedInstance.h" />
|
<ClInclude Include="mapObjects\CArmedInstance.h" />
|
||||||
@ -332,12 +335,15 @@
|
|||||||
<ClInclude Include="mapObjects\MiscObjects.h" />
|
<ClInclude Include="mapObjects\MiscObjects.h" />
|
||||||
<ClInclude Include="mapObjects\ObjectTemplate.h" />
|
<ClInclude Include="mapObjects\ObjectTemplate.h" />
|
||||||
<ClInclude Include="mapping\CCampaignHandler.h" />
|
<ClInclude Include="mapping\CCampaignHandler.h" />
|
||||||
|
<ClInclude Include="mapping\CDrawRoadsOperation.h" />
|
||||||
<ClInclude Include="mapping\CMap.h" />
|
<ClInclude Include="mapping\CMap.h" />
|
||||||
|
<ClInclude Include="mapping\CMapDefines.h" />
|
||||||
<ClInclude Include="mapping\CMapInfo.h" />
|
<ClInclude Include="mapping\CMapInfo.h" />
|
||||||
<ClInclude Include="mapping\CMapService.h" />
|
<ClInclude Include="mapping\CMapService.h" />
|
||||||
<ClInclude Include="mapping\CMapEditManager.h" />
|
<ClInclude Include="mapping\CMapEditManager.h" />
|
||||||
<ClInclude Include="mapping\MapFormatH3M.h" />
|
<ClInclude Include="mapping\MapFormatH3M.h" />
|
||||||
<ClInclude Include="mapping\MapFormatJson.h" />
|
<ClInclude Include="mapping\MapFormatJson.h" />
|
||||||
|
<ClInclude Include="NetPacksBase.h" />
|
||||||
<ClInclude Include="registerTypes\RegisterTypes.h" />
|
<ClInclude Include="registerTypes\RegisterTypes.h" />
|
||||||
<ClInclude Include="rmg\CMapGenerator.h" />
|
<ClInclude Include="rmg\CMapGenerator.h" />
|
||||||
<ClInclude Include="logging\CLogger.h" />
|
<ClInclude Include="logging\CLogger.h" />
|
||||||
@ -360,6 +366,7 @@
|
|||||||
<ClInclude Include="rmg\CZoneGraphGenerator.h" />
|
<ClInclude Include="rmg\CZoneGraphGenerator.h" />
|
||||||
<ClInclude Include="rmg\CZonePlacer.h" />
|
<ClInclude Include="rmg\CZonePlacer.h" />
|
||||||
<ClInclude Include="rmg\float3.h" />
|
<ClInclude Include="rmg\float3.h" />
|
||||||
|
<ClInclude Include="ScopeGuard.h" />
|
||||||
<ClInclude Include="spells\AdventureSpellMechanics.h" />
|
<ClInclude Include="spells\AdventureSpellMechanics.h" />
|
||||||
<ClInclude Include="spells\BattleSpellMechanics.h" />
|
<ClInclude Include="spells\BattleSpellMechanics.h" />
|
||||||
<ClInclude Include="spells\CDefaultSpellMechanics.h" />
|
<ClInclude Include="spells\CDefaultSpellMechanics.h" />
|
||||||
@ -371,7 +378,9 @@
|
|||||||
<ClInclude Include="spells\ViewSpellInt.h" />
|
<ClInclude Include="spells\ViewSpellInt.h" />
|
||||||
<ClInclude Include="StartInfo.h" />
|
<ClInclude Include="StartInfo.h" />
|
||||||
<ClInclude Include="StdInc.h" />
|
<ClInclude Include="StdInc.h" />
|
||||||
|
<ClInclude Include="StringConstants.h" />
|
||||||
<ClInclude Include="UnlockGuard.h" />
|
<ClInclude Include="UnlockGuard.h" />
|
||||||
|
<ClInclude Include="vcmi_endian.h" />
|
||||||
<ClInclude Include="VCMI_Lib.h" />
|
<ClInclude Include="VCMI_Lib.h" />
|
||||||
<ClInclude Include="VCMIDirs.h" />
|
<ClInclude Include="VCMIDirs.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -155,8 +155,6 @@
|
|||||||
<ClCompile Include="registerTypes\TypesClientPacks1.cpp">
|
<ClCompile Include="registerTypes\TypesClientPacks1.cpp">
|
||||||
<Filter>registerTypes</Filter>
|
<Filter>registerTypes</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="registerTypes\TypesMapObjects1.cpp" />
|
|
||||||
<ClCompile Include="registerTypes\TypesMapObjects2.cpp" />
|
|
||||||
<ClCompile Include="mapObjects\CArmedInstance.cpp">
|
<ClCompile Include="mapObjects\CArmedInstance.cpp">
|
||||||
<Filter>mapObjects</Filter>
|
<Filter>mapObjects</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -202,7 +200,6 @@
|
|||||||
<ClCompile Include="mapObjects\ObjectTemplate.cpp">
|
<ClCompile Include="mapObjects\ObjectTemplate.cpp">
|
||||||
<Filter>mapObjects</Filter>
|
<Filter>mapObjects</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="registerTypes\TypesMapObjects3.cpp" />
|
|
||||||
<ClCompile Include="IHandlerBase.cpp" />
|
<ClCompile Include="IHandlerBase.cpp" />
|
||||||
<ClCompile Include="spells\AdventureSpellMechanics.cpp">
|
<ClCompile Include="spells\AdventureSpellMechanics.cpp">
|
||||||
<Filter>spells</Filter>
|
<Filter>spells</Filter>
|
||||||
@ -227,6 +224,15 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="mapping\CDrawRoadsOperation.cpp" />
|
<ClCompile Include="mapping\CDrawRoadsOperation.cpp" />
|
||||||
<ClCompile Include="CPathfinder.cpp" />
|
<ClCompile Include="CPathfinder.cpp" />
|
||||||
|
<ClCompile Include="registerTypes\TypesMapObjects1.cpp">
|
||||||
|
<Filter>registerTypes</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="registerTypes\TypesMapObjects2.cpp">
|
||||||
|
<Filter>registerTypes</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="registerTypes\TypesMapObjects3.cpp">
|
||||||
|
<Filter>registerTypes</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="CCreatureSet.h">
|
<ClInclude Include="CCreatureSet.h">
|
||||||
@ -541,5 +547,32 @@
|
|||||||
<ClInclude Include="CPathfinder.h">
|
<ClInclude Include="CPathfinder.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="CPlayerState.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="mapping\CMapDefines.h">
|
||||||
|
<Filter>mapping</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="CSoundBase.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="IHandlerBase.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="NetPacksBase.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ScopeGuard.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="StringConstants.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="vcmi_endian.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="mapping\CDrawRoadsOperation.h">
|
||||||
|
<Filter>mapping</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CLodStream.h, part of VCMI engine
|
* CCompressedStream.h, part of VCMI engine
|
||||||
*
|
*
|
||||||
* Authors: listed in file AUTHORS in main folder
|
* Authors: listed in file AUTHORS in main folder
|
||||||
*
|
*
|
||||||
|
@ -134,7 +134,7 @@ void CLogger::setLevel(ELogLevel::ELogLevel level)
|
|||||||
|
|
||||||
const CLoggerDomain & CLogger::getDomain() const { return domain; }
|
const CLoggerDomain & CLogger::getDomain() const { return domain; }
|
||||||
|
|
||||||
void CLogger::addTarget(unique_ptr<ILogTarget> && target)
|
void CLogger::addTarget(std::unique_ptr<ILogTarget> && target)
|
||||||
{
|
{
|
||||||
TLockGuard _(mx);
|
TLockGuard _(mx);
|
||||||
targets.push_back(std::move(target));
|
targets.push_back(std::move(target));
|
||||||
|
@ -105,7 +105,7 @@ public:
|
|||||||
|
|
||||||
inline void log(ELogLevel::ELogLevel level, const std::string & message) const;
|
inline void log(ELogLevel::ELogLevel level, const std::string & message) const;
|
||||||
|
|
||||||
void addTarget(unique_ptr<ILogTarget> && target);
|
void addTarget(std::unique_ptr<ILogTarget> && target);
|
||||||
void clearTargets();
|
void clearTargets();
|
||||||
|
|
||||||
/// Returns true if a debug/trace log message will be logged, false if not.
|
/// Returns true if a debug/trace log message will be logged, false if not.
|
||||||
@ -121,7 +121,7 @@ private:
|
|||||||
CLoggerDomain domain;
|
CLoggerDomain domain;
|
||||||
CLogger * parent;
|
CLogger * parent;
|
||||||
ELogLevel::ELogLevel level;
|
ELogLevel::ELogLevel level;
|
||||||
std::vector<unique_ptr<ILogTarget> > targets;
|
std::vector<std::unique_ptr<ILogTarget> > targets;
|
||||||
mutable boost::mutex mx;
|
mutable boost::mutex mx;
|
||||||
static boost::recursive_mutex smx;
|
static boost::recursive_mutex smx;
|
||||||
};
|
};
|
||||||
@ -149,7 +149,7 @@ private:
|
|||||||
/// the first statement in the function. Logging traces via this macro have almost no impact when the trace is disabled.
|
/// the first statement in the function. Logging traces via this macro have almost no impact when the trace is disabled.
|
||||||
///
|
///
|
||||||
#define RAII_TRACE(logger, onEntry, onLeave) \
|
#define RAII_TRACE(logger, onEntry, onLeave) \
|
||||||
unique_ptr<CTraceLogger> ctl00; \
|
std::unique_ptr<CTraceLogger> ctl00; \
|
||||||
if(logger->isTraceEnabled()) \
|
if(logger->isTraceEnabled()) \
|
||||||
ctl00 = make_unique<CTraceLogger>(logger, onEntry, onLeave);
|
ctl00 = make_unique<CTraceLogger>(logger, onEntry, onLeave);
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ void CArmedInstance::updateMoraleBonusFromArmy()
|
|||||||
if(!validTypes(false)) //object not randomized, don't bother
|
if(!validTypes(false)) //object not randomized, don't bother
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Bonus *b = getBonusList().getFirst(Selector::sourceType(Bonus::ARMY).And(Selector::type(Bonus::MORALE)));
|
Bonus *b = getExportedBonusList().getFirst(Selector::sourceType(Bonus::ARMY).And(Selector::type(Bonus::MORALE)));
|
||||||
if(!b)
|
if(!b)
|
||||||
{
|
{
|
||||||
b = new Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, 0, -1);
|
b = new Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, 0, -1);
|
||||||
@ -96,10 +96,11 @@ void CArmedInstance::updateMoraleBonusFromArmy()
|
|||||||
b->description = b->description.substr(0, b->description.size()-2);//trim value
|
b->description = b->description.substr(0, b->description.size()-2);//trim value
|
||||||
}
|
}
|
||||||
boost::algorithm::trim(b->description);
|
boost::algorithm::trim(b->description);
|
||||||
|
CBonusSystemNode::treeHasChanged();
|
||||||
|
|
||||||
//-1 modifier for any Undead unit in army
|
//-1 modifier for any Undead unit in army
|
||||||
const ui8 UNDEAD_MODIFIER_ID = -2;
|
const ui8 UNDEAD_MODIFIER_ID = -2;
|
||||||
Bonus *undeadModifier = getBonusList().getFirst(Selector::source(Bonus::ARMY, UNDEAD_MODIFIER_ID));
|
Bonus *undeadModifier = getExportedBonusList().getFirst(Selector::source(Bonus::ARMY, UNDEAD_MODIFIER_ID));
|
||||||
if(hasUndead)
|
if(hasUndead)
|
||||||
{
|
{
|
||||||
if(!undeadModifier)
|
if(!undeadModifier)
|
||||||
|
@ -292,9 +292,9 @@ void CBank::doVisit(const CGHeroInstance * hero) const
|
|||||||
loot.addReplacement(*elem.second);
|
loot.addReplacement(*elem.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ourArmy.Slots().size())
|
if(ourArmy.stacksCount())
|
||||||
{
|
{
|
||||||
if (ourArmy.Slots().size() == 1 && ourArmy.Slots().begin()->second->count == 1)
|
if(ourArmy.stacksCount() == 1 && ourArmy.Slots().begin()->second->count == 1)
|
||||||
iw.text.addTxt (MetaString::ADVOB_TXT, 185);
|
iw.text.addTxt (MetaString::ADVOB_TXT, 185);
|
||||||
else
|
else
|
||||||
iw.text.addTxt (MetaString::ADVOB_TXT, 186);
|
iw.text.addTxt (MetaString::ADVOB_TXT, 186);
|
||||||
|
@ -43,7 +43,7 @@ static void showInfoDialog(const CGHeroInstance* h, const ui32 txtID, const ui16
|
|||||||
|
|
||||||
static int lowestSpeed(const CGHeroInstance * chi)
|
static int lowestSpeed(const CGHeroInstance * chi)
|
||||||
{
|
{
|
||||||
if(!chi->Slots().size())
|
if(!chi->stacksCount())
|
||||||
{
|
{
|
||||||
logGlobal->errorStream() << "Error! Hero " << chi->id.getNum() << " ("<<chi->name<<") has no army!";
|
logGlobal->errorStream() << "Error! Hero " << chi->id.getNum() << " ("<<chi->name<<") has no army!";
|
||||||
return 20;
|
return 20;
|
||||||
@ -818,7 +818,7 @@ void CGHeroInstance::updateSkill(SecondarySkill which, int val)
|
|||||||
|
|
||||||
|
|
||||||
Bonus::ValueType skillValType = skillVal ? Bonus::BASE_NUMBER : Bonus::INDEPENDENT_MIN;
|
Bonus::ValueType skillValType = skillVal ? Bonus::BASE_NUMBER : Bonus::INDEPENDENT_MIN;
|
||||||
if(Bonus * b = getBonusList().getFirst(Selector::typeSubtype(Bonus::SECONDARY_SKILL_PREMY, which)
|
if(Bonus * b = getExportedBonusList().getFirst(Selector::typeSubtype(Bonus::SECONDARY_SKILL_PREMY, which)
|
||||||
.And(Selector::sourceType(Bonus::SECONDARY_SKILL)))) //only local hero bonus
|
.And(Selector::sourceType(Bonus::SECONDARY_SKILL)))) //only local hero bonus
|
||||||
{
|
{
|
||||||
b->val = skillVal;
|
b->val = skillVal;
|
||||||
@ -831,6 +831,7 @@ void CGHeroInstance::updateSkill(SecondarySkill which, int val)
|
|||||||
addNewBonus(bonus);
|
addNewBonus(bonus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CBonusSystemNode::treeHasChanged();
|
||||||
}
|
}
|
||||||
void CGHeroInstance::setPropertyDer( ui8 what, ui32 val )
|
void CGHeroInstance::setPropertyDer( ui8 what, ui32 val )
|
||||||
{
|
{
|
||||||
@ -1365,6 +1366,7 @@ void CGHeroInstance::setPrimarySkill(PrimarySkill::PrimarySkill primarySkill, si
|
|||||||
{
|
{
|
||||||
skill->val += value;
|
skill->val += value;
|
||||||
}
|
}
|
||||||
|
CBonusSystemNode::treeHasChanged();
|
||||||
}
|
}
|
||||||
else if(primarySkill == PrimarySkill::EXPERIENCE)
|
else if(primarySkill == PrimarySkill::EXPERIENCE)
|
||||||
{
|
{
|
||||||
|
@ -79,7 +79,7 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & patrolling;
|
h & patrolling;
|
||||||
if(version >= 755)
|
if(version >= 755) //save format backward compatibility
|
||||||
{
|
{
|
||||||
h & initialPos;
|
h & initialPos;
|
||||||
}
|
}
|
||||||
|
@ -235,7 +235,7 @@ void CGPandoraBox::giveContentsAfterExp(const CGHeroInstance *h) const
|
|||||||
iw.components.clear();
|
iw.components.clear();
|
||||||
iw.text.clear();
|
iw.text.clear();
|
||||||
|
|
||||||
if (creatures.Slots().size())
|
if(creatures.stacksCount())
|
||||||
{ //this part is taken straight from creature bank
|
{ //this part is taken straight from creature bank
|
||||||
MetaString loot;
|
MetaString loot;
|
||||||
for(auto & elem : creatures.Slots())
|
for(auto & elem : creatures.Slots())
|
||||||
@ -245,7 +245,7 @@ void CGPandoraBox::giveContentsAfterExp(const CGHeroInstance *h) const
|
|||||||
loot.addReplacement(*elem.second);
|
loot.addReplacement(*elem.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (creatures.Slots().size() == 1 && creatures.Slots().begin()->second->count == 1)
|
if(creatures.stacksCount() == 1 && creatures.Slots().begin()->second->count == 1)
|
||||||
iw.text.addTxt(MetaString::ADVOB_TXT, 185);
|
iw.text.addTxt(MetaString::ADVOB_TXT, 185);
|
||||||
else
|
else
|
||||||
iw.text.addTxt(MetaString::ADVOB_TXT, 186);
|
iw.text.addTxt(MetaString::ADVOB_TXT, 186);
|
||||||
@ -313,7 +313,7 @@ void CGPandoraBox::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answe
|
|||||||
else if(message.size() == 0 && resources.size() == 0
|
else if(message.size() == 0 && resources.size() == 0
|
||||||
&& primskills.size() == 0 && abilities.size() == 0
|
&& primskills.size() == 0 && abilities.size() == 0
|
||||||
&& abilityLevels.size() == 0 && artifacts.size() == 0
|
&& abilityLevels.size() == 0 && artifacts.size() == 0
|
||||||
&& spells.size() == 0 && creatures.Slots().size() > 0
|
&& spells.size() == 0 && creatures.stacksCount() > 0
|
||||||
&& gainedExp == 0 && manaDiff == 0 && moraleDiff == 0 && luckDiff == 0) //if it gives nothing without battle
|
&& gainedExp == 0 && manaDiff == 0 && moraleDiff == 0 && luckDiff == 0) //if it gives nothing without battle
|
||||||
{
|
{
|
||||||
showInfoDialog(hero,15,0);
|
showInfoDialog(hero,15,0);
|
||||||
|
@ -856,7 +856,7 @@ void CGTownInstance::deserializationFix()
|
|||||||
|
|
||||||
void CGTownInstance::updateMoraleBonusFromArmy()
|
void CGTownInstance::updateMoraleBonusFromArmy()
|
||||||
{
|
{
|
||||||
Bonus *b = getBonusList().getFirst(Selector::sourceType(Bonus::ARMY).And(Selector::type(Bonus::MORALE)));
|
Bonus *b = getExportedBonusList().getFirst(Selector::sourceType(Bonus::ARMY).And(Selector::type(Bonus::MORALE)));
|
||||||
if(!b)
|
if(!b)
|
||||||
{
|
{
|
||||||
b = new Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, 0, -1);
|
b = new Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, 0, -1);
|
||||||
@ -864,7 +864,10 @@ void CGTownInstance::updateMoraleBonusFromArmy()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (garrisonHero)
|
if (garrisonHero)
|
||||||
|
{
|
||||||
b->val = 0;
|
b->val = 0;
|
||||||
|
CBonusSystemNode::treeHasChanged();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
CArmedInstance::updateMoraleBonusFromArmy();
|
CArmedInstance::updateMoraleBonusFromArmy();
|
||||||
}
|
}
|
||||||
|
@ -409,7 +409,7 @@ int3 IBoatGenerator::bestLocation() const
|
|||||||
{
|
{
|
||||||
if (const TerrainTile *tile = IObjectInterface::cb->getTile(o->pos + offset, false)) //tile is in the map
|
if (const TerrainTile *tile = IObjectInterface::cb->getTile(o->pos + offset, false)) //tile is in the map
|
||||||
{
|
{
|
||||||
if (tile->terType == ETerrainType::WATER && (!tile->blocked || tile->blockingObjects.front()->ID == 8)) //and is water and is not blocked or is blocked by boat
|
if (tile->terType == ETerrainType::WATER && (!tile->blocked || tile->blockingObjects.front()->ID == Obj::BOAT)) //and is water and is not blocked or is blocked by boat
|
||||||
return o->pos + offset;
|
return o->pos + offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -325,10 +325,10 @@ void CBankInstanceConstructor::configureObject(CGObjectInstance * object, CRando
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CBankInfo::CBankInfo(JsonVector config):
|
CBankInfo::CBankInfo(const JsonVector & Config):
|
||||||
config(config)
|
config(Config)
|
||||||
{
|
{
|
||||||
assert(!config.empty());
|
assert(!Config.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addStackToArmy(IObjectInfo::CArmyStructure & army, const CCreature * crea, si32 amount)
|
static void addStackToArmy(IObjectInfo::CArmyStructure & army, const CCreature * crea, si32 amount)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "CObjectClassesHandler.h"
|
#include "CObjectClassesHandler.h"
|
||||||
#include "../CTownHandler.h" // for building ID-based filters
|
#include "../CTownHandler.h" // for building ID-based filters
|
||||||
|
#include "MapObjects.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CommonConstructors.h, part of VCMI engine
|
* CommonConstructors.h, part of VCMI engine
|
||||||
@ -155,9 +156,9 @@ typedef std::vector<std::pair<ui8, IObjectInfo::CArmyStructure>> TPossibleGuards
|
|||||||
|
|
||||||
class DLL_LINKAGE CBankInfo : public IObjectInfo
|
class DLL_LINKAGE CBankInfo : public IObjectInfo
|
||||||
{
|
{
|
||||||
JsonVector config;
|
const JsonVector & config;
|
||||||
public:
|
public:
|
||||||
CBankInfo(JsonVector config);
|
CBankInfo(const JsonVector & Config);
|
||||||
|
|
||||||
TPossibleGuards getPossibleGuards() const;
|
TPossibleGuards getPossibleGuards() const;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* CRewardableObject.cpp, part of VCMI engine
|
* JsonRandom.cpp, part of VCMI engine
|
||||||
*
|
*
|
||||||
* Authors: listed in file AUTHORS in main folder
|
* Authors: listed in file AUTHORS in main folder
|
||||||
*
|
*
|
||||||
|
@ -640,7 +640,6 @@ std::string CGMine::getObjectName() const
|
|||||||
|
|
||||||
std::string CGMine::getHoverText(PlayerColor player) const
|
std::string CGMine::getHoverText(PlayerColor player) const
|
||||||
{
|
{
|
||||||
|
|
||||||
std::string hoverName = getObjectName(); // Sawmill
|
std::string hoverName = getObjectName(); // Sawmill
|
||||||
|
|
||||||
if (tempOwner != PlayerColor::NEUTRAL)
|
if (tempOwner != PlayerColor::NEUTRAL)
|
||||||
@ -650,11 +649,12 @@ std::string CGMine::getHoverText(PlayerColor player) const
|
|||||||
hoverName += "\n(" + VLC->generaltexth->restypes[producedResource] + ")";
|
hoverName += "\n(" + VLC->generaltexth->restypes[producedResource] + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto & slot : Slots()) // guarded by a few Pikeman
|
if(stacksCount())
|
||||||
{
|
{
|
||||||
hoverName += "\n";
|
hoverName += "\n";
|
||||||
hoverName += getRoughAmount(slot.first);
|
hoverName += VLC->generaltexth->allTexts[202]; //Guarded by
|
||||||
hoverName += getCreature(slot.first)->namePl;
|
hoverName += " ";
|
||||||
|
hoverName += getArmyDescription();
|
||||||
}
|
}
|
||||||
return hoverName;
|
return hoverName;
|
||||||
}
|
}
|
||||||
@ -907,12 +907,12 @@ std::vector<ObjectInstanceID> CGTeleport::getPassableExits(CGameState * gs, cons
|
|||||||
return exits;
|
return exits;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGTeleport::addToChannel(std::map<TeleportChannelID, shared_ptr<TeleportChannel> > &channelsList, const CGTeleport * obj)
|
void CGTeleport::addToChannel(std::map<TeleportChannelID, std::shared_ptr<TeleportChannel> > &channelsList, const CGTeleport * obj)
|
||||||
{
|
{
|
||||||
shared_ptr<TeleportChannel> tc;
|
std::shared_ptr<TeleportChannel> tc;
|
||||||
if(channelsList.find(obj->channel) == channelsList.end())
|
if(channelsList.find(obj->channel) == channelsList.end())
|
||||||
{
|
{
|
||||||
tc = make_shared<TeleportChannel>();
|
tc = std::make_shared<TeleportChannel>();
|
||||||
channelsList.insert(std::make_pair(obj->channel, tc));
|
channelsList.insert(std::make_pair(obj->channel, tc));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -973,17 +973,18 @@ void CGMonolith::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
void CGMonolith::teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const
|
void CGMonolith::teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const
|
||||||
{
|
{
|
||||||
int3 dPos;
|
int3 dPos;
|
||||||
|
auto randomExit = getRandomExit(hero);
|
||||||
auto realExits = getAllExits(true);
|
auto realExits = getAllExits(true);
|
||||||
if(!isEntrance() // Do nothing if hero visited exit only object
|
if(!isEntrance() // Do nothing if hero visited exit only object
|
||||||
|| (!exits.size() && !realExits.size()) // Do nothing if there no exits on this channel
|
|| (!exits.size() && !realExits.size()) // Do nothing if there no exits on this channel
|
||||||
|| (!exits.size() && ObjectInstanceID() == getRandomExit(hero))) // Do nothing if all exits are blocked by friendly hero and it's not subterranean gate
|
|| ObjectInstanceID() == randomExit) // Do nothing if all exits are blocked by friendly hero and it's not subterranean gate
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(vstd::isValidIndex(exits, answer))
|
else if(vstd::isValidIndex(exits, answer))
|
||||||
dPos = exits[answer].second;
|
dPos = exits[answer].second;
|
||||||
else
|
else
|
||||||
dPos = CGHeroInstance::convertPosition(cb->getObj(getRandomExit(hero))->visitablePos(), true);
|
dPos = CGHeroInstance::convertPosition(cb->getObj(randomExit)->visitablePos(), true);
|
||||||
|
|
||||||
cb->moveHero(hero->id, dPos, true);
|
cb->moveHero(hero->id, dPos, true);
|
||||||
}
|
}
|
||||||
@ -1160,8 +1161,8 @@ void CGWhirlpool::teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer
|
|||||||
|
|
||||||
bool CGWhirlpool::isProtected(const CGHeroInstance * h)
|
bool CGWhirlpool::isProtected(const CGHeroInstance * h)
|
||||||
{
|
{
|
||||||
if(h->hasBonusOfType(Bonus::WHIRLPOOL_PROTECTION)
|
if(h->hasBonusOfType(Bonus::WHIRLPOOL_PROTECTION) ||
|
||||||
|| (h->Slots().size() == 1 && h->Slots().begin()->second->count == 1)) //we can't remove last unit
|
(h->stacksCount() == 1 && h->Slots().begin()->second->count == 1)) //we can't remove last unit
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1219,7 +1220,6 @@ void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
iw.text.addTxt(MetaString::ADVOB_TXT, 183); //% has found treasure
|
iw.text.addTxt(MetaString::ADVOB_TXT, 183); //% has found treasure
|
||||||
iw.text.addReplacement(h->name);
|
iw.text.addReplacement(h->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1227,9 +1227,14 @@ void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
{
|
{
|
||||||
int spellID = storedArtifact->getGivenSpellID();
|
int spellID = storedArtifact->getGivenSpellID();
|
||||||
iw.components.push_back(Component(Component::SPELL, spellID, 0, 0));
|
iw.components.push_back(Component(Component::SPELL, spellID, 0, 0));
|
||||||
|
if(message.length())
|
||||||
|
iw.text << message;
|
||||||
|
else
|
||||||
|
{
|
||||||
iw.text.addTxt(MetaString::ADVOB_TXT,135);
|
iw.text.addTxt(MetaString::ADVOB_TXT,135);
|
||||||
iw.text.addReplacement(MetaString::SPELL_NAME, spellID);
|
iw.text.addReplacement(MetaString::SPELL_NAME, spellID);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cb->showInfoDialog(&iw);
|
cb->showInfoDialog(&iw);
|
||||||
@ -1237,7 +1242,28 @@ void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(message.size())
|
switch(ID)
|
||||||
|
{
|
||||||
|
case Obj::ARTIFACT:
|
||||||
|
{
|
||||||
|
BlockingDialog ynd(true,false);
|
||||||
|
ynd.player = h->getOwner();
|
||||||
|
if(message.length())
|
||||||
|
ynd.text << message;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: Guard text is more complex in H3, see mantis issue 2325 for details
|
||||||
|
ynd.text.addTxt(MetaString::GENERAL_TXT, 420);
|
||||||
|
ynd.text.addReplacement("");
|
||||||
|
ynd.text.addReplacement(getArmyDescription());
|
||||||
|
ynd.text.addReplacement(MetaString::GENERAL_TXT, 43); // creatures
|
||||||
|
}
|
||||||
|
cb->showBlockingDialog(&ynd);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Obj::SPELL_SCROLL:
|
||||||
|
{
|
||||||
|
if(message.length())
|
||||||
{
|
{
|
||||||
BlockingDialog ynd(true,false);
|
BlockingDialog ynd(true,false);
|
||||||
ynd.player = h->getOwner();
|
ynd.player = h->getOwner();
|
||||||
@ -1245,9 +1271,10 @@ void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
cb->showBlockingDialog(&ynd);
|
cb->showBlockingDialog(&ynd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
blockingDialogAnswered(h, true);
|
blockingDialogAnswered(h, true);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,7 +317,7 @@ public:
|
|||||||
static bool isTeleport(const CGObjectInstance * dst);
|
static bool isTeleport(const CGObjectInstance * dst);
|
||||||
static bool isConnected(const CGTeleport * src, const CGTeleport * dst);
|
static bool isConnected(const CGTeleport * src, const CGTeleport * dst);
|
||||||
static bool isConnected(const CGObjectInstance * src, const CGObjectInstance * dst);
|
static bool isConnected(const CGObjectInstance * src, const CGObjectInstance * dst);
|
||||||
static void addToChannel(std::map<TeleportChannelID, shared_ptr<TeleportChannel> > &channelsList, const CGTeleport * obj);
|
static void addToChannel(std::map<TeleportChannelID, std::shared_ptr<TeleportChannel> > &channelsList, const CGTeleport * obj);
|
||||||
static std::vector<ObjectInstanceID> getPassableExits(CGameState * gs, const CGHeroInstance * h, std::vector<ObjectInstanceID> exits);
|
static std::vector<ObjectInstanceID> getPassableExits(CGameState * gs, const CGHeroInstance * h, std::vector<ObjectInstanceID> exits);
|
||||||
static bool isExitPassable(CGameState * gs, const CGHeroInstance * h, const CGObjectInstance * obj);
|
static bool isExitPassable(CGameState * gs, const CGHeroInstance * h, const CGObjectInstance * obj);
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ CCampaignHeader CCampaignHandler::getHeader( const std::string & name)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & name )
|
std::unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & name )
|
||||||
{
|
{
|
||||||
auto ret = make_unique<CCampaign>();
|
auto ret = make_unique<CCampaign>();
|
||||||
|
|
||||||
@ -411,7 +411,7 @@ CCampaignState::CCampaignState()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CCampaignState::CCampaignState( unique_ptr<CCampaign> _camp ) : camp(std::move(_camp))
|
CCampaignState::CCampaignState( std::unique_ptr<CCampaign> _camp ) : camp(std::move(_camp))
|
||||||
{
|
{
|
||||||
for(int i = 0; i < camp->scenarios.size(); i++)
|
for(int i = 0; i < camp->scenarios.size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -144,7 +144,7 @@ public:
|
|||||||
class DLL_LINKAGE CCampaignState
|
class DLL_LINKAGE CCampaignState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
unique_ptr<CCampaign> camp;
|
std::unique_ptr<CCampaign> camp;
|
||||||
std::string campaignName;
|
std::string campaignName;
|
||||||
std::vector<ui8> mapsConquered, mapsRemaining;
|
std::vector<ui8> mapsConquered, mapsRemaining;
|
||||||
boost::optional<si32> currentMap;
|
boost::optional<si32> currentMap;
|
||||||
@ -159,7 +159,7 @@ public:
|
|||||||
ui8 currentBonusID() const;
|
ui8 currentBonusID() const;
|
||||||
|
|
||||||
CCampaignState();
|
CCampaignState();
|
||||||
CCampaignState(unique_ptr<CCampaign> _camp);
|
CCampaignState(std::unique_ptr<CCampaign> _camp);
|
||||||
~CCampaignState(){};
|
~CCampaignState(){};
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
@ -184,5 +184,5 @@ public:
|
|||||||
|
|
||||||
static CCampaignHeader getHeader( const std::string & name); //name - name of appropriate file
|
static CCampaignHeader getHeader( const std::string & name); //name - name of appropriate file
|
||||||
|
|
||||||
static unique_ptr<CCampaign> getCampaign(const std::string & name); //name - name of appropriate file
|
static std::unique_ptr<CCampaign> getCampaign(const std::string & name); //name - name of appropriate file
|
||||||
};
|
};
|
||||||
|
@ -153,7 +153,7 @@ EDiggingStatus TerrainTile::getDiggingStatus(const bool excludeTop) const
|
|||||||
return EDiggingStatus::CAN_DIG;
|
return EDiggingStatus::CAN_DIG;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TerrainTile::hasFavourableWinds() const
|
bool TerrainTile::hasFavorableWinds() const
|
||||||
{
|
{
|
||||||
return extTileFlags & 128;
|
return extTileFlags & 128;
|
||||||
}
|
}
|
||||||
|
@ -319,12 +319,12 @@ public:
|
|||||||
|
|
||||||
//Helper lists
|
//Helper lists
|
||||||
std::vector< ConstTransitivePtr<CGHeroInstance> > heroesOnMap;
|
std::vector< ConstTransitivePtr<CGHeroInstance> > heroesOnMap;
|
||||||
std::map<TeleportChannelID, shared_ptr<TeleportChannel> > teleportChannels;
|
std::map<TeleportChannelID, std::shared_ptr<TeleportChannel> > teleportChannels;
|
||||||
|
|
||||||
/// associative list to identify which hero/creature id belongs to which object id(index for objects)
|
/// associative list to identify which hero/creature id belongs to which object id(index for objects)
|
||||||
std::map<si32, ObjectInstanceID> questIdentifierToId;
|
std::map<si32, ObjectInstanceID> questIdentifierToId;
|
||||||
|
|
||||||
unique_ptr<CMapEditManager> editManager;
|
std::unique_ptr<CMapEditManager> editManager;
|
||||||
|
|
||||||
int3 ***guardingCreaturePositions;
|
int3 ***guardingCreaturePositions;
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ struct DLL_LINKAGE TerrainTile
|
|||||||
CGObjectInstance * topVisitableObj(bool excludeTop = false) const;
|
CGObjectInstance * topVisitableObj(bool excludeTop = false) const;
|
||||||
bool isWater() const;
|
bool isWater() const;
|
||||||
EDiggingStatus getDiggingStatus(const bool excludeTop = true) const;
|
EDiggingStatus getDiggingStatus(const bool excludeTop = true) const;
|
||||||
bool hasFavourableWinds() const;
|
bool hasFavorableWinds() const;
|
||||||
|
|
||||||
ETerrainType terType;
|
ETerrainType terType;
|
||||||
ui8 terView;
|
ui8 terView;
|
||||||
@ -80,7 +80,7 @@ struct DLL_LINKAGE TerrainTile
|
|||||||
ERoadType::ERoadType roadType;
|
ERoadType::ERoadType roadType;
|
||||||
ui8 roadDir;
|
ui8 roadDir;
|
||||||
/// first two bits - how to rotate terrain graphic (next two - river graphic, next two - road);
|
/// first two bits - how to rotate terrain graphic (next two - river graphic, next two - road);
|
||||||
/// 7th bit - whether tile is coastal (allows disembarking if land or block movement if water); 8th bit - Favourable Winds effect
|
/// 7th bit - whether tile is coastal (allows disembarking if land or block movement if water); 8th bit - Favorable Winds effect
|
||||||
ui8 extTileFlags;
|
ui8 extTileFlags;
|
||||||
bool visitable;
|
bool visitable;
|
||||||
bool blocked;
|
bool blocked;
|
||||||
|
@ -189,7 +189,7 @@ const CMapOperation * CMapUndoManager::peekUndo() const
|
|||||||
return peek(undoStack);
|
return peek(undoStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapUndoManager::addOperation(unique_ptr<CMapOperation> && operation)
|
void CMapUndoManager::addOperation(std::unique_ptr<CMapOperation> && operation)
|
||||||
{
|
{
|
||||||
undoStack.push_front(std::move(operation));
|
undoStack.push_front(std::move(operation));
|
||||||
if(undoStack.size() > undoRedoLimit) undoStack.pop_back();
|
if(undoStack.size() > undoRedoLimit) undoStack.pop_back();
|
||||||
@ -252,7 +252,7 @@ void CMapEditManager::insertObject(CGObjectInstance * obj, const int3 & pos)
|
|||||||
execute(make_unique<CInsertObjectOperation>(map, obj, pos));
|
execute(make_unique<CInsertObjectOperation>(map, obj, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapEditManager::execute(unique_ptr<CMapOperation> && operation)
|
void CMapEditManager::execute(std::unique_ptr<CMapOperation> && operation)
|
||||||
{
|
{
|
||||||
operation->execute();
|
operation->execute();
|
||||||
undoManager.addOperation(std::move(operation));
|
undoManager.addOperation(std::move(operation));
|
||||||
@ -302,7 +302,7 @@ void CComposedOperation::redo()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CComposedOperation::addOperation(unique_ptr<CMapOperation> && operation)
|
void CComposedOperation::addOperation(std::unique_ptr<CMapOperation> && operation)
|
||||||
{
|
{
|
||||||
operations.push_back(std::move(operation));
|
operations.push_back(std::move(operation));
|
||||||
}
|
}
|
||||||
|
@ -144,10 +144,10 @@ public:
|
|||||||
const CMapOperation * peekRedo() const;
|
const CMapOperation * peekRedo() const;
|
||||||
const CMapOperation * peekUndo() const;
|
const CMapOperation * peekUndo() const;
|
||||||
|
|
||||||
void addOperation(unique_ptr<CMapOperation> && operation); /// Client code does not need to call this method.
|
void addOperation(std::unique_ptr<CMapOperation> && operation); /// Client code does not need to call this method.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::list<unique_ptr<CMapOperation> > TStack;
|
typedef std::list<std::unique_ptr<CMapOperation> > TStack;
|
||||||
|
|
||||||
void doOperation(TStack & fromStack, TStack & toStack, bool doUndo);
|
void doOperation(TStack & fromStack, TStack & toStack, bool doUndo);
|
||||||
const CMapOperation * peek(const TStack & stack) const;
|
const CMapOperation * peek(const TStack & stack) const;
|
||||||
@ -182,7 +182,7 @@ public:
|
|||||||
CMapUndoManager & getUndoManager();
|
CMapUndoManager & getUndoManager();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void execute(unique_ptr<CMapOperation> && operation);
|
void execute(std::unique_ptr<CMapOperation> && operation);
|
||||||
|
|
||||||
CMap * map;
|
CMap * map;
|
||||||
CMapUndoManager undoManager;
|
CMapUndoManager undoManager;
|
||||||
@ -205,10 +205,10 @@ public:
|
|||||||
void undo() override;
|
void undo() override;
|
||||||
void redo() override;
|
void redo() override;
|
||||||
|
|
||||||
void addOperation(unique_ptr<CMapOperation> && operation);
|
void addOperation(std::unique_ptr<CMapOperation> && operation);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::list<unique_ptr<CMapOperation> > operations;
|
std::list<std::unique_ptr<CMapOperation> > operations;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace ETerrainGroup
|
namespace ETerrainGroup
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Forward class declarations aren't enough here. The compiler
|
// Forward class declarations aren't enough here. The compiler
|
||||||
// generated CMapInfo d-tor, generates the unique_ptr d-tor as well here
|
// generated CMapInfo d-tor, generates the std::unique_ptr d-tor as well here
|
||||||
// as a inline method. The unique_ptr d-tor requires a complete type. Defining
|
// as a inline method. The std::unique_ptr d-tor requires a complete type. Defining
|
||||||
// the CMapInfo d-tor to let the compiler add the d-tor stuff in the .cpp file
|
// the CMapInfo d-tor to let the compiler add the d-tor stuff in the .cpp file
|
||||||
// would work with one exception. It prevents the generation of the move
|
// would work with one exception. It prevents the generation of the move
|
||||||
// constructor which is needed. (Writing such a c-tor is nasty.) With the
|
// constructor which is needed. (Writing such a c-tor is nasty.) With the
|
||||||
@ -20,8 +20,8 @@ struct StartInfo;
|
|||||||
class DLL_LINKAGE CMapInfo
|
class DLL_LINKAGE CMapInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
unique_ptr<CMapHeader> mapHeader; //may be nullptr if campaign
|
std::unique_ptr<CMapHeader> mapHeader; //may be nullptr if campaign
|
||||||
unique_ptr<CCampaignHeader> campaignHeader; //may be nullptr if scenario
|
std::unique_ptr<CCampaignHeader> campaignHeader; //may be nullptr if scenario
|
||||||
StartInfo * scenarioOpts; //options with which scenario has been started (used only with saved games)
|
StartInfo * scenarioOpts; //options with which scenario has been started (used only with saved games)
|
||||||
std::string fileURI;
|
std::string fileURI;
|
||||||
std::string date;
|
std::string date;
|
||||||
|
@ -52,7 +52,7 @@ class DLL_LINKAGE CMapGenerator
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit CMapGenerator();
|
explicit CMapGenerator();
|
||||||
~CMapGenerator(); // required due to unique_ptr
|
~CMapGenerator(); // required due to std::unique_ptr
|
||||||
|
|
||||||
std::unique_ptr<CMap> generate(CMapGenOptions * mapGenOptions, int RandomSeed = std::time(nullptr));
|
std::unique_ptr<CMap> generate(CMapGenOptions * mapGenOptions, int RandomSeed = std::time(nullptr));
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ CZoneGraphGenerator::CZoneGraphGenerator()// : gen(nullptr)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<CZoneGraph> CZoneGraphGenerator::generate(const CMapGenOptions & options, CRandomGenerator * gen)
|
std::unique_ptr<CZoneGraph> CZoneGraphGenerator::generate(const CMapGenOptions & options, CRandomGenerator * gen)
|
||||||
{
|
{
|
||||||
return make_unique<CZoneGraph>();
|
return make_unique<CZoneGraph>();
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user