1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-25 21:38:59 +02:00

* restored 0.74 savegames compatibility (for easier reproducing reported issues)

* Fixed #184 and #189
* minor fixes
This commit is contained in:
Michał W. Urbańczyk 2009-11-13 19:04:36 +00:00
parent f99c4d3c66
commit a6f61e33bd
12 changed files with 81 additions and 55 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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