1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

Merge pull request #46 from linuxrocks123/pleasepull

Okay, looks good. I hope this one won't cause any new issues with save/load.
This commit is contained in:
DjWarmonger
2014-10-26 08:47:18 +01:00
8 changed files with 166 additions and 44 deletions

View File

@@ -224,7 +224,13 @@ int main(int argc, char** argv)
("oneGoodAI", "puts one default AI and the rest will be EmptyAI")
("autoSkip", "automatically skip turns in GUI")
("disable-video", "disable video player")
("nointro,i", "skips intro movies");
("nointro,i", "skips intro movies")
("loadserver","specifies we are the multiplayer server for loaded games")
("loadnumplayers",po::value<int>(),"specifies the number of players connecting to a multiplayer game")
("loadhumanplayerindices",po::value<std::vector<int>>(),"Indexes of human players (0=Red, etc.)")
("loadplayer", po::value<int>(),"specifies which player we are in multiplayer loaded games (0=Red, etc.)")
("loadserverip",po::value<std::string>(),"IP for loaded game server")
("loadserverport",po::value<std::string>(),"port for loaded game server");
if(argc > 1)
{
@@ -1222,7 +1228,10 @@ void startGame(StartInfo * options, CConnection *serv/* = nullptr*/)
case StartInfo::LOAD_GAME:
std::string fname = options->mapname;
boost::algorithm::erase_last(fname,".vlgm1");
client->loadGame(fname);
if(!vm.count("loadplayer"))
client->loadGame(fname);
else
client->loadGame(fname,vm.count("loadserver"),vm.count("loadhumanplayerindices") ? vm["loadhumanplayerindices"].as<std::vector<int>>() : std::vector<int>(),vm.count("loadnumplayers") ? vm["loadnumplayers"].as<int>() : 1,vm["loadplayer"].as<int>(),vm.count("loadserverip") ? vm["loadserverip"].as<std::string>() : "", vm.count("loadserverport") ? vm["loadserverport"].as<std::string>() : "3030");
break;
}

View File

