1
0
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:
Michał W. Urbańczyk 2013-05-09 11:09:23 +00:00
parent 5de00c752c
commit 5c2473d436
17 changed files with 227 additions and 144 deletions

View File

@ -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");
}

View File

@ -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

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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());

View File

@ -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

View File

@ -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;

View File

@ -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++)
{
ObjectInstanceID hid;
if (h.saving)
hid = sleepingHeroes[i]->id;
h & hid;
if (!h.saving)
{
const CGHeroInstance *hero = cb->getHero(hid);
sleepingHeroes += hero;
}
}
h & observerInDuelMode;
//hero list order
ui8 heroListSize = 0; //fix for uninitialized warning
if (h.saving)
heroListSize = wanderingHeroes.size();
h & wanderingHeroes & towns & sleepingHeroes;
std::map<const CGHeroInstance *, int3> pathsMap; //hero -> dest
if(h.saving)
{
BOOST_FOREACH(auto &p, paths)
pathsMap[p.first] = p.second.endPos();
h & pathsMap;
}
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);

View File

@ -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

View File

@ -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))

View File

@ -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);

View File

@ -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)

View File

@ -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)
{
}

View File

@ -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
};

View File

@ -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);
}

View File

@ -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)

View File

@ -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){};