1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Changes towards campaign support.

This commit is contained in:
mateuszb 2010-08-20 13:34:39 +00:00
parent 6ebfe25f86
commit d681afe1c1
14 changed files with 170 additions and 67 deletions

View File

@ -553,7 +553,7 @@ static void listenForEvents()
(ev->type == SDL_KEYDOWN && ev->key.keysym.sym==SDLK_F4 && (ev->key.keysym.mod & KMOD_ALT))) (ev->type == SDL_KEYDOWN && ev->key.keysym.sym==SDLK_F4 && (ev->key.keysym.mod & KMOD_ALT)))
{ {
if (client) if (client)
client->stop(); client->endGame();
if (mainGUIThread) if (mainGUIThread)
{ {
GH.terminate = true; GH.terminate = true;
@ -577,27 +577,34 @@ static void listenForEvents()
delete ev; delete ev;
continue; continue;
} }
else if(ev->type == SDL_USEREVENT && ev->user.code == 1) else if(ev->type == SDL_USEREVENT)
{ {
tlog0 << "Changing resolution has been requested\n"; switch(ev->user.code)
setScreenRes(conf.cc.resx,conf.cc.resy,conf.cc.bpp,conf.cc.fullscreen); {
delete ev; case 1:
continue; tlog0 << "Changing resolution has been requested\n";
} setScreenRes(conf.cc.resx,conf.cc.resy,conf.cc.bpp,conf.cc.fullscreen);
else if (ev->type == SDL_USEREVENT && ev->user.code == 2) //something want to quit to main menu break;
{
client->stop(); case 2:
delete client; client->endGame();
client = NULL; delete client;
client = NULL;
delete CGI->dobjinfo;
CGI->dobjinfo = new CDefObjInfoHandler;
CGI->dobjinfo->load();
GH.curInt = CGP;
GH.defActionsDef = 63;
break;
case 3:
client->endGame(false);
break;
}
delete ev; delete ev;
delete CGI->dobjinfo;
CGI->dobjinfo = new CDefObjInfoHandler;
CGI->dobjinfo->load();
GH.curInt = CGP;
GH.defActionsDef = 63;
continue; continue;
} }

View File

@ -1813,8 +1813,8 @@ void CPlayerInterface::gameOver(ui8 player, bool victory )
{ {
if(cb->getStartInfo()->mode != StartInfo::CAMPAIGN) if(cb->getStartInfo()->mode != StartInfo::CAMPAIGN)
requestReturningToMainMenu(); requestReturningToMainMenu();
else
//TODO next campaign scenario requestStoppingClient();
} }
} }
@ -2077,10 +2077,20 @@ void CPlayerInterface::showShipyardDialogOrProblemPopup(const IShipyard *obj)
} }
void CPlayerInterface::requestReturningToMainMenu() void CPlayerInterface::requestReturningToMainMenu()
{
sendCustomEvent(2);
}
void CPlayerInterface::requestStoppingClient()
{
sendCustomEvent(3);
}
void CPlayerInterface::sendCustomEvent( int code )
{ {
SDL_Event event; SDL_Event event;
event.type = SDL_USEREVENT; event.type = SDL_USEREVENT;
event.user.code = 2; event.user.code = code;
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }

View File

@ -245,6 +245,8 @@ public:
void tryDiggging(const CGHeroInstance *h); void tryDiggging(const CGHeroInstance *h);
void showShipyardDialogOrProblemPopup(const IShipyard *obj); //obj may be town or shipyard; void showShipyardDialogOrProblemPopup(const IShipyard *obj); //obj may be town or shipyard;
void requestReturningToMainMenu(); void requestReturningToMainMenu();
void requestStoppingClient();
void sendCustomEvent(int code);
CPlayerInterface(int Player);//c-tor CPlayerInterface(int Player);//c-tor
~CPlayerInterface();//d-tor ~CPlayerInterface();//d-tor

View File

@ -260,8 +260,8 @@ CGPreGame::~CGPreGame()
void CGPreGame::openSel( CMenuScreen::EState type, bool multi ) void CGPreGame::openSel( CMenuScreen::EState type, bool multi )
{ {
playerNames.clear(); resetPlayerNames();
playerNames.push_back(CGI->generaltexth->allTexts[434]); //we have only one player and his name is "Player"
GH.pushInt(new CSelectionScreen(type, multi)); GH.pushInt(new CSelectionScreen(type, multi));
} }
@ -306,6 +306,12 @@ void CGPreGame::update()
GH.handleEvents(); GH.handleEvents();
} }
void CGPreGame::resetPlayerNames()
{
playerNames.clear();
playerNames.push_back(CGI->generaltexth->allTexts[434]); //we have only one player and his name is "Player"
}
CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, bool MultiPlayer) CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, bool MultiPlayer)
:multiPlayer(MultiPlayer) :multiPlayer(MultiPlayer)
{ {
@ -2206,11 +2212,16 @@ CBonusSelection::CBonusSelection( CCampaignState * _ourCampaign )
: ourCampaign(_ourCampaign), highlightedRegion(NULL), ourHeader(NULL), bonuses(NULL), : ourCampaign(_ourCampaign), highlightedRegion(NULL), ourHeader(NULL), bonuses(NULL),
diffLb(NULL), diffRb(NULL) diffLb(NULL), diffRb(NULL)
{ {
OBJ_CONSTRUCTION; OBJ_CONSTRUCTION_CAPTURING_ALL;
static const std::string bgNames [] = {"E1_BG.BMP", "G2_BG.BMP", "E2_BG.BMP", "G1_BG.BMP", "G3_BG.BMP", "N1_BG.BMP", static const std::string bgNames [] = {"E1_BG.BMP", "G2_BG.BMP", "E2_BG.BMP", "G1_BG.BMP", "G3_BG.BMP", "N1_BG.BMP",
"S1_BG.BMP", "BR_BG.BMP", "IS_BG.BMP", "KR_BG.BMP", "NI_BG.BMP", "TA_BG.BMP", "AR_BG.BMP", "HS_BG.BMP", "S1_BG.BMP", "BR_BG.BMP", "IS_BG.BMP", "KR_BG.BMP", "NI_BG.BMP", "TA_BG.BMP", "AR_BG.BMP", "HS_BG.BMP",
"BB_BG.BMP", "NB_BG.BMP", "EL_BG.BMP", "RN_BG.BMP", "UA_BG.BMP", "SP_BG.BMP"}; "BB_BG.BMP", "NB_BG.BMP", "EL_BG.BMP", "RN_BG.BMP", "UA_BG.BMP", "SP_BG.BMP"};
if(ourCampaign->mapsConquered.size())
{
CGP->resetPlayerNames();
}
loadPositionsOfGraphics(); loadPositionsOfGraphics();
background = BitmapHandler::loadBitmap(bgNames[ourCampaign->camp->header.mapVersion]); background = BitmapHandler::loadBitmap(bgNames[ourCampaign->camp->header.mapVersion]);
@ -2370,12 +2381,15 @@ void CBonusSelection::selectMap( int whichOne )
delete ourHeader; delete ourHeader;
ourHeader = new CMapHeader(); ourHeader = new CMapHeader();
ourHeader->initFromMemory((const unsigned char*)ourCampaign->camp->mapPieces.find(whichOne)->second.c_str(), i); ourHeader->initFromMemory((const unsigned char*)ourCampaign->camp->mapPieces.find(whichOne)->second.c_str(), i);
CMapInfo *mapInfo = const_cast<CMapInfo *>(curMap); // CMapInfo *mapInfo = const_cast<CMapInfo *>(curMap);
mapInfo->mapHeader = ourHeader; // mapInfo->mapHeader = ourHeader;
mapInfo->countPlayers(); // mapInfo->countPlayers();
mapInfo->mapHeader = NULL; // mapInfo->mapHeader = NULL;
CMapInfo dummyInfo(false);
dummyInfo.filename = "lala";
CSelectionScreen::updateStartInfo(curMap, sInfo, ourHeader); CSelectionScreen::updateStartInfo(curMap ? curMap : &dummyInfo, sInfo, ourHeader);
sInfo.turnTime = 0; sInfo.turnTime = 0;
sInfo.whichMapInCampaign = whichOne; sInfo.whichMapInCampaign = whichOne;
sInfo.difficulty = ourCampaign->camp->scenarios[whichOne].difficulty; sInfo.difficulty = ourCampaign->camp->scenarios[whichOne].difficulty;

View File

@ -360,6 +360,8 @@ public:
void update(); void update();
void run(); void run();
void openSel(CMenuScreen::EState type, bool multi = false); void openSel(CMenuScreen::EState type, bool multi = false);
void resetPlayerNames();
void loadGraphics(); void loadGraphics();
void disposeGraphics(); void disposeGraphics();
}; };

View File

@ -27,6 +27,7 @@
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include <boost/thread/shared_mutex.hpp> #include <boost/thread/shared_mutex.hpp>
#include <sstream> #include <sstream>
#include "CPreGame.h"
#undef DLL_EXPORT #undef DLL_EXPORT
#define DLL_EXPORT #define DLL_EXPORT
@ -168,18 +169,6 @@ void CClient::run()
} }
} }
void CClient::stop()
{
// Game is ending
// Tell the network thread to reach a stable state
terminate = true;
GH.curInt = NULL;
LOCPLINT->terminate_cond.setn(true);
LOCPLINT->pim->lock();
endGame();
tlog0 << "Client stopped." << std::endl;
}
void CClient::save(const std::string & fname) void CClient::save(const std::string & fname)
{ {
if(gs->curB) if(gs->curB)
@ -216,8 +205,14 @@ void initVillagesCapitols(Mapa * map)
} }
} }
void CClient::endGame() void CClient::endGame( bool closeConnection /*= true*/ )
{ {
// Game is ending
// Tell the network thread to reach a stable state
GH.curInt = NULL;
LOCPLINT->terminate_cond.setn(true);
LOCPLINT->pim->lock();
tlog0 << "\n\nEnding current game!" << std::endl; tlog0 << "\n\nEnding current game!" << std::endl;
if(GH.topInt()) if(GH.topInt())
GH.topInt()->deactivate(); GH.topInt()->deactivate();
@ -246,24 +241,10 @@ void CClient::endGame()
} }
tlog0 << "Deleted playerInts." << std::endl; tlog0 << "Deleted playerInts." << std::endl;
if (serv) if(closeConnection)
{ stopConnection();
tlog0 << "Connection has been requested to be closed.\n";
boost::unique_lock<boost::mutex>(*serv->wmx);
*serv << &CloseServer();
tlog0 << "Sent closing signal to the server\n";
serv->close(); tlog0 << "Client stopped." << std::endl;
delete serv;
serv = NULL;
tlog3 << "Our socket has been closed." << std::endl;
}
connectionHandler->join();
tlog0 << "Connection handler thread joined" << std::endl;
delete connectionHandler;
connectionHandler = NULL;
} }
void CClient::loadGame( const std::string & fname ) void CClient::loadGame( const std::string & fname )
@ -541,5 +522,45 @@ void CClient::updatePaths()
if (h)//if we have selected hero... if (h)//if we have selected hero...
gs->calculatePaths(h, *pathInfo); gs->calculatePaths(h, *pathInfo);
} }
void CClient::finishCampaign( CCampaignState * camp )
{
}
void CClient::proposeNextMission( CCampaignState * camp )
{
GH.pushInt(new CBonusSelection(camp));
GH.curInt = CGP;
}
void CClient::stopConnection()
{
terminate = true;
if (serv)
{
tlog0 << "Connection has been requested to be closed.\n";
boost::unique_lock<boost::mutex>(*serv->wmx);
*serv << &CloseServer();
tlog0 << "Sent closing signal to the server\n";
serv->close();
delete serv;
serv = NULL;
tlog3 << "Our socket has been closed." << std::endl;
}
if(connectionHandler)
{
if(connectionHandler->get_id() != boost::this_thread::get_id())
connectionHandler->join();
tlog0 << "Connection handler thread joined" << std::endl;
delete connectionHandler;
connectionHandler = NULL;
}
}
template void CClient::serialize( CISer<CLoadFile> &h, const int version ); template void CClient::serialize( CISer<CLoadFile> &h, const int version );
template void CClient::serialize( COSer<CSaveFile> &h, const int version ); template void CClient::serialize( COSer<CSaveFile> &h, const int version );