@@ -1257,14 +1257,15 @@ template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, c
{
h & pathsMap;
for(auto &p : pathsMap)
{
CGPath path;
cb->getPathsInfo(p.first)->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();
}
if(cb)
for(auto &p : pathsMap)
{
CGPath path;
cb->getPathsInfo(p.first)->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;

View File

@@ -236,14 +236,21 @@ void CClient::endGame( bool closeConnection /*= true*/ )
logNetwork->infoStream() << "Client stopped.";
}
void CClient::loadGame( const std::string & fname )
#if 1
void CClient::loadGame(const std::string & fname, const bool server, const std::vector<int>& humanplayerindices, const int loadNumPlayers, int player_, const std::string & ipaddr, const std::string & port)
{
PlayerColor player(player_); //intentional shadowing
logNetwork->infoStream() <<"Loading procedure started!";
CServerHandler sh;
sh.startServer();
if(server)
sh.startServer();
else
serv = sh.justConnectToServer(ipaddr,port=="" ? "3030" : port);
CStopWatch tmh;
unique_ptr<CLoadFile> loader;
try
{
std::string clientSaveName = *CResourceHandler::get("local")->getResourceName(ResourceID(fname, EResType::CLIENT_SAVEGAME));
@@ -264,7 +271,6 @@ void CClient::loadGame( const std::string & fname )
if(controlServerSaveName.empty())
throw std::runtime_error("Cannot open server part of " + fname);
unique_ptr<CLoadFile> loader;
{
CLoadIntegrityValidator checkingLoader(clientSaveName, controlServerSaveName, minSupportedVersion);
loadCommonState(checkingLoader);
@@ -276,9 +282,6 @@ void CClient::loadGame( const std::string & fname )
pathInfo = make_unique<CPathsInfo>(getMapSize());
CGI->mh->init();
logNetwork->infoStream() <<"Initing maphandler: "<<tmh.getDiff();
*loader >> *this;
logNetwork->infoStream() << "Loaded client part of save " << tmh.getDiff();
}
catch(std::exception &e)
{
@@ -286,27 +289,60 @@ void CClient::loadGame( const std::string & fname )
throw; //obviously we cannot continue here
}
serv = sh.connectToServer();
serv->addStdVecItems(gs);
/*
if(!server)
player = PlayerColor(player_);
*/
tmh.update();
ui8 pom8;
*serv << ui8(3) << ui8(1); //load game; one client
*serv << fname;
*serv >> pom8;
if(pom8)
throw std::runtime_error("Server cannot open the savegame!");
else
logNetwork->infoStream() << "Server opened savegame properly.";
std::set<PlayerColor> clientPlayers;
if(server)
serv = sh.connectToServer();
//*loader >> *this;
if(server)
{
tmh.update();
ui8 pom8;
*serv << ui8(3) << ui8(loadNumPlayers); //load game; one client if single-player
*serv << fname;
*serv >> pom8;
if(pom8)
throw std::runtime_error("Server cannot open the savegame!");
else
logNetwork->infoStream() << "Server opened savegame properly.";
}
if(server)
{
for(auto & elem : gs->scenarioOps->playerInfos)
if(!std::count(humanplayerindices.begin(),humanplayerindices.end(),elem.first.getNum()) || elem.first==player)
{
clientPlayers.insert(elem.first);
}
clientPlayers.insert(PlayerColor::NEUTRAL);
}
else
{
clientPlayers.insert(player);
}
std::cout << "CLIENTPLAYERS:\n";
for(auto x : clientPlayers)
std::cout << x << std::endl;
std::cout << "ENDCLIENTPLAYERS\n";
serialize(*loader,0,clientPlayers);
*serv << ui32(clientPlayers.size());
for(auto & elem : clientPlayers)
*serv << ui8(elem.getNum());
serv->addStdVecItems(gs); /*why is this here?*/
//*loader >> *this;
logNetwork->infoStream() << "Loaded client part of save " << tmh.getDiff();
*serv << ui32(gs->scenarioOps->playerInfos.size()+1); //number of players + neutral
for(auto & elem : gs->scenarioOps->playerInfos)
{
*serv << ui8(elem.first.getNum()); //players
}
*serv << ui8(PlayerColor::NEUTRAL.getNum());
logNetwork->infoStream() <<"Sent info to server: "<<tmh.getDiff();
//*serv << clientPlayers;
serv->enableStackSendingByID();
serv->disableSmartPointerSerialization();
@@ -320,6 +356,7 @@ void CClient::loadGame( const std::string & fname )
// logGlobal->traceStream() << boost::format("\tindex=%5d --- nullptr") % i;
// }
}
#endif
void CClient::newGame( CConnection *con, StartInfo *si )
{
@@ -522,6 +559,75 @@ void CClient::serialize( Handler &h, const int version )
}
}
template <typename Handler>
void CClient::serialize( Handler &h, const int version, const std::set<PlayerColor>& playerIDs)
{
h & hotSeat;
if(h.saving)
{
ui8 players = playerint.size();
h & players;
for(auto i = playerint.begin(); i != playerint.end(); i++)
{
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
{
ui8 players = 0; //fix for uninitialized warning
h & players;
for(int i=0; i < players; i++)
{
std::string dllname;
PlayerColor pid;
bool isHuman = false;
h & pid & dllname & isHuman;
LOG_TRACE_PARAMS(logGlobal, "Loading player %s interface", pid);
shared_ptr<CGameInterface> nInt;
if(dllname.length())
{
if(pid == PlayerColor::NEUTRAL)
{
if(playerIDs.count(pid))
installNewBattleInterface(CDynLibHandler::getNewBattleAI(dllname), pid);
//TODO? consider serialization
continue;
}
else
{
assert(!isHuman);
nInt = CDynLibHandler::getNewAI(dllname);
}
}
else
{
assert(isHuman);
nInt = make_shared<CPlayerInterface>(pid);
}
nInt->dllName = dllname;
nInt->human = isHuman;
nInt->playerID = pid;
if(playerIDs.count(pid))
installNewPlayerInterface(nInt, pid);
nInt->loadGame(dynamic_cast<CISer<CLoadFile>&>(h), version); //another evil cast, check above
}
if(playerIDs.count(PlayerColor::NEUTRAL))
loadNeutralBattleAI();
}
}
void CClient::handlePack( CPack * pack )
{
CBaseForCLApply *apply = applier->apps[typeList.getTypeID(pack)]; //find the applier
@@ -833,6 +939,7 @@ CConnection * CServerHandler::connectToServer()
#endif
th.update(); //put breakpoint here to attach to server before it does something stupid
CConnection *ret = justConnectToServer(settings["server"]["server"].String(), port);
if(verbose)

View File

@@ -151,7 +151,7 @@ public:
void endGame(bool closeConnection = true);
void stopConnection();
void save(const std::string & fname);
void loadGame(const std::string & fname);
void loadGame(const std::string & fname, const bool server = true, const std::vector<int>& humanplayerindices = std::vector<int>(), const int loadnumplayers = 1, int player_ = -1, const std::string & ipaddr = "", const std::string & port = "");
void run();
void campaignMapFinished( shared_ptr<CCampaignState> camp );
void finishCampaign( shared_ptr<CCampaignState> camp );
@@ -237,5 +237,6 @@ public:
//////////////////////////////////////////////////////////////////////////
template <typename Handler> void serialize(Handler &h, const int version);
template <typename Handler> void serialize(Handler &h, const int version, const std::set<PlayerColor>& playerIDs);
void battleFinished();
};

View File

@@ -1656,7 +1656,7 @@
"bonuses" : [
{
"type" : "CREATURE_GROWTH",
"subtype" : 2,
"subtype" : 1,
"val" : 5,
"propagator": "VISITED_TOWN_AND_VISITOR"
}
@@ -1669,7 +1669,7 @@
"bonuses" : [
{
"type" : "CREATURE_GROWTH",
"subtype" : 3,
"subtype" : 2,
"val" : 4,
"propagator": "VISITED_TOWN_AND_VISITOR"
}
@@ -1682,7 +1682,7 @@
"bonuses" : [
{
"type" : "CREATURE_GROWTH",
"subtype" : 4,
"subtype" : 3,
"val" : 3,
"propagator": "VISITED_TOWN_AND_VISITOR"
}
@@ -1695,7 +1695,7 @@
"bonuses" : [
{
"type" : "CREATURE_GROWTH",
"subtype" : 5,
"subtype" : 4,
"val" : 2,
"propagator": "VISITED_TOWN_AND_VISITOR"
}
@@ -1708,7 +1708,7 @@
"bonuses" : [
{
"type" : "CREATURE_GROWTH",
"subtype" : 6,
"subtype" : 5,
"val" : 1,
"propagator": "VISITED_TOWN_AND_VISITOR"
}

View File

@@ -387,11 +387,12 @@ CStackInstance * CCreatureSet::detachStack(SlotID slot)
CStackInstance *ret = stacks[slot];
//if(CArmedInstance *armedObj = castToArmyObj())
if(ret)
{
ret->setArmyObj(nullptr); //detaches from current armyobj
assert(!ret->armyObj); //we failed detaching?
}
assert(!ret->armyObj); //we failed detaching?
stacks.erase(slot);
armyChanged();
return ret;

View File

@@ -101,7 +101,11 @@ ui32 CGHeroInstance::getTileCost(const TerrainTile &dest, const TerrainTile &fro
}
}
if (!nativeArmy)
{
ret = VLC->heroh->terrCosts[from.terType];
ret-=getSecSkillLevel(SecondarySkill::PATHFINDING)*25;
ret = ret < 100 ? 100 : ret;
}
}
return ret;
}

View File

@@ -463,7 +463,7 @@ void CVCMIServer::loadGame()
boost::system::error_code error;
ui8 clients;
c >> clients >> fname; //how many clients should be connected - TODO: support more than one
c >> clients >> fname; //how many clients should be connected
// {
// char sig[8];
@@ -508,7 +508,6 @@ void CVCMIServer::loadGame()
continue;
}
cc = new CConnection(s,NAME);
cc->addStdVecItems(gh.gs);
}
gh.conns.insert(cc);
}