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

* most of .h3c reading

This commit is contained in:
mateuszb
2010-02-11 14:12:22 +00:00
parent 68a9de5ab7
commit a975c54f86
3 changed files with 271 additions and 8 deletions

View File

@@ -106,7 +106,11 @@ CMenuScreen::CMenuScreen( EState which )
buttons[2] = new AdventureMapButton("", "", 0 /*cb*/, 486, 241, "ZSSARM.DEF", SDLK_c);
buttons[3] = new AdventureMapButton("", "", 0 /*cb*/, 550, 358, "ZSSCUS.DEF", SDLK_t);
buttons[4] = new AdventureMapButton("", "", bind(&CMenuScreen::moveTo, this, CGP->scrs[newGame]), 582, 464, "ZSSEXIT.DEF", SDLK_ESCAPE);
(new CCampaignHandler())->getCampaignHeaders(); //just for testing
////just for testing
CCampaignHandler * ch = new CCampaignHandler();
ch->getCampaignHeaders();
//ch->getCampaign("./Maps/1 Test cmpgn.h3c");
}
break;
}

View File

@@ -50,16 +50,193 @@ CCampaignHeader CCampaignHandler::getHeader( const std::string & name, int size
int realSize;
unsigned char * cmpgn = CLodHandler::getUnpackedFile(name, &realSize);
CCampaignHeader ret;
int it = 0;//iterator for reading
ret.version = readNormalNr(cmpgn, it); it+=4;
ret.mapVersion = readChar(cmpgn, it);
ret.name = readString(cmpgn, it);
ret.description = readString(cmpgn, it);
ret.difficultyChoosenByPlayer = readChar(cmpgn, it);
ret.music = readChar(cmpgn, it);
CCampaignHeader ret = readHeaderFromMemory(cmpgn, it);
delete [] cmpgn;
return ret;
}
CCampaign * CCampaignHandler::getCampaign( const std::string & name )
{
CCampaign * ret = new CCampaign();
int realSize;
unsigned char * cmpgn = CLodHandler::getUnpackedFile(name, &realSize);
int it = 0; //iterator for reading
ret->header = readHeaderFromMemory(cmpgn, it);
it += 112; //omitting rubbish
CCampaignScenario sc = readScenarioFromMemory(cmpgn, it);
CCampaignScenario sc2 = readScenarioFromMemory(cmpgn, it);
delete [] cmpgn;
return ret;
}
CCampaignHeader CCampaignHandler::readHeaderFromMemory( const unsigned char *buffer, int & outIt )
{
CCampaignHeader ret;
ret.version = readNormalNr(buffer, outIt); outIt+=4;
ret.mapVersion = readChar(buffer, outIt);
ret.name = readString(buffer, outIt);
ret.description = readString(buffer, outIt);
ret.difficultyChoosenByPlayer = readChar(buffer, outIt);
ret.music = readChar(buffer, outIt);
return ret;
}
CCampaignScenario CCampaignHandler::readScenarioFromMemory( const unsigned char *buffer, int & outIt )
{
struct HLP
{
//reads prolog/epilog info from memory
static CCampaignScenario::SScenarioPrologEpilog prologEpilogReader( const unsigned char *buffer, int & outIt )
{
CCampaignScenario::SScenarioPrologEpilog ret;
ret.hasPrologEpilog = buffer[outIt++];
if(ret.hasPrologEpilog)
{
ret.prologVideo = buffer[outIt++];
ret.prologMusic = buffer[outIt++];
ret.prologText = readString(buffer, outIt);
}
return ret;
}
};
CCampaignScenario ret;
ret.mapName = readString(buffer, outIt);
ret.packedMapSize = readNormalNr(buffer, outIt); outIt += 4;
ret.preconditionRegion = buffer[outIt++];
ret.regionColor = buffer[outIt++];
ret.difficulty = buffer[outIt++];
ret.regionText = readString(buffer, outIt);
ret.prolog = HLP::prologEpilogReader(buffer, outIt);
ret.epilog = HLP::prologEpilogReader(buffer, outIt);
ret.travelOptions = readScenarioTravelFromMemory(buffer, outIt);
return ret;
}
CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const unsigned char * buffer, int & outIt )
{
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);
ret.startOptions = buffer[outIt++];
switch(ret.startOptions)
{
case 1: //reading of bonuses player can choose
{
ret.playerColor = buffer[outIt++];
ui8 numOfBonuses = buffer[outIt++];
for (int g=0; g<numOfBonuses; ++g)
{
CScenarioTravel::STravelBonus bonus;
bonus.type = buffer[outIt++];
switch(bonus.type)
{
case 0: //spell
{
bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero
bonus.info2 = buffer[outIt++]; //spell ID
break;
}
case 1: //monster
{
bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero
bonus.info2 = readNormalNr(buffer, outIt, 2); outIt += 2; //monster type
bonus.info3 = readNormalNr(buffer, outIt, 2); outIt += 2; //monster count
break;
}
case 2: //building
{
//TODO
break;
}
case 3: //artifact
{
bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero
bonus.info2 = readNormalNr(buffer, outIt, 2); outIt += 2; //artifact ID
break;
}
case 4: //spell scroll
{
bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero
bonus.info2 = readNormalNr(buffer, outIt, 2); outIt += 2; //spell ID
break;
}
case 5: //prim skill
{
bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero
bonus.info2 = readNormalNr(buffer, outIt, 4); outIt += 4; //bonuses (4 bytes for 4 skills)
break;
}
case 6: //sec skills
{
bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero
bonus.info2 = buffer[outIt++]; //skill ID
bonus.info3 = buffer[outIt++]; //skill level
break;
}
case 7: //resources
{
bonus.info1 = buffer[outIt++]; //type
//FD - wood+ore
//FE - mercury+sulfur+crystal+gem
bonus.info2 = readNormalNr(buffer, outIt, 4); outIt += 4; //count
break;
}
}
ret.bonusesToChoose.push_back(bonus);
}
break;
}
case 2: //reading of players (colors / scenarios ?) player can choose
{
ui8 numOfBonuses = buffer[outIt++];
for (int g=0; g<numOfBonuses; ++g)
{
CScenarioTravel::STravelBonus bonus;
bonus.type = 8;
bonus.info1 = buffer[outIt++]; //player color
bonus.info2 = buffer[outIt++]; //from what scenario
ret.bonusesToChoose.push_back(bonus);
}
break;
}
case 3: //heroes player can choose between
{
ui8 numOfBonuses = buffer[outIt++];
for (int g=0; g<numOfBonuses; ++g)
{
CScenarioTravel::STravelBonus bonus;
bonus.type = 9;
bonus.info1 = buffer[outIt++]; //player color
bonus.info2 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero, FF FF - random
ret.bonusesToChoose.push_back(bonus);
}
break;
}
default:
{
tlog1<<"Corrupted h3c file"<<std::endl;
break;
}
}
return ret;
}

