1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-15 20:03:15 +02:00

Load custom campaigns from gzip

This commit is contained in:
nordsoft
2023-04-20 19:22:27 +04:00
parent be6667acf5
commit db33558abc

View File

@@ -90,21 +90,19 @@ CCampaignHeader CCampaignHandler::getHeader( const std::string & name)
std::string language = VLC->modh->getModLanguage(modName); std::string language = VLC->modh->getModLanguage(modName);
std::string encoding = Languages::getLanguageOptions(language).encoding; std::string encoding = Languages::getLanguageOptions(language).encoding;
JsonNode jsonCampaign(resourceID);
if(jsonCampaign.isNull())
{
auto fileStream = CResourceHandler::get(modName)->load(resourceID); auto fileStream = CResourceHandler::get(modName)->load(resourceID);
std::vector<ui8> cmpgn = getFile(std::move(fileStream), true)[0]; std::vector<ui8> cmpgn = getFile(std::move(fileStream), true)[0];
JsonNode jsonCampaign((const char*)cmpgn.data(), cmpgn.size());
if(jsonCampaign.isNull())
{
//legacy OH3 campaign (*.h3c)
CMemoryStream stream(cmpgn.data(), cmpgn.size()); CMemoryStream stream(cmpgn.data(), cmpgn.size());
CBinaryReader reader(&stream); CBinaryReader reader(&stream);
CCampaignHeader ret = readHeaderFromMemory(reader, resourceID.getName(), modName, encoding); return readHeaderFromMemory(reader, resourceID.getName(), modName, encoding);
return ret;
}
else
{
CCampaignHeader ret = readHeaderFromJson(jsonCampaign, resourceID.getName(), modName, encoding);
return ret;
} }
//VCMI (*.vcmp)
return readHeaderFromJson(jsonCampaign, resourceID.getName(), modName, encoding);
} }
std::unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & name ) std::unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & name )
@@ -116,40 +114,39 @@ std::unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & na
auto ret = std::make_unique<CCampaign>(); auto ret = std::make_unique<CCampaign>();
JsonNode jsonCampaign(resourceID);
if(jsonCampaign.isNull())
{
auto fileStream = CResourceHandler::get(modName)->load(resourceID); auto fileStream = CResourceHandler::get(modName)->load(resourceID);
std::vector<std::vector<ui8>> file = getFile(std::move(fileStream), false); std::vector<std::vector<ui8>> files = getFile(std::move(fileStream), false);
CMemoryStream stream(file[0].data(), file[0].size()); JsonNode jsonCampaign((const char*)files[0].data(), files[0].size());
if(jsonCampaign.isNull())
{
CMemoryStream stream(files[0].data(), files[0].size());
CBinaryReader reader(&stream); CBinaryReader reader(&stream);
ret->header = readHeaderFromMemory(reader, resourceID.getName(), modName, encoding); ret->header = readHeaderFromMemory(reader, resourceID.getName(), modName, encoding);
int howManyScenarios = ret->header.numberOfScenarios; for(int g = 0; g < ret->header.numberOfScenarios; ++g)
for(int g = 0; g < howManyScenarios; ++g) ret->scenarios.emplace_back(readScenarioFromMemory(reader, ret->header));
{ }
CCampaignScenario sc = readScenarioFromMemory(reader, ret->header); else
ret->scenarios.push_back(sc); {
ret->header = readHeaderFromJson(jsonCampaign, resourceID.getName(), modName, encoding);
for(auto & scenario : jsonCampaign["scenarios"].Vector())
ret->scenarios.emplace_back(readScenarioFromJson(scenario));
} }
int scenarioID = 0;
//first entry is campaign header. start loop from 1 //first entry is campaign header. start loop from 1
for (int g=1; g<file.size() && scenarioID<howManyScenarios; ++g) for(int scenarioID = 0, g = 1; g < files.size() && scenarioID < ret->header.numberOfScenarios; ++g)
{ {
while(!ret->scenarios[scenarioID].isNotVoid()) //skip void scenarios while(!ret->scenarios[scenarioID].isNotVoid()) //skip void scenarios
{
scenarioID++; scenarioID++;
}
std::string scenarioName = resourceID.getName(); std::string scenarioName = resourceID.getName();
boost::to_lower(scenarioName); boost::to_lower(scenarioName);
scenarioName += ':' + std::to_string(g - 1); scenarioName += ':' + std::to_string(g - 1);
//set map piece appropriately, convert vector to string //set map piece appropriately, convert vector to string
ret->mapPieces[scenarioID].assign(reinterpret_cast< const char* >(file[g].data()), file[g].size()); ret->mapPieces[scenarioID].assign(reinterpret_cast<const char*>(files[g].data()), files[g].size());
CMapService mapService; CMapService mapService;
auto hdr = mapService.loadMapHeader( auto hdr = mapService.loadMapHeader(
reinterpret_cast<const ui8 *>(ret->mapPieces[scenarioID].c_str()), reinterpret_cast<const ui8 *>(ret->mapPieces[scenarioID].c_str()),
@@ -160,23 +157,6 @@ std::unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & na
ret->scenarios[scenarioID].scenarioName = hdr->name; ret->scenarios[scenarioID].scenarioName = hdr->name;
scenarioID++; scenarioID++;
} }
}
else
{
ret->header = readHeaderFromJson(jsonCampaign, resourceID.getName(), modName, encoding);
for(auto & scenario : jsonCampaign["scenarios"].Vector())
{
CCampaignScenario sc = readScenarioFromJson(scenario);
if(sc.isNotVoid())
{
CMapService mapService;
if(auto hdr = mapService.loadMapHeader(ResourceID(sc.mapName, EResType::MAP)))
sc.scenarioName = hdr->name;
}
ret->scenarios.push_back(sc);
}
}
// handle campaign specific discrepancies // handle campaign specific discrepancies
if(resourceID.getName() == "DATA/AB") if(resourceID.getName() == "DATA/AB")
@@ -818,9 +798,6 @@ CMap * CCampaignState::getMap(int scenarioId) const
scenarioId = currentMap.value(); scenarioId = currentMap.value();
CMapService mapService; CMapService mapService;
if(camp->header.version == CampaignVersion::Version::VCMI)
return mapService.loadMap(ResourceID(camp->scenarios.at(scenarioId).mapName, EResType::MAP)).release();
std::string scenarioName = camp->header.filename.substr(0, camp->header.filename.find('.')); std::string scenarioName = camp->header.filename.substr(0, camp->header.filename.find('.'));
boost::to_lower(scenarioName); boost::to_lower(scenarioName);
scenarioName += ':' + std::to_string(scenarioId); scenarioName += ':' + std::to_string(scenarioId);