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

View File

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

View File

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

View File

@ -260,8 +260,8 @@ CGPreGame::~CGPreGame()
void CGPreGame::openSel( CMenuScreen::EState type, bool multi )
{
playerNames.clear();
playerNames.push_back(CGI->generaltexth->allTexts[434]); //we have only one player and his name is "Player"
resetPlayerNames();
GH.pushInt(new CSelectionScreen(type, multi));
}
@ -306,6 +306,12 @@ void CGPreGame::update()
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)
:multiPlayer(MultiPlayer)
{
@ -2206,11 +2212,16 @@ CBonusSelection::CBonusSelection( CCampaignState * _ourCampaign )
: ourCampaign(_ourCampaign), highlightedRegion(NULL), ourHeader(NULL), bonuses(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",
"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"};
if(ourCampaign->mapsConquered.size())
{
CGP->resetPlayerNames();
}
loadPositionsOfGraphics();
background = BitmapHandler::loadBitmap(bgNames[ourCampaign->camp->header.mapVersion]);
@ -2370,12 +2381,15 @@ void CBonusSelection::selectMap( int whichOne )
delete ourHeader;
ourHeader = new CMapHeader();
ourHeader->initFromMemory((const unsigned char*)ourCampaign->camp->mapPieces.find(whichOne)->second.c_str(), i);
CMapInfo *mapInfo = const_cast<CMapInfo *>(curMap);
mapInfo->mapHeader = ourHeader;
mapInfo->countPlayers();
mapInfo->mapHeader = NULL;
// CMapInfo *mapInfo = const_cast<CMapInfo *>(curMap);
// mapInfo->mapHeader = ourHeader;
// mapInfo->countPlayers();
// 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.whichMapInCampaign = whichOne;
sInfo.difficulty = ourCampaign->camp->scenarios[whichOne].difficulty;

View File

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

View File

@ -27,6 +27,7 @@
#include <boost/thread.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <sstream>
#include "CPreGame.h"
#undef 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)
{
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;
if(GH.topInt())
GH.topInt()->deactivate();
@ -246,24 +241,10 @@ void CClient::endGame()
}
tlog0 << "Deleted playerInts." << std::endl;
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";
if(closeConnection)
stopConnection();
serv->close();
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;
tlog0 << "Client stopped." << std::endl;
}
void CClient::loadGame( const std::string & fname )
@ -541,5 +522,45 @@ void CClient::updatePaths()
if (h)//if we have selected hero...
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( COSer<CSaveFile> &h, const int version );

View File

@ -55,11 +55,13 @@ public:
void init();
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 loadGame(const std::string & fname);
void run();
void stop();
void finishCampaign( CCampaignState * camp );
void proposeNextMission( CCampaignState * camp );
bool terminate; // tell to terminate
boost::thread *connectionHandler; //thread running run() method

View File

@ -22,6 +22,7 @@
#include "CConfigHandler.h"
#include "SDL_Extensions.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
#define INTERFACE_CALL_IF_PRESENT(player,function,...) \
@ -161,8 +162,8 @@ void PlayerEndsGame::applyCl( CClient *cl )
i->second->gameOver(player, victory);
if(!CPlayerInterface::howManyPeople)
cl->terminate = true;
// if(!CPlayerInterface::howManyPeople)
// cl->terminate = true;
}
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 )
{
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++)
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;
void initNewCampaign(const StartInfo &si);
void mapConquered();
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;
case StartInfo::CAMPAIGN:
{
assert(vstd::contains(campaign->camp->mapPieces, si->whichMapInCampaign));
campaign = new CCampaignState();
campaign->initNewCampaign(*si);
assert(vstd::contains(campaign->camp->mapPieces, si->whichMapInCampaign));
std::string &mapContent = campaign->camp->mapPieces[si->whichMapInCampaign];
map = new Mapa();
@ -2250,7 +2250,6 @@ int CGameState::canBuildStructure( const CGTownInstance *t, int ID )
void CGameState::apply(CPack *pack)
{
ui16 typ = typeList.getTypeID(pack);
assert(typ >= 0);
applierGs->apps[typ]->applyOnGS(this,pack);
}

View File

@ -21,7 +21,7 @@ class CClient;
class CGameState;
class CGameHandler;
class CConnection;
class CCampaignState;
class CArtifact;
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
{
RemoveObject(){type = 500;};

View File

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

View File

@ -4668,7 +4668,18 @@ void CGameHandler::checkLossVictory( ui8 player )
}
if(vic)
{
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