mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-25 22:42:04 +02:00
Improvements to type safety of Identifier class
- Constructor of Identifier from integer is now explicit - Lobby hero/town selection now uses Identifiers instead of int's - Removed serialization workaround for hero portraits - Added dummy objects for custom heroes portraits for ID resolver to use - HeroInstance now stores portrait ID only in case of custom portrait - Fixed loading of campaign heroes portraits on RoE maps
This commit is contained in:
@@ -729,7 +729,7 @@ void CVCMIServer::updateStartInfoOnMapChange(std::shared_ptr<CMapInfo> mapInfo,
|
||||
pset.castle = pinfo.defaultCastle();
|
||||
pset.hero = pinfo.defaultHero();
|
||||
|
||||
if(pset.hero.getNum() != PlayerSettings::RANDOM && pinfo.hasCustomMainHero())
|
||||
if(pset.hero != HeroTypeID::RANDOM && pinfo.hasCustomMainHero())
|
||||
{
|
||||
pset.hero = pinfo.mainCustomHeroId;
|
||||
pset.heroNameTextId = pinfo.mainCustomHeroNameTextId;
|
||||
@@ -839,13 +839,13 @@ void CVCMIServer::optionNextCastle(PlayerColor player, int dir)
|
||||
{
|
||||
PlayerSettings & s = si->playerInfos[player];
|
||||
FactionID & cur = s.castle;
|
||||
auto & allowed = getPlayerInfo(player.getNum()).allowedFactions;
|
||||
const bool allowRandomTown = getPlayerInfo(player.getNum()).isFactionRandom;
|
||||
auto & allowed = getPlayerInfo(player).allowedFactions;
|
||||
const bool allowRandomTown = getPlayerInfo(player).isFactionRandom;
|
||||
|
||||
if(cur.getNum() == PlayerSettings::NONE) //no change
|
||||
if(cur == FactionID::NONE) //no change
|
||||
return;
|
||||
|
||||
if(cur.getNum() == PlayerSettings::RANDOM) //first/last available
|
||||
if(cur == FactionID::RANDOM) //first/last available
|
||||
{
|
||||
if(dir > 0)
|
||||
cur = *allowed.begin(); //id of first town
|
||||
@@ -859,7 +859,7 @@ void CVCMIServer::optionNextCastle(PlayerColor player, int dir)
|
||||
{
|
||||
if(allowRandomTown)
|
||||
{
|
||||
cur = PlayerSettings::RANDOM;
|
||||
cur = FactionID::RANDOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -878,34 +878,34 @@ void CVCMIServer::optionNextCastle(PlayerColor player, int dir)
|
||||
}
|
||||
}
|
||||
|
||||
if(s.hero.getNum() >= 0 && !getPlayerInfo(player.getNum()).hasCustomMainHero()) // remove hero unless it set to fixed one in map editor
|
||||
if(s.hero.isValid() && !getPlayerInfo(player).hasCustomMainHero()) // remove hero unless it set to fixed one in map editor
|
||||
{
|
||||
s.hero = PlayerSettings::RANDOM;
|
||||
s.hero = HeroTypeID::RANDOM;
|
||||
}
|
||||
if(cur.getNum() < 0 && s.bonus == PlayerSettings::RESOURCE)
|
||||
s.bonus = PlayerSettings::RANDOM;
|
||||
if(!cur.isValid() && s.bonus == PlayerStartingBonus::RESOURCE)
|
||||
s.bonus = PlayerStartingBonus::RANDOM;
|
||||
}
|
||||
|
||||
void CVCMIServer::optionSetCastle(PlayerColor player, int id)
|
||||
void CVCMIServer::optionSetCastle(PlayerColor player, FactionID id)
|
||||
{
|
||||
PlayerSettings & s = si->playerInfos[player];
|
||||
FactionID & cur = s.castle;
|
||||
auto & allowed = getPlayerInfo(player.getNum()).allowedFactions;
|
||||
auto & allowed = getPlayerInfo(player).allowedFactions;
|
||||
|
||||
if(cur.getNum() == PlayerSettings::NONE) //no change
|
||||
if(cur == FactionID::NONE) //no change
|
||||
return;
|
||||
|
||||
if(allowed.find(static_cast<FactionID>(id)) == allowed.end() && id != PlayerSettings::RANDOM) // valid id
|
||||
if(allowed.find(id) == allowed.end() && id != FactionID::RANDOM) // valid id
|
||||
return;
|
||||
|
||||
cur = static_cast<FactionID>(id);
|
||||
|
||||
if(s.hero.getNum() >= 0 && !getPlayerInfo(player.getNum()).hasCustomMainHero()) // remove hero unless it set to fixed one in map editor
|
||||
if(s.hero.isValid() && !getPlayerInfo(player).hasCustomMainHero()) // remove hero unless it set to fixed one in map editor
|
||||
{
|
||||
s.hero = PlayerSettings::RANDOM;
|
||||
s.hero = HeroTypeID::RANDOM;
|
||||
}
|
||||
if(cur.getNum() < 0 && s.bonus == PlayerSettings::RESOURCE)
|
||||
s.bonus = PlayerSettings::RANDOM;
|
||||
if(!cur.isValid() && s.bonus == PlayerStartingBonus::RESOURCE)
|
||||
s.bonus = PlayerStartingBonus::RANDOM;
|
||||
}
|
||||
|
||||
void CVCMIServer::setCampaignMap(CampaignScenarioID mapId)
|
||||
@@ -937,105 +937,105 @@ void CVCMIServer::setCampaignBonus(int bonusId)
|
||||
void CVCMIServer::optionNextHero(PlayerColor player, int dir)
|
||||
{
|
||||
PlayerSettings & s = si->playerInfos[player];
|
||||
if(s.castle.getNum() < 0 || s.hero.getNum() == PlayerSettings::NONE)
|
||||
if(!s.castle.isValid() || s.hero == HeroTypeID::NONE)
|
||||
return;
|
||||
|
||||
if(s.hero.getNum() == PlayerSettings::RANDOM) // first/last available
|
||||
if(s.hero == HeroTypeID::RANDOM) // first/last available
|
||||
{
|
||||
int max = static_cast<int>(VLC->heroh->size()),
|
||||
min = 0;
|
||||
s.hero = nextAllowedHero(player, min, max, 0, dir);
|
||||
if (dir > 0)
|
||||
s.hero = nextAllowedHero(player, HeroTypeID(-1), dir);
|
||||
else
|
||||
s.hero = nextAllowedHero(player, HeroTypeID(VLC->heroh->size()), dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dir > 0)
|
||||
s.hero = nextAllowedHero(player, s.hero, (int)VLC->heroh->size(), 1, dir);
|
||||
else
|
||||
s.hero = nextAllowedHero(player, -1, s.hero, 1, dir); // min needs to be -1 -- hero at index 0 would be skipped otherwise
|
||||
s.hero = nextAllowedHero(player, s.hero, dir);
|
||||
}
|
||||
}
|
||||
|
||||
void CVCMIServer::optionSetHero(PlayerColor player, int id)
|
||||
void CVCMIServer::optionSetHero(PlayerColor player, HeroTypeID id)
|
||||
{
|
||||
PlayerSettings & s = si->playerInfos[player];
|
||||
if(s.castle.getNum() < 0 || s.hero.getNum() == PlayerSettings::NONE)
|
||||
if(!s.castle.isValid() || s.hero == HeroTypeID::NONE)
|
||||
return;
|
||||
|
||||
if(id == PlayerSettings::RANDOM)
|
||||
if(id == HeroTypeID::RANDOM)
|
||||
{
|
||||
s.hero = PlayerSettings::RANDOM;
|
||||
s.hero = HeroTypeID::RANDOM;
|
||||
}
|
||||
if(canUseThisHero(player, id))
|
||||
s.hero = static_cast<HeroTypeID>(id);
|
||||
}
|
||||
|
||||
HeroTypeID CVCMIServer::nextAllowedHero(PlayerColor player, int min, int max, int incl, int dir)
|
||||
HeroTypeID CVCMIServer::nextAllowedHero(PlayerColor player, HeroTypeID initial, int direction)
|
||||
{
|
||||
if(dir > 0)
|
||||
HeroTypeID first(initial.getNum() + direction);
|
||||
|
||||
if(direction > 0)
|
||||
{
|
||||
for(int i = min + incl; i <= max - incl; i++)
|
||||
for (auto i = first; i.getNum() < VLC->heroh->size(); ++i)
|
||||
if(canUseThisHero(player, i))
|
||||
return HeroTypeID(i);
|
||||
return i;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = max - incl; i >= min + incl; i--)
|
||||
for (auto i = first; i.getNum() >= 0; --i)
|
||||
if(canUseThisHero(player, i))
|
||||
return HeroTypeID(i);
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
return HeroTypeID::RANDOM;
|
||||
}
|
||||
|
||||
void CVCMIServer::optionNextBonus(PlayerColor player, int dir)
|
||||
{
|
||||
PlayerSettings & s = si->playerInfos[player];
|
||||
PlayerSettings::Ebonus & ret = s.bonus = static_cast<PlayerSettings::Ebonus>(static_cast<int>(s.bonus) + dir);
|
||||
PlayerStartingBonus & ret = s.bonus = static_cast<PlayerStartingBonus>(static_cast<int>(s.bonus) + dir);
|
||||
|
||||
if(s.hero.getNum() == PlayerSettings::NONE &&
|
||||
!getPlayerInfo(player.getNum()).heroesNames.size() &&
|
||||
ret == PlayerSettings::ARTIFACT) //no hero - can't be artifact
|
||||
if(s.hero == HeroTypeID::NONE &&
|
||||
!getPlayerInfo(player).heroesNames.size() &&
|
||||
ret == PlayerStartingBonus::ARTIFACT) //no hero - can't be artifact
|
||||
{
|
||||
if(dir < 0)
|
||||
ret = PlayerSettings::RANDOM;
|
||||
ret = PlayerStartingBonus::RANDOM;
|
||||
else
|
||||
ret = PlayerSettings::GOLD;
|
||||
ret = PlayerStartingBonus::GOLD;
|
||||
}
|
||||
|
||||
if(ret > PlayerSettings::RESOURCE)
|
||||
ret = PlayerSettings::RANDOM;
|
||||
if(ret < PlayerSettings::RANDOM)
|
||||
ret = PlayerSettings::RESOURCE;
|
||||
if(ret > PlayerStartingBonus::RESOURCE)
|
||||
ret = PlayerStartingBonus::RANDOM;
|
||||
if(ret < PlayerStartingBonus::RANDOM)
|
||||
ret = PlayerStartingBonus::RESOURCE;
|
||||
|
||||
if(s.castle.getNum() == PlayerSettings::RANDOM && ret == PlayerSettings::RESOURCE) //random castle - can't be resource
|
||||
if(s.castle == FactionID::RANDOM && ret == PlayerStartingBonus::RESOURCE) //random castle - can't be resource
|
||||
{
|
||||
if(dir < 0)
|
||||
ret = PlayerSettings::GOLD;
|
||||
ret = PlayerStartingBonus::GOLD;
|
||||
else
|
||||
ret = PlayerSettings::RANDOM;
|
||||
ret = PlayerStartingBonus::RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
void CVCMIServer::optionSetBonus(PlayerColor player, int id)
|
||||
void CVCMIServer::optionSetBonus(PlayerColor player, PlayerStartingBonus id)
|
||||
{
|
||||
PlayerSettings & s = si->playerInfos[player];
|
||||
|
||||
if(s.hero.getNum() == PlayerSettings::NONE &&
|
||||
!getPlayerInfo(player.getNum()).heroesNames.size() &&
|
||||
id == PlayerSettings::ARTIFACT) //no hero - can't be artifact
|
||||
if(s.hero == HeroTypeID::NONE &&
|
||||
!getPlayerInfo(player).heroesNames.size() &&
|
||||
id == PlayerStartingBonus::ARTIFACT) //no hero - can't be artifact
|
||||
return;
|
||||
|
||||
if(id > PlayerSettings::RESOURCE)
|
||||
if(id > PlayerStartingBonus::RESOURCE)
|
||||
return;
|
||||
if(id < PlayerSettings::RANDOM)
|
||||
if(id < PlayerStartingBonus::RANDOM)
|
||||
return;
|
||||
|
||||
if(s.castle.getNum() == PlayerSettings::RANDOM && id == PlayerSettings::RESOURCE) //random castle - can't be resource
|
||||
if(s.castle == FactionID::RANDOM && id == PlayerStartingBonus::RESOURCE) //random castle - can't be resource
|
||||
return;
|
||||
|
||||
s.bonus = static_cast<PlayerSettings::Ebonus>(static_cast<int>(id));
|
||||
s.bonus = id;;
|
||||
}
|
||||
|
||||
bool CVCMIServer::canUseThisHero(PlayerColor player, int ID)
|
||||
bool CVCMIServer::canUseThisHero(PlayerColor player, HeroTypeID ID)
|
||||
{
|
||||
return VLC->heroh->size() > ID
|
||||
&& si->playerInfos[player].castle == VLC->heroh->objects[ID]->heroClass->faction
|
||||
@@ -1043,17 +1043,17 @@ bool CVCMIServer::canUseThisHero(PlayerColor player, int ID)
|
||||
&& mi->mapHeader->allowedHeroes[ID];
|
||||
}
|
||||
|
||||
std::vector<int> CVCMIServer::getUsedHeroes()
|
||||
std::vector<HeroTypeID> CVCMIServer::getUsedHeroes()
|
||||
{
|
||||
std::vector<int> heroIds;
|
||||
std::vector<HeroTypeID> heroIds;
|
||||
for(auto & p : si->playerInfos)
|
||||
{
|
||||
const auto & heroes = getPlayerInfo(p.first.getNum()).heroesNames;
|
||||
const auto & heroes = getPlayerInfo(p.first).heroesNames;
|
||||
for(auto & hero : heroes)
|
||||
if(hero.heroId >= 0) //in VCMI map format heroId = -1 means random hero
|
||||
heroIds.push_back(hero.heroId);
|
||||
|
||||
if(p.second.hero.getNum() != PlayerSettings::RANDOM)
|
||||
if(p.second.hero != HeroTypeID::RANDOM)
|
||||
heroIds.push_back(p.second.hero);
|
||||
}
|
||||
return heroIds;
|
||||
|
||||
Reference in New Issue
Block a user