mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-15 01:24:45 +02:00
Further refactoring
This commit is contained in:
@ -1266,7 +1266,7 @@ void CGameState::prepareCrossoverHeroes(std::vector<CGameState::CampaignHeroRepl
|
|||||||
|
|
||||||
// TODO replace magic numbers with named constants
|
// TODO replace magic numbers with named constants
|
||||||
// TODO this logic (what should be kept) should be part of CScenarioTravel and be exposed via some clean set of methods
|
// TODO this logic (what should be kept) should be part of CScenarioTravel and be exposed via some clean set of methods
|
||||||
if(!(travelOptions.whatHeroKeeps & 1))
|
if(!travelOptions.whatHeroKeeps.experience)
|
||||||
{
|
{
|
||||||
//trimming experience
|
//trimming experience
|
||||||
for(CGHeroInstance * cgh : crossoverHeroes)
|
for(CGHeroInstance * cgh : crossoverHeroes)
|
||||||
@ -1275,7 +1275,7 @@ void CGameState::prepareCrossoverHeroes(std::vector<CGameState::CampaignHeroRepl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(travelOptions.whatHeroKeeps & 2))
|
if(!travelOptions.whatHeroKeeps.primarySkills)
|
||||||
{
|
{
|
||||||
//trimming prim skills
|
//trimming prim skills
|
||||||
for(CGHeroInstance * cgh : crossoverHeroes)
|
for(CGHeroInstance * cgh : crossoverHeroes)
|
||||||
@ -1291,7 +1291,7 @@ void CGameState::prepareCrossoverHeroes(std::vector<CGameState::CampaignHeroRepl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(travelOptions.whatHeroKeeps & 4))
|
if(!travelOptions.whatHeroKeeps.secondarySkills)
|
||||||
{
|
{
|
||||||
//trimming sec skills
|
//trimming sec skills
|
||||||
for(CGHeroInstance * cgh : crossoverHeroes)
|
for(CGHeroInstance * cgh : crossoverHeroes)
|
||||||
@ -1301,7 +1301,7 @@ void CGameState::prepareCrossoverHeroes(std::vector<CGameState::CampaignHeroRepl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(travelOptions.whatHeroKeeps & 8))
|
if(!travelOptions.whatHeroKeeps.spells)
|
||||||
{
|
{
|
||||||
for(CGHeroInstance * cgh : crossoverHeroes)
|
for(CGHeroInstance * cgh : crossoverHeroes)
|
||||||
{
|
{
|
||||||
@ -1309,7 +1309,7 @@ void CGameState::prepareCrossoverHeroes(std::vector<CGameState::CampaignHeroRepl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(travelOptions.whatHeroKeeps & 16))
|
if(!travelOptions.whatHeroKeeps.artifacts)
|
||||||
{
|
{
|
||||||
//trimming artifacts
|
//trimming artifacts
|
||||||
for(CGHeroInstance * hero : crossoverHeroes)
|
for(CGHeroInstance * hero : crossoverHeroes)
|
||||||
@ -1329,9 +1329,7 @@ void CGameState::prepareCrossoverHeroes(std::vector<CGameState::CampaignHeroRepl
|
|||||||
if(!art)
|
if(!art)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int id = art->artType->getId();
|
bool takeable = travelOptions.artifactsKeptByHero.count(art->artType->getId());
|
||||||
assert( 8*18 > id );//number of arts that fits into h3m format
|
|
||||||
bool takeable = travelOptions.artifsKeptByHero[id / 8] & ( 1 << (id%8) );
|
|
||||||
|
|
||||||
ArtifactLocation al(hero, artifactPosition);
|
ArtifactLocation al(hero, artifactPosition);
|
||||||
if(!takeable && !al.getSlot()->locked) //don't try removing locked artifacts -> it crashes #1719
|
if(!takeable && !al.getSlot()->locked) //don't try removing locked artifacts -> it crashes #1719
|
||||||
@ -1346,7 +1344,7 @@ void CGameState::prepareCrossoverHeroes(std::vector<CGameState::CampaignHeroRepl
|
|||||||
auto shouldSlotBeErased = [&](const std::pair<SlotID, CStackInstance *> & j) -> bool
|
auto shouldSlotBeErased = [&](const std::pair<SlotID, CStackInstance *> & j) -> bool
|
||||||
{
|
{
|
||||||
CreatureID::ECreatureID crid = j.second->getCreatureID().toEnum();
|
CreatureID::ECreatureID crid = j.second->getCreatureID().toEnum();
|
||||||
return !(travelOptions.monstersKeptByHero[crid / 8] & (1 << (crid % 8)));
|
return !travelOptions.monstersKeptByHero.count(crid);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto stacksCopy = cgh->stacks; //copy of the map, so we can iterate iover it and remove stacks
|
auto stacksCopy = cgh->stacks; //copy of the map, so we can iterate iover it and remove stacks
|
||||||
|
@ -282,13 +282,6 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromJson(JsonNode & reader)
|
|||||||
{
|
{
|
||||||
CScenarioTravel ret;
|
CScenarioTravel ret;
|
||||||
|
|
||||||
std::map<std::string, ui8> heroKeepsMap = {
|
|
||||||
{"experience", 1},
|
|
||||||
{"primarySkill", 2},
|
|
||||||
{"secondarySkill", 4},
|
|
||||||
{"spells", 8},
|
|
||||||
{"artifacts", 16}
|
|
||||||
};
|
|
||||||
std::map<std::string, ui8> startOptionsMap = {
|
std::map<std::string, ui8> startOptionsMap = {
|
||||||
{"none", 0},
|
{"none", 0},
|
||||||
{"bonus", 1},
|
{"bonus", 1},
|
||||||
@ -337,31 +330,25 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromJson(JsonNode & reader)
|
|||||||
};
|
};
|
||||||
|
|
||||||
for(auto & k : reader["heroKeeps"].Vector())
|
for(auto & k : reader["heroKeeps"].Vector())
|
||||||
ret.whatHeroKeeps |= heroKeepsMap[k.String()];
|
{
|
||||||
|
if(k.String() == "experience") ret.whatHeroKeeps.experience = true;
|
||||||
|
if(k.String() == "primarySkills") ret.whatHeroKeeps.primarySkills = true;
|
||||||
|
if(k.String() == "secondarySkills") ret.whatHeroKeeps.secondarySkills = true;
|
||||||
|
if(k.String() == "spells") ret.whatHeroKeeps.spells = true;
|
||||||
|
if(k.String() == "artifacts") ret.whatHeroKeeps.artifacts = true;
|
||||||
|
}
|
||||||
|
|
||||||
for(auto & k : reader["keepCreatures"].Vector())
|
for(auto & k : reader["keepCreatures"].Vector())
|
||||||
{
|
{
|
||||||
if(auto identifier = VLC->modh->identifiers.getIdentifier(CModHandler::scopeMap(), "creature", k.String()))
|
if(auto identifier = VLC->modh->identifiers.getIdentifier(CModHandler::scopeMap(), "creature", k.String()))
|
||||||
{
|
ret.monstersKeptByHero.insert(CreatureID(identifier.get()));
|
||||||
int creId = identifier.get();
|
|
||||||
if(creId >= ret.monstersKeptByHero.size())
|
|
||||||
logGlobal->warn("VCMP Loading: creature %s with id %d isn't supported yet", k.String(), creId);
|
|
||||||
else
|
|
||||||
ret.monstersKeptByHero[creId / 8] |= (1 << creId % 8);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
logGlobal->warn("VCMP Loading: keepCreatures contains unresolved identifier %s", k.String());
|
logGlobal->warn("VCMP Loading: keepCreatures contains unresolved identifier %s", k.String());
|
||||||
}
|
}
|
||||||
for(auto & k : reader["keepArtifacts"].Vector())
|
for(auto & k : reader["keepArtifacts"].Vector())
|
||||||
{
|
{
|
||||||
if(auto identifier = VLC->modh->identifiers.getIdentifier(CModHandler::scopeMap(), "artifact", k.String()))
|
if(auto identifier = VLC->modh->identifiers.getIdentifier(CModHandler::scopeMap(), "artifact", k.String()))
|
||||||
{
|
ret.artifactsKeptByHero.insert(ArtifactID(identifier.get()));
|
||||||
int artId = identifier.get();
|
|
||||||
if(artId >= ret.artifsKeptByHero.size())
|
|
||||||
logGlobal->warn("VCMP Loading: artifact %s with id %d isn't supported yet", k.String(), artId);
|
|
||||||
else
|
|
||||||
ret.artifsKeptByHero[artId / 8] |= (1 << artId % 8);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
logGlobal->warn("VCMP Loading: keepArtifacts contains unresolved identifier %s", k.String());
|
logGlobal->warn("VCMP Loading: keepArtifacts contains unresolved identifier %s", k.String());
|
||||||
}
|
}
|
||||||
@ -491,8 +478,8 @@ CCampaignHeader CCampaignHandler::readHeaderFromMemory( CBinaryReader & reader,
|
|||||||
if (ret.version > CampaignVersion::RoE)
|
if (ret.version > CampaignVersion::RoE)
|
||||||
ret.difficultyChoosenByPlayer = reader.readInt8();
|
ret.difficultyChoosenByPlayer = reader.readInt8();
|
||||||
else
|
else
|
||||||
ret.difficultyChoosenByPlayer = 0;
|
ret.difficultyChoosenByPlayer = false;
|
||||||
ret.music = reader.readInt8();
|
reader.readInt8(); //music - skip as unused
|
||||||
ret.filename = filename;
|
ret.filename = filename;
|
||||||
ret.modName = modName;
|
ret.modName = modName;
|
||||||
ret.encoding = encoding;
|
ret.encoding = encoding;
|
||||||
@ -518,7 +505,7 @@ CCampaignScenario CCampaignHandler::readScenarioFromMemory( CBinaryReader & read
|
|||||||
CCampaignScenario ret;
|
CCampaignScenario ret;
|
||||||
ret.conquered = false;
|
ret.conquered = false;
|
||||||
ret.mapName = reader.readBaseString();
|
ret.mapName = reader.readBaseString();
|
||||||
ret.packedMapSize = reader.readUInt32();
|
reader.readUInt32(); //packedMapSize - not used
|
||||||
if(header.numberOfScenarios > 8) //unholy alliance
|
if(header.numberOfScenarios > 8) //unholy alliance
|
||||||
{
|
{
|
||||||
ret.loadPreconditionRegions(reader.readUInt16());
|
ret.loadPreconditionRegions(reader.readUInt16());
|
||||||
@ -551,18 +538,29 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory(CBinaryReader & r
|
|||||||
{
|
{
|
||||||
CScenarioTravel ret;
|
CScenarioTravel ret;
|
||||||
|
|
||||||
ret.whatHeroKeeps = reader.readUInt8();
|
ui8 whatHeroKeeps = reader.readUInt8();
|
||||||
reader.getStream()->read(ret.monstersKeptByHero.data(), ret.monstersKeptByHero.size());
|
ret.whatHeroKeeps.experience = whatHeroKeeps & 1;
|
||||||
|
ret.whatHeroKeeps.primarySkills = whatHeroKeeps & 2;
|
||||||
if (version < CampaignVersion::SoD)
|
ret.whatHeroKeeps.secondarySkills = whatHeroKeeps & 4;
|
||||||
|
ret.whatHeroKeeps.spells = whatHeroKeeps & 8;
|
||||||
|
ret.whatHeroKeeps.artifacts = whatHeroKeeps & 16;
|
||||||
|
|
||||||
|
auto bitMaskToId = [&reader]<typename T>(std::set<T> & container, int size)
|
||||||
{
|
{
|
||||||
ret.artifsKeptByHero.fill(0);
|
for(int iId = 0, byte = 0; iId < size * 8; ++iId)
|
||||||
reader.getStream()->read(ret.artifsKeptByHero.data(), ret.artifsKeptByHero.size() - 1);
|
{
|
||||||
}
|
if(iId % 8 == 0)
|
||||||
|
byte = reader.readUInt8();
|
||||||
|
if(byte & (1 << iId % 8))
|
||||||
|
container.insert(T(iId));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bitMaskToId(ret.monstersKeptByHero, 19);
|
||||||
|
if(version < CampaignVersion::SoD)
|
||||||
|
bitMaskToId(ret.artifactsKeptByHero, 17);
|
||||||
else
|
else
|
||||||
{
|
bitMaskToId(ret.artifactsKeptByHero, 18);
|
||||||
reader.getStream()->read(ret.artifsKeptByHero.data(), ret.artifsKeptByHero.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.startOptions = reader.readUInt8();
|
ret.startOptions = reader.readUInt8();
|
||||||
|
|
||||||
|
@ -77,8 +77,7 @@ public:
|
|||||||
CampaignRegions campaignRegions;
|
CampaignRegions campaignRegions;
|
||||||
int numberOfScenarios = 0;
|
int numberOfScenarios = 0;
|
||||||
std::string name, description;
|
std::string name, description;
|
||||||
ui8 difficultyChoosenByPlayer = 0;
|
bool difficultyChoosenByPlayer = false;
|
||||||
ui8 music = 0; //CmpMusic.txt, start from 0, field is unused in vcmi
|
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
|
|
||||||
std::string filename;
|
std::string filename;
|
||||||
@ -90,34 +89,44 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler &h, const int formatVersion)
|
template <typename Handler> void serialize(Handler &h, const int formatVersion)
|
||||||
{
|
{
|
||||||
h & version;
|
h & version;
|
||||||
if(!h.saving && formatVersion < 821)
|
h & campaignRegions;
|
||||||
{
|
h & numberOfScenarios;
|
||||||
ui8 campId = 0; //legacy field
|
|
||||||
h & campId;
|
|
||||||
loadLegacyData(campId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
h & campaignRegions;
|
|
||||||
h & numberOfScenarios;
|
|
||||||
}
|
|
||||||
h & name;
|
h & name;
|
||||||
h & description;
|
h & description;
|
||||||
h & difficultyChoosenByPlayer;
|
h & difficultyChoosenByPlayer;
|
||||||
if(formatVersion < 821)
|
|
||||||
h & music; //deprecated
|
|
||||||
h & filename;
|
h & filename;
|
||||||
h & modName;
|
h & modName;
|
||||||
h & encoding;
|
h & encoding;
|
||||||
|
h & valid;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CScenarioTravel
|
class DLL_LINKAGE CScenarioTravel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ui8 whatHeroKeeps = 0; //bitfield [0] - experience, [1] - prim skills, [2] - sec skills, [3] - spells, [4] - artifacts
|
|
||||||
std::array<ui8, 19> monstersKeptByHero;
|
struct DLL_LINKAGE WhatHeroKeeps
|
||||||
std::array<ui8, 18> artifsKeptByHero;
|
{
|
||||||
|
bool experience = false;
|
||||||
|
bool primarySkills = false;
|
||||||
|
bool secondarySkills = false;
|
||||||
|
bool spells = false;
|
||||||
|
bool artifacts = false;
|
||||||
|
|
||||||
|
template <typename Handler> void serialize(Handler &h, const int formatVersion)
|
||||||
|
{
|
||||||
|
h & experience;
|
||||||
|
h & primarySkills;
|
||||||
|
h & secondarySkills;
|
||||||
|
h & spells;
|
||||||
|
h & artifacts;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
WhatHeroKeeps whatHeroKeeps;
|
||||||
|
|
||||||
|
std::set<CreatureID> monstersKeptByHero;
|
||||||
|
std::set<ArtifactID> artifactsKeptByHero;
|
||||||
|
|
||||||
ui8 startOptions = 0; //1 - start bonus, 2 - traveling hero, 3 - hero options
|
ui8 startOptions = 0; //1 - start bonus, 2 - traveling hero, 3 - hero options
|
||||||
|
|
||||||
@ -147,7 +156,7 @@ public:
|
|||||||
{
|
{
|
||||||
h & whatHeroKeeps;
|
h & whatHeroKeeps;
|
||||||
h & monstersKeptByHero;
|
h & monstersKeptByHero;
|
||||||
h & artifsKeptByHero;
|
h & artifactsKeptByHero;
|
||||||
h & startOptions;
|
h & startOptions;
|
||||||
h & playerColor;
|
h & playerColor;
|
||||||
h & bonusesToChoose;
|
h & bonusesToChoose;
|
||||||
@ -176,7 +185,6 @@ public:
|
|||||||
|
|
||||||
std::string mapName; //*.h3m
|
std::string mapName; //*.h3m
|
||||||
std::string scenarioName; //from header. human-readble
|
std::string scenarioName; //from header. human-readble
|
||||||
ui32 packedMapSize = 0; //generally not used
|
|
||||||
std::set<ui8> preconditionRegions; //what we need to conquer to conquer this one (stored as bitfield in h3c)
|
std::set<ui8> preconditionRegions; //what we need to conquer to conquer this one (stored as bitfield in h3c)
|
||||||
ui8 regionColor = 0;
|
ui8 regionColor = 0;
|
||||||
ui8 difficulty = 0;
|
ui8 difficulty = 0;
|
||||||
@ -200,7 +208,6 @@ public:
|
|||||||
{
|
{
|
||||||
h & mapName;
|
h & mapName;
|
||||||
h & scenarioName;
|
h & scenarioName;
|
||||||
h & packedMapSize;
|
|
||||||
h & preconditionRegions;
|
h & preconditionRegions;
|
||||||
h & regionColor;
|
h & regionColor;
|
||||||
h & difficulty;
|
h & difficulty;
|
||||||
|
Reference in New Issue
Block a user