1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

* next part of campaign support

* a few fixes for .h3c reading
This commit is contained in:
mateuszb 2010-02-15 12:12:21 +00:00
parent 49b99f470f
commit 448c2e7225
4 changed files with 207 additions and 35 deletions

View File

@ -268,6 +268,13 @@ CSelectionScreen::CSelectionScreen( CMenuScreen::EState Type, const std::vector<
{ {
center(pos); center(pos);
} }
else if(Type == CMenuScreen::campaignList)
{
bg = new CPicture(BitmapHandler::loadBitmap("CamCust.bmp"), 0, 0, true);
pos.x = 3;
pos.y = 6;
}
else else
{ {
pos.x = 3; pos.x = 3;
@ -326,13 +333,24 @@ CSelectionScreen::CSelectionScreen( CMenuScreen::EState Type, const std::vector<
break; break;
case CMenuScreen::campaignList: case CMenuScreen::campaignList:
sel->recActions = 255; sel->recActions = 255;
start = new AdventureMapButton(std::pair<std::string, std::string>(), 0 /*cb*/, 411, 529, "SCNRBEG.DEF", SDLK_b); start = new AdventureMapButton(std::pair<std::string, std::string>(), bind(&CSelectionScreen::startCampaign, this), 411, 529, "SCNRLOD.DEF", SDLK_b);
break; break;
} }
start->assignedKeys.insert(SDLK_RETURN); start->assignedKeys.insert(SDLK_RETURN);
back = new AdventureMapButton("", CGI->generaltexth->zelp[105].second, bind(&CGuiHandler::popIntTotally, &GH, this), 581, 529, "SCNRBACK.DEF", SDLK_ESCAPE); std::string backName;
if(Type == CMenuScreen::campaignList)
{
backName = "SCNRBACK.DEF";
}
else
{
backName = "SCNRBACK.DEF";
}
back = new AdventureMapButton("", CGI->generaltexth->zelp[105].second, bind(&CGuiHandler::popIntTotally, &GH, this), 581, 529, backName, SDLK_ESCAPE);
} }
CSelectionScreen::~CSelectionScreen() CSelectionScreen::~CSelectionScreen()
@ -446,6 +464,12 @@ void CSelectionScreen::updateStartInfo( const CMapInfo * to )
} }
} }
void CSelectionScreen::startCampaign()
{
CCampaign * ourCampaign = CCampaignHandler::getCampaign(curMap->filename);
GH.pushInt( new CBonusSelection(ourCampaign, 0) );
}
void CSelectionScreen::startGame() void CSelectionScreen::startGame()
{ {
if(type != CMenuScreen::saveGame) if(type != CMenuScreen::saveGame)
@ -596,7 +620,7 @@ void SelectionTab::parseCampaigns( std::vector<FileInfo> & files )
} }
SelectionTab::SelectionTab(CMenuScreen::EState Type, const boost::function<void(CMapInfo *)> &OnSelect) SelectionTab::SelectionTab(CMenuScreen::EState Type, const boost::function<void(CMapInfo *)> &OnSelect)
:onSelect(OnSelect) :onSelect(OnSelect), bg(NULL)
{ {
OBJ_CONSTRUCTION; OBJ_CONSTRUCTION;
selectionPos = 0; selectionPos = 0;
@ -605,16 +629,12 @@ SelectionTab::SelectionTab(CMenuScreen::EState Type, const boost::function<void(
txt = NULL; txt = NULL;
tabType = Type; tabType = Type;
if (Type == CMenuScreen::campaignList) // if (Type != CMenuScreen::campaignList)
{ /*{*/
bg = new CPicture(BitmapHandler::loadBitmap("CamCust.bmp"), 0, 0, true);
}
else
{
bg = new CPicture(BitmapHandler::loadBitmap("SCSELBCK.bmp"), 0, 0, true); bg = new CPicture(BitmapHandler::loadBitmap("SCSELBCK.bmp"), 0, 0, true);
}
pos.w = bg->pos.w; pos.w = bg->pos.w;
pos.h = bg->pos.h; pos.h = bg->pos.h;
/*}*/
std::vector<FileInfo> toParse; std::vector<FileInfo> toParse;
switch(tabType) switch(tabType)
@ -643,6 +663,7 @@ SelectionTab::SelectionTab(CMenuScreen::EState Type, const boost::function<void(
case CMenuScreen::campaignList: case CMenuScreen::campaignList:
getFiles(toParse, DATA_DIR "/Maps", "h3c"); //get all campaigns getFiles(toParse, DATA_DIR "/Maps", "h3c"); //get all campaigns
parseCampaigns(toParse); parseCampaigns(toParse);
positions = 18;
break; break;
default: default:
@ -786,13 +807,13 @@ void SelectionTab::printMaps(SDL_Surface *to)
{ {
CMapInfo* curMap = curItems[elemIdx]; CMapInfo* curMap = curItems[elemIdx];
if(tabType != CMenuScreen::campaignList)
{
if (elemIdx == selectionPos) if (elemIdx == selectionPos)
itemColor=tytulowy; itemColor=tytulowy;
else else
itemColor=zwykly; itemColor=zwykly;
if(tabType != CMenuScreen::campaignList)
{
//amount of players //amount of players
std::ostringstream ostr(std::ostringstream::out); std::ostringstream ostr(std::ostringstream::out);
ostr << curMap->playerAmnt << "/" << curMap->humenPlayers; ostr << curMap->playerAmnt << "/" << curMap->humenPlayers;
@ -853,6 +874,13 @@ void SelectionTab::printMaps(SDL_Surface *to)
temp=curMap->mapHeader->lossCondition.typeOfLossCon; temp=curMap->mapHeader->lossCondition.typeOfLossCon;
blitAt(CGP->loss->ourImages[temp].bitmap, POS(339, 117), to); blitAt(CGP->loss->ourImages[temp].bitmap, POS(339, 117), to);
} }
else //if campaign
{
//number of maps in campaign
std::ostringstream ostr(std::ostringstream::out);
ostr << CGI->generaltexth->campaignRegionNames[ curMap->campaignHeader->mapVersion ].size();
CSDL_Ext::printAt(ostr.str(), POS(29, 120), FONT_SMALL, itemColor, to);
}
std::string name; std::string name;
if(tabType != CMenuScreen::campaignList) if(tabType != CMenuScreen::campaignList)
@ -867,7 +895,7 @@ void SelectionTab::printMaps(SDL_Surface *to)
} }
//print name //print name
if (tabType == CMenuScreen::newGame) { if (tabType == CMenuScreen::newGame || tabType == CMenuScreen::campaignList) {
CSDL_Ext::printAtMiddle(name, POS(213, 128), FONT_SMALL, itemColor, to); CSDL_Ext::printAtMiddle(name, POS(213, 128), FONT_SMALL, itemColor, to);
} else } else
@ -899,8 +927,11 @@ void SelectionTab::showAll( SDL_Surface * to )
} }
CSDL_Ext::printAtMiddle(title, pos.x+205, pos.y+28, FONT_MEDIUM, tytulowy, to); //Select a Scenario to Play CSDL_Ext::printAtMiddle(title, pos.x+205, pos.y+28, FONT_MEDIUM, tytulowy, to); //Select a Scenario to Play
if(tabType != CMenuScreen::campaignList)
{
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[510], pos.x+87, pos.y+62, FONT_SMALL, tytulowy, to); //Map sizes CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[510], pos.x+87, pos.y+62, FONT_SMALL, tytulowy, to); //Map sizes
} }
}
void SelectionTab::clickLeft( tribool down, bool previousState ) void SelectionTab::clickLeft( tribool down, bool previousState )
{ {
@ -990,19 +1021,25 @@ void SelectionTab::selectFName( const std::string &fname )
InfoCard::InfoCard( CMenuScreen::EState Type ) InfoCard::InfoCard( CMenuScreen::EState Type )
: difficulty(NULL), sizes(NULL), sFlags(NULL) : difficulty(NULL), sizes(NULL), sFlags(NULL), bg(NULL)
{ {
OBJ_CONSTRUCTION; OBJ_CONSTRUCTION;
pos.x += 393; pos.x += 393;
used = RCLICK; used = RCLICK;
type = Type; type = Type;
if(type == CMenuScreen::campaignList)
{
/*bg = new CPicture(BitmapHandler::loadBitmap("CamCust.bmp"), 0, 0, true);
bg->pos.x = 0;
bg->pos.y = 0;*/
}
else
{
bg = new CPicture(BitmapHandler::loadBitmap("GSELPOP1.bmp"), 0, 0, true); bg = new CPicture(BitmapHandler::loadBitmap("GSELPOP1.bmp"), 0, 0, true);
pos.w = bg->pos.w; pos.w = bg->pos.w;
pos.h = bg->pos.h; pos.h = bg->pos.h;
if(type != CMenuScreen::campaignList)
{
sizes = CDefHandler::giveDef("SCNRMPSZ.DEF"); sizes = CDefHandler::giveDef("SCNRMPSZ.DEF");
sFlags = CDefHandler::giveDef("ITGFLAGS.DEF"); sFlags = CDefHandler::giveDef("ITGFLAGS.DEF");
@ -1104,6 +1141,8 @@ void InfoCard::showAll( SDL_Surface * to )
break; break;
} }
blitAtLoc(sizes->ourImages[temp].bitmap, 318, 22, to); blitAtLoc(sizes->ourImages[temp].bitmap, 318, 22, to);
//conditions
temp = curMap->mapHeader->victoryCondition.condition; temp = curMap->mapHeader->victoryCondition.condition;
if (temp>12) temp=11; if (temp>12) temp=11;
blitAtLoc(CGP->victory->ourImages[temp].bitmap, 24, 302, to); //victory cond descr blitAtLoc(CGP->victory->ourImages[temp].bitmap, 24, 302, to); //victory cond descr
@ -1929,3 +1968,109 @@ void CHotSeatPlayers::enterSelectionScreen()
GH.popInts(2); GH.popInts(2);
GH.pushInt(new CSelectionScreen(CMenuScreen::newGame, playerNames)); GH.pushInt(new CSelectionScreen(CMenuScreen::newGame, playerNames));
} }
CBonusSelection::CBonusSelection( const CCampaign * ourCampaign, int whichMap )
{
OBJ_CONSTRUCTION;
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"};
background = BitmapHandler::loadBitmap(bgNames[ourCampaign->header.mapVersion]);
SDL_Surface * panel = BitmapHandler::loadBitmap("CAMPBRF.BMP");
blitAt(panel, 456, 6, background);
startB = new AdventureMapButton("", "", 0 /*cb*/, 475, 536, "SCNRBEG.DEF", SDLK_RETURN);
backB = new AdventureMapButton("", "", boost::bind(&CBonusSelection::goBack, this), 624, 536, "SCNRBACK.DEF", SDLK_ESCAPE);
CMapHeader ourHeader;
int _it=0;
ourHeader.initFromMemory((const unsigned char*)ourCampaign->mapPieces[whichMap].c_str(), _it);
//campaign name
if (ourCampaign->header.name.length())
printAtLoc(ourCampaign->header.name, 481, 28, FONT_BIG, tytulowy, background);
else
printAtLoc("Unnamed", 481, 28, FONT_BIG, tytulowy, background);
//map size icon
CDefHandler *sizes = CDefHandler::giveDef("SCNRMPSZ.DEF");
int temp;
switch (ourHeader.width)
{
case 36:
temp=0;
break;
case 72:
temp=1;
break;
case 108:
temp=2;
break;
case 144:
temp=3;
break;
default:
temp=4;
break;
}
blitAtLoc(sizes->ourImages[temp].bitmap, 735, 26, background);
delete sizes;
//campaign description
printAtLoc(CGI->generaltexth->allTexts[38], 481, 63, FONT_SMALL, tytulowy, background);
std::vector<std::string> *desc = CMessage::breakText(ourCampaign->header.description, 45);
for (int i=0; i<desc->size() ;i++)
printAtLoc((*desc)[i], 481, 86 + i*16, FONT_SMALL, zwykly, background);
delete desc;
//map name
std::string mapDesc = ourHeader.description, mapName = ourHeader.name;
if (mapName.length())
printAtLoc(mapName, 481, 219, FONT_BIG, tytulowy, background);
else
printAtLoc("Unnamed", 481, 219, FONT_BIG, tytulowy, background);
//map description
printAtLoc(CGI->generaltexth->allTexts[496], 481, 253, FONT_SMALL, tytulowy, background);
desc = CMessage::breakText(mapDesc, 45);
for (int i=0; i<desc->size(); i++)
printAtLoc((*desc)[i], 481, 281 + i*16, FONT_SMALL, zwykly, background);
delete desc;
//allies / enemies
printAtLoc(CGI->generaltexth->allTexts[390] + ":", 486, 407, FONT_SMALL, zwykly, background); //Allies
printAtLoc(CGI->generaltexth->allTexts[391] + ":", 619, 407, FONT_SMALL, zwykly, background); //Enemies
int fx=64, ex=244, myT;
myT = ourHeader.players[playerColor].team;
/*for (std::vector<PlayerSettings>::const_iterator i = curOpts->playerInfos.begin(); i != curOpts->playerInfos.end(); i++)
{
int *myx = ((i->color == playerColor || ourHeader.players[i->color].team == myT) ? &fx : &ex);
blitAtLoc(sFlags->ourImages[i->color].bitmap, *myx, 399, to);
*myx += sFlags->ourImages[i->color].bitmap->w;
}*/
SDL_FreeSurface(panel);
}
CBonusSelection::~CBonusSelection()
{
SDL_FreeSurface(background);
}
void CBonusSelection::goBack()
{
GH.popIntTotally(this);
}
void CBonusSelection::showAll( SDL_Surface * to )
{
CIntObject::showAll(to);
blitAt(background, pos.x, pos.y, to);
}

View File

@ -21,6 +21,7 @@ struct CMusicHandler;
class CMapHeader; class CMapHeader;
class CCampaignHeader; class CCampaignHeader;
class CTextInput; class CTextInput;
class CCampaign;
class CGStatusBar; class CGStatusBar;
class CMapInfo class CMapInfo
@ -212,6 +213,7 @@ public:
void toggleTab(CIntObject *tab); void toggleTab(CIntObject *tab);
void changeSelection(const CMapInfo *to); void changeSelection(const CMapInfo *to);
void updateStartInfo(const CMapInfo * to); void updateStartInfo(const CMapInfo * to);
void startCampaign();
void startGame(); void startGame();
void difficultyChange(int to); void difficultyChange(int to);
}; };
@ -251,6 +253,20 @@ public:
void enterSelectionScreen(); void enterSelectionScreen();
}; };
class CBonusSelection : public CIntObject
{
SDL_Surface * background;
AdventureMapButton * startB, * backB;
public:
CBonusSelection(const CCampaign * ourCampaign, int whichMap);
~CBonusSelection();
void showAll(SDL_Surface * to);
void goBack();
void startMap();
};
class CGPreGame : public CIntObject, public IUpdateable class CGPreGame : public CIntObject, public IUpdateable
{ {
public: public:

View File

@ -73,7 +73,7 @@ CCampaign * CCampaignHandler::getCampaign( const std::string & name )
int howManyScenarios = VLC->generaltexth->campaignRegionNames[ret->header.mapVersion].size(); int howManyScenarios = VLC->generaltexth->campaignRegionNames[ret->header.mapVersion].size();
for(int g=0; g<howManyScenarios; ++g) for(int g=0; g<howManyScenarios; ++g)
{ {
CCampaignScenario sc = readScenarioFromMemory(cmpgn, it); CCampaignScenario sc = readScenarioFromMemory(cmpgn, it, ret->header.version);
ret->scenarios.push_back(sc); ret->scenarios.push_back(sc);
} }
@ -109,6 +109,7 @@ CCampaignHeader CCampaignHandler::readHeaderFromMemory( const unsigned char *buf
CCampaignHeader ret; CCampaignHeader ret;
ret.version = readNormalNr(buffer, outIt); outIt+=4; ret.version = readNormalNr(buffer, outIt); outIt+=4;
ret.mapVersion = readChar(buffer, outIt); ret.mapVersion = readChar(buffer, outIt);
ret.mapVersion -= 1; //change range of it from [1, 20] to [0, 19]
ret.name = readString(buffer, outIt); ret.name = readString(buffer, outIt);
ret.description = readString(buffer, outIt); ret.description = readString(buffer, outIt);
ret.difficultyChoosenByPlayer = readChar(buffer, outIt); ret.difficultyChoosenByPlayer = readChar(buffer, outIt);
@ -121,7 +122,7 @@ CCampaignHeader CCampaignHandler::readHeaderFromMemory( const unsigned char *buf
return ret; return ret;
} }
CCampaignScenario CCampaignHandler::readScenarioFromMemory( const unsigned char *buffer, int & outIt ) CCampaignScenario CCampaignHandler::readScenarioFromMemory( const unsigned char *buffer, int & outIt, int version )
{ {
struct HLP struct HLP
{ {
@ -149,20 +150,30 @@ CCampaignScenario CCampaignHandler::readScenarioFromMemory( const unsigned char
ret.prolog = HLP::prologEpilogReader(buffer, outIt); ret.prolog = HLP::prologEpilogReader(buffer, outIt);
ret.epilog = HLP::prologEpilogReader(buffer, outIt); ret.epilog = HLP::prologEpilogReader(buffer, outIt);
ret.travelOptions = readScenarioTravelFromMemory(buffer, outIt); ret.travelOptions = readScenarioTravelFromMemory(buffer, outIt, version);
return ret; return ret;
} }
CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const unsigned char * buffer, int & outIt ) CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const unsigned char * buffer, int & outIt , int version )
{ {
CScenarioTravel ret; CScenarioTravel ret;
ret.whatHeroKeeps = buffer[outIt++]; ret.whatHeroKeeps = buffer[outIt++];
memcpy(ret.monstersKeptByHero, buffer+outIt, ARRAY_COUNT(ret.monstersKeptByHero)); memcpy(ret.monstersKeptByHero, buffer+outIt, ARRAY_COUNT(ret.monstersKeptByHero));
outIt += ARRAY_COUNT(ret.monstersKeptByHero); outIt += ARRAY_COUNT(ret.monstersKeptByHero);
memcpy(ret.artifsKeptByHero, buffer+outIt, ARRAY_COUNT(ret.artifsKeptByHero)); int artifBytes;
outIt += ARRAY_COUNT(ret.artifsKeptByHero); if (version == 5) //AB
{
artifBytes = 17;
ret.artifsKeptByHero[17] = 0;
}
else //SoD+
{
artifBytes = 18;
}
memcpy(ret.artifsKeptByHero, buffer+outIt, artifBytes);
outIt += artifBytes;
ret.startOptions = buffer[outIt++]; ret.startOptions = buffer[outIt++];
@ -205,7 +216,7 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const unsigned c
case 4: //spell scroll case 4: //spell scroll
{ {
bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero
bonus.info2 = readNormalNr(buffer, outIt, 2); outIt += 2; //spell ID bonus.info2 = buffer[outIt++]; //spell ID
break; break;
} }
case 5: //prim skill case 5: //prim skill

View File

@ -112,15 +112,15 @@ public:
class DLL_EXPORT CCampaignHandler class DLL_EXPORT CCampaignHandler
{ {
static CCampaignHeader readHeaderFromMemory( const unsigned char *buffer, int & outIt ); static CCampaignHeader readHeaderFromMemory( const unsigned char *buffer, int & outIt );
static CCampaignScenario readScenarioFromMemory( const unsigned char *buffer, int & outIt ); static CCampaignScenario readScenarioFromMemory( const unsigned char *buffer, int & outIt, int version );
static CScenarioTravel readScenarioTravelFromMemory( const unsigned char * buffer, int & outIt ); static CScenarioTravel readScenarioTravelFromMemory( const unsigned char * buffer, int & outIt , int version);
static std::vector<ui32> locateH3mStarts(const unsigned char * buffer, int start, int size); static std::vector<ui32> locateH3mStarts(const unsigned char * buffer, int start, int size);
static bool startsAt( const unsigned char * buffer, int size, int pos ); //a simple heuristic that checks if a h3m starts at given pos static bool startsAt( const unsigned char * buffer, int size, int pos ); //a simple heuristic that checks if a h3m starts at given pos
public: public:
static std::vector<CCampaignHeader> getCampaignHeaders(); static std::vector<CCampaignHeader> getCampaignHeaders();
static CCampaignHeader getHeader( const std::string & name ); static CCampaignHeader getHeader( const std::string & name ); //name - name of appropriate file
static CCampaign * getCampaign(const std::string & name); static CCampaign * getCampaign(const std::string & name); //name - name of appropriate file
}; };