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:
parent
49b99f470f
commit
448c2e7225
@ -268,6 +268,13 @@ CSelectionScreen::CSelectionScreen( CMenuScreen::EState Type, const std::vector<
|
||||
{
|
||||
center(pos);
|
||||
}
|
||||
else if(Type == CMenuScreen::campaignList)
|
||||
{
|
||||
bg = new CPicture(BitmapHandler::loadBitmap("CamCust.bmp"), 0, 0, true);
|
||||
|
||||
pos.x = 3;
|
||||
pos.y = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos.x = 3;
|
||||
@ -326,13 +333,24 @@ CSelectionScreen::CSelectionScreen( CMenuScreen::EState Type, const std::vector<
|
||||
break;
|
||||
case CMenuScreen::campaignList:
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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()
|
||||
@ -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()
|
||||
{
|
||||
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)
|
||||
:onSelect(OnSelect)
|
||||
:onSelect(OnSelect), bg(NULL)
|
||||
{
|
||||
OBJ_CONSTRUCTION;
|
||||
selectionPos = 0;
|
||||
@ -605,16 +629,12 @@ SelectionTab::SelectionTab(CMenuScreen::EState Type, const boost::function<void(
|
||||
txt = NULL;
|
||||
tabType = Type;
|
||||
|
||||
if (Type == CMenuScreen::campaignList)
|
||||
{
|
||||
bg = new CPicture(BitmapHandler::loadBitmap("CamCust.bmp"), 0, 0, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if (Type != CMenuScreen::campaignList)
|
||||
/*{*/
|
||||
bg = new CPicture(BitmapHandler::loadBitmap("SCSELBCK.bmp"), 0, 0, true);
|
||||
}
|
||||
pos.w = bg->pos.w;
|
||||
pos.h = bg->pos.h;
|
||||
pos.w = bg->pos.w;
|
||||
pos.h = bg->pos.h;
|
||||
/*}*/
|
||||
|
||||
std::vector<FileInfo> toParse;
|
||||
switch(tabType)
|
||||
@ -643,6 +663,7 @@ SelectionTab::SelectionTab(CMenuScreen::EState Type, const boost::function<void(
|
||||
case CMenuScreen::campaignList:
|
||||
getFiles(toParse, DATA_DIR "/Maps", "h3c"); //get all campaigns
|
||||
parseCampaigns(toParse);
|
||||
positions = 18;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -786,13 +807,13 @@ void SelectionTab::printMaps(SDL_Surface *to)
|
||||
{
|
||||
CMapInfo* curMap = curItems[elemIdx];
|
||||
|
||||
if (elemIdx == selectionPos)
|
||||
itemColor=tytulowy;
|
||||
else
|
||||
itemColor=zwykly;
|
||||
|
||||
if(tabType != CMenuScreen::campaignList)
|
||||
{
|
||||
if (elemIdx == selectionPos)
|
||||
itemColor=tytulowy;
|
||||
else
|
||||
itemColor=zwykly;
|
||||
|
||||
//amount of players
|
||||
std::ostringstream ostr(std::ostringstream::out);
|
||||
ostr << curMap->playerAmnt << "/" << curMap->humenPlayers;
|
||||
@ -853,6 +874,13 @@ void SelectionTab::printMaps(SDL_Surface *to)
|
||||
temp=curMap->mapHeader->lossCondition.typeOfLossCon;
|
||||
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;
|
||||
if(tabType != CMenuScreen::campaignList)
|
||||
@ -867,7 +895,7 @@ void SelectionTab::printMaps(SDL_Surface *to)
|
||||
}
|
||||
|
||||
//print name
|
||||
if (tabType == CMenuScreen::newGame) {
|
||||
if (tabType == CMenuScreen::newGame || tabType == CMenuScreen::campaignList) {
|
||||
|
||||
CSDL_Ext::printAtMiddle(name, POS(213, 128), FONT_SMALL, itemColor, to);
|
||||
} else
|
||||
@ -899,7 +927,10 @@ 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(CGI->generaltexth->allTexts[510], pos.x+87, pos.y+62, FONT_SMALL, tytulowy, to); //Map sizes
|
||||
if(tabType != CMenuScreen::campaignList)
|
||||
{
|
||||
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 )
|
||||
@ -990,19 +1021,25 @@ void SelectionTab::selectFName( const std::string &fname )
|
||||
|
||||
|
||||
InfoCard::InfoCard( CMenuScreen::EState Type )
|
||||
: difficulty(NULL), sizes(NULL), sFlags(NULL)
|
||||
: difficulty(NULL), sizes(NULL), sFlags(NULL), bg(NULL)
|
||||
{
|
||||
OBJ_CONSTRUCTION;
|
||||
pos.x += 393;
|
||||
used = RCLICK;
|
||||
|
||||
type = Type;
|
||||
bg = new CPicture(BitmapHandler::loadBitmap("GSELPOP1.bmp"), 0, 0, true);
|
||||
pos.w = bg->pos.w;
|
||||
pos.h = bg->pos.h;
|
||||
|
||||
if(type != CMenuScreen::campaignList)
|
||||
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);
|
||||
pos.w = bg->pos.w;
|
||||
pos.h = bg->pos.h;
|
||||
sizes = CDefHandler::giveDef("SCNRMPSZ.DEF");
|
||||
sFlags = CDefHandler::giveDef("ITGFLAGS.DEF");
|
||||
|
||||
@ -1104,6 +1141,8 @@ void InfoCard::showAll( SDL_Surface * to )
|
||||
break;
|
||||
}
|
||||
blitAtLoc(sizes->ourImages[temp].bitmap, 318, 22, to);
|
||||
|
||||
//conditions
|
||||
temp = curMap->mapHeader->victoryCondition.condition;
|
||||
if (temp>12) temp=11;
|
||||
blitAtLoc(CGP->victory->ourImages[temp].bitmap, 24, 302, to); //victory cond descr
|
||||
@ -1928,4 +1967,110 @@ void CHotSeatPlayers::enterSelectionScreen()
|
||||
|
||||
GH.popInts(2);
|
||||
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);
|
||||
}
|
@ -21,6 +21,7 @@ struct CMusicHandler;
|
||||
class CMapHeader;
|
||||
class CCampaignHeader;
|
||||
class CTextInput;
|
||||
class CCampaign;
|
||||
class CGStatusBar;
|
||||
|
||||
class CMapInfo
|
||||
@ -212,6 +213,7 @@ public:
|
||||
void toggleTab(CIntObject *tab);
|
||||
void changeSelection(const CMapInfo *to);
|
||||
void updateStartInfo(const CMapInfo * to);
|
||||
void startCampaign();
|
||||
void startGame();
|
||||
void difficultyChange(int to);
|
||||
};
|
||||
@ -251,6 +253,20 @@ public:
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
@ -73,7 +73,7 @@ CCampaign * CCampaignHandler::getCampaign( const std::string & name )
|
||||
int howManyScenarios = VLC->generaltexth->campaignRegionNames[ret->header.mapVersion].size();
|
||||
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);
|
||||
}
|
||||
|
||||
@ -109,6 +109,7 @@ CCampaignHeader CCampaignHandler::readHeaderFromMemory( const unsigned char *buf
|
||||
CCampaignHeader ret;
|
||||
ret.version = readNormalNr(buffer, outIt); outIt+=4;
|
||||
ret.mapVersion = readChar(buffer, outIt);
|
||||
ret.mapVersion -= 1; //change range of it from [1, 20] to [0, 19]
|
||||
ret.name = readString(buffer, outIt);
|
||||
ret.description = readString(buffer, outIt);
|
||||
ret.difficultyChoosenByPlayer = readChar(buffer, outIt);
|
||||
@ -121,7 +122,7 @@ CCampaignHeader CCampaignHandler::readHeaderFromMemory( const unsigned char *buf
|
||||
return ret;
|
||||
}
|
||||
|
||||
CCampaignScenario CCampaignHandler::readScenarioFromMemory( const unsigned char *buffer, int & outIt )
|
||||
CCampaignScenario CCampaignHandler::readScenarioFromMemory( const unsigned char *buffer, int & outIt, int version )
|
||||
{
|
||||
struct HLP
|
||||
{
|
||||
@ -149,20 +150,30 @@ CCampaignScenario CCampaignHandler::readScenarioFromMemory( const unsigned char
|
||||
ret.prolog = HLP::prologEpilogReader(buffer, outIt);
|
||||
ret.epilog = HLP::prologEpilogReader(buffer, outIt);
|
||||
|
||||
ret.travelOptions = readScenarioTravelFromMemory(buffer, outIt);
|
||||
ret.travelOptions = readScenarioTravelFromMemory(buffer, outIt, version);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const unsigned char * buffer, int & outIt )
|
||||
CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const unsigned char * buffer, int & outIt , int version )
|
||||
{
|
||||
CScenarioTravel ret;
|
||||
|
||||
ret.whatHeroKeeps = buffer[outIt++];
|
||||
memcpy(ret.monstersKeptByHero, buffer+outIt, ARRAY_COUNT(ret.monstersKeptByHero));
|
||||
outIt += ARRAY_COUNT(ret.monstersKeptByHero);
|
||||
memcpy(ret.artifsKeptByHero, buffer+outIt, ARRAY_COUNT(ret.artifsKeptByHero));
|
||||
outIt += ARRAY_COUNT(ret.artifsKeptByHero);
|
||||
int artifBytes;
|
||||
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++];
|
||||
|
||||
@ -205,7 +216,7 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const unsigned c
|
||||
case 4: //spell scroll
|
||||
{
|
||||
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;
|
||||
}
|
||||
case 5: //prim skill
|
||||
|
@ -112,15 +112,15 @@ public:
|
||||
class DLL_EXPORT CCampaignHandler
|
||||
{
|
||||
static CCampaignHeader readHeaderFromMemory( const unsigned char *buffer, int & outIt );
|
||||
static CCampaignScenario readScenarioFromMemory( const unsigned char *buffer, int & outIt );
|
||||
static CScenarioTravel readScenarioTravelFromMemory( 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 , int version);
|
||||
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
|
||||
public:
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user