mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	* restored 0.74 savegames compatibility (for easier reproducing reported issues)
* Fixed #184 and #189 * minor fixes
This commit is contained in:
		| @@ -1985,6 +1985,9 @@ void CBattleInterface::clickRight(tribool down, bool previousState) | ||||
|  | ||||
| void CBattleInterface::bOptionsf() | ||||
| { | ||||
| 	if(activeStack < 0) //workaround to prevent crashing calls in the middle of movement (action) | ||||
| 		return;			//TODO: disable options button during action (other buttons should be disabled as well) | ||||
|  | ||||
| 	if(spellDestSelectMode) //we are casting a spell | ||||
| 		return; | ||||
|  | ||||
|   | ||||
| @@ -263,7 +263,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details) | ||||
| 			adventureInt->paths.erase(ho); | ||||
| 			adventureInt->terrain.currentPath = NULL; | ||||
| 		} | ||||
| 		else if(adventureInt->terrain.currentPath) //&& hero is moving | ||||
| 		else if(adventureInt->terrain.currentPath  &&  details.result == TryMoveHero::SUCCESS) //&& hero is moving | ||||
| 		{ | ||||
| 			//remove one node from the path (the one we went) | ||||
| 			adventureInt->terrain.currentPath->nodes.erase(adventureInt->terrain.currentPath->nodes.end()-1); | ||||
| @@ -1204,17 +1204,7 @@ void CPlayerInterface::showYesNoDialog(const std::string &text, const std::vecto | ||||
| { | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	LOCPLINT->showingDialog->setn(true); | ||||
| 	std::vector<std::pair<std::string,CFunctionList<void()> > > pom; | ||||
| 	pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",0)); | ||||
| 	pom.push_back(std::pair<std::string,CFunctionList<void()> >("ICANCEL.DEF",0)); | ||||
| 	CInfoWindow * temp = new CInfoWindow(text,playerID,0,components,pom,DelComps); | ||||
| 	temp->delComps = DelComps; | ||||
| 	for(int i=0;i<onYes.funcs.size();i++) | ||||
| 		temp->buttons[0]->callback += onYes.funcs[i]; | ||||
| 	for(int i=0;i<onNo.funcs.size();i++) | ||||
| 		temp->buttons[1]->callback += onNo.funcs[i]; | ||||
|  | ||||
| 	GH.pushInt(temp); | ||||
| 	CInfoWindow::showYesNoDialog(text, &components, onYes, onNo, DelComps, playerID); | ||||
| } | ||||
|  | ||||
| void CPlayerInterface::showBlockingDialog( const std::string &text, const std::vector<Component> &components, ui32 askID, int soundID, bool selection, bool cancel ) | ||||
| @@ -1378,8 +1368,8 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path ) | ||||
|  | ||||
| 	for(int i=path.nodes.size()-1; i>0 && stillMoveHero.data == CONTINUE_MOVE; i--) | ||||
| 	{ | ||||
| 		//stop sending move requests if hero exhausted all his move points | ||||
| 		if(!h->movement) | ||||
| 		//stop sending move requests if the next node can't be reached at the current turn (hero exhausted his move points) | ||||
| 		if(path.nodes[i-1].turns) | ||||
| 		{ | ||||
| 			stillMoveHero.data = STOP_MOVE; | ||||
| 			break; | ||||
|   | ||||
| @@ -70,6 +70,7 @@ CMenuScreen::CMenuScreen( EState which ) | ||||
| 			buttons[1] = new AdventureMapButton("", CGI->generaltexth->zelp[4].second, bind(&CMenuScreen::moveTo, this, ref(CGP->scrs[loadGame])), 532, 132, "ZMENULG.DEF", SDLK_l); | ||||
| 			buttons[2] = new AdventureMapButton("", CGI->generaltexth->zelp[5].second, 0 /*cb*/, 524, 251, "ZMENUHS.DEF", SDLK_h); | ||||
| 			buttons[3] = new AdventureMapButton("", CGI->generaltexth->zelp[6].second, 0 /*cb*/, 557, 359, "ZMENUCR.DEF", SDLK_c); | ||||
| 			//boost::function<void()> confWindow = bind(CInfoWindow::showYesNoDialog, ) | ||||
| 			buttons[4] = new AdventureMapButton("", CGI->generaltexth->zelp[7].second, do_quit, 586, 468, "ZMENUQT.DEF", SDLK_ESCAPE); | ||||
| 		} | ||||
| 		break; | ||||
|   | ||||
| @@ -699,6 +699,22 @@ void CInfoWindow::showAll( SDL_Surface * to ) | ||||
| 	show(to); | ||||
| } | ||||
|  | ||||
| void CInfoWindow::showYesNoDialog(const std::string & text, const std::vector<SComponent*> *components, const CFunctionList<void( ) > &onYes, const CFunctionList<void()> &onNo, bool DelComps, int player) | ||||
| { | ||||
| 	assert(!LOCPLINT || LOCPLINT->showingDialog->get()); | ||||
| 	std::vector<std::pair<std::string,CFunctionList<void()> > > pom; | ||||
| 	pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",0)); | ||||
| 	pom.push_back(std::pair<std::string,CFunctionList<void()> >("ICANCEL.DEF",0)); | ||||
| 	CInfoWindow * temp = new CInfoWindow(text, player, 0, *components, pom, DelComps); | ||||
| 	temp->delComps = DelComps; | ||||
| 	for(int i=0;i<onYes.funcs.size();i++) | ||||
| 		temp->buttons[0]->callback += onYes.funcs[i]; | ||||
| 	for(int i=0;i<onNo.funcs.size();i++) | ||||
| 		temp->buttons[1]->callback += onNo.funcs[i]; | ||||
|  | ||||
| 	GH.pushInt(temp); | ||||
| } | ||||
|  | ||||
| void CRClickPopup::clickRight(tribool down, bool previousState) | ||||
| { | ||||
| 	if(down) | ||||
|   | ||||
| @@ -79,6 +79,8 @@ public: | ||||
| 	CInfoWindow(std::string text, int player, int charperline, const std::vector<SComponent*> &comps, std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, bool delComps); //c-tor | ||||
| 	CInfoWindow(); //c-tor | ||||
| 	~CInfoWindow(); //d-tor | ||||
|  | ||||
| 	static void showYesNoDialog( const std::string & text, const std::vector<SComponent*> *components, const CFunctionList<void( ) > &onYes, const CFunctionList<void()> &onNo, bool DelComps, int player); //use only before the game starts! (showYesNoDialog in LOCPLINT must be used then) | ||||
| }; | ||||
| class CSelWindow : public CInfoWindow //component selection window | ||||
| { //warning - this window deletes its components by closing! | ||||
|   | ||||
| @@ -75,6 +75,12 @@ public: | ||||
| 			& timeBetweenFidgets & walkAnimationTime & attackAnimationTime & flightAnimationDistance | ||||
| 			& upperRightMissleOffsetX & rightMissleOffsetX & lowerRightMissleOffsetX & upperRightMissleOffsetY & rightMissleOffsetY & lowerRightMissleOffsetY | ||||
| 			& missleFrameAngles & troopCountLocationOffset & attackClimaxFrame; | ||||
|  | ||||
| 		if(version == 710) //temporary, for 0.74 savegames compatibility | ||||
| 		{ | ||||
| 			char snd[40]; | ||||
| 			h & snd; | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -2150,6 +2150,9 @@ void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int | ||||
| 		getNeighbours(ct, cp->coord, neighbours, boost::logic::indeterminate); | ||||
| 		for(unsigned int i=0; i < neighbours.size(); i++) | ||||
| 		{ | ||||
| 			int moveAtNextTile = movement; | ||||
| 			int turnAtNextTile = turn; | ||||
|  | ||||
| 			const int3 &n = neighbours[i]; //current neighbor | ||||
| 			CGPathNode & dp = graph[n.x][n.y][n.z]; | ||||
| 			if( !checkForVisitableDir(cp->coord, dp.coord)  | ||||
| @@ -2165,19 +2168,19 @@ void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int | ||||
| 			if(remains < 0) | ||||
| 			{ | ||||
| 				//occurs rarely, when hero with low movepoints tries to go leave the road | ||||
| 				turn++; | ||||
| 				movement = hero->maxMovePoints(ct.tertype != TerrainTile::water); | ||||
| 				cost = getMovementCost(hero, cp->coord, dp.coord, movement); //cost must be updated, movement points changed :( | ||||
| 				remains = movement - cost; | ||||
| 				turnAtNextTile++; | ||||
| 				moveAtNextTile = hero->maxMovePoints(ct.tertype != TerrainTile::water); | ||||
| 				cost = getMovementCost(hero, cp->coord, dp.coord, moveAtNextTile); //cost must be updated, movement points changed :( | ||||
| 				remains = moveAtNextTile - cost; | ||||
| 			} | ||||
|  | ||||
| 			if(dp.turns==0xff		//we haven't been here before | ||||
| 				|| dp.turns > turn | ||||
| 				|| (dp.turns >= turn  &&  dp.moveRemains < remains)) //this route is faster | ||||
| 				|| dp.turns > turnAtNextTile | ||||
| 				|| (dp.turns >= turnAtNextTile  &&  dp.moveRemains < remains)) //this route is faster | ||||
| 			{ | ||||
| 				assert(&dp != cp->theNodeBefore); //two tiles can't point to each other | ||||
| 				dp.moveRemains = remains; | ||||
| 				dp.turns = turn; | ||||
| 				dp.turns = turnAtNextTile; | ||||
| 				dp.theNodeBefore = cp; | ||||
| 				if(dp.accessible == CGPathNode::ACCESSIBLE) | ||||
| 				{ | ||||
|   | ||||
| @@ -253,7 +253,7 @@ CLoadFile::CLoadFile( const std::string &fname ) | ||||
| 		} | ||||
|  | ||||
| 		*this >> myVersion;	 | ||||
| 		if(myVersion != version) | ||||
| 		if(myVersion > version  ||  myVersion < 110) | ||||
| 		{ | ||||
| 			tlog1 << "Wrong save format! (file " << fname << " )\n"; | ||||
| 			delete sfile; | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
| #include <boost/mpl/identity.hpp> | ||||
|  | ||||
| #include <boost/type_traits/is_array.hpp> | ||||
| const ui32 version = 710; | ||||
| const ui32 version = 711; | ||||
| class CConnection; | ||||
| class CGObjectInstance; | ||||
| class CGameState; | ||||
|   | ||||
| @@ -37,12 +37,14 @@ | ||||
|  | ||||
| DLL_EXPORT void SetResource::applyGs( CGameState *gs ) | ||||
| { | ||||
| 	assert(player < PLAYER_LIMIT); | ||||
| 	amax(val, 0); //new value must be >= 0 | ||||
| 	gs->getPlayer(player)->resources[resid] = val; | ||||
| } | ||||
|  | ||||
| DLL_EXPORT void SetResources::applyGs( CGameState *gs ) | ||||
| { | ||||
| 	assert(player < PLAYER_LIMIT); | ||||
| 	for(int i=0;i<res.size();i++) | ||||
| 		gs->getPlayer(player)->resources[i] = res[i]; | ||||
| } | ||||
|   | ||||
| @@ -23,7 +23,6 @@ void registerTypes1(Serializer &s) | ||||
| 	s.template registerType<CGHeroInstance>(); | ||||
| 	s.template registerType<CGTownInstance>(); | ||||
| 	s.template registerType<CTownBonus>(); | ||||
| 	s.template registerType<COPWBonus>(); | ||||
| 	s.template registerType<CGPandoraBox>(); | ||||
| 	s.template registerType<CGEvent>(); | ||||
| 	s.template registerType<CGDwelling>(); | ||||
| @@ -58,6 +57,7 @@ void registerTypes1(Serializer &s) | ||||
| 	s.template registerType<CGShipyard>(); | ||||
| 	s.template registerType<CCartographer>(); | ||||
| 	s.template registerType<CGObjectInstance>(); | ||||
| 	s.template registerType<COPWBonus>(); | ||||
| } | ||||
|  | ||||
| template<typename Serializer> DLL_EXPORT  | ||||
|   | ||||
| @@ -782,6 +782,8 @@ void CGameHandler::newTurn() | ||||
| 	for ( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++) | ||||
| 	{ | ||||
| 		if(i->first == 255) continue; | ||||
| 		else if(i->first > PLAYER_LIMIT) assert(0); //illegal player number! | ||||
|  | ||||
| 		if(gs->getDate(1)==7) //first day of week - new heroes in tavern | ||||
| 		{ | ||||
| 			SetAvailableHeroes sah; | ||||
| @@ -843,42 +845,43 @@ void CGameHandler::newTurn() | ||||
| 		n.res.push_back(r); | ||||
| 	} | ||||
| 	for(std::vector<CGTownInstance *>::iterator j = gs->map->towns.begin(); j!=gs->map->towns.end(); j++)//handle towns | ||||
| 	{ | ||||
| 		if(gs->getDate(1)==7) //first day of week | ||||
| 		{ | ||||
| 			if(gs->getDate(1)==7) //first day of week | ||||
| 			SetAvailableCreatures sac; | ||||
| 			sac.tid = (**j).id; | ||||
| 			sac.creatures = (**j).creatures; | ||||
| 			for(int k=0;k<CREATURES_PER_TOWN;k++) //creature growths | ||||
| 			{ | ||||
| 				SetAvailableCreatures sac; | ||||
| 				sac.tid = (**j).id; | ||||
| 				sac.creatures = (**j).creatures; | ||||
| 				for(int k=0;k<CREATURES_PER_TOWN;k++) //creature growths | ||||
| 				if((**j).creatureDwelling(k))//there is dwelling (k-level) | ||||
| 				{ | ||||
| 					if((**j).creatureDwelling(k))//there is dwelling (k-level) | ||||
| 					{ | ||||
| 						sac.creatures[k].first += (**j).creatureGrowth(k); | ||||
| 						if(!gs->getDate(0)) //first day of game: use only basic growths | ||||
| 							amin(sac.creatures[k].first, VLC->creh->creatures[(*j)->town->basicCreatures[k]].growth); | ||||
| 					} | ||||
| 					sac.creatures[k].first += (**j).creatureGrowth(k); | ||||
| 					if(!gs->getDate(0)) //first day of game: use only basic growths | ||||
| 						amin(sac.creatures[k].first, VLC->creh->creatures[(*j)->town->basicCreatures[k]].growth); | ||||
| 				} | ||||
| 				n.cres.push_back(sac); | ||||
| 			} | ||||
| 			if(gs->day  &&  (*j)->tempOwner < PLAYER_LIMIT)//not the first day and town not neutral | ||||
| 			{ | ||||
| 				SetResources r; | ||||
| 				if(vstd::contains((**j).builtBuildings,15)) //there is resource silo | ||||
| 				{ | ||||
| 					if((**j).town->primaryRes == 127) //we'll give wood and ore | ||||
| 					{ | ||||
| 						r.res[0] += 1; | ||||
| 						r.res[2] += 1; | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						r.res[(**j).town->primaryRes] += 1; | ||||
| 					} | ||||
| 				} | ||||
| 				r.res[6] += (**j).dailyIncome(); | ||||
| 				n.res.push_back(r); | ||||
| 			}	 | ||||
| 			n.cres.push_back(sac); | ||||
| 		} | ||||
| 		if(gs->day  &&  (*j)->tempOwner < PLAYER_LIMIT)//not the first day and town not neutral | ||||
| 		{ | ||||
| 			SetResources r; | ||||
| 			r.player = (**j).tempOwner; | ||||
| 			if(vstd::contains((**j).builtBuildings,15)) //there is resource silo | ||||
| 			{ | ||||
| 				if((**j).town->primaryRes == 127) //we'll give wood and ore | ||||
| 				{ | ||||
| 					r.res[0] += 1; | ||||
| 					r.res[2] += 1; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					r.res[(**j).town->primaryRes] += 1; | ||||
| 				} | ||||
| 			} | ||||
| 			r.res[6] += (**j).dailyIncome(); | ||||
| 			n.res.push_back(r); | ||||
| 		}	 | ||||
| 	} | ||||
|  | ||||
| 	sendAndApply(&n); | ||||
| 	tlog5 << "Info about turn " << n.day << "has been sent!" << std::endl; | ||||
| @@ -1862,7 +1865,7 @@ void CGameHandler::save( const std::string &fname ) | ||||
| 		CSaveFile save(GVCMIDirs.UserPath + "/Games/" + fname + ".vsgm1"); | ||||
| 		save << *this; | ||||
| 	} | ||||
| 	tlog0 << "Game has been succesfully saved!\n"; | ||||
| 	tlog0 << "Game has been successfully saved!\n"; | ||||
| } | ||||
|  | ||||
| void CGameHandler::close() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user