View File

@@ -30,12 +30,94 @@ public:
}
};
class DLL_EXPORT CScenarioTravel
{
public:
ui8 whatHeroKeeps; //bitfield [0] - experience, [1] - prim skills, [2] - sec skills, [3] - spells, [4] - artifacts
ui8 monstersKeptByHero[19];
ui8 artifsKeptByHero[18];
ui8 startOptions; //1 - start bonus, 2 - traveling hero, 3 - hero options
ui8 playerColor; //only for startOptions == 1
struct DLL_EXPORT STravelBonus
{
ui8 type; //0 - spell, 1 - monster, 2 - building, 3 - artifact, 4 - spell scroll, 5 - prim skill, 6 - sec skill, 7 - resource,
//8 - player from previous scenario, 9 - hero [???]
si32 info1, info2, info3; //purpose depends on type
template <typename Handler> void serialize(Handler &h, const int formatVersion)
{
h & type & info1 & info2 & info3;
}
};
std::vector<STravelBonus> bonusesToChoose;
template <typename Handler> void serialize(Handler &h, const int formatVersion)
{
h & whatHeroKeeps & monstersKeptByHero & artifsKeptByHero & startOptions & playerColor & bonusesToChoose;
}
};
class DLL_EXPORT CCampaignScenario
{
public:
std::string mapName;
ui32 packedMapSize;
ui8 preconditionRegion;
ui8 regionColor;
ui8 difficulty;
std::string regionText;
struct DLL_EXPORT SScenarioPrologEpilog
{
ui8 hasPrologEpilog;
ui8 prologVideo; // from CmpMovie.txt
ui8 prologMusic; // from CmpMusic.txt
std::string prologText;
template <typename Handler> void serialize(Handler &h, const int formatVersion)
{
h & hasPrologEpilog & prologVideo & prologMusic & prologText;
}
};
SScenarioPrologEpilog prolog, epilog;
CScenarioTravel travelOptions;
template <typename Handler> void serialize(Handler &h, const int formatVersion)
{
h & mapName & packedMapSize & preconditionRegion & regionColor & difficulty & regionText & prolog & epilog & travelOptions;
}
};
class DLL_EXPORT CCampaign
{
public:
CCampaignHeader header;
std::vector<CCampaignScenario> scenarios;
template <typename Handler> void serialize(Handler &h, const int formatVersion)
{
h & header & scenarios;
}
};
class DLL_EXPORT CCampaignHandler
{
CCampaignHeader readHeaderFromMemory( const unsigned char *buffer, int & outIt );
CCampaignScenario readScenarioFromMemory( const unsigned char *buffer, int & outIt );
CScenarioTravel readScenarioTravelFromMemory( const unsigned char * buffer, int & outIt );
CCampaignHeader getHeader( const std::string & name, int size );
public:
std::vector<CCampaignHeader> getCampaignHeaders();
CCampaign * getCampaign(const std::string & name);
};