mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
- move campaigns description into new config file, campaignSets.json
- campaigns parser uses binary reader, fixes #1711 - fixed description of change resolution button
This commit is contained in:
parent
f5e3e578e6
commit
48d6e2cd59
@ -445,7 +445,15 @@ const JsonNode & CGPreGameConfig::getConfig() const
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGPreGameConfig::CGPreGameConfig() : config(JsonNode(ResourceID("config/mainmenu.json")))
|
const JsonNode & CGPreGameConfig::getCampaigns() const
|
||||||
|
{
|
||||||
|
return campaignSets;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CGPreGameConfig::CGPreGameConfig() :
|
||||||
|
campaignSets(JsonNode(ResourceID("config/campaignSets.json"))),
|
||||||
|
config(JsonNode(ResourceID("config/mainmenu.json")))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -528,15 +536,12 @@ void CGPreGame::update()
|
|||||||
|
|
||||||
void CGPreGame::openCampaignScreen(std::string name)
|
void CGPreGame::openCampaignScreen(std::string name)
|
||||||
{
|
{
|
||||||
for(const JsonNode& node : CGPreGameConfig::get().getConfig()["campaignsset"].Vector())
|
if (vstd::contains(CGPreGameConfig::get().getCampaigns().Struct(), name))
|
||||||
{
|
{
|
||||||
if (node["name"].String() == name)
|
GH.pushInt(new CCampaignScreen(CGPreGameConfig::get().getCampaigns()[name]));
|
||||||
{
|
return;
|
||||||
GH.pushInt(new CCampaignScreen(node));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
logGlobal->errorStream()<<"Unknown campaign set: "<<name;
|
logGlobal->errorStream()<<"Unknown campaign set: "<<name;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGPreGame *CGPreGame::create()
|
CGPreGame *CGPreGame::create()
|
||||||
|
@ -578,10 +578,12 @@ class CGPreGameConfig
|
|||||||
public:
|
public:
|
||||||
static CGPreGameConfig & get();
|
static CGPreGameConfig & get();
|
||||||
const JsonNode & getConfig() const;
|
const JsonNode & getConfig() const;
|
||||||
|
const JsonNode & getCampaigns() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CGPreGameConfig();
|
CGPreGameConfig();
|
||||||
|
|
||||||
|
const JsonNode campaignSets;
|
||||||
const JsonNode config;
|
const JsonNode config;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
64
config/campaignSets.json
Normal file
64
config/campaignSets.json
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
{
|
||||||
|
"roe" :
|
||||||
|
{
|
||||||
|
"images" : [ {"x": 0, "y": 0, "name":"CAMPBACK"} ],
|
||||||
|
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
|
||||||
|
"items":
|
||||||
|
[
|
||||||
|
{ "x":90, "y":72, "file":"DATA/GOOD1.H3C", "image":"CAMPGD1S", "video":"CGOOD1", "open": true },
|
||||||
|
{ "x":539, "y":72, "file":"DATA/EVIL1.H3C", "image":"CAMPEV1S", "video":"CEVIL1", "open": true },
|
||||||
|
{ "x":43, "y":245, "file":"DATA/GOOD2.H3C", "image":"CAMPGD2S", "video":"CGOOD2", "open": true },
|
||||||
|
{ "x":313, "y":244, "file":"DATA/NEUTRAL1.H3C", "image":"CAMPNEUS", "video":"CNEUTRAL", "open": true },
|
||||||
|
{ "x":586, "y":246, "file":"DATA/EVIL2.H3C", "image":"CAMPEV2S", "video":"CEVIL2", "open": true },
|
||||||
|
{ "x":34, "y":417, "file":"DATA/GOOD3.H3C", "image":"CAMPGD3S", "video":"CGOOD3", "open": true },
|
||||||
|
{ "x":404, "y":414, "file":"DATA/SECRET1.H3C", "image":"CAMPSCTS", "video":"CSECRET", "open": true }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ab" :
|
||||||
|
{
|
||||||
|
"images" :
|
||||||
|
[
|
||||||
|
{"x": 0, "y": 0, "name":"CAMPBACK"},
|
||||||
|
{"x": 34, "y": 417, "name":"CAMP1FWX"},//one campaign have special inactive image
|
||||||
|
{"x": 385, "y": 401, "name":"CAMPNOSC"},//and the last one is not present
|
||||||
|
],
|
||||||
|
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
|
||||||
|
"items":
|
||||||
|
[
|
||||||
|
{ "x":90, "y":72, "file":"DATA/AB.H3C", "image":"CAMP1AB7", "video":"C1ab7", "open": true },
|
||||||
|
{ "x":539, "y":72, "file":"DATA/BLOOD.H3C", "image":"CAMP1DB2", "video":"C1db2", "open": true },
|
||||||
|
{ "x":43, "y":245, "file":"DATA/SLAYER.H3C", "image":"CAMP1DS1", "video":"C1ds1", "open": true },
|
||||||
|
{ "x":313, "y":244, "file":"DATA/FESTIVAL.H3C", "image":"CAMP1FL3", "video":"C1fl3", "open": true },
|
||||||
|
{ "x":586, "y":246, "file":"DATA/FIRE.H3C", "image":"CAMP1PF2", "video":"C1pf2", "open": true },
|
||||||
|
{ "x":34, "y":417, "file":"DATA/FOOL.H3C", "image":"CAMP1FW1", "video":"C1fw1", "open": true }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sod":
|
||||||
|
{
|
||||||
|
"images" : [ {"x": 0, "y": 0, "name":"CAMPBKX2"} ],
|
||||||
|
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
|
||||||
|
"items":
|
||||||
|
[
|
||||||
|
{ "x":90, "y":72, "file":"DATA/GEM.H3C", "image":"CAMPNB1", "video":"NEW", "open": true },
|
||||||
|
{ "x":539, "y":72, "file":"DATA/GELU.H3C", "image":"CAMPEL1", "video":"ELIXIR", "open": true },
|
||||||
|
{ "x":43, "y":245, "file":"DATA/CRAG.H3C", "image":"CAMPHS1", "video":"HACK", "open": true },
|
||||||
|
{ "x":313, "y":244, "file":"DATA/SANDRO.H3C", "image":"CAMPRN1", "video":"RISE", "open": true },
|
||||||
|
{ "x":586, "y":246, "file":"DATA/YOG.H3C", "image":"CAMPBB1", "video":"BIRTH", "open": true },
|
||||||
|
{ "x":34, "y":417, "file":"DATA/FINAL.H3C", "image":"CAMPUA1", "video":"UNHOLY", "open": true },
|
||||||
|
{ "x":404, "y":414, "file":"DATA/SECRET.H3C", "image":"CAMPSP1", "video":"SPECTRE", "open": true }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"wog" :
|
||||||
|
{
|
||||||
|
/// wog campaigns, currently has no assigned button in campaign screen and thus unused
|
||||||
|
"images" : [ {"x": 0, "y": 0, "name":"CAMPZALL"} ],
|
||||||
|
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
|
||||||
|
"items":
|
||||||
|
[
|
||||||
|
{ "x":90, "y":72, "file":"DATA/ZC1.H3C", "image":"CAMPZ01", "open": true},
|
||||||
|
{ "x":539, "y":72, "file":"DATA/ZC2.H3C", "image":"CAMPZ02", "open": true},
|
||||||
|
{ "x":43, "y":245, "file":"DATA/ZC3.H3C", "image":"CAMPZ03", "open": true},
|
||||||
|
{ "x":311, "y":242, "file":"DATA/ZC4.H3C", "image":"CAMPZ04", "open": true}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -60,73 +60,5 @@
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
//Campaigns windows, each campaigns set is a separate window activated by "campaigns %name%" command from main menu
|
|
||||||
"campaignsset":
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"name":"roe",
|
|
||||||
"images" : [ {"x": 0, "y": 0, "name":"CAMPBACK"} ],
|
|
||||||
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
|
|
||||||
"items":
|
|
||||||
[
|
|
||||||
{ "x":90, "y":72, "file":"DATA/GOOD1.H3C", "image":"CAMPGD1S", "video":"CGOOD1", "open": true },
|
|
||||||
{ "x":539, "y":72, "file":"DATA/EVIL1.H3C", "image":"CAMPEV1S", "video":"CEVIL1", "open": true },
|
|
||||||
{ "x":43, "y":245, "file":"DATA/GOOD2.H3C", "image":"CAMPGD2S", "video":"CGOOD2", "open": true },
|
|
||||||
{ "x":313, "y":244, "file":"DATA/NEUTRAL1.H3C", "image":"CAMPNEUS", "video":"CNEUTRAL", "open": true },
|
|
||||||
{ "x":586, "y":246, "file":"DATA/EVIL2.H3C", "image":"CAMPEV2S", "video":"CEVIL2", "open": true },
|
|
||||||
{ "x":34, "y":417, "file":"DATA/GOOD3.H3C", "image":"CAMPGD3S", "video":"CGOOD3", "open": true },
|
|
||||||
{ "x":404, "y":414, "file":"DATA/SECRET1.H3C", "image":"CAMPSCTS", "video":"CSECRET", "open": true }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"ab",
|
|
||||||
"images" :
|
|
||||||
[
|
|
||||||
{"x": 0, "y": 0, "name":"CAMPBACK"},
|
|
||||||
{"x": 34, "y": 417, "name":"CAMP1FWX"},//one campaign have special inactive image
|
|
||||||
{"x": 385, "y": 401, "name":"CAMPNOSC"},//and the last one is not present
|
|
||||||
],
|
|
||||||
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
|
|
||||||
"items":
|
|
||||||
[
|
|
||||||
{ "x":90, "y":72, "file":"DATA/AB.H3C", "image":"CAMP1AB7", "video":"C1ab7", "open": true },
|
|
||||||
{ "x":539, "y":72, "file":"DATA/BLOOD.H3C", "image":"CAMP1DB2", "video":"C1db2", "open": true },
|
|
||||||
{ "x":43, "y":245, "file":"DATA/SLAYER.H3C", "image":"CAMP1DS1", "video":"C1ds1", "open": true },
|
|
||||||
{ "x":313, "y":244, "file":"DATA/FESTIVAL.H3C", "image":"CAMP1FL3", "video":"C1fl3", "open": true },
|
|
||||||
{ "x":586, "y":246, "file":"DATA/FIRE.H3C", "image":"CAMP1PF2", "video":"C1pf2", "open": true },
|
|
||||||
{ "x":34, "y":417, "file":"DATA/FOOL.H3C", "image":"CAMP1FW1", "video":"C1fw1", "open": true }
|
|
||||||
]
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"sod",
|
|
||||||
"images" : [ {"x": 0, "y": 0, "name":"CAMPBKX2"} ],
|
|
||||||
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
|
|
||||||
"items":
|
|
||||||
[
|
|
||||||
{ "x":90, "y":72, "file":"DATA/GEM.H3C", "image":"CAMPNB1", "video":"NEW", "open": true },
|
|
||||||
{ "x":539, "y":72, "file":"DATA/GELU.H3C", "image":"CAMPEL1", "video":"ELIXIR", "open": true },
|
|
||||||
{ "x":43, "y":245, "file":"DATA/CRAG.H3C", "image":"CAMPHS1", "video":"HACK", "open": true },
|
|
||||||
{ "x":313, "y":244, "file":"DATA/SANDRO.H3C", "image":"CAMPRN1", "video":"RISE", "open": true },
|
|
||||||
{ "x":586, "y":246, "file":"DATA/YOG.H3C", "image":"CAMPBB1", "video":"BIRTH", "open": true },
|
|
||||||
{ "x":34, "y":417, "file":"DATA/FINAL.H3C", "image":"CAMPUA1", "video":"UNHOLY", "open": true },
|
|
||||||
{ "x":404, "y":414, "file":"DATA/SECRET.H3C", "image":"CAMPSP1", "video":"SPECTRE", "open": true }
|
|
||||||
]
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"wog", /// wog campaigns, currently has no assigned button in campaign screen and thus unused
|
|
||||||
"images" : [ {"x": 0, "y": 0, "name":"CAMPZALL"} ],
|
|
||||||
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
|
|
||||||
"items":
|
|
||||||
[
|
|
||||||
{ "x":90, "y":72, "file":"DATA/ZC1.H3C", "image":"CAMPZ01", "open": true},
|
|
||||||
{ "x":539, "y":72, "file":"DATA/ZC2.H3C", "image":"CAMPZ02", "open": true},
|
|
||||||
{ "x":43, "y":245, "file":"DATA/ZC3.H3C", "image":"CAMPZ03", "open": true},
|
|
||||||
{ "x":311, "y":242, "file":"DATA/ZC4.H3C", "image":"CAMPZ04", "open": true}
|
|
||||||
]
|
|
||||||
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
"resolutionButton" :
|
"resolutionButton" :
|
||||||
{
|
{
|
||||||
"label" : "Resolution",
|
"label" : "Resolution",
|
||||||
"help" : "{Select resolution}\n\n Change in-game screen resolution. Will only affect adventure map. Game restart required to apply new resolution."
|
"help" : "{Select resolution}\n\n Change in-game screen resolution. Game restart required to apply new resolution."
|
||||||
},
|
},
|
||||||
"resolutionMenu" :
|
"resolutionMenu" :
|
||||||
{
|
{
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "../filesystem/Filesystem.h"
|
#include "../filesystem/Filesystem.h"
|
||||||
#include "../filesystem/CCompressedStream.h"
|
#include "../filesystem/CCompressedStream.h"
|
||||||
|
#include "../filesystem/CMemoryStream.h"
|
||||||
|
#include "../filesystem/CBinaryReader.h"
|
||||||
#include "../VCMI_Lib.h"
|
#include "../VCMI_Lib.h"
|
||||||
#include "../vcmi_endian.h"
|
#include "../vcmi_endian.h"
|
||||||
#include "../CGeneralTextHandler.h"
|
#include "../CGeneralTextHandler.h"
|
||||||
@ -30,8 +32,9 @@ CCampaignHeader CCampaignHandler::getHeader( const std::string & name)
|
|||||||
{
|
{
|
||||||
std::vector<ui8> cmpgn = getFile(name, true)[0];
|
std::vector<ui8> cmpgn = getFile(name, true)[0];
|
||||||
|
|
||||||
int it = 0;//iterator for reading
|
CMemoryStream stream(cmpgn.data(), cmpgn.size());
|
||||||
CCampaignHeader ret = readHeaderFromMemory(cmpgn.data(), it);
|
CBinaryReader reader(&stream);
|
||||||
|
CCampaignHeader ret = readHeaderFromMemory(reader);
|
||||||
ret.filename = name;
|
ret.filename = name;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -43,14 +46,15 @@ unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & name )
|
|||||||
|
|
||||||
std::vector<std::vector<ui8>> file = getFile(name, false);
|
std::vector<std::vector<ui8>> file = getFile(name, false);
|
||||||
|
|
||||||
int it = 0; //iterator for reading
|
CMemoryStream stream(file[0].data(), file[0].size());
|
||||||
ret->header = readHeaderFromMemory(file[0].data(), it);
|
CBinaryReader reader(&stream);
|
||||||
|
ret->header = readHeaderFromMemory(reader);
|
||||||
ret->header.filename = name;
|
ret->header.filename = 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(file[0].data(), it, ret->header.version, ret->header.mapVersion);
|
CCampaignScenario sc = readScenarioFromMemory(reader, ret->header.version, ret->header.mapVersion);
|
||||||
ret->scenarios.push_back(sc);
|
ret->scenarios.push_back(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,59 +81,56 @@ unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & name )
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
CCampaignHeader CCampaignHandler::readHeaderFromMemory( const ui8 *buffer, int & outIt )
|
CCampaignHeader CCampaignHandler::readHeaderFromMemory( CBinaryReader & reader )
|
||||||
{
|
{
|
||||||
CCampaignHeader ret;
|
CCampaignHeader ret;
|
||||||
ret.version = read_le_u32(buffer + outIt); outIt+=4;
|
|
||||||
ret.mapVersion = buffer[outIt++]; //1 byte only
|
ret.version = reader.readUInt32();
|
||||||
ret.mapVersion -= 1; //change range of it from [1, 20] to [0, 19]
|
ret.mapVersion = reader.readUInt8() - 1;//change range of it from [1, 20] to [0, 19]
|
||||||
ret.name = readString(buffer, outIt);
|
ret.name = reader.readString();
|
||||||
ret.description = readString(buffer, outIt);
|
ret.description = reader.readString();
|
||||||
if (ret.version > CampaignVersion::RoE)
|
if (ret.version > CampaignVersion::RoE)
|
||||||
ret.difficultyChoosenByPlayer = readChar(buffer, outIt);
|
ret.difficultyChoosenByPlayer = reader.readInt8();
|
||||||
else
|
else
|
||||||
ret.difficultyChoosenByPlayer = 0;
|
ret.difficultyChoosenByPlayer = 0;
|
||||||
ret.music = readChar(buffer, outIt);
|
ret.music = reader.readInt8();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
CCampaignScenario CCampaignHandler::readScenarioFromMemory( const ui8 *buffer, int & outIt, int version, int mapVersion )
|
CCampaignScenario CCampaignHandler::readScenarioFromMemory( CBinaryReader & reader, int version, int mapVersion )
|
||||||
{
|
{
|
||||||
struct HLP
|
auto prologEpilogReader = [&]() -> CCampaignScenario::SScenarioPrologEpilog
|
||||||
{
|
{
|
||||||
//reads prolog/epilog info from memory
|
CCampaignScenario::SScenarioPrologEpilog ret;
|
||||||
static CCampaignScenario::SScenarioPrologEpilog prologEpilogReader( const ui8 *buffer, int & outIt )
|
ret.hasPrologEpilog = reader.readUInt8();
|
||||||
|
if(ret.hasPrologEpilog)
|
||||||
{
|
{
|
||||||
CCampaignScenario::SScenarioPrologEpilog ret;
|
ret.prologVideo = reader.readUInt8();
|
||||||
ret.hasPrologEpilog = buffer[outIt++];
|
ret.prologMusic = reader.readUInt8();
|
||||||
if(ret.hasPrologEpilog)
|
ret.prologText = reader.readString();
|
||||||
{
|
|
||||||
ret.prologVideo = buffer[outIt++];
|
|
||||||
ret.prologMusic = buffer[outIt++];
|
|
||||||
ret.prologText = readString(buffer, outIt);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
CCampaignScenario ret;
|
CCampaignScenario ret;
|
||||||
ret.conquered = false;
|
ret.conquered = false;
|
||||||
ret.mapName = readString(buffer, outIt);
|
ret.mapName = reader.readString();
|
||||||
ret.packedMapSize = read_le_u32(buffer + outIt); outIt += 4;
|
ret.packedMapSize = reader.readUInt32();
|
||||||
if(mapVersion == 18)//unholy alliance
|
if(mapVersion == 18)//unholy alliance
|
||||||
{
|
{
|
||||||
ret.loadPreconditionRegions(read_le_u16(buffer + outIt)); outIt += 2;
|
ret.loadPreconditionRegions(reader.readUInt16());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret.loadPreconditionRegions(buffer[outIt++]);
|
ret.loadPreconditionRegions(reader.readUInt8());
|
||||||
}
|
}
|
||||||
ret.regionColor = buffer[outIt++];
|
ret.regionColor = reader.readUInt8();
|
||||||
ret.difficulty = buffer[outIt++];
|
ret.difficulty = reader.readUInt8();
|
||||||
ret.regionText = readString(buffer, outIt);
|
ret.regionText = reader.readString();
|
||||||
ret.prolog = HLP::prologEpilogReader(buffer, outIt);
|
ret.prolog = prologEpilogReader();
|
||||||
ret.epilog = HLP::prologEpilogReader(buffer, outIt);
|
ret.epilog = prologEpilogReader();
|
||||||
|
|
||||||
ret.travelOptions = readScenarioTravelFromMemory(buffer, outIt, version);
|
ret.travelOptions = readScenarioTravelFromMemory(reader, version);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -143,28 +144,25 @@ void CCampaignScenario::loadPreconditionRegions(ui32 regions)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const ui8 * buffer, int & outIt , int version )
|
CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory(CBinaryReader & reader, int version )
|
||||||
{
|
{
|
||||||
CScenarioTravel ret;
|
CScenarioTravel ret;
|
||||||
|
|
||||||
ret.whatHeroKeeps = buffer[outIt++];
|
ret.whatHeroKeeps = reader.readUInt8();
|
||||||
memcpy(ret.monstersKeptByHero, buffer+outIt, ARRAY_COUNT(ret.monstersKeptByHero));
|
reader.getStream()->read(ret.monstersKeptByHero.data(), ret.monstersKeptByHero.size());
|
||||||
outIt += ARRAY_COUNT(ret.monstersKeptByHero);
|
|
||||||
int artifBytes;
|
|
||||||
if (version < CampaignVersion::SoD)
|
if (version < CampaignVersion::SoD)
|
||||||
{
|
{
|
||||||
artifBytes = 17;
|
ret.artifsKeptByHero.fill(0);
|
||||||
ret.artifsKeptByHero[17] = 0;
|
reader.getStream()->read(ret.artifsKeptByHero.data(), ret.artifsKeptByHero.size() - 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
artifBytes = 18;
|
reader.getStream()->read(ret.artifsKeptByHero.data(), ret.artifsKeptByHero.size());
|
||||||
}
|
}
|
||||||
memcpy(ret.artifsKeptByHero, buffer+outIt, artifBytes);
|
|
||||||
outIt += artifBytes;
|
|
||||||
|
|
||||||
ret.startOptions = buffer[outIt++];
|
ret.startOptions = reader.readUInt8();
|
||||||
|
|
||||||
switch(ret.startOptions)
|
switch(ret.startOptions)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@ -172,64 +170,64 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const ui8 * buff
|
|||||||
break;
|
break;
|
||||||
case 1: //reading of bonuses player can choose
|
case 1: //reading of bonuses player can choose
|
||||||
{
|
{
|
||||||
ret.playerColor = buffer[outIt++];
|
ret.playerColor = reader.readUInt8();
|
||||||
ui8 numOfBonuses = buffer[outIt++];
|
ui8 numOfBonuses = reader.readUInt8();
|
||||||
for (int g=0; g<numOfBonuses; ++g)
|
for (int g=0; g<numOfBonuses; ++g)
|
||||||
{
|
{
|
||||||
CScenarioTravel::STravelBonus bonus;
|
CScenarioTravel::STravelBonus bonus;
|
||||||
bonus.type = static_cast<CScenarioTravel::STravelBonus::EBonusType>(buffer[outIt++]);
|
bonus.type = static_cast<CScenarioTravel::STravelBonus::EBonusType>(reader.readUInt8());
|
||||||
//hero: FFFD means 'most powerful' and FFFE means 'generated'
|
//hero: FFFD means 'most powerful' and FFFE means 'generated'
|
||||||
switch(bonus.type)
|
switch(bonus.type)
|
||||||
{
|
{
|
||||||
case CScenarioTravel::STravelBonus::SPELL:
|
case CScenarioTravel::STravelBonus::SPELL:
|
||||||
{
|
{
|
||||||
bonus.info1 = read_le_u16(buffer + outIt); outIt += 2; //hero
|
bonus.info1 = reader.readUInt16(); //hero
|
||||||
bonus.info2 = buffer[outIt++]; //spell ID
|
bonus.info2 = reader.readUInt8(); //spell ID
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CScenarioTravel::STravelBonus::MONSTER:
|
case CScenarioTravel::STravelBonus::MONSTER:
|
||||||
{
|
{
|
||||||
bonus.info1 = read_le_u16(buffer + outIt); outIt += 2; //hero
|
bonus.info1 = reader.readUInt16(); //hero
|
||||||
bonus.info2 = read_le_u16(buffer + outIt); outIt += 2; //monster type
|
bonus.info2 = reader.readUInt16(); //monster type
|
||||||
bonus.info3 = read_le_u16(buffer + outIt); outIt += 2; //monster count
|
bonus.info3 = reader.readUInt16(); //monster count
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CScenarioTravel::STravelBonus::BUILDING:
|
case CScenarioTravel::STravelBonus::BUILDING:
|
||||||
{
|
{
|
||||||
bonus.info1 = buffer[outIt++]; //building ID (0 - town hall, 1 - city hall, 2 - capitol, etc)
|
bonus.info1 = reader.readUInt8(); //building ID (0 - town hall, 1 - city hall, 2 - capitol, etc)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CScenarioTravel::STravelBonus::ARTIFACT:
|
case CScenarioTravel::STravelBonus::ARTIFACT:
|
||||||
{
|
{
|
||||||
bonus.info1 = read_le_u16(buffer + outIt); outIt += 2; //hero
|
bonus.info1 = reader.readUInt16(); //hero
|
||||||
bonus.info2 = read_le_u16(buffer + outIt); outIt += 2; //artifact ID
|
bonus.info2 = reader.readUInt16(); //artifact ID
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CScenarioTravel::STravelBonus::SPELL_SCROLL:
|
case CScenarioTravel::STravelBonus::SPELL_SCROLL:
|
||||||
{
|
{
|
||||||
bonus.info1 = read_le_u16(buffer + outIt); outIt += 2; //hero
|
bonus.info1 = reader.readUInt16(); //hero
|
||||||
bonus.info2 = buffer[outIt++]; //spell ID
|
bonus.info2 = reader.readUInt8(); //spell ID
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CScenarioTravel::STravelBonus::PRIMARY_SKILL:
|
case CScenarioTravel::STravelBonus::PRIMARY_SKILL:
|
||||||
{
|
{
|
||||||
bonus.info1 = read_le_u16(buffer + outIt); outIt += 2; //hero
|
bonus.info1 = reader.readUInt16(); //hero
|
||||||
bonus.info2 = read_le_u32(buffer + outIt); outIt += 4; //bonuses (4 bytes for 4 skills)
|
bonus.info2 = reader.readUInt32(); //bonuses (4 bytes for 4 skills)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CScenarioTravel::STravelBonus::SECONDARY_SKILL:
|
case CScenarioTravel::STravelBonus::SECONDARY_SKILL:
|
||||||
{
|
{
|
||||||
bonus.info1 = read_le_u16(buffer + outIt); outIt += 2; //hero
|
bonus.info1 = reader.readUInt16(); //hero
|
||||||
bonus.info2 = buffer[outIt++]; //skill ID
|
bonus.info2 = reader.readUInt8(); //skill ID
|
||||||
bonus.info3 = buffer[outIt++]; //skill level
|
bonus.info3 = reader.readUInt8(); //skill level
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CScenarioTravel::STravelBonus::RESOURCE:
|
case CScenarioTravel::STravelBonus::RESOURCE:
|
||||||
{
|
{
|
||||||
bonus.info1 = buffer[outIt++]; //type
|
bonus.info1 = reader.readUInt8(); //type
|
||||||
//FD - wood+ore
|
//FD - wood+ore
|
||||||
//FE - mercury+sulfur+crystal+gem
|
//FE - mercury+sulfur+crystal+gem
|
||||||
bonus.info2 = read_le_u32(buffer + outIt); outIt += 4; //count
|
bonus.info2 = reader.readUInt32(); //count
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -242,13 +240,13 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const ui8 * buff
|
|||||||
}
|
}
|
||||||
case 2: //reading of players (colors / scenarios ?) player can choose
|
case 2: //reading of players (colors / scenarios ?) player can choose
|
||||||
{
|
{
|
||||||
ui8 numOfBonuses = buffer[outIt++];
|
ui8 numOfBonuses = reader.readUInt8();
|
||||||
for (int g=0; g<numOfBonuses; ++g)
|
for (int g=0; g<numOfBonuses; ++g)
|
||||||
{
|
{
|
||||||
CScenarioTravel::STravelBonus bonus;
|
CScenarioTravel::STravelBonus bonus;
|
||||||
bonus.type = CScenarioTravel::STravelBonus::HEROES_FROM_PREVIOUS_SCENARIO;
|
bonus.type = CScenarioTravel::STravelBonus::HEROES_FROM_PREVIOUS_SCENARIO;
|
||||||
bonus.info1 = buffer[outIt++]; //player color
|
bonus.info1 = reader.readUInt8(); //player color
|
||||||
bonus.info2 = buffer[outIt++]; //from what scenario
|
bonus.info2 = reader.readUInt8(); //from what scenario
|
||||||
|
|
||||||
ret.bonusesToChoose.push_back(bonus);
|
ret.bonusesToChoose.push_back(bonus);
|
||||||
}
|
}
|
||||||
@ -256,13 +254,13 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const ui8 * buff
|
|||||||
}
|
}
|
||||||
case 3: //heroes player can choose between
|
case 3: //heroes player can choose between
|
||||||
{
|
{
|
||||||
ui8 numOfBonuses = buffer[outIt++];
|
ui8 numOfBonuses = reader.readUInt8();
|
||||||
for (int g=0; g<numOfBonuses; ++g)
|
for (int g=0; g<numOfBonuses; ++g)
|
||||||
{
|
{
|
||||||
CScenarioTravel::STravelBonus bonus;
|
CScenarioTravel::STravelBonus bonus;
|
||||||
bonus.type = CScenarioTravel::STravelBonus::HERO;
|
bonus.type = CScenarioTravel::STravelBonus::HERO;
|
||||||
bonus.info1 = buffer[outIt++]; //player color
|
bonus.info1 = reader.readUInt8(); //player color
|
||||||
bonus.info2 = read_le_u16(buffer + outIt); outIt += 2; //hero, FF FF - random
|
bonus.info2 = reader.readUInt16(); //hero, FF FF - random
|
||||||
|
|
||||||
ret.bonusesToChoose.push_back(bonus);
|
ret.bonusesToChoose.push_back(bonus);
|
||||||
}
|
}
|
||||||
@ -360,17 +358,6 @@ bool CScenarioTravel::STravelBonus::isBonusForHero() const
|
|||||||
|| type == SECONDARY_SKILL;
|
|| type == SECONDARY_SKILL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// void CCampaignState::initNewCampaign( const StartInfo &si )
|
|
||||||
// {
|
|
||||||
// assert(si.mode == StartInfo::CAMPAIGN);
|
|
||||||
// campaignName = si.mapname;
|
|
||||||
// currentMap = si.campState->currentMap;
|
|
||||||
//
|
|
||||||
// camp = CCampaignHandler::getCampaign(campaignName);
|
|
||||||
// for (ui8 i = 0; i < camp->mapPieces.size(); i++)
|
|
||||||
// mapsRemaining.push_back(i);
|
|
||||||
// }
|
|
||||||
|
|
||||||
void CCampaignState::setCurrentMapAsConquered( const std::vector<CGHeroInstance*> & heroes )
|
void CCampaignState::setCurrentMapAsConquered( const std::vector<CGHeroInstance*> & heroes )
|
||||||
{
|
{
|
||||||
camp->scenarios[*currentMap].crossoverHeroes = heroes;
|
camp->scenarios[*currentMap].crossoverHeroes = heroes;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
struct StartInfo;
|
struct StartInfo;
|
||||||
class CGHeroInstance;
|
class CGHeroInstance;
|
||||||
|
class CBinaryReader;
|
||||||
|
|
||||||
namespace CampaignVersion
|
namespace CampaignVersion
|
||||||
{
|
{
|
||||||
@ -49,8 +50,8 @@ class DLL_LINKAGE CScenarioTravel
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ui8 whatHeroKeeps; //bitfield [0] - experience, [1] - prim skills, [2] - sec skills, [3] - spells, [4] - artifacts
|
ui8 whatHeroKeeps; //bitfield [0] - experience, [1] - prim skills, [2] - sec skills, [3] - spells, [4] - artifacts
|
||||||
ui8 monstersKeptByHero[19];
|
std::array<ui8, 19> monstersKeptByHero;
|
||||||
ui8 artifsKeptByHero[18];
|
std::array<ui8, 18> artifsKeptByHero;
|
||||||
|
|
||||||
ui8 startOptions; //1 - start bonus, 2 - traveling hero, 3 - hero options
|
ui8 startOptions; //1 - start bonus, 2 - traveling hero, 3 - hero options
|
||||||
|
|
||||||
@ -170,9 +171,9 @@ public:
|
|||||||
|
|
||||||
class DLL_LINKAGE CCampaignHandler
|
class DLL_LINKAGE CCampaignHandler
|
||||||
{
|
{
|
||||||
static CCampaignHeader readHeaderFromMemory( const ui8 *buffer, int & outIt );
|
static CCampaignHeader readHeaderFromMemory(CBinaryReader & reader);
|
||||||
static CCampaignScenario readScenarioFromMemory( const ui8 *buffer, int & outIt, int version, int mapVersion );
|
static CCampaignScenario readScenarioFromMemory(CBinaryReader & reader, int version, int mapVersion );
|
||||||
static CScenarioTravel readScenarioTravelFromMemory( const ui8 * buffer, int & outIt , int version);
|
static CScenarioTravel readScenarioTravelFromMemory(CBinaryReader & reader, int version);
|
||||||
/// returns h3c split in parts. 0 = h3c header, 1-end - maps (binary h3m)
|
/// returns h3c split in parts. 0 = h3c header, 1-end - maps (binary h3m)
|
||||||
/// headerOnly - only header will be decompressed, returned vector wont have any maps
|
/// headerOnly - only header will be decompressed, returned vector wont have any maps
|
||||||
static std::vector< std::vector<ui8> > getFile(const std::string & name, bool headerOnly);
|
static std::vector< std::vector<ui8> > getFile(const std::string & name, bool headerOnly);
|
||||||
|
Loading…
Reference in New Issue
Block a user