mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Support for saving/loading in player interfaces, including VCAI.
Minor changes.
This commit is contained in:
parent
5de00c752c
commit
5c2473d436
@ -89,12 +89,12 @@ void CBattleAI::init( CBattleCallback * CB )
|
||||
CB->unlockGsWhenWaiting = false;
|
||||
}
|
||||
|
||||
void CBattleAI::actionFinished( const BattleAction *action )
|
||||
void CBattleAI::actionFinished(const BattleAction &action)
|
||||
{
|
||||
print("actionFinished called");
|
||||
}
|
||||
|
||||
void CBattleAI::actionStarted( const BattleAction *action )
|
||||
void CBattleAI::actionStarted(const BattleAction &action)
|
||||
{
|
||||
print("actionStarted called");
|
||||
}
|
||||
|
@ -18,8 +18,8 @@ public:
|
||||
~CBattleAI(void);
|
||||
|
||||
void init(CBattleCallback * CB) OVERRIDE;
|
||||
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 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
|
||||
BattleAction activeStack(const CStack * stack) OVERRIDE; //called when it's turn of that stack
|
||||
|
||||
void battleAttack(const BattleAttack *ba) OVERRIDE; //called when stack is performing attack
|
||||
|
@ -25,12 +25,12 @@ void CStupidAI::init( CBattleCallback * CB )
|
||||
cbc = cb = CB;
|
||||
}
|
||||
|
||||
void CStupidAI::actionFinished( const BattleAction *action )
|
||||
void CStupidAI::actionFinished(const BattleAction &action)
|
||||
{
|
||||
print("actionFinished called");
|
||||
}
|
||||
|
||||
void CStupidAI::actionStarted( const BattleAction *action )
|
||||
void CStupidAI::actionStarted(const BattleAction &action)
|
||||
{
|
||||
print("actionStarted called");
|
||||
}
|
||||
@ -312,3 +312,15 @@ BattleAction CStupidAI::goTowards(const CStack * stack, BattleHex destination)
|
||||
}
|
||||
}
|
||||
|
||||
void CStupidAI::saveGame(COSer<CSaveFile> &h, const int version)
|
||||
{
|
||||
//TODO to be implemented with saving/loading during the battles
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void CStupidAI::loadGame(CISer<CLoadFile> &h, const int version)
|
||||
{
|
||||
//TODO to be implemented with saving/loading during the battles
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
@ -13,8 +13,8 @@ public:
|
||||
~CStupidAI(void);
|
||||
|
||||
void init(CBattleCallback * CB) OVERRIDE;
|
||||
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 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
|
||||
BattleAction activeStack(const CStack * stack) OVERRIDE; //called when it's turn of that stack
|
||||
|
||||
void battleAttack(const BattleAttack *ba) OVERRIDE; //called when stack is performing attack
|
||||
@ -35,5 +35,9 @@ public:
|
||||
void battleStacksRemoved(const BattleStacksRemoved & bsr) OVERRIDE; //called when certain stack is completely removed from battlefield
|
||||
|
||||
BattleAction goTowards(const CStack * stack, BattleHex hex );
|
||||
|
||||
virtual void saveGame(COSer<CSaveFile> &h, const int version) OVERRIDE;
|
||||
virtual void loadGame(CISer<CLoadFile> &h, const int version) OVERRIDE;
|
||||
|
||||
};
|
||||
|
||||
|
@ -573,7 +573,6 @@ void VCAI::heroVisit(const CGHeroInstance *visitor, const CGObjectInstance *visi
|
||||
NET_EVENT_HANDLER;
|
||||
if (start)
|
||||
{
|
||||
visitedObject = const_cast<CGObjectInstance *>(visitedObj); // remember the object and wait for return
|
||||
markObjectVisited (visitedObj);
|
||||
erase_if_present(reservedObjs, visitedObj); //unreserve objects
|
||||
erase_if_present(reservedHeroesMap[visitor], visitedObj);
|
||||
@ -677,6 +676,10 @@ void VCAI::objectRemoved(const CGObjectInstance *obj)
|
||||
NET_EVENT_HANDLER;
|
||||
|
||||
erase_if_present(visitableObjs, obj);
|
||||
erase_if_present(alreadyVisited, obj);
|
||||
erase_if_present(reservedObjs, obj);
|
||||
|
||||
|
||||
BOOST_FOREACH(auto &p, reservedHeroesMap)
|
||||
erase_if_present(p.second, obj);
|
||||
|
||||
@ -837,7 +840,7 @@ void VCAI::yourTurn()
|
||||
LOG_TRACE(logAi);
|
||||
NET_EVENT_HANDLER;
|
||||
status.startedTurn();
|
||||
makingTurn = new boost::thread(&VCAI::makeTurn, this);
|
||||
makingTurn = make_unique<boost::thread>(&VCAI::makeTurn, this);
|
||||
}
|
||||
|
||||
void VCAI::heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, int queryID)
|
||||
@ -894,16 +897,20 @@ void VCAI::showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *do
|
||||
});
|
||||
}
|
||||
|
||||
void VCAI::serialize(COSer<CSaveFile> &h, const int version)
|
||||
void VCAI::saveGame(COSer<CSaveFile> &h, const int version)
|
||||
{
|
||||
LOG_TRACE_PARAMS(logAi, "version '%i'", version);
|
||||
NET_EVENT_HANDLER;
|
||||
CAdventureAI::saveGame(h, version);
|
||||
serializeInternal(h, version);
|
||||
}
|
||||
|
||||
void VCAI::serialize(CISer<CLoadFile> &h, const int version)
|
||||
void VCAI::loadGame(CISer<CLoadFile> &h, const int version)
|
||||
{
|
||||
LOG_TRACE_PARAMS(logAi, "version '%i'", version);
|
||||
NET_EVENT_HANDLER;
|
||||
CAdventureAI::loadGame(h, version);
|
||||
serializeInternal(h, version);
|
||||
}
|
||||
|
||||
void makePossibleUpgrades(const CArmedInstance *obj)
|
||||
@ -982,7 +989,7 @@ void VCAI::makeTurn()
|
||||
cb->recalculatePaths();
|
||||
|
||||
makeTurnInternal();
|
||||
vstd::clear_pointer(makingTurn);
|
||||
makingTurn.reset();
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1067,6 +1074,7 @@ bool VCAI::goVisitObj(const CGObjectInstance * obj, HeroPtr h)
|
||||
|
||||
void VCAI::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h)
|
||||
{
|
||||
LOG_TRACE_PARAMS(logAi, "Hero %s and object %s at %s", h->name % obj->getHoverText() % obj->pos);
|
||||
switch (obj->ID)
|
||||
{
|
||||
case Obj::CREATURE_GENERATOR1:
|
||||
@ -1692,7 +1700,6 @@ bool VCAI::isAccessibleForHero(const int3 & pos, HeroPtr h, bool includeAllies /
|
||||
bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
||||
{
|
||||
logAi->debugStream() << boost::format("Moving hero %s to tile %s") % h->name % dst;
|
||||
visitedObject = NULL;
|
||||
int3 startHpos = h->visitablePos();
|
||||
bool ret = false;
|
||||
if(startHpos == dst)
|
||||
@ -1750,7 +1757,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
||||
}
|
||||
ret = !i;
|
||||
}
|
||||
if (visitedObject) //we step into something interesting
|
||||
if (auto visitedObject = frontOrNull(cb->getVisitableObjs(h->visitablePos()))) //we stand on something interesting
|
||||
{
|
||||
performObjectInteraction (visitedObject, h);
|
||||
//BNLOG("Hero %s moved from %s to %s at %s", h->name % startHpos % visitedObject->hoverName % h->visitablePos());
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "../../lib/AI_Base.h"
|
||||
#include "../../CCallback.h"
|
||||
#include "../../lib/CDefObjInfoHandler.h"
|
||||
#include "../../lib/CObjectHandler.h"
|
||||
|
||||
#include "../../lib/CThreadHelper.h"
|
||||
@ -50,6 +51,12 @@ public:
|
||||
|
||||
const CGHeroInstance *get(bool doWeExpectNull = false) const;
|
||||
bool validAndSet() const;
|
||||
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & this->h & hid & name;
|
||||
}
|
||||
};
|
||||
|
||||
enum BattleState
|
||||
@ -85,6 +92,12 @@ public:
|
||||
bool haveTurn();
|
||||
void attemptedAnsweringQuery(int queryID, int answerRequestID);
|
||||
void receivedAnswerConfirmation(int answerRequestID, int result);
|
||||
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & battle & remainingQueries & requestToQueryID & havingTurn;
|
||||
}
|
||||
};
|
||||
|
||||
enum EGoals
|
||||
@ -168,6 +181,13 @@ struct CGoal
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & goalType & isElementar & isAbstract & priority;
|
||||
h & value & resID & objid & aid & tile & hero & town & bid;
|
||||
}
|
||||
};
|
||||
|
||||
enum {NOT_VISIBLE = 0, NOT_CHECKED = 1, NOT_AVAILABLE};
|
||||
@ -228,6 +248,12 @@ struct ObjectIdRef
|
||||
ObjectIdRef(const CGObjectInstance *obj);
|
||||
|
||||
bool operator<(const ObjectIdRef &rhs) const;
|
||||
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & id;
|
||||
}
|
||||
};
|
||||
|
||||
class ObjsVector : public std::vector<ObjectIdRef>
|
||||
@ -266,13 +292,12 @@ public:
|
||||
std::string battlename;
|
||||
|
||||
CCallback *myCb;
|
||||
|
||||
unique_ptr<boost::thread> makingTurn;
|
||||
|
||||
VCAI(void);
|
||||
~VCAI(void);
|
||||
|
||||
CGObjectInstance * visitedObject; //remember currently visted object
|
||||
|
||||
boost::thread *makingTurn;
|
||||
|
||||
void tryRealize(CGoal g);
|
||||
|
||||
int3 explorationBestNeighbour(int3 hpos, int radius, HeroPtr h);
|
||||
@ -288,8 +313,8 @@ public:
|
||||
virtual void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, int queryID) OVERRIDE; //TODO
|
||||
virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, const int soundID, bool selection, bool cancel) OVERRIDE; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
||||
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, int queryID) OVERRIDE; //all stacks operations between these objects become allowed, interface has to call onEnd when done
|
||||
virtual void serialize(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving
|
||||
virtual void serialize(CISer<CLoadFile> &h, const int version) OVERRIDE; //loading
|
||||
virtual void saveGame(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving
|
||||
virtual void loadGame(CISer<CLoadFile> &h, const int version) OVERRIDE; //loading
|
||||
virtual void finish() OVERRIDE;
|
||||
|
||||
virtual void availableCreaturesChanged(const CGDwelling *town) OVERRIDE;
|
||||
@ -403,6 +428,17 @@ public:
|
||||
void answerQuery(int queryID, int selection);
|
||||
//special function that can be called ONLY from game events handling thread and will send request ASAP
|
||||
void requestActionASAP(boost::function<void()> whatToDo);
|
||||
|
||||
|
||||
template <typename Handler> void serializeInternal(Handler &h, const int version)
|
||||
{
|
||||
h & knownSubterraneanGates & townVisitsThisWeek & lockedHeroes & reservedHeroesMap;
|
||||
h & visitableObjs & alreadyVisited & reservedObjs;
|
||||
h & saving & status & battlename;
|
||||
|
||||
|
||||
//myCB is restored after load by init call
|
||||
}
|
||||
};
|
||||
|
||||
class cannotFulfillGoalException : public std::exception
|
||||
|
@ -50,7 +50,6 @@ extern CClientState * CCS;
|
||||
/// for allowing different functions for accessing game informations
|
||||
class CGameInfo
|
||||
{
|
||||
ConstTransitivePtr<CGameState> state; //don't touch it in client's code
|
||||
public:
|
||||
ConstTransitivePtr<CModHandler> modh; //public?
|
||||
ConstTransitivePtr<CArtHandler> arth;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "StdInc.h"
|
||||
|
||||
#include "../lib/CDefObjInfoHandler.h"
|
||||
#include "CAdvmapInterface.h"
|
||||
#include "battle/CBattleInterface.h"
|
||||
#include "battle/CBattleInterfaceClasses.h"
|
||||
@ -731,7 +731,7 @@ void CPlayerInterface::battleNewRound(int round) //called at the beginning of ea
|
||||
battleInt->newRound(round);
|
||||
}
|
||||
|
||||
void CPlayerInterface::actionStarted(const BattleAction* action)
|
||||
void CPlayerInterface::actionStarted(const BattleAction &action)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
if(LOCPLINT != this)
|
||||
@ -739,11 +739,11 @@ void CPlayerInterface::actionStarted(const BattleAction* action)
|
||||
return;
|
||||
}
|
||||
|
||||
curAction = new BattleAction(*action);
|
||||
battleInt->startAction(action);
|
||||
curAction = new BattleAction(action);
|
||||
battleInt->startAction(curAction);
|
||||
}
|
||||
|
||||
void CPlayerInterface::actionFinished(const BattleAction* action)
|
||||
void CPlayerInterface::actionFinished(const BattleAction &action)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
if(LOCPLINT != this)
|
||||
@ -751,9 +751,9 @@ void CPlayerInterface::actionFinished(const BattleAction* action)
|
||||
return;
|
||||
}
|
||||
|
||||
battleInt->endAction(curAction);
|
||||
delete curAction;
|
||||
curAction = NULL;
|
||||
battleInt->endAction(action);
|
||||
}
|
||||
|
||||
BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when it's turn of that stack
|
||||
@ -1160,55 +1160,44 @@ void CPlayerInterface::heroBonusChanged( const CGHeroInstance *hero, const Bonus
|
||||
|
||||
template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, const int version )
|
||||
{
|
||||
h & playerID;
|
||||
h & spellbookSettings;
|
||||
|
||||
//sleeping heroes
|
||||
ui8 sleepingSize = 0; //fix for uninitialized warning
|
||||
if (h.saving)
|
||||
sleepingSize = sleepingHeroes.size();
|
||||
h & sleepingSize;
|
||||
for (int i = 0; i < sleepingSize; i++)
|
||||
h & observerInDuelMode;
|
||||
|
||||
h & wanderingHeroes & towns & sleepingHeroes;
|
||||
|
||||
std::map<const CGHeroInstance *, int3> pathsMap; //hero -> dest
|
||||
if(h.saving)
|
||||
{
|
||||
ObjectInstanceID hid;
|
||||
if (h.saving)
|
||||
hid = sleepingHeroes[i]->id;
|
||||
h & hid;
|
||||
if (!h.saving)
|
||||
{
|
||||
const CGHeroInstance *hero = cb->getHero(hid);
|
||||
sleepingHeroes += hero;
|
||||
}
|
||||
BOOST_FOREACH(auto &p, paths)
|
||||
pathsMap[p.first] = p.second.endPos();
|
||||
h & pathsMap;
|
||||
}
|
||||
|
||||
//hero list order
|
||||
ui8 heroListSize = 0; //fix for uninitialized warning
|
||||
if (h.saving)
|
||||
heroListSize = wanderingHeroes.size();
|
||||
else
|
||||
wanderingHeroes.clear();
|
||||
h & heroListSize;
|
||||
for (int i = 0; i < heroListSize; i++)
|
||||
{
|
||||
ObjectInstanceID hid;
|
||||
if (h.saving)
|
||||
hid = wanderingHeroes[i]->id;
|
||||
h & hid;
|
||||
if (!h.saving)
|
||||
h & pathsMap;
|
||||
|
||||
CPathsInfo pathsInfo(cb->getMapSize());
|
||||
BOOST_FOREACH(auto &p, pathsMap)
|
||||
{
|
||||
const CGHeroInstance *hero = cb->getHero(hid);
|
||||
wanderingHeroes += hero;
|
||||
cb->calculatePaths(p.first, pathsInfo);
|
||||
CGPath path;
|
||||
pathsInfo.getPath(p.second, path);
|
||||
paths[p.first] = path;
|
||||
logGlobal->traceStream() << boost::format("Restored path for hero %s leading to %s with %d nodes")
|
||||
% p.first->nodeName() % p.second % path.nodes.size();
|
||||
}
|
||||
}
|
||||
|
||||
h & spellbookSettings;
|
||||
}
|
||||
|
||||
void CPlayerInterface::serialize( COSer<CSaveFile> &h, const int version )
|
||||
void CPlayerInterface::saveGame( COSer<CSaveFile> &h, const int version )
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
serializeTempl(h,version);
|
||||
}
|
||||
|
||||
void CPlayerInterface::serialize( CISer<CLoadFile> &h, const int version )
|
||||
void CPlayerInterface::loadGame( CISer<CLoadFile> &h, const int version )
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
serializeTempl(h,version);
|
||||
|
@ -182,12 +182,12 @@ public:
|
||||
void gameOver(PlayerColor player, bool victory) OVERRIDE;
|
||||
void playerStartsTurn(PlayerColor player) OVERRIDE; //called before yourTurn on active itnerface
|
||||
void showComp(const Component &comp, std::string message) OVERRIDE; //display component in the advmapint infobox
|
||||
void serialize(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving
|
||||
void serialize(CISer<CLoadFile> &h, const int version) OVERRIDE; //loading
|
||||
void saveGame(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving
|
||||
void loadGame(CISer<CLoadFile> &h, const int version) OVERRIDE; //loading
|
||||
|
||||
//for battles
|
||||
void actionFinished(const BattleAction* action) OVERRIDE;//occurs AFTER action taken by active stack or by the hero
|
||||
void actionStarted(const BattleAction* action) OVERRIDE;//occurs BEFORE action taken by active stack or by the hero
|
||||
void actionFinished(const BattleAction& action) OVERRIDE;//occurs AFTER action taken by active stack or by the hero
|
||||
void actionStarted(const BattleAction& action) OVERRIDE;//occurs BEFORE action taken by active stack or by the hero
|
||||
BattleAction activeStack(const CStack * stack) OVERRIDE; //called when it's turn of that stack
|
||||
void battleAttack(const BattleAttack *ba) OVERRIDE; //stack performs attack
|
||||
void battleEnd(const BattleResult *br) OVERRIDE; //end of battle
|
||||
|
@ -78,20 +78,20 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static CApplier<CBaseForCLApply> *applier = NULL;
|
||||
static CApplier<CBaseForCLApply> *applier = nullptr;
|
||||
|
||||
void CClient::init()
|
||||
{
|
||||
hotSeat = false;
|
||||
connectionHandler = NULL;
|
||||
pathInfo = NULL;
|
||||
connectionHandler = nullptr;
|
||||
pathInfo = nullptr;
|
||||
applier = new CApplier<CBaseForCLApply>;
|
||||
registerTypes2(*applier);
|
||||
IObjectInterface::cb = this;
|
||||
serv = NULL;
|
||||
gs = NULL;
|
||||
cb = NULL;
|
||||
erm = NULL;
|
||||
serv = nullptr;
|
||||
gs = nullptr;
|
||||
cb = nullptr;
|
||||
erm = nullptr;
|
||||
terminate = false;
|
||||
}
|
||||
|
||||
@ -108,7 +108,6 @@ CClient::CClient(CConnection *con, StartInfo *si)
|
||||
|
||||
CClient::~CClient(void)
|
||||
{
|
||||
delete pathInfo;
|
||||
delete applier;
|
||||
}
|
||||
|
||||
@ -202,11 +201,9 @@ void CClient::endGame( bool closeConnection /*= true*/ )
|
||||
GH.statusbar = NULL;
|
||||
logNetwork->infoStream() << "Removed GUI.";
|
||||
|
||||
vstd::clear_pointer(const_cast<CGameInfo*>(CGI)->mh);
|
||||
vstd::clear_pointer(gs);
|
||||
|
||||
delete CGI->mh;
|
||||
const_cast<CGameInfo*>(CGI)->mh = NULL;
|
||||
|
||||
const_cast<CGameInfo*>(CGI)->state.dellNull();
|
||||
logNetwork->infoStream() << "Deleted mapHandler and gameState.";
|
||||
LOCPLINT = NULL;
|
||||
}
|
||||
@ -242,10 +239,9 @@ void CClient::loadGame( const std::string & fname )
|
||||
loader = checkingLoader.decay();
|
||||
}
|
||||
logNetwork->infoStream() << "Loaded common part of save " << tmh.getDiff();
|
||||
const_cast<CGameInfo*>(CGI)->state = gs;
|
||||
const_cast<CGameInfo*>(CGI)->mh = new CMapHandler();
|
||||
const_cast<CGameInfo*>(CGI)->mh->map = gs->map;
|
||||
pathInfo = new CPathsInfo(int3(gs->map->width, gs->map->height, gs->map->twoLevel ? 2 : 1));
|
||||
pathInfo = make_unique<CPathsInfo>(getMapSize());
|
||||
CGI->mh->init();
|
||||
logNetwork->infoStream() <<"Initing maphandler: "<<tmh.getDiff();
|
||||
|
||||
@ -295,12 +291,12 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
networkMode = (con->connectionID == 1) ? HOST : GUEST;
|
||||
}
|
||||
|
||||
CStopWatch tmh;
|
||||
const_cast<CGameInfo*>(CGI)->state = new CGameState();
|
||||
logNetwork->infoStream() <<"\tGamestate: "<<tmh.getDiff();
|
||||
CConnection &c(*serv);
|
||||
CConnection &c = *serv;
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
logNetwork->infoStream() <<"\tWill send info to server...";
|
||||
CStopWatch tmh;
|
||||
|
||||
if(networkMode == SINGLE)
|
||||
{
|
||||
ui8 pom8;
|
||||
@ -319,7 +315,9 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
c.disableSmartPointerSerialization();
|
||||
|
||||
// Initialize game state
|
||||
gs = const_cast<CGameInfo*>(CGI)->state;
|
||||
gs = new CGameState();
|
||||
logNetwork->infoStream() <<"\tCreating gamestate: "<<tmh.getDiff();
|
||||
|
||||
gs->scenarioOps = si;
|
||||
gs->init(si);
|
||||
logNetwork->infoStream() <<"Initializing GameState (together): "<<tmh.getDiff();
|
||||
@ -347,7 +345,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
CGI->mh->map = gs->map;
|
||||
logNetwork->infoStream() <<"Creating mapHandler: "<<tmh.getDiff();
|
||||
CGI->mh->init();
|
||||
pathInfo = new CPathsInfo(int3(gs->map->width, gs->map->height, gs->map->twoLevel ? 2 : 1));
|
||||
pathInfo = make_unique<CPathsInfo>(getMapSize());
|
||||
logNetwork->infoStream() <<"Initializing mapHandler (together): "<<tmh.getDiff();
|
||||
}
|
||||
|
||||
@ -416,7 +414,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
loadNeutralBattleAI();
|
||||
}
|
||||
|
||||
serv->addStdVecItems(const_cast<CGameInfo*>(CGI)->state);
|
||||
serv->addStdVecItems(gs);
|
||||
hotSeat = (humanPlayers > 1);
|
||||
|
||||
// std::vector<FileInfo> scriptModules;
|
||||
@ -445,8 +443,11 @@ void CClient::serialize( Handler &h, const int version )
|
||||
|
||||
for(auto i = playerint.begin(); i != playerint.end(); i++)
|
||||
{
|
||||
h & i->first & i->second->dllName;
|
||||
i->second->serialize(h,version);
|
||||
LOG_TRACE_PARAMS(logGlobal, "Saving player %s interface", i->first);
|
||||
assert(i->first == i->second->playerID);
|
||||
h & i->first & i->second->dllName & i->second->human;
|
||||
i->second->saveGame(dynamic_cast<COSer<CSaveFile>&>(h), version);
|
||||
//evil cast that i still like better than sfinae-magic. If I had a "static if"...
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -457,11 +458,13 @@ void CClient::serialize( Handler &h, const int version )
|
||||
for(int i=0; i < players; i++)
|
||||
{
|
||||
std::string dllname;
|
||||
PlayerColor pid = PlayerColor(0); //fix for uninitialized warning
|
||||
h & pid & dllname;
|
||||
PlayerColor pid;
|
||||
bool isHuman = false;
|
||||
|
||||
h & pid & dllname & isHuman;
|
||||
LOG_TRACE_PARAMS(logGlobal, "Loading player %s interface", pid);
|
||||
|
||||
CGameInterface *nInt = NULL;
|
||||
CGameInterface *nInt = nullptr;
|
||||
if(dllname.length())
|
||||
{
|
||||
if(pid == PlayerColor::NEUTRAL)
|
||||
@ -474,15 +477,25 @@ void CClient::serialize( Handler &h, const int version )
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!isHuman);
|
||||
nInt = CDynLibHandler::getNewAI(dllname);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(isHuman);
|
||||
nInt = new CPlayerInterface(pid);
|
||||
}
|
||||
|
||||
nInt->dllName = dllname;
|
||||
nInt->human = isHuman;
|
||||
nInt->playerID = pid;
|
||||
|
||||
battleCallbacks[pid] = callbacks[pid] = make_shared<CCallback>(gs,pid,this);
|
||||
battleints[pid] = playerint[pid] = nInt;
|
||||
nInt->init(callbacks[pid].get());
|
||||
nInt->serialize(h, version);
|
||||
nInt->loadGame(dynamic_cast<CISer<CLoadFile>&>(h), version); //another evil cast, check above
|
||||
}
|
||||
|
||||
if(!vstd::contains(battleints, PlayerColor::NEUTRAL))
|
||||
|
@ -121,18 +121,16 @@ public:
|
||||
std::map<PlayerColor,CBattleGameInterface *> battleints;
|
||||
bool hotSeat;
|
||||
CConnection *serv;
|
||||
BattleAction *curbaction;
|
||||
|
||||
CPathsInfo *pathInfo;
|
||||
boost::optional<BattleAction> curbaction;
|
||||
|
||||
unique_ptr<CPathsInfo> pathInfo;
|
||||
boost::mutex pathMx; //protects the variable above
|
||||
|
||||
CScriptingModule *erm;
|
||||
|
||||
ThreadSafeVector<int> waitingRequest;
|
||||
|
||||
std::queue<CPack *> packs;
|
||||
boost::mutex packsM;
|
||||
|
||||
void waitForMoveAndSend(PlayerColor color);
|
||||
//void sendRequest(const CPackForServer *request, bool waitForRealization);
|
||||
CClient(void);
|
||||
|
@ -671,8 +671,8 @@ void BattleAttack::applyCl( CClient *cl )
|
||||
|
||||
void StartAction::applyFirstCl( CClient *cl )
|
||||
{
|
||||
cl->curbaction = new BattleAction(ba);
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(actionStarted, &ba);
|
||||
cl->curbaction = ba;
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(actionStarted, ba);
|
||||
}
|
||||
|
||||
void BattleSpellCast::applyCl( CClient *cl )
|
||||
@ -744,10 +744,8 @@ CGameState* CPackForClient::GS( CClient *cl )
|
||||
|
||||
void EndAction::applyCl( CClient *cl )
|
||||
{
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(actionFinished, cl->curbaction);
|
||||
|
||||
delete cl->curbaction;
|
||||
cl->curbaction = NULL;
|
||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(actionFinished, *cl->curbaction);
|
||||
cl->curbaction.reset();
|
||||
}
|
||||
|
||||
void PackageApplied::applyCl( CClient *cl )
|
||||
@ -793,24 +791,6 @@ void SaveGame::applyCl(CClient *cl)
|
||||
{
|
||||
logNetwork->errorStream() << "Failed to save game:" << e.what();
|
||||
}
|
||||
|
||||
// try
|
||||
// {
|
||||
// auto clientPart = CResourceHandler::get()->getResourceName(ResourceID(info.getStem(), EResType::CLIENT_SAVEGAME));
|
||||
// auto libPart = CResourceHandler::get()->getResourceName(ResourceID(info.getStem(), EResType::LIB_SAVEGAME));
|
||||
// CLoadIntegrityValidator checker(clientPart, libPart);
|
||||
//
|
||||
// CMapHeader mh;
|
||||
// StartInfo *si;
|
||||
// LibClasses *lib;
|
||||
// CGameState *game;
|
||||
//
|
||||
// checker.checkMagicBytes(SAVEGAME_MAGIC);
|
||||
// checker >> mh >> si >> lib >> game;
|
||||
// }
|
||||
// catch(...)
|
||||
// {
|
||||
// }
|
||||
}
|
||||
|
||||
void PlayerMessage::applyCl(CClient *cl)
|
||||
|
@ -10,6 +10,7 @@
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#include "Connection.h"
|
||||
|
||||
/*
|
||||
* CGameInterface.cpp, part of VCMI engine
|
||||
@ -133,7 +134,7 @@ void CAdventureAI::battleStacksAttacked(const std::vector<BattleStackAttacked> &
|
||||
battleAI->battleStacksAttacked(bsa);
|
||||
}
|
||||
|
||||
void CAdventureAI::actionStarted(const BattleAction *action)
|
||||
void CAdventureAI::actionStarted(const BattleAction &action)
|
||||
{
|
||||
battleAI->actionStarted(action);
|
||||
}
|
||||
@ -143,7 +144,7 @@ void CAdventureAI::battleNewRoundFirst(int round)
|
||||
battleAI->battleNewRoundFirst(round);
|
||||
}
|
||||
|
||||
void CAdventureAI::actionFinished(const BattleAction *action)
|
||||
void CAdventureAI::actionFinished(const BattleAction &action)
|
||||
{
|
||||
battleAI->actionFinished(action);
|
||||
}
|
||||
@ -203,3 +204,41 @@ void CAdventureAI::yourTacticPhase(int distance)
|
||||
{
|
||||
battleAI->yourTacticPhase(distance);
|
||||
}
|
||||
|
||||
void CAdventureAI::saveGame(COSer<CSaveFile> &h, const int version) /*saving */
|
||||
{
|
||||
LOG_TRACE_PARAMS(logAi, "version '%i'", version);
|
||||
CGlobalAI::saveGame(h, version);
|
||||
bool hasBattleAI = battleAI;
|
||||
h << hasBattleAI;
|
||||
if(hasBattleAI)
|
||||
{
|
||||
h << std::string(battleAI->dllName);
|
||||
battleAI->saveGame(h, version);
|
||||
}
|
||||
}
|
||||
|
||||
void CAdventureAI::loadGame(CISer<CLoadFile> &h, const int version) /*loading */
|
||||
{
|
||||
LOG_TRACE_PARAMS(logAi, "version '%i'", version);
|
||||
CGlobalAI::loadGame(h, version);
|
||||
bool hasBattleAI = false;
|
||||
h >> hasBattleAI;
|
||||
if(hasBattleAI)
|
||||
{
|
||||
std::string dllName;
|
||||
h >> dllName;
|
||||
battleAI = CDynLibHandler::getNewBattleAI(dllName);
|
||||
assert(cbc); //it should have been set by the one who new'ed us
|
||||
battleAI->init(cbc);
|
||||
//battleAI->loadGame(h, version);
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleGameInterface::saveGame(COSer<CSaveFile> &h, const int version)
|
||||
{
|
||||
}
|
||||
|
||||
void CBattleGameInterface::loadGame(CISer<CLoadFile> &h, const int version)
|
||||
{
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ template <typename Serializer> class COSer;
|
||||
struct ArtifactLocation;
|
||||
class CScriptingModule;
|
||||
|
||||
class CBattleGameInterface : public IBattleEventsReceiver
|
||||
class DLL_LINKAGE CBattleGameInterface : public IBattleEventsReceiver
|
||||
{
|
||||
public:
|
||||
bool human;
|
||||
@ -66,6 +66,10 @@ public:
|
||||
//battle call-ins
|
||||
virtual BattleAction activeStack(const CStack * stack)=0; //called when it's turn of that stack
|
||||
virtual void yourTacticPhase(int distance){}; //called when interface has opportunity to use Tactics skill -> use cb->battleMakeTacticAction from this function
|
||||
|
||||
virtual void saveGame(COSer<CSaveFile> &h, const int version);
|
||||
virtual void loadGame(CISer<CLoadFile> &h, const int version);
|
||||
|
||||
};
|
||||
|
||||
/// Central class for managing human player / AI interface logic
|
||||
@ -86,8 +90,6 @@ public:
|
||||
|
||||
// all stacks operations between these objects become allowed, interface has to call onEnd when done
|
||||
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, int queryID) = 0;
|
||||
virtual void serialize(COSer<CSaveFile> &h, const int version){}; //saving
|
||||
virtual void serialize(CISer<CLoadFile> &h, const int version){}; //loading
|
||||
virtual void finish(){}; //if for some reason we want to end
|
||||
};
|
||||
|
||||
@ -124,9 +126,9 @@ public:
|
||||
virtual void battleCatapultAttacked(const CatapultAttack & ca);
|
||||
virtual void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side);
|
||||
virtual void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa);
|
||||
virtual void actionStarted(const BattleAction *action);
|
||||
virtual void actionStarted(const BattleAction &action);
|
||||
virtual void battleNewRoundFirst(int round);
|
||||
virtual void actionFinished(const BattleAction *action);
|
||||
virtual void actionFinished(const BattleAction &action);
|
||||
virtual void battleStacksEffectsSet(const SetStackEffect & sse);
|
||||
//virtual void battleTriggerEffect(const BattleTriggerEffect & bte);
|
||||
virtual void battleStacksRemoved(const BattleStacksRemoved & bsr);
|
||||
@ -137,4 +139,7 @@ public:
|
||||
virtual void battleSpellCast(const BattleSpellCast *sc);
|
||||
virtual void battleEnd(const BattleResult *br);
|
||||
virtual void battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, bool tentHeal, si32 lifeDrainFrom);
|
||||
|
||||
virtual void saveGame(COSer<CSaveFile> &h, const int version); //saving
|
||||
virtual void loadGame(CISer<CLoadFile> &h, const int version); //loading
|
||||
};
|
||||
|
@ -511,6 +511,7 @@ int CLoadIntegrityValidator::read( const void * data, unsigned size )
|
||||
|
||||
unique_ptr<CLoadFile> CLoadIntegrityValidator::decay()
|
||||
{
|
||||
primaryFile->loadedPointers = this->loadedPointers;
|
||||
return std::move(primaryFile);
|
||||
}
|
||||
|
||||
|
@ -1160,19 +1160,19 @@ public:
|
||||
data = boost::optional<T>();
|
||||
}
|
||||
}
|
||||
void loadSerializable(CStackInstance *&s)
|
||||
{
|
||||
if(sendStackInstanceByIds)
|
||||
{
|
||||
CArmedInstance *armed;
|
||||
SlotID slot;
|
||||
*this >> armed >> slot;
|
||||
assert(armed->hasStackAtSlot(slot));
|
||||
s = armed->stacks[slot];
|
||||
}
|
||||
else
|
||||
loadSerializableBySerializeCall(s);
|
||||
}
|
||||
// void loadSerializable(CStackInstance *&s)
|
||||
// {
|
||||
// if(sendStackInstanceByIds)
|
||||
// {
|
||||
// CArmedInstance *armed;
|
||||
// SlotID slot;
|
||||
// *this >> armed >> slot;
|
||||
// assert(armed->hasStackAtSlot(slot));
|
||||
// s = armed->stacks[slot];
|
||||
// }
|
||||
// else
|
||||
// loadSerializableBySerializeCall(s);
|
||||
// }
|
||||
|
||||
template <typename E>
|
||||
void loadEnum(E &data)
|
||||
|
@ -49,8 +49,8 @@ struct CPackForServer;
|
||||
class DLL_LINKAGE IBattleEventsReceiver
|
||||
{
|
||||
public:
|
||||
virtual void actionFinished(const BattleAction *action){};//occurs AFTER every action taken by any stack or by the hero
|
||||
virtual void actionStarted(const BattleAction *action){};//occurs BEFORE every action taken by any stack or by the hero
|
||||
virtual void actionFinished(const BattleAction &action){};//occurs AFTER every action taken by any stack or by the hero
|
||||
virtual void actionStarted(const BattleAction &action){};//occurs BEFORE every action taken by any stack or by the hero
|
||||
virtual void battleAttack(const BattleAttack *ba){}; //called when stack is performing attack
|
||||
virtual void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa){}; //called when stack receives damage (after battleAttack())
|
||||
virtual void battleEnd(const BattleResult *br){};
|
||||
|
Loading…
Reference in New Issue
Block a user