1 #include "StrategicMapSecretModel.h"
2 #include "Campaign_Types.h"
3 #include "JsonObject.h"
4 #include "JsonUtility.h"
5 #include "SamSiteModel.h"
6 #include <set>
7 #include <stdexcept>
8 #include <utility>
9 
StrategicMapSecretModel(uint8_t sectorID_,bool isSAMSite_,ST::string secretMapIcon_,uint8_t secretLandType_,uint8_t foundLandType_)10 StrategicMapSecretModel::StrategicMapSecretModel(
11 	uint8_t sectorID_, bool isSAMSite_, ST::string secretMapIcon_, uint8_t secretLandType_, uint8_t foundLandType_
12 	) : sectorID(sectorID_), isSAMSite(isSAMSite_),
13 		secretMapIcon(std::move(secretMapIcon_)),
14 		secretLandType(secretLandType_ ), foundLandType(foundLandType_) {}
15 
deserialize(const rapidjson::Value & json,const TraversibilityMap & mapping)16 StrategicMapSecretModel* StrategicMapSecretModel::deserialize(const rapidjson::Value& json, const TraversibilityMap &mapping)
17 {
18 	JsonObjectReader r(json);
19 	auto sector         = JsonUtility::parseSectorID(r.GetString("sector"));
20 	auto landTypeString = r.GetString("secretLandType");
21 	auto secretLandType = mapping.at(landTypeString);
22 
23 	landTypeString = r.GetString("foundLandType");
24 	auto foundLandType = mapping.at(landTypeString);
25 
26 	return new StrategicMapSecretModel(
27 		sector,
28 		r.getOptionalBool("isSAMSite"),
29 		r.getOptionalString("secretMapIcon") ,
30 		secretLandType,
31 		foundLandType
32 	);
33 }
34 
validateData(const std::vector<const StrategicMapSecretModel * > & models,const std::vector<const SamSiteModel * > & samModels)35 void StrategicMapSecretModel::validateData(const std::vector<const StrategicMapSecretModel *>& models, const std::vector<const SamSiteModel*>& samModels)
36 {
37 	std::set<uint8_t> samSiteLocations;
38 	for (auto s : samModels)
39 	{
40 		samSiteLocations.insert(s->sectorId);
41 	}
42 
43 	int countNonSAMSites = 0;
44 	std::set<uint8_t> uniqueSectors;
45 	for (auto m : models)
46 	{
47 		// if it's a SAM site secret, ensure we have the corresponding SAM site
48 		if (m->isSAMSite)
49 		{
50 			if (samSiteLocations.find(m->sectorID) == samSiteLocations.end())
51 			{
52 				ST::string err = ST::format("No SAM site at sector {}", m->sectorID);
53 				throw std::runtime_error(err.to_std_string());
54 			}
55 		}
56 		else
57 		{
58 			countNonSAMSites++;
59 		}
60 
61 		// must not have duplicated keys
62 		if (uniqueSectors.find(m->sectorID) != uniqueSectors.end())
63 		{
64 			ST::string err = ST::format("Sector {} has more than one secret", m->sectorID);
65 			throw std::runtime_error(err.to_std_string());
66 		}
67 		uniqueSectors.insert(m->sectorID);
68 	}
69 
70 	if (countNonSAMSites > 2)
71 	{
72 		// Limitation for now, to maintain vanilla game compatibility.
73 		// If there is a need, we can use something like a bitset to provide more map secret slots in saves.
74 		SLOGW("There are more than 2 map secrets that are not SAM sites. Only the first 2 will be persisted in saves");
75 	}
76 }
77 
getLandType(bool isSecretFound) const78 uint8_t StrategicMapSecretModel::getLandType(bool isSecretFound) const
79 {
80 	return isSecretFound ? foundLandType : secretLandType;
81 }
82