mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Support for saving/loading in player interfaces, including VCAI.
Minor changes.
This commit is contained in:
		| @@ -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){}; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user