View File

@ -55,11 +55,13 @@ public:
void init(); void init();
void newGame(CConnection *con, StartInfo *si); //con - connection to server void newGame(CConnection *con, StartInfo *si); //con - connection to server
void endGame(); void endGame(bool closeConnection = true);
void stopConnection();
void save(const std::string & fname); void save(const std::string & fname);
void loadGame(const std::string & fname); void loadGame(const std::string & fname);
void run(); void run();
void stop(); void finishCampaign( CCampaignState * camp );
void proposeNextMission( CCampaignState * camp );
bool terminate; // tell to terminate bool terminate; // tell to terminate
boost::thread *connectionHandler; //thread running run() method boost::thread *connectionHandler; //thread running run() method

View File

@ -22,6 +22,7 @@
#include "CConfigHandler.h" #include "CConfigHandler.h"
#include "SDL_Extensions.h" #include "SDL_Extensions.h"
#include "CBattleInterface.h" #include "CBattleInterface.h"
#include "../hch/CCampaignHandler.h"
//macro to avoid code duplication - calls given method with given arguments if interface for specific player is present //macro to avoid code duplication - calls given method with given arguments if interface for specific player is present
#define INTERFACE_CALL_IF_PRESENT(player,function,...) \ #define INTERFACE_CALL_IF_PRESENT(player,function,...) \
@ -161,8 +162,8 @@ void PlayerEndsGame::applyCl( CClient *cl )
i->second->gameOver(player, victory); i->second->gameOver(player, victory);
if(!CPlayerInterface::howManyPeople) // if(!CPlayerInterface::howManyPeople)
cl->terminate = true; // cl->terminate = true;
} }
void RemoveBonus::applyCl( CClient *cl ) void RemoveBonus::applyCl( CClient *cl )
@ -184,6 +185,15 @@ void RemoveBonus::applyCl( CClient *cl )
} }
} }
void UpdateCampaignState::applyCl( CClient *cl )
{
cl->stopConnection();
if(camp->mapsRemaining.size())
cl->proposeNextMission(camp);
else
cl->finishCampaign(camp);
}
void RemoveObject::applyFirstCl( CClient *cl ) void RemoveObject::applyFirstCl( CClient *cl )
{ {
const CGObjectInstance *o = cl->getObj(id); const CGObjectInstance *o = cl->getObj(id);

View File

@ -481,3 +481,10 @@ void CCampaignState::initNewCampaign( const StartInfo &si )
for (ui8 i = 0; i < camp->mapPieces.size(); i++) for (ui8 i = 0; i < camp->mapPieces.size(); i++)
mapsRemaining.push_back(i); mapsRemaining.push_back(i);
} }
void CCampaignState::mapConquered()
{
mapsConquered.push_back(currentMap);
mapsRemaining -= currentMap;
camp->scenarios[currentMap].conquered = true;
}

View File

@ -133,6 +133,7 @@ public:
ui8 currentMap; ui8 currentMap;
void initNewCampaign(const StartInfo &si); void initNewCampaign(const StartInfo &si);
void mapConquered();
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {

View File

@ -1275,9 +1275,9 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
break; break;
case StartInfo::CAMPAIGN: case StartInfo::CAMPAIGN:
{ {
assert(vstd::contains(campaign->camp->mapPieces, si->whichMapInCampaign));
campaign = new CCampaignState(); campaign = new CCampaignState();
campaign->initNewCampaign(*si); campaign->initNewCampaign(*si);
assert(vstd::contains(campaign->camp->mapPieces, si->whichMapInCampaign));
std::string &mapContent = campaign->camp->mapPieces[si->whichMapInCampaign]; std::string &mapContent = campaign->camp->mapPieces[si->whichMapInCampaign];
map = new Mapa(); map = new Mapa();
@ -2250,7 +2250,6 @@ int CGameState::canBuildStructure( const CGTownInstance *t, int ID )
void CGameState::apply(CPack *pack) void CGameState::apply(CPack *pack)
{ {
ui16 typ = typeList.getTypeID(pack); ui16 typ = typeList.getTypeID(pack);
assert(typ >= 0);
applierGs->apps[typ]->applyOnGS(this,pack); applierGs->apps[typ]->applyOnGS(this,pack);
} }

View File

@ -21,7 +21,7 @@ class CClient;
class CGameState; class CGameState;
class CGameHandler; class CGameHandler;
class CConnection; class CConnection;
class CCampaignState;
class CArtifact; class CArtifact;
struct CPack struct CPack
@ -462,6 +462,22 @@ struct RemoveBonus : public CPackForClient //118
} }
}; };
struct UpdateCampaignState : public CPackForClient //119
{
UpdateCampaignState()
{
type = 119;
}
CCampaignState *camp;
void applyCl(CClient *cl);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & camp;
}
};
struct RemoveObject : public CPackForClient //500 struct RemoveObject : public CPackForClient //500
{ {
RemoveObject(){type = 500;}; RemoveObject(){type = 500;};

View File

@ -92,6 +92,7 @@ void registerTypes2(Serializer &s)
s.template registerType<ChangeObjPos>(); s.template registerType<ChangeObjPos>();
s.template registerType<PlayerEndsGame>(); s.template registerType<PlayerEndsGame>();
s.template registerType<RemoveBonus>(); s.template registerType<RemoveBonus>();
s.template registerType<UpdateCampaignState>();
s.template registerType<RemoveObject>(); s.template registerType<RemoveObject>();
s.template registerType<TryMoveHero>(); s.template registerType<TryMoveHero>();
s.template registerType<SetGarrisons>(); s.template registerType<SetGarrisons>();

View File

@ -4668,7 +4668,18 @@ void CGameHandler::checkLossVictory( ui8 player )
} }
if(vic) if(vic)
{
end2 = true; end2 = true;
if(gs->campaign)
{
gs->campaign->mapConquered();
UpdateCampaignState ucs;
ucs.camp = gs->campaign;
sendAndApply(&ucs);
}
}
} }
void CGameHandler::getLossVicMessage( ui8 player, ui8 standard, bool victory, InfoWindow &out ) const void CGameHandler::getLossVicMessage( ui8 player, ui8 standard, bool victory, InfoWindow &out ) const