mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Refactor campaign regions
This commit is contained in:
parent
e4c147db16
commit
70f4cc5e0f
@ -51,6 +51,7 @@
|
||||
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
|
||||
|
||||
std::shared_ptr<CCampaignState> CBonusSelection::getCampaign()
|
||||
{
|
||||
return CSH->si->campState;
|
||||
@ -61,8 +62,7 @@ CBonusSelection::CBonusSelection()
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
||||
|
||||
loadPositionsOfGraphics();
|
||||
std::string bgName = campDescriptions[getCampaign()->camp->header.mapVersion].campPrefix + "_BG.BMP";
|
||||
std::string bgName = getCampaign()->camp->header.campaignRegions.campPrefix + "_BG.BMP";
|
||||
setBackground(bgName);
|
||||
|
||||
panelBackground = std::make_shared<CPicture>("CAMPBRF.BMP", 456, 6);
|
||||
@ -106,35 +106,9 @@ CBonusSelection::CBonusSelection()
|
||||
for(int g = 0; g < getCampaign()->camp->scenarios.size(); ++g)
|
||||
{
|
||||
if(getCampaign()->camp->conquerable(g))
|
||||
regions.push_back(std::make_shared<CRegion>(g, true, true, campDescriptions[getCampaign()->camp->header.mapVersion]));
|
||||
regions.push_back(std::make_shared<CRegion>(g, true, true, getCampaign()->camp->header.campaignRegions));
|
||||
else if(getCampaign()->camp->scenarios[g].conquered) //display as striped
|
||||
regions.push_back(std::make_shared<CRegion>(g, false, false, campDescriptions[getCampaign()->camp->header.mapVersion]));
|
||||
}
|
||||
}
|
||||
|
||||
void CBonusSelection::loadPositionsOfGraphics()
|
||||
{
|
||||
const JsonNode config(ResourceID("config/campaign_regions.json"));
|
||||
|
||||
for(const JsonNode & campaign : config["campaign_regions"].Vector())
|
||||
{
|
||||
SCampPositions sc;
|
||||
|
||||
sc.campPrefix = campaign["prefix"].String();
|
||||
sc.colorSuffixLength = static_cast<int>(campaign["color_suffix_length"].Float());
|
||||
|
||||
for(const JsonNode & desc : campaign["desc"].Vector())
|
||||
{
|
||||
SCampPositions::SRegionDesc rd;
|
||||
|
||||
rd.infix = desc["infix"].String();
|
||||
rd.xpos = static_cast<int>(desc["x"].Float());
|
||||
rd.ypos = static_cast<int>(desc["y"].Float());
|
||||
sc.regions.push_back(rd);
|
||||
}
|
||||
|
||||
campDescriptions.push_back(sc);
|
||||
|
||||
regions.push_back(std::make_shared<CRegion>(g, false, false, getCampaign()->camp->header.campaignRegions));
|
||||
}
|
||||
}
|
||||
|
||||
@ -470,7 +444,7 @@ void CBonusSelection::decreaseDifficulty()
|
||||
CSH->setDifficulty(CSH->si->difficulty - 1);
|
||||
}
|
||||
|
||||
CBonusSelection::CRegion::CRegion(int id, bool accessible, bool selectable, const SCampPositions & campDsc)
|
||||
CBonusSelection::CRegion::CRegion(int id, bool accessible, bool selectable, const CampaignRegions & campDsc)
|
||||
: CIntObject(LCLICK | RCLICK), idOfMapAndRegion(id), accessible(accessible), selectable(selectable)
|
||||
{
|
||||
OBJ_CONSTRUCTION;
|
||||
@ -480,7 +454,7 @@ CBonusSelection::CRegion::CRegion(int id, bool accessible, bool selectable, cons
|
||||
{"Re", "Bl", "Br", "Gr", "Or", "Vi", "Te", "Pi"}
|
||||
};
|
||||
|
||||
const SCampPositions::SRegionDesc & desc = campDsc.regions[idOfMapAndRegion];
|
||||
const CampaignRegions::RegionDescription & desc = campDsc.regions[idOfMapAndRegion];
|
||||
pos.x += desc.xpos;
|
||||
pos.y += desc.ypos;
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include "../../lib/mapping/CCampaignHandler.h"
|
||||
#include "../windows/CWindowObject.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
@ -32,21 +33,6 @@ public:
|
||||
std::shared_ptr<CCampaignState> getCampaign();
|
||||
CBonusSelection();
|
||||
|
||||
struct SCampPositions
|
||||
{
|
||||
std::string campPrefix;
|
||||
int colorSuffixLength;
|
||||
|
||||
struct SRegionDesc
|
||||
{
|
||||
std::string infix;
|
||||
int xpos, ypos;
|
||||
};
|
||||
|
||||
std::vector<SRegionDesc> regions;
|
||||
|
||||
};
|
||||
|
||||
class CRegion
|
||||
: public CIntObject
|
||||
{
|
||||
@ -57,13 +43,12 @@ public:
|
||||
bool accessible; // false if region should be striped
|
||||
bool selectable; // true if region should be selectable
|
||||
public:
|
||||
CRegion(int id, bool accessible, bool selectable, const SCampPositions & campDsc);
|
||||
CRegion(int id, bool accessible, bool selectable, const CampaignRegions & campDsc);
|
||||
void updateState();
|
||||
void clickLeft(tribool down, bool previousState) override;
|
||||
void clickRight(tribool down, bool previousState) override;
|
||||
};
|
||||
|
||||
void loadPositionsOfGraphics();
|
||||
void createBonusesIcons();
|
||||
void updateAfterStateChange();
|
||||
|
||||
@ -84,7 +69,6 @@ public:
|
||||
std::shared_ptr<CLabel> mapName;
|
||||
std::shared_ptr<CLabel> labelMapDescription;
|
||||
std::shared_ptr<CTextBox> mapDescription;
|
||||
std::vector<SCampPositions> campDescriptions;
|
||||
std::vector<std::shared_ptr<CRegion>> regions;
|
||||
std::shared_ptr<CFlagBox> flagbox;
|
||||
|
||||
|
@ -100,8 +100,8 @@ bool mapSorter::operator()(const std::shared_ptr<CMapInfo> aaa, const std::share
|
||||
switch(sortBy)
|
||||
{
|
||||
case _numOfMaps: //by number of maps in campaign
|
||||
return CGI->generaltexth->getCampaignLength(aaa->campaignHeader->mapVersion) <
|
||||
CGI->generaltexth->getCampaignLength(bbb->campaignHeader->mapVersion);
|
||||
return aaa->campaignHeader->numberOfScenarios <
|
||||
bbb->campaignHeader->numberOfScenarios;
|
||||
break;
|
||||
case _name: //by name
|
||||
return boost::ilexicographical_compare(aaa->campaignHeader->name, bbb->campaignHeader->name);
|
||||
@ -665,7 +665,7 @@ void SelectionTab::ListItem::updateItem(std::shared_ptr<CMapInfo> info, bool sel
|
||||
iconLossCondition->disable();
|
||||
labelNumberOfCampaignMaps->enable();
|
||||
std::ostringstream ostr(std::ostringstream::out);
|
||||
ostr << CGI->generaltexth->getCampaignLength(info->campaignHeader->mapVersion);
|
||||
ostr << info->campaignHeader->numberOfScenarios;
|
||||
labelNumberOfCampaignMaps->setText(ostr.str());
|
||||
labelNumberOfCampaignMaps->setColor(color);
|
||||
}
|
||||
|
@ -36,12 +36,53 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
CampaignRegions::RegionDescription CampaignRegions::RegionDescription::fromJson(const JsonNode & node)
|
||||
{
|
||||
CampaignRegions::RegionDescription rd;
|
||||
rd.infix = node["infix"].String();
|
||||
rd.xpos = static_cast<int>(node["x"].Float());
|
||||
rd.ypos = static_cast<int>(node["y"].Float());
|
||||
return rd;
|
||||
}
|
||||
|
||||
CampaignRegions CampaignRegions::fromJson(const JsonNode & node)
|
||||
{
|
||||
CampaignRegions cr;
|
||||
cr.campPrefix = node["prefix"].String();
|
||||
cr.colorSuffixLength = static_cast<int>(node["color_suffix_length"].Float());
|
||||
|
||||
for(const JsonNode & desc : node["desc"].Vector())
|
||||
cr.regions.push_back(CampaignRegions::RegionDescription::fromJson(desc));
|
||||
|
||||
return cr;
|
||||
}
|
||||
|
||||
CampaignRegions CampaignRegions::getLegacy(int campId)
|
||||
{
|
||||
static std::vector<CampaignRegions> campDescriptions;
|
||||
if(campDescriptions.empty()) //read once
|
||||
{
|
||||
const JsonNode config(ResourceID("config/campaign_regions.json"));
|
||||
for(const JsonNode & campaign : config["campaign_regions"].Vector())
|
||||
campDescriptions.push_back(CampaignRegions::fromJson(campaign));
|
||||
}
|
||||
|
||||
return campDescriptions.at(campId);
|
||||
}
|
||||
|
||||
|
||||
bool CScenarioTravel::STravelBonus::isBonusForHero() const
|
||||
{
|
||||
return type == SPELL || type == MONSTER || type == ARTIFACT || type == SPELL_SCROLL || type == PRIMARY_SKILL
|
||||
|| type == SECONDARY_SKILL;
|
||||
}
|
||||
|
||||
void CCampaignHeader::loadLegacyData(ui8 campId)
|
||||
{
|
||||
campaignRegions = CampaignRegions::getLegacy(campId);
|
||||
numberOfScenarios = VLC->generaltexth->getCampaignLength(campId);
|
||||
}
|
||||
|
||||
CCampaignHeader CCampaignHandler::getHeader( const std::string & name)
|
||||
{
|
||||
ResourceID resourceID(name, EResType::CAMPAIGN);
|
||||
@ -86,10 +127,10 @@ std::unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & na
|
||||
CBinaryReader reader(&stream);
|
||||
ret->header = readHeaderFromMemory(reader, resourceID.getName(), modName, encoding);
|
||||
|
||||
int howManyScenarios = static_cast<int>(VLC->generaltexth->getCampaignLength(ret->header.mapVersion));
|
||||
for(int g=0; g<howManyScenarios; ++g)
|
||||
int howManyScenarios = ret->header.numberOfScenarios;
|
||||
for(int g = 0; g < howManyScenarios; ++g)
|
||||
{
|
||||
CCampaignScenario sc = readScenarioFromMemory(reader, resourceID.getName(), modName, encoding, ret->header.version, ret->header.mapVersion);
|
||||
CCampaignScenario sc = readScenarioFromMemory(reader, ret->header);
|
||||
ret->scenarios.push_back(sc);
|
||||
}
|
||||
|
||||
@ -126,7 +167,7 @@ std::unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & na
|
||||
|
||||
for(auto & scenario : jsonCampaign["scenarios"].Vector())
|
||||
{
|
||||
CCampaignScenario sc = readScenarioFromJson(scenario, resourceID.getName(), modName, encoding, ret->header.version, ret->header.mapVersion);
|
||||
CCampaignScenario sc = readScenarioFromJson(scenario);
|
||||
if(sc.isNotVoid())
|
||||
{
|
||||
CMapService mapService;
|
||||
@ -180,7 +221,7 @@ std::string CCampaignHandler::readLocalizedString(CBinaryReader & reader, std::s
|
||||
return VLC->generaltexth->translate(stringID.get());
|
||||
}
|
||||
|
||||
CCampaignHeader CCampaignHandler::readHeaderFromJson(JsonNode & reader, std::string filename, std::string modName, std::string encoding )
|
||||
CCampaignHeader CCampaignHandler::readHeaderFromJson(JsonNode & reader, std::string filename, std::string modName, std::string encoding)
|
||||
{
|
||||
CCampaignHeader ret;
|
||||
|
||||
@ -192,7 +233,8 @@ CCampaignHeader CCampaignHandler::readHeaderFromJson(JsonNode & reader, std::str
|
||||
}
|
||||
|
||||
ret.version = CampaignVersion::VCMI;
|
||||
ret.mapVersion = reader["campaignId"].Integer();
|
||||
ret.campaignRegions = CampaignRegions::fromJson(reader["regions"]);
|
||||
ret.numberOfScenarios = reader["scenarios"].Vector().size();
|
||||
ret.name = reader["name"].String();
|
||||
ret.description = reader["description"].String();
|
||||
ret.difficultyChoosenByPlayer = reader["allowDifficultySelection"].Bool();
|
||||
@ -204,7 +246,7 @@ CCampaignHeader CCampaignHandler::readHeaderFromJson(JsonNode & reader, std::str
|
||||
return ret;
|
||||
}
|
||||
|
||||
CCampaignScenario CCampaignHandler::readScenarioFromJson(JsonNode & reader, std::string filename, std::string modName, std::string encoding, int version, int mapVersion)
|
||||
CCampaignScenario CCampaignHandler::readScenarioFromJson(JsonNode & reader)
|
||||
{
|
||||
auto prologEpilogReader = [](JsonNode & identifier) -> CCampaignScenario::SScenarioPrologEpilog
|
||||
{
|
||||
@ -231,12 +273,12 @@ CCampaignScenario CCampaignHandler::readScenarioFromJson(JsonNode & reader, std:
|
||||
ret.prolog = prologEpilogReader(reader["prolog"]);
|
||||
ret.epilog = prologEpilogReader(reader["epilog"]);
|
||||
|
||||
ret.travelOptions = readScenarioTravelFromJson(reader, version);
|
||||
ret.travelOptions = readScenarioTravelFromJson(reader);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
CScenarioTravel CCampaignHandler::readScenarioTravelFromJson(JsonNode & reader, int version )
|
||||
CScenarioTravel CCampaignHandler::readScenarioTravelFromJson(JsonNode & reader)
|
||||
{
|
||||
CScenarioTravel ret;
|
||||
|
||||
@ -442,7 +484,8 @@ CCampaignHeader CCampaignHandler::readHeaderFromMemory( CBinaryReader & reader,
|
||||
CCampaignHeader ret;
|
||||
|
||||
ret.version = reader.readUInt32();
|
||||
ret.mapVersion = reader.readUInt8() - 1;//change range of it from [1, 20] to [0, 19]
|
||||
ui8 campId = reader.readUInt8() - 1;//change range of it from [1, 20] to [0, 19]
|
||||
ret.loadLegacyData(campId);
|
||||
ret.name = readLocalizedString(reader, filename, modName, encoding, "name");
|
||||
ret.description = readLocalizedString(reader, filename, modName, encoding, "description");
|
||||
if (ret.version > CampaignVersion::RoE)
|
||||
@ -457,7 +500,7 @@ CCampaignHeader CCampaignHandler::readHeaderFromMemory( CBinaryReader & reader,
|
||||
return ret;
|
||||
}
|
||||
|
||||
CCampaignScenario CCampaignHandler::readScenarioFromMemory( CBinaryReader & reader, std::string filename, std::string modName, std::string encoding, int version, int mapVersion )
|
||||
CCampaignScenario CCampaignHandler::readScenarioFromMemory( CBinaryReader & reader, const CCampaignHeader & header)
|
||||
{
|
||||
auto prologEpilogReader = [&](const std::string & identifier) -> CCampaignScenario::SScenarioPrologEpilog
|
||||
{
|
||||
@ -467,7 +510,7 @@ CCampaignScenario CCampaignHandler::readScenarioFromMemory( CBinaryReader & read
|
||||
{
|
||||
ret.prologVideo = reader.readUInt8();
|
||||
ret.prologMusic = reader.readUInt8();
|
||||
ret.prologText = readLocalizedString(reader, filename, modName, encoding, identifier);
|
||||
ret.prologText = readLocalizedString(reader, header.filename, header.modName, header.encoding, identifier);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
@ -476,7 +519,7 @@ CCampaignScenario CCampaignHandler::readScenarioFromMemory( CBinaryReader & read
|
||||
ret.conquered = false;
|
||||
ret.mapName = reader.readBaseString();
|
||||
ret.packedMapSize = reader.readUInt32();
|
||||
if(mapVersion == 18)//unholy alliance
|
||||
if(header.numberOfScenarios > 0) //unholy alliance
|
||||
{
|
||||
ret.loadPreconditionRegions(reader.readUInt16());
|
||||
}
|
||||
@ -486,11 +529,11 @@ CCampaignScenario CCampaignHandler::readScenarioFromMemory( CBinaryReader & read
|
||||
}
|
||||
ret.regionColor = reader.readUInt8();
|
||||
ret.difficulty = reader.readUInt8();
|
||||
ret.regionText = readLocalizedString(reader, filename, modName, encoding, ret.mapName + ".region");
|
||||
ret.regionText = readLocalizedString(reader, header.filename, header.modName, header.encoding, ret.mapName + ".region");
|
||||
ret.prolog = prologEpilogReader(ret.mapName + ".prolog");
|
||||
ret.epilog = prologEpilogReader(ret.mapName + ".epilog");
|
||||
|
||||
ret.travelOptions = readScenarioTravelFromMemory(reader, version);
|
||||
ret.travelOptions = readScenarioTravelFromMemory(reader, header.version);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -37,11 +37,45 @@ namespace CampaignVersion
|
||||
const int VCMI_MAX = 1;
|
||||
}
|
||||
|
||||
struct DLL_LINKAGE CampaignRegions
|
||||
{
|
||||
std::string campPrefix;
|
||||
int colorSuffixLength;
|
||||
|
||||
struct DLL_LINKAGE RegionDescription
|
||||
{
|
||||
std::string infix;
|
||||
int xpos, ypos;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int formatVersion)
|
||||
{
|
||||
h & infix;
|
||||
h & xpos;
|
||||
h & ypos;
|
||||
}
|
||||
|
||||
static CampaignRegions::RegionDescription fromJson(const JsonNode & node);
|
||||
};
|
||||
|
||||
std::vector<RegionDescription> regions;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int formatVersion)
|
||||
{
|
||||
h & campPrefix;
|
||||
h & colorSuffixLength;
|
||||
h & regions;
|
||||
}
|
||||
|
||||
static CampaignRegions fromJson(const JsonNode & node);
|
||||
static CampaignRegions getLegacy(int campId);
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CCampaignHeader
|
||||
{
|
||||
public:
|
||||
si32 version = 0; //4 - RoE, 5 - AB, 6 - SoD and WoG
|
||||
ui8 mapVersion = 0; //CampText.txt's format
|
||||
CampaignRegions campaignRegions;
|
||||
int numberOfScenarios = 0;
|
||||
std::string name, description;
|
||||
ui8 difficultyChoosenByPlayer = 0;
|
||||
ui8 music = 0; //CmpMusic.txt, start from 0, field is unused in vcmi
|
||||
@ -50,15 +84,28 @@ public:
|
||||
std::string filename;
|
||||
std::string modName;
|
||||
std::string encoding;
|
||||
|
||||
void loadLegacyData(ui8 campId);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int formatVersion)
|
||||
{
|
||||
h & version;
|
||||
h & mapVersion;
|
||||
if(!h.saving && formatVersion < 821)
|
||||
{
|
||||
ui8 campId = 0; //legacy field
|
||||
h & campId;
|
||||
loadLegacyData(campId);
|
||||
}
|
||||
else
|
||||
{
|
||||
h & campaignRegions;
|
||||
h & numberOfScenarios;
|
||||
}
|
||||
h & name;
|
||||
h & description;
|
||||
h & difficultyChoosenByPlayer;
|
||||
h & music;
|
||||
if(formatVersion < 821)
|
||||
h & music; //deprecated
|
||||
h & filename;
|
||||
h & modName;
|
||||
h & encoding;
|
||||
@ -223,18 +270,16 @@ public:
|
||||
|
||||
class DLL_LINKAGE CCampaignHandler
|
||||
{
|
||||
std::vector<size_t> scenariosCountPerCampaign;
|
||||
|
||||
static std::string readLocalizedString(CBinaryReader & reader, std::string filename, std::string modName, std::string encoding, std::string identifier);
|
||||
|
||||
//parsers for VCMI campaigns (*.vcmp)
|
||||
static CCampaignHeader readHeaderFromJson(JsonNode & reader, std::string filename, std::string modName, std::string encoding);
|
||||
static CCampaignScenario readScenarioFromJson(JsonNode & reader, std::string filename, std::string modName, std::string encoding, int version, int mapVersion );
|
||||
static CScenarioTravel readScenarioTravelFromJson(JsonNode & reader, int version);
|
||||
static CCampaignScenario readScenarioFromJson(JsonNode & reader);
|
||||
static CScenarioTravel readScenarioTravelFromJson(JsonNode & reader);
|
||||
|
||||
//parsers for original H3C campaigns
|
||||
static CCampaignHeader readHeaderFromMemory(CBinaryReader & reader, std::string filename, std::string modName, std::string encoding);
|
||||
static CCampaignScenario readScenarioFromMemory(CBinaryReader & reader, std::string filename, std::string modName, std::string encoding, int version, int mapVersion );
|
||||
static CCampaignScenario readScenarioFromMemory(CBinaryReader & reader, const CCampaignHeader & header);
|
||||
static CScenarioTravel readScenarioTravelFromMemory(CBinaryReader & reader, int version);
|
||||
/// 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
|
||||
|
Loading…
Reference in New Issue
Block a user