mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-20 20:23:03 +02:00
PlayerState now stores all objects owned by player
This commit is contained in:
parent
0fd9dbf240
commit
a481f07daf
@ -237,7 +237,7 @@ void CGameInfoCallback::getThievesGuildInfo(SThievesGuildInfo & thi, const CGObj
|
||||
if(obj->ID == Obj::TOWN || obj->ID == Obj::TAVERN)
|
||||
{
|
||||
int taverns = 0;
|
||||
for(auto town : gs->players[*getPlayerID()].towns)
|
||||
for(auto town : gs->players[*getPlayerID()].getTowns())
|
||||
{
|
||||
if(town->hasBuilt(BuildingID::TAVERN))
|
||||
taverns++;
|
||||
@ -256,7 +256,7 @@ void CGameInfoCallback::getThievesGuildInfo(SThievesGuildInfo & thi, const CGObj
|
||||
int CGameInfoCallback::howManyTowns(PlayerColor Player) const
|
||||
{
|
||||
ERROR_RET_VAL_IF(!hasAccess(Player), "Access forbidden!", -1);
|
||||
return static_cast<int>(gs->players[Player].towns.size());
|
||||
return static_cast<int>(gs->players[Player].getTowns().size());
|
||||
}
|
||||
|
||||
bool CGameInfoCallback::getTownInfo(const CGObjectInstance * town, InfoAboutTown & dest, const CGObjectInstance * selectedObject) const
|
||||
@ -609,7 +609,7 @@ EBuildingState CGameInfoCallback::canBuildStructure( const CGTownInstance *t, Bu
|
||||
const PlayerState *ps = getPlayerState(t->tempOwner, false);
|
||||
if(ps)
|
||||
{
|
||||
for(const CGTownInstance *town : ps->towns)
|
||||
for(const CGTownInstance *town : ps->getTowns())
|
||||
{
|
||||
if(town->hasBuilt(BuildingID::CAPITOL))
|
||||
{
|
||||
@ -711,9 +711,9 @@ int CGameInfoCallback::getHeroCount( PlayerColor player, bool includeGarrisoned
|
||||
ERROR_RET_VAL_IF(!p, "No such player!", -1);
|
||||
|
||||
if(includeGarrisoned)
|
||||
return static_cast<int>(p->heroes.size());
|
||||
return static_cast<int>(p->getHeroes().size());
|
||||
else
|
||||
for(const auto & elem : p->heroes)
|
||||
for(const auto & elem : p->getHeroes())
|
||||
if(!elem->inTownGarrison)
|
||||
ret++;
|
||||
return ret;
|
||||
@ -757,7 +757,7 @@ std::vector < const CGTownInstance *> CPlayerSpecificInfoCallback::getTownsInfo(
|
||||
auto ret = std::vector < const CGTownInstance *>();
|
||||
for(const auto & i : gs->players)
|
||||
{
|
||||
for(const auto & town : i.second.towns)
|
||||
for(const auto & town : i.second.getTowns())
|
||||
{
|
||||
if(i.first == getPlayerID() || (!onlyOur && isVisible(town, getPlayerID())))
|
||||
{
|
||||
@ -789,7 +789,7 @@ int CPlayerSpecificInfoCallback::getHeroSerial(const CGHeroInstance * hero, bool
|
||||
return -1;
|
||||
|
||||
size_t index = 0;
|
||||
auto & heroes = gs->players[*getPlayerID()].heroes;
|
||||
const auto & heroes = gs->players[*getPlayerID()].getHeroes();
|
||||
|
||||
for (auto & possibleHero : heroes)
|
||||
{
|
||||
@ -835,7 +835,7 @@ std::vector < const CGDwelling * > CPlayerSpecificInfoCallback::getMyDwellings()
|
||||
{
|
||||
ASSERT_IF_CALLED_WITH_PLAYER
|
||||
std::vector < const CGDwelling * > ret;
|
||||
for(CGDwelling * dw : gs->getPlayerState(*getPlayerID())->dwellings)
|
||||
for(const CGDwelling * dw : gs->getPlayerState(*getPlayerID())->getDwellings())
|
||||
{
|
||||
ret.push_back(dw);
|
||||
}
|
||||
@ -867,12 +867,12 @@ const CGHeroInstance* CPlayerSpecificInfoCallback::getHeroBySerial(int serialId,
|
||||
|
||||
if (!includeGarrisoned)
|
||||
{
|
||||
for(ui32 i = 0; i < p->heroes.size() && static_cast<int>(i) <= serialId; i++)
|
||||
if(p->heroes[i]->inTownGarrison)
|
||||
for(ui32 i = 0; i < p->getHeroes().size() && static_cast<int>(i) <= serialId; i++)
|
||||
if(p->getHeroes()[i]->inTownGarrison)
|
||||
serialId++;
|
||||
}
|
||||
ERROR_RET_VAL_IF(serialId < 0 || serialId >= p->heroes.size(), "No player info", nullptr);
|
||||
return p->heroes[serialId];
|
||||
ERROR_RET_VAL_IF(serialId < 0 || serialId >= p->getHeroes().size(), "No player info", nullptr);
|
||||
return p->getHeroes()[serialId];
|
||||
}
|
||||
|
||||
const CGTownInstance* CPlayerSpecificInfoCallback::getTownBySerial(int serialId) const
|
||||
@ -880,8 +880,8 @@ const CGTownInstance* CPlayerSpecificInfoCallback::getTownBySerial(int serialId)
|
||||
ASSERT_IF_CALLED_WITH_PLAYER
|
||||
const PlayerState *p = getPlayerState(*getPlayerID());
|
||||
ERROR_RET_VAL_IF(!p, "No player info", nullptr);
|
||||
ERROR_RET_VAL_IF(serialId < 0 || serialId >= p->towns.size(), "No player info", nullptr);
|
||||
return p->towns[serialId];
|
||||
ERROR_RET_VAL_IF(serialId < 0 || serialId >= p->getTowns().size(), "No player info", nullptr);
|
||||
return p->getTowns()[serialId];
|
||||
}
|
||||
|
||||
int CPlayerSpecificInfoCallback::getResourceAmount(GameResID type) const
|
||||
|
@ -23,7 +23,7 @@ struct InfoWindow;
|
||||
struct PlayerSettings;
|
||||
struct CPackForClient;
|
||||
struct TerrainTile;
|
||||
struct PlayerState;
|
||||
class PlayerState;
|
||||
class CTown;
|
||||
struct StartInfo;
|
||||
struct CPathsInfo;
|
||||
|
@ -10,6 +10,9 @@
|
||||
#include "StdInc.h"
|
||||
|
||||
#include "CPlayerState.h"
|
||||
#include "mapObjects/CGDwelling.h"
|
||||
#include "mapObjects/CGTownInstance.h"
|
||||
#include "mapObjects/CGHeroInstance.h"
|
||||
#include "gameState/QuestInfo.h"
|
||||
#include "texts/CGeneralTextHandler.h"
|
||||
#include "VCMI_Lib.h"
|
||||
@ -90,4 +93,66 @@ int PlayerState::getResourceAmount(int type) const
|
||||
return vstd::atOrDefault(resources, static_cast<size_t>(type), 0);
|
||||
}
|
||||
|
||||
std::vector<const CGDwelling* > PlayerState::getDwellings() const
|
||||
{
|
||||
std::vector<const CGDwelling* > result;
|
||||
for (auto const & object : ownedObjects)
|
||||
{
|
||||
auto dwelling = dynamic_cast<const CGDwelling *>(object);
|
||||
auto town = dynamic_cast<const CGTownInstance *>(object);
|
||||
if (dwelling && !town)
|
||||
result.push_back(dwelling);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> PlayerState::getObjectsOfType() const
|
||||
{
|
||||
std::vector<T> result;
|
||||
for (auto const & object : ownedObjects)
|
||||
{
|
||||
auto casted = dynamic_cast<T>(object);
|
||||
if (casted)
|
||||
result.push_back(casted);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<const CGHeroInstance *> PlayerState::getHeroes() const
|
||||
{
|
||||
return getObjectsOfType<const CGHeroInstance *>();
|
||||
}
|
||||
|
||||
std::vector<const CGTownInstance *> PlayerState::getTowns() const
|
||||
{
|
||||
return getObjectsOfType<const CGTownInstance *>();
|
||||
}
|
||||
|
||||
std::vector<CGHeroInstance *> PlayerState::getHeroes()
|
||||
{
|
||||
return getObjectsOfType<CGHeroInstance *>();
|
||||
}
|
||||
|
||||
std::vector<CGTownInstance *> PlayerState::getTowns()
|
||||
{
|
||||
return getObjectsOfType<CGTownInstance *>();
|
||||
}
|
||||
|
||||
std::vector<const CGObjectInstance *> PlayerState::getOwnedObjects() const
|
||||
{
|
||||
return {ownedObjects.begin(), ownedObjects.end()};
|
||||
}
|
||||
|
||||
void PlayerState::addOwnedObject(CGObjectInstance * object)
|
||||
{
|
||||
ownedObjects.push_back(object);
|
||||
}
|
||||
|
||||
void PlayerState::removeOwnedObject(CGObjectInstance * object)
|
||||
{
|
||||
vstd::erase(ownedObjects, object);
|
||||
}
|
||||
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -20,12 +20,13 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class CGObjectInstance;
|
||||
class CGHeroInstance;
|
||||
class CGTownInstance;
|
||||
class CGDwelling;
|
||||
struct QuestInfo;
|
||||
|
||||
struct DLL_LINKAGE PlayerState : public CBonusSystemNode, public Player
|
||||
class DLL_LINKAGE PlayerState : public CBonusSystemNode, public Player
|
||||
{
|
||||
struct VisitedObjectGlobal
|
||||
{
|
||||
@ -47,6 +48,11 @@ struct DLL_LINKAGE PlayerState : public CBonusSystemNode, public Player
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<CGObjectInstance*> ownedObjects;
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> getObjectsOfType() const;
|
||||
|
||||
public:
|
||||
PlayerColor color;
|
||||
bool human; //true if human controlled player, false for AI
|
||||
@ -55,12 +61,8 @@ public:
|
||||
|
||||
/// list of objects that were "destroyed" by player, either via simple pick-up (e.g. resources) or defeated heroes or wandering monsters
|
||||
std::set<ObjectInstanceID> destroyedObjects;
|
||||
|
||||
std::set<ObjectInstanceID> visitedObjects; // as a std::set, since most accesses here will be from visited status checks
|
||||
std::set<VisitedObjectGlobal> visitedObjectsGlobal;
|
||||
std::vector<ConstTransitivePtr<CGHeroInstance> > heroes;
|
||||
std::vector<ConstTransitivePtr<CGTownInstance> > towns;
|
||||
std::vector<ConstTransitivePtr<CGDwelling> > dwellings; //used for town growth
|
||||
std::vector<QuestInfo> quests; //store info about all received quests
|
||||
std::vector<Bonus> battleBonuses; //additional bonuses to be added during battle with neutrals
|
||||
std::map<uint32_t, std::map<ArtifactPosition, ArtifactID>> costumesArtifacts;
|
||||
@ -90,9 +92,20 @@ public:
|
||||
std::string getNameTextID() const override;
|
||||
void registerIcons(const IconRegistar & cb) const override;
|
||||
|
||||
std::vector<const CGHeroInstance* > getHeroes() const;
|
||||
std::vector<const CGTownInstance* > getTowns() const;
|
||||
std::vector<CGHeroInstance* > getHeroes();
|
||||
std::vector<CGTownInstance* > getTowns();
|
||||
|
||||
std::vector<const CGDwelling* > getDwellings() const;
|
||||
std::vector<const CGObjectInstance* > getOwnedObjects() const;
|
||||
|
||||
void addOwnedObject(CGObjectInstance * object);
|
||||
void removeOwnedObject(CGObjectInstance * object);
|
||||
|
||||
bool checkVanquished() const
|
||||
{
|
||||
return heroes.empty() && towns.empty();
|
||||
return ownedObjects.empty();
|
||||
}
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
@ -103,9 +116,10 @@ public:
|
||||
h & resources;
|
||||
h & status;
|
||||
h & turnTimer;
|
||||
h & heroes;
|
||||
h & towns;
|
||||
h & dwellings;
|
||||
h & ownedObjects;
|
||||
//h & heroes;
|
||||
//h & towns;
|
||||
//h & dwellings;
|
||||
h & quests;
|
||||
h & visitedObjects;
|
||||
h & visitedObjectsGlobal;
|
||||
|
@ -574,7 +574,6 @@ void CGameState::initHeroes()
|
||||
}
|
||||
|
||||
hero->initHero(getRandomGenerator());
|
||||
getPlayerState(hero->getOwner())->heroes.push_back(hero);
|
||||
map->allHeroes[hero->getHeroType().getNum()] = hero;
|
||||
}
|
||||
|
||||
@ -699,14 +698,14 @@ void CGameState::initStartingBonus()
|
||||
}
|
||||
case PlayerStartingBonus::ARTIFACT:
|
||||
{
|
||||
if(elem.second.heroes.empty())
|
||||
if(elem.second.getHeroes().empty())
|
||||
{
|
||||
logGlobal->error("Cannot give starting artifact - no heroes!");
|
||||
break;
|
||||
}
|
||||
const Artifact * toGive = pickRandomArtifact(getRandomGenerator(), CArtifact::ART_TREASURE).toEntity(VLC);
|
||||
|
||||
CGHeroInstance *hero = elem.second.heroes[0];
|
||||
CGHeroInstance *hero = elem.second.getHeroes()[0];
|
||||
if(!giveHeroArtifact(hero, toGive->getId()))
|
||||
logGlobal->error("Cannot give starting artifact - no free slots!");
|
||||
}
|
||||
@ -893,8 +892,6 @@ void CGameState::initTowns()
|
||||
vti->possibleSpells -= s->id;
|
||||
}
|
||||
vti->possibleSpells.clear();
|
||||
if(vti->getOwner() != PlayerColor::NEUTRAL)
|
||||
getPlayerState(vti->getOwner())->towns.emplace_back(vti);
|
||||
}
|
||||
}
|
||||
|
||||
@ -902,6 +899,12 @@ void CGameState::initMapObjects()
|
||||
{
|
||||
logGlobal->debug("\tObject initialization");
|
||||
|
||||
for(CGObjectInstance *obj : map->objects)
|
||||
{
|
||||
if (obj && obj->getOwner().isValidPlayer())
|
||||
getPlayerState(obj->getOwner())->addOwnedObject(obj);
|
||||
}
|
||||
|
||||
// objCaller->preInit();
|
||||
for(CGObjectInstance *obj : map->objects)
|
||||
{
|
||||
@ -937,9 +940,9 @@ void CGameState::placeHeroesInTowns()
|
||||
if(player.first == PlayerColor::NEUTRAL)
|
||||
continue;
|
||||
|
||||
for(CGHeroInstance * h : player.second.heroes)
|
||||
for(CGHeroInstance * h : player.second.getHeroes())
|
||||
{
|
||||
for(CGTownInstance * t : player.second.towns)
|
||||
for(CGTownInstance * t : player.second.getTowns())
|
||||
{
|
||||
if(h->visitablePos().z != t->visitablePos().z)
|
||||
continue;
|
||||
@ -971,9 +974,9 @@ void CGameState::initVisitingAndGarrisonedHeroes()
|
||||
continue;
|
||||
|
||||
//init visiting and garrisoned heroes
|
||||
for(CGHeroInstance * h : player.second.heroes)
|
||||
for(CGHeroInstance * h : player.second.getHeroes())
|
||||
{
|
||||
for(CGTownInstance * t : player.second.towns)
|
||||
for(CGTownInstance * t : player.second.getTowns())
|
||||
{
|
||||
if(h->visitablePos().z != t->visitablePos().z)
|
||||
continue;
|
||||
@ -1371,7 +1374,7 @@ bool CGameState::checkForVictory(const PlayerColor & player, const EventConditio
|
||||
}
|
||||
case EventCondition::HAVE_ARTIFACT: //check if any hero has winning artifact
|
||||
{
|
||||
for(const auto & elem : p->heroes)
|
||||
for(const auto & elem : p->getHeroes())
|
||||
if(elem->hasArt(condition.objectType.as<ArtifactID>()))
|
||||
return true;
|
||||
return false;
|
||||
@ -1405,7 +1408,7 @@ bool CGameState::checkForVictory(const PlayerColor & player, const EventConditio
|
||||
}
|
||||
else // any town
|
||||
{
|
||||
for (const CGTownInstance * t : p->towns)
|
||||
for (const CGTownInstance * t : p->getTowns())
|
||||
{
|
||||
if (t->hasBuilt(condition.objectType.as<BuildingID>()))
|
||||
return true;
|
||||
@ -1550,9 +1553,9 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
|
||||
if(level >= 0) //num of towns & num of heroes
|
||||
{
|
||||
//num of towns
|
||||
FILL_FIELD(numOfTowns, g->second.towns.size())
|
||||
FILL_FIELD(numOfTowns, g->second.getTowns().size())
|
||||
//num of heroes
|
||||
FILL_FIELD(numOfHeroes, g->second.heroes.size())
|
||||
FILL_FIELD(numOfHeroes, g->second.getHeroes().size())
|
||||
}
|
||||
if(level >= 1) //best hero's portrait
|
||||
{
|
||||
@ -1624,7 +1627,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
|
||||
if(playerInactive(player.second.color)) //do nothing for neutral player
|
||||
continue;
|
||||
CreatureID bestCre; //best creature's ID
|
||||
for(const auto & elem : player.second.heroes)
|
||||
for(const auto & elem : player.second.getHeroes())
|
||||
{
|
||||
for(const auto & it : elem->Slots())
|
||||
{
|
||||
|
@ -536,7 +536,7 @@ void CGameStateCampaign::initHeroes()
|
||||
}
|
||||
assert(humanPlayer != PlayerColor::NEUTRAL);
|
||||
|
||||
std::vector<ConstTransitivePtr<CGHeroInstance> > & heroes = gameState->players[humanPlayer].heroes;
|
||||
const auto & heroes = gameState->players[humanPlayer].getHeroes();
|
||||
|
||||
if (chosenBonus->info1 == 0xFFFD) //most powerful
|
||||
{
|
||||
|
@ -50,10 +50,10 @@ StatisticDataSetEntry StatisticDataSet::createEntry(const PlayerState * ps, cons
|
||||
data.isHuman = ps->isHuman();
|
||||
data.status = ps->status;
|
||||
data.resources = ps->resources;
|
||||
data.numberHeroes = ps->heroes.size();
|
||||
data.numberHeroes = ps->getHeroes().size();
|
||||
data.numberTowns = gs->howManyTowns(ps->color);
|
||||
data.numberArtifacts = Statistic::getNumberOfArts(ps);
|
||||
data.numberDwellings = gs->getPlayerState(ps->color)->dwellings.size();
|
||||
data.numberDwellings = gs->getPlayerState(ps->color)->getDwellings().size();
|
||||
data.armyStrength = Statistic::getArmyStrength(ps, true);
|
||||
data.totalExperience = Statistic::getTotalExperience(ps);
|
||||
data.income = Statistic::getIncome(gs, ps);
|
||||
@ -221,7 +221,7 @@ std::vector<const CGMine *> Statistic::getMines(const CGameState * gs, const Pla
|
||||
int Statistic::getNumberOfArts(const PlayerState * ps)
|
||||
{
|
||||
int ret = 0;
|
||||
for(auto h : ps->heroes)
|
||||
for(auto h : ps->getHeroes())
|
||||
{
|
||||
ret += h->artifactsInBackpack.size() + h->artifactsWorn.size();
|
||||
}
|
||||
@ -233,7 +233,7 @@ si64 Statistic::getArmyStrength(const PlayerState * ps, bool withTownGarrison)
|
||||
{
|
||||
si64 str = 0;
|
||||
|
||||
for(auto h : ps->heroes)
|
||||
for(auto h : ps->getHeroes())
|
||||
{
|
||||
if(!h->inTownGarrison || withTownGarrison) //original h3 behavior
|
||||
str += h->getArmyStrength();
|
||||
@ -246,7 +246,7 @@ si64 Statistic::getTotalExperience(const PlayerState * ps)
|
||||
{
|
||||
si64 tmp = 0;
|
||||
|
||||
for(auto h : ps->heroes)
|
||||
for(auto h : ps->getHeroes())
|
||||
tmp += h->exp;
|
||||
|
||||
return tmp;
|
||||
@ -258,11 +258,11 @@ int Statistic::getIncome(const CGameState * gs, const PlayerState * ps)
|
||||
int totalIncome = 0;
|
||||
|
||||
//Heroes can produce gold as well - skill, specialty or arts
|
||||
for(const auto & h : ps->heroes)
|
||||
for(const auto & h : ps->getHeroes())
|
||||
totalIncome += h->dailyIncome()[EGameResID::GOLD];
|
||||
|
||||
//Add town income of all towns
|
||||
for(const auto & t : ps->towns)
|
||||
for(const auto & t : ps->getTowns())
|
||||
totalIncome += t->dailyIncome()[EGameResID::GOLD];
|
||||
|
||||
for(const CGMine * mine : getMines(gs, ps))
|
||||
@ -295,7 +295,7 @@ float Statistic::getMapExploredRatio(const CGameState * gs, PlayerColor player)
|
||||
|
||||
const CGHeroInstance * Statistic::findBestHero(const CGameState * gs, const PlayerColor & color)
|
||||
{
|
||||
auto &h = gs->players.at(color).heroes;
|
||||
const auto &h = gs->players.at(color).getHeroes();
|
||||
if(h.empty())
|
||||
return nullptr;
|
||||
//best hero will be that with highest exp
|
||||
@ -368,7 +368,7 @@ float Statistic::getTownBuiltRatio(const PlayerState * ps)
|
||||
float built = 0.0;
|
||||
float total = 0.0;
|
||||
|
||||
for(const auto & t : ps->towns)
|
||||
for(const auto & t : ps->getTowns())
|
||||
{
|
||||
built += t->getBuildings().size();
|
||||
for(const auto & b : t->town->buildings)
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
struct PlayerState;
|
||||
class PlayerState;
|
||||
class CGameState;
|
||||
class CGHeroInstance;
|
||||
class CGMine;
|
||||
|
@ -29,10 +29,10 @@ HighScoreParameter HighScore::prepareHighScores(const CGameState * gs, PlayerCol
|
||||
param.townAmount = gs->howManyTowns(player);
|
||||
param.usedCheat = gs->getPlayerState(player)->cheated;
|
||||
param.hasGrail = false;
|
||||
for(const CGHeroInstance * h : playerState->heroes)
|
||||
for(const CGHeroInstance * h : playerState->getHeroes())
|
||||
if(h->hasArt(ArtifactID::GRAIL))
|
||||
param.hasGrail = true;
|
||||
for(const CGTownInstance * t : playerState->towns)
|
||||
for(const CGTownInstance * t : playerState->getTowns())
|
||||
if(t->hasBuilt(BuildingID::GRAIL))
|
||||
param.hasGrail = true;
|
||||
param.allEnemiesDefeated = true;
|
||||
|
@ -182,10 +182,6 @@ void CGDwelling::initObj(vstd::RNG & rand)
|
||||
case Obj::CREATURE_GENERATOR4:
|
||||
{
|
||||
getObjectHandler()->configureObject(this, rand);
|
||||
|
||||
if (getOwner() != PlayerColor::NEUTRAL)
|
||||
cb->gameState()->players[getOwner()].dwellings.emplace_back(this);
|
||||
|
||||
assert(!creatures.empty());
|
||||
assert(!creatures[0].second.empty());
|
||||
break;
|
||||
@ -211,19 +207,6 @@ void CGDwelling::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
|
||||
{
|
||||
switch (what)
|
||||
{
|
||||
case ObjProperty::OWNER: //change owner
|
||||
if (ID == Obj::CREATURE_GENERATOR1 || ID == Obj::CREATURE_GENERATOR2
|
||||
|| ID == Obj::CREATURE_GENERATOR3 || ID == Obj::CREATURE_GENERATOR4)
|
||||
{
|
||||
if (tempOwner != PlayerColor::NEUTRAL)
|
||||
{
|
||||
std::vector<ConstTransitivePtr<CGDwelling> >* dwellings = &cb->gameState()->players[tempOwner].dwellings;
|
||||
dwellings->erase (std::find(dwellings->begin(), dwellings->end(), this));
|
||||
}
|
||||
if (identifier.as<PlayerColor>().isValidPlayer())
|
||||
cb->gameState()->players[identifier.as<PlayerColor>()].dwellings.emplace_back(this);
|
||||
}
|
||||
break;
|
||||
case ObjProperty::AVAILABLE_CREATURE:
|
||||
creatures.resize(1);
|
||||
creatures[0].second.resize(1);
|
||||
|
@ -181,7 +181,7 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
|
||||
int dwellingBonus = 0;
|
||||
if(const PlayerState *p = cb->getPlayerState(tempOwner, false))
|
||||
{
|
||||
dwellingBonus = getDwellingBonus(creatures[level].second, p->dwellings);
|
||||
dwellingBonus = getDwellingBonus(creatures[level].second, p->getDwellings());
|
||||
}
|
||||
if(dwellingBonus)
|
||||
ret.entries.emplace_back(VLC->generaltexth->allTexts[591], dwellingBonus); // \nExternal dwellings %+d
|
||||
@ -192,7 +192,7 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CGTownInstance::getDwellingBonus(const std::vector<CreatureID>& creatureIds, const std::vector<ConstTransitivePtr<CGDwelling> >& dwellings) const
|
||||
int CGTownInstance::getDwellingBonus(const std::vector<CreatureID>& creatureIds, const std::vector<const CGDwelling * >& dwellings) const
|
||||
{
|
||||
int totalBonus = 0;
|
||||
for (const auto& dwelling : dwellings)
|
||||
@ -635,9 +635,9 @@ void CGTownInstance::removeCapitols(const PlayerColor & owner) const
|
||||
if (hasCapitol()) // search if there's an older capitol
|
||||
{
|
||||
PlayerState* state = cb->gameState()->getPlayerState(owner); //get all towns owned by player
|
||||
for (auto i = state->towns.cbegin(); i < state->towns.cend(); ++i)
|
||||
for (const auto & town : state->getTowns())
|
||||
{
|
||||
if (*i != this && (*i)->hasCapitol())
|
||||
if (town != this && town->hasCapitol())
|
||||
{
|
||||
RazeStructures rs;
|
||||
rs.tid = id;
|
||||
@ -672,7 +672,7 @@ int CGTownInstance::getMarketEfficiency() const
|
||||
assert(p);
|
||||
|
||||
int marketCount = 0;
|
||||
for(const CGTownInstance *t : p->towns)
|
||||
for(const CGTownInstance *t : p->getTowns())
|
||||
if(t->hasBuiltSomeTradeBuilding())
|
||||
marketCount++;
|
||||
|
||||
|
@ -239,7 +239,7 @@ private:
|
||||
FactionID randomizeFaction(vstd::RNG & rand);
|
||||
void setOwner(const PlayerColor & owner) const;
|
||||
void onTownCaptured(const PlayerColor & winner) const;
|
||||
int getDwellingBonus(const std::vector<CreatureID>& creatureIds, const std::vector<ConstTransitivePtr<CGDwelling> >& dwellings) const;
|
||||
int getDwellingBonus(const std::vector<CreatureID>& creatureIds, const std::vector<const CGDwelling* >& dwellings) const;
|
||||
bool townEnvisagesBuilding(BuildingSubID::EBuildingSubID bid) const;
|
||||
void initializeConfigurableBuildings(vstd::RNG & rand);
|
||||
};
|
||||
|
@ -1171,7 +1171,7 @@ void RemoveObject::applyGs(CGameState *gs)
|
||||
assert(beatenHero);
|
||||
PlayerState * p = gs->getPlayerState(beatenHero->tempOwner);
|
||||
gs->map->heroesOnMap -= beatenHero;
|
||||
p->heroes -= beatenHero;
|
||||
p->removeOwnedObject(beatenHero);
|
||||
|
||||
|
||||
auto * siegeNode = beatenHero->whereShouldBeAttachedOnSiege(gs);
|
||||
@ -1417,7 +1417,7 @@ void HeroRecruited::applyGs(CGameState *gs)
|
||||
gs->map->objects[h->id.getNum()] = h;
|
||||
|
||||
gs->map->heroesOnMap.emplace_back(h);
|
||||
p->heroes.emplace_back(h);
|
||||
p->addOwnedObject(h);
|
||||
h->attachTo(*p);
|
||||
gs->map->addBlockVisTiles(h);
|
||||
|
||||
@ -1452,7 +1452,7 @@ void GiveHero::applyGs(CGameState *gs)
|
||||
h->setMovementPoints(h->movementPointsLimit(true));
|
||||
h->pos = h->convertFromVisitablePos(oldVisitablePos);
|
||||
gs->map->heroesOnMap.emplace_back(h);
|
||||
gs->getPlayerState(h->getOwner())->heroes.emplace_back(h);
|
||||
gs->getPlayerState(h->getOwner())->addOwnedObject(h);
|
||||
|
||||
gs->map->addBlockVisTiles(h);
|
||||
h->inTownGarrison = false;
|
||||
@ -1942,6 +1942,18 @@ void SetObjectProperty::applyGs(CGameState *gs)
|
||||
}
|
||||
|
||||
auto * cai = dynamic_cast<CArmedInstance *>(obj);
|
||||
|
||||
if(what == ObjProperty::OWNER)
|
||||
{
|
||||
PlayerColor oldOwner = obj->getOwner();
|
||||
PlayerColor newOwner = identifier.as<PlayerColor>();
|
||||
if(oldOwner.isValidPlayer())
|
||||
gs->getPlayerState(oldOwner)->removeOwnedObject(obj);;
|
||||
|
||||
if(newOwner.isValidPlayer())
|
||||
gs->getPlayerState(newOwner)->addOwnedObject(obj);;
|
||||
}
|
||||
|
||||
if(what == ObjProperty::OWNER && cai)
|
||||
{
|
||||
if(obj->ID == Obj::TOWN)
|
||||
@ -1953,17 +1965,13 @@ void SetObjectProperty::applyGs(CGameState *gs)
|
||||
if(oldOwner.isValidPlayer())
|
||||
{
|
||||
auto * state = gs->getPlayerState(oldOwner);
|
||||
state->towns -= t;
|
||||
|
||||
if(state->towns.empty())
|
||||
if(state->getTowns().empty())
|
||||
state->daysWithoutCastle = 0;
|
||||
}
|
||||
if(identifier.as<PlayerColor>().isValidPlayer())
|
||||
{
|
||||
PlayerState * p = gs->getPlayerState(identifier.as<PlayerColor>());
|
||||
p->towns.emplace_back(t);
|
||||
|
||||
//reset counter before NewTurn to avoid no town message if game loaded at turn when one already captured
|
||||
PlayerState * p = gs->getPlayerState(identifier.as<PlayerColor>());
|
||||
if(p->daysWithoutCastle)
|
||||
p->daysWithoutCastle = std::nullopt;
|
||||
}
|
||||
|
@ -264,8 +264,7 @@ TeleporterTilesVector CPathfinderHelper::getCastleGates(const PathNodeInfo & sou
|
||||
{
|
||||
TeleporterTilesVector allowedExits;
|
||||
|
||||
auto towns = getPlayerState(hero->tempOwner)->towns;
|
||||
for(const auto & town : towns)
|
||||
for(const auto & town : getPlayerState(hero->tempOwner)->getTowns())
|
||||
{
|
||||
if(town->id != source.nodeObject->id && town->visitingHero == nullptr
|
||||
&& town->hasBuilt(BuildingID::CASTLE_GATE, ETownType::INFERNO))
|
||||
|
@ -692,9 +692,9 @@ std::vector <const CGTownInstance*> TownPortalMechanics::getPossibleTowns(SpellC
|
||||
|
||||
for(const auto & color : team->players)
|
||||
{
|
||||
for(auto currTown : env->getCb()->getPlayerState(color)->towns)
|
||||
for(auto currTown : env->getCb()->getPlayerState(color)->getTowns())
|
||||
{
|
||||
ret.push_back(currTown.get());
|
||||
ret.push_back(currTown);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -555,7 +555,7 @@ void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=fa
|
||||
ssi.creatures = town->creatures;
|
||||
ssi.creatures[town->town->creatures.size()].second.clear();//remove old one
|
||||
|
||||
const std::vector<ConstTransitivePtr<CGDwelling> > &dwellings = p->dwellings;
|
||||
const auto &dwellings = p->getDwellings();
|
||||
if (dwellings.empty())//no dwellings - just remove
|
||||
{
|
||||
sendAndApply(&ssi);
|
||||
@ -639,7 +639,7 @@ void CGameHandler::onNewTurn()
|
||||
if (player.second.status != EPlayerStatus::INGAME)
|
||||
continue;
|
||||
|
||||
if (player.second.heroes.empty() && player.second.towns.empty())
|
||||
if (player.second.getHeroes().empty() && player.second.getTowns().empty())
|
||||
throw std::runtime_error("Invalid player in player state! Player " + std::to_string(player.first.getNum()) + ", map name: " + gs->map->name.toString() + ", map description: " + gs->map->description.toString());
|
||||
}
|
||||
|
||||
@ -724,7 +724,7 @@ void CGameHandler::onNewTurn()
|
||||
if (firstTurn)
|
||||
heroPool->onNewWeek(elem.first);
|
||||
|
||||
for (CGHeroInstance *h : (elem).second.heroes)
|
||||
for (CGHeroInstance *h : (elem).second.getHeroes())
|
||||
{
|
||||
if (h->visitedTown)
|
||||
giveSpells(h->visitedTown, h);
|
||||
@ -1286,9 +1286,9 @@ void CGameHandler::setOwner(const CGObjectInstance * obj, const PlayerColor owne
|
||||
|
||||
const PlayerState * p = getPlayerState(owner);
|
||||
|
||||
if ((obj->ID == Obj::CREATURE_GENERATOR1 || obj->ID == Obj::CREATURE_GENERATOR4) && p && p->dwellings.size()==1)//first dwelling captured
|
||||
if ((obj->ID == Obj::CREATURE_GENERATOR1 || obj->ID == Obj::CREATURE_GENERATOR4) && p && p->getDwellings().size()==1)//first dwelling captured
|
||||
{
|
||||
for (const CGTownInstance * t : getPlayerState(owner)->towns)
|
||||
for (const CGTownInstance * t : getPlayerState(owner)->getTowns())
|
||||
{
|
||||
if (t->hasBuilt(BuildingSubID::PORTAL_OF_SUMMONING))
|
||||
setPortalDwelling(t);//set initial creatures for all portals of summoning
|
||||
@ -3297,7 +3297,7 @@ void CGameHandler::handleTimeEvents(PlayerColor color)
|
||||
}
|
||||
}
|
||||
|
||||
void CGameHandler::handleTownEvents(CGTownInstance * town)
|
||||
void CGameHandler::handleTownEvents(const CGTownInstance * town)
|
||||
{
|
||||
for (auto const & event : town->events)
|
||||
{
|
||||
@ -3631,10 +3631,10 @@ void CGameHandler::checkVictoryLossConditionsForPlayer(PlayerColor player)
|
||||
else
|
||||
{
|
||||
//copy heroes vector to avoid iterator invalidation as removal change PlayerState
|
||||
auto hlp = p->heroes;
|
||||
auto hlp = p->getHeroes();
|
||||
for (auto h : hlp) //eliminate heroes
|
||||
{
|
||||
if (h.get())
|
||||
if (h)
|
||||
removeObject(h, player);
|
||||
}
|
||||
|
||||
@ -4159,11 +4159,11 @@ void CGameHandler::changeFogOfWar(int3 center, ui32 radius, PlayerColor player,
|
||||
|
||||
std::unordered_set<int3> observedTiles; //do not hide tiles observed by heroes. May lead to disastrous AI problems
|
||||
auto p = getPlayerState(player);
|
||||
for (auto h : p->heroes)
|
||||
for (auto h : p->getHeroes())
|
||||
{
|
||||
getTilesInRange(observedTiles, h->getSightCenter(), h->getSightRadius(), ETileVisibility::REVEALED, h->tempOwner);
|
||||
}
|
||||
for (auto t : p->towns)
|
||||
for (auto t : p->getTowns())
|
||||
{
|
||||
getTilesInRange(observedTiles, t->getSightCenter(), t->getSightRadius(), ETileVisibility::REVEALED, t->tempOwner);
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ public:
|
||||
void addStatistics(StatisticDataSet &stat) const;
|
||||
|
||||
void handleTimeEvents(PlayerColor player);
|
||||
void handleTownEvents(CGTownInstance *town);
|
||||
void handleTownEvents(const CGTownInstance *town);
|
||||
bool complain(const std::string &problem); //sends message to all clients, prints on the logs and return true
|
||||
void objectVisited( const CGObjectInstance * obj, const CGHeroInstance * h );
|
||||
void objectVisitEnded(const CObjectVisitQuery &query);
|
||||
|
@ -484,7 +484,7 @@ void BattleResultProcessor::endBattleConfirm(const CBattleInfoCallback & battle)
|
||||
if(!finishingBattle->isDraw())
|
||||
{
|
||||
ConstTransitivePtr<CGHeroInstance> strongestHero = nullptr;
|
||||
for(auto & hero : gameHandler->gameState()->getPlayerState(finishingBattle->loser)->heroes)
|
||||
for(auto & hero : gameHandler->gameState()->getPlayerState(finishingBattle->loser)->getHeroes())
|
||||
if(!strongestHero || hero->exp > strongestHero->exp)
|
||||
strongestHero = hero;
|
||||
if(strongestHero->id == finishingBattle->loserHero->id && strongestHero->level > 5)
|
||||
|
@ -40,10 +40,10 @@ void NewTurnProcessor::onPlayerTurnStarted(PlayerColor which)
|
||||
const auto * playerState = gameHandler->gameState()->getPlayerState(which);
|
||||
|
||||
gameHandler->handleTimeEvents(which);
|
||||
for (auto t : playerState->towns)
|
||||
for (const auto * t : playerState->getTowns())
|
||||
gameHandler->handleTownEvents(t);
|
||||
|
||||
for (auto t : playerState->towns)
|
||||
for (const auto * t : playerState->getTowns())
|
||||
{
|
||||
//garrison hero first - consistent with original H3 Mana Vortex and Battle Scholar Academy levelup windows order
|
||||
if (t->garrisonHero != nullptr)
|
||||
@ -59,7 +59,7 @@ void NewTurnProcessor::onPlayerTurnEnded(PlayerColor which)
|
||||
const auto * playerState = gameHandler->gameState()->getPlayerState(which);
|
||||
assert(playerState->status == EPlayerStatus::INGAME);
|
||||
|
||||
if (playerState->towns.empty())
|
||||
if (playerState->getTowns().empty())
|
||||
{
|
||||
DaysWithoutTown pack;
|
||||
pack.player = which;
|
||||
@ -92,7 +92,7 @@ ResourceSet NewTurnProcessor::generatePlayerIncome(PlayerColor playerID, bool ne
|
||||
const PlayerState & state = gameHandler->gameState()->players.at(playerID);
|
||||
ResourceSet income;
|
||||
|
||||
for (const auto & town : state.towns)
|
||||
for (const auto & town : state.getTowns())
|
||||
{
|
||||
if (newWeek && town->hasBuilt(BuildingSubID::TREASURY))
|
||||
{
|
||||
@ -123,18 +123,18 @@ ResourceSet NewTurnProcessor::generatePlayerIncome(PlayerColor playerID, bool ne
|
||||
for (GameResID k = GameResID::WOOD; k < GameResID::COUNT; k++)
|
||||
{
|
||||
income += state.valOfBonuses(BonusType::RESOURCES_CONSTANT_BOOST, BonusSubtypeID(k));
|
||||
income += state.valOfBonuses(BonusType::RESOURCES_TOWN_MULTIPLYING_BOOST, BonusSubtypeID(k)) * state.towns.size();
|
||||
income += state.valOfBonuses(BonusType::RESOURCES_TOWN_MULTIPLYING_BOOST, BonusSubtypeID(k)) * state.getTowns().size();
|
||||
}
|
||||
|
||||
if(newWeek) //weekly crystal generation if 1 or more crystal dragons in any hero army or town garrison
|
||||
{
|
||||
bool hasCrystalGenCreature = false;
|
||||
for (const auto & hero : state.heroes)
|
||||
for (const auto & hero : state.getHeroes())
|
||||
for(auto stack : hero->stacks)
|
||||
if(stack.second->hasBonusOfType(BonusType::SPECIAL_CRYSTAL_GENERATION))
|
||||
hasCrystalGenCreature = true;
|
||||
|
||||
for(const auto & town : state.towns)
|
||||
for(const auto & town : state.getTowns())
|
||||
for(auto stack : town->stacks)
|
||||
if(stack.second->hasBonusOfType(BonusType::SPECIAL_CRYSTAL_GENERATION))
|
||||
hasCrystalGenCreature = true;
|
||||
@ -146,10 +146,9 @@ ResourceSet NewTurnProcessor::generatePlayerIncome(PlayerColor playerID, bool ne
|
||||
TResources incomeHandicapped = income;
|
||||
incomeHandicapped.applyHandicap(playerSettings->handicap.percentIncome);
|
||||
|
||||
// FIXME: store pre-filtered, all owned objects in PlayerState
|
||||
for (auto obj : gameHandler->gameState()->map->objects)
|
||||
for (auto obj : state.getOwnedObjects())
|
||||
{
|
||||
if (obj && obj->asOwnable() && obj->getOwner() == playerID)
|
||||
if (obj->asOwnable())
|
||||
incomeHandicapped += obj->asOwnable()->dailyIncome();
|
||||
}
|
||||
|
||||
|
@ -710,11 +710,11 @@ bool PlayerMessageProcessor::handleCheatCode(const std::string & cheat, PlayerCo
|
||||
executeCheatCode(cheatName, i.first, ObjectInstanceID::NONE, parameters);
|
||||
|
||||
if (vstd::contains(townTargetedCheats, cheatName))
|
||||
for (const auto & t : i.second.towns)
|
||||
for (const auto & t : i.second.getTowns())
|
||||
executeCheatCode(cheatName, i.first, t->id, parameters);
|
||||
|
||||
if (vstd::contains(heroTargetedCheats, cheatName))
|
||||
for (const auto & h : i.second.heroes)
|
||||
for (const auto & h : i.second.getHeroes())
|
||||
executeCheatCode(cheatName, i.first, h->id, parameters);
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ bool TurnOrderProcessor::playersInContact(PlayerColor left, PlayerColor right) c
|
||||
}
|
||||
}
|
||||
|
||||
for(const auto & hero : leftInfo->heroes)
|
||||
for(const auto & hero : leftInfo->getHeroes())
|
||||
{
|
||||
CPathsInfo out(mapSize, hero);
|
||||
auto config = std::make_shared<SingleHeroPathfinderConfig>(out, gameHandler->gameState(), hero);
|
||||
@ -137,7 +137,7 @@ bool TurnOrderProcessor::playersInContact(PlayerColor left, PlayerColor right) c
|
||||
leftReachability[z][x][y] = true;
|
||||
}
|
||||
|
||||
for(const auto & hero : rightInfo->heroes)
|
||||
for(const auto & hero : rightInfo->getHeroes())
|
||||
{
|
||||
CPathsInfo out(mapSize, hero);
|
||||
auto config = std::make_shared<SingleHeroPathfinderConfig>(out, gameHandler->gameState(), hero);
|
||||
|
Loading…
Reference in New Issue
Block a user