mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-20 20:23:03 +02:00
All objects that can be owned by player now implement IOwnableObject
This commit is contained in:
parent
a481f07daf
commit
d49a61645c
@ -822,34 +822,12 @@ int3 CPlayerSpecificInfoCallback::getGrailPos( double *outKnownRatio )
|
||||
|
||||
std::vector < const CGObjectInstance * > CPlayerSpecificInfoCallback::getMyObjects() const
|
||||
{
|
||||
std::vector < const CGObjectInstance * > ret;
|
||||
for(const CGObjectInstance * obj : gs->map->objects)
|
||||
{
|
||||
if(obj && obj->tempOwner == getPlayerID())
|
||||
ret.push_back(obj);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector < const CGDwelling * > CPlayerSpecificInfoCallback::getMyDwellings() const
|
||||
{
|
||||
ASSERT_IF_CALLED_WITH_PLAYER
|
||||
std::vector < const CGDwelling * > ret;
|
||||
for(const CGDwelling * dw : gs->getPlayerState(*getPlayerID())->getDwellings())
|
||||
{
|
||||
ret.push_back(dw);
|
||||
}
|
||||
return ret;
|
||||
return gs->getPlayerState(*getPlayerID())->getOwnedObjects();
|
||||
}
|
||||
|
||||
std::vector <QuestInfo> CPlayerSpecificInfoCallback::getMyQuests() const
|
||||
{
|
||||
std::vector <QuestInfo> ret;
|
||||
for(const auto & quest : gs->getPlayerState(*getPlayerID())->quests)
|
||||
{
|
||||
ret.push_back (quest);
|
||||
}
|
||||
return ret;
|
||||
return gs->getPlayerState(*getPlayerID())->quests;
|
||||
}
|
||||
|
||||
int CPlayerSpecificInfoCallback::howManyHeroes(bool includeGarrisoned) const
|
||||
|
@ -247,7 +247,6 @@ public:
|
||||
virtual const CGTownInstance* getTownBySerial(int serialId) const; // serial id is [0, number of towns)
|
||||
virtual const CGHeroInstance* getHeroBySerial(int serialId, bool includeGarrisoned=true) const; // serial id is [0, number of heroes)
|
||||
virtual std::vector <const CGHeroInstance *> getHeroesInfo(bool onlyOur = true) const; //true -> only owned; false -> all visible
|
||||
virtual std::vector <const CGDwelling *> getMyDwellings() const; //returns all dwellings that belong to player
|
||||
virtual std::vector <const CGObjectInstance * > getMyObjects() const; //returns all objects flagged by belonging player
|
||||
virtual std::vector <QuestInfo> getMyQuests() const;
|
||||
|
||||
|
@ -93,19 +93,6 @@ 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
|
||||
{
|
||||
@ -146,6 +133,7 @@ std::vector<const CGObjectInstance *> PlayerState::getOwnedObjects() const
|
||||
|
||||
void PlayerState::addOwnedObject(CGObjectInstance * object)
|
||||
{
|
||||
assert(object->asOwnable() != nullptr);
|
||||
ownedObjects.push_back(object);
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,6 @@ public:
|
||||
std::vector<CGHeroInstance* > getHeroes();
|
||||
std::vector<CGTownInstance* > getTowns();
|
||||
|
||||
std::vector<const CGDwelling* > getDwellings() const;
|
||||
std::vector<const CGObjectInstance* > getOwnedObjects() const;
|
||||
|
||||
void addOwnedObject(CGObjectInstance * object);
|
||||
|
@ -53,7 +53,7 @@ StatisticDataSetEntry StatisticDataSet::createEntry(const PlayerState * ps, cons
|
||||
data.numberHeroes = ps->getHeroes().size();
|
||||
data.numberTowns = gs->howManyTowns(ps->color);
|
||||
data.numberArtifacts = Statistic::getNumberOfArts(ps);
|
||||
data.numberDwellings = gs->getPlayerState(ps->color)->getDwellings().size();
|
||||
data.numberDwellings = Statistic::getNumberOfDwellings(ps);
|
||||
data.armyStrength = Statistic::getArmyStrength(ps, true);
|
||||
data.totalExperience = Statistic::getTotalExperience(ps);
|
||||
data.income = Statistic::getIncome(gs, ps);
|
||||
@ -228,6 +228,16 @@ int Statistic::getNumberOfArts(const PlayerState * ps)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Statistic::getNumberOfDwellings(const PlayerState * ps)
|
||||
{
|
||||
int ret = 0;
|
||||
for(const auto * obj : ps->getOwnedObjects())
|
||||
if (!obj->asOwnable()->providedCreatures().empty())
|
||||
ret += 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// get total strength of player army
|
||||
si64 Statistic::getArmyStrength(const PlayerState * ps, bool withTownGarrison)
|
||||
{
|
||||
|
@ -158,6 +158,7 @@ class DLL_LINKAGE Statistic
|
||||
static std::vector<const CGMine *> getMines(const CGameState * gs, const PlayerState * ps);
|
||||
public:
|
||||
static int getNumberOfArts(const PlayerState * ps);
|
||||
static int getNumberOfDwellings(const PlayerState * ps);
|
||||
static si64 getArmyStrength(const PlayerState * ps, bool withTownGarrison = false);
|
||||
static si64 getTotalExperience(const PlayerState * ps);
|
||||
static int getIncome(const CGameState * gs, const PlayerState * ps);
|
||||
|
@ -534,4 +534,26 @@ void CGDwelling::serializeJsonOptions(JsonSerializeFormat & handler)
|
||||
}
|
||||
}
|
||||
|
||||
const IOwnableObject * CGDwelling::asOwnable() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
ResourceSet CGDwelling::dailyIncome() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<CreatureID> CGDwelling::providedCreatures() const
|
||||
{
|
||||
if (ID == Obj::WAR_MACHINE_FACTORY || ID == Obj::REFUGEE_CAMP)
|
||||
return {};
|
||||
|
||||
std::vector<CreatureID> result;
|
||||
for (const auto & level : creatures)
|
||||
result.insert(result.end(), level.second.begin(), level.second.end());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -11,6 +11,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CArmedInstance.h"
|
||||
#include "IOwnableObject.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@ -30,7 +31,7 @@ public:
|
||||
void serializeJson(JsonSerializeFormat & handler);
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CGDwelling : public CArmedInstance
|
||||
class DLL_LINKAGE CGDwelling : public CArmedInstance, public IOwnableObject
|
||||
{
|
||||
public:
|
||||
using TCreaturesSet = std::vector<std::pair<ui32, std::vector<CreatureID> > >;
|
||||
@ -41,6 +42,10 @@ public:
|
||||
CGDwelling(IGameCallback *cb);
|
||||
~CGDwelling() override;
|
||||
|
||||
const IOwnableObject * asOwnable() const final;
|
||||
ResourceSet dailyIncome() const override;
|
||||
std::vector<CreatureID> providedCreatures() const override;
|
||||
|
||||
protected:
|
||||
void serializeJsonOptions(JsonSerializeFormat & handler) override;
|
||||
|
||||
|
@ -1834,6 +1834,11 @@ ResourceSet CGHeroInstance::dailyIncome() const
|
||||
return income;
|
||||
}
|
||||
|
||||
std::vector<CreatureID> CGHeroInstance::providedCreatures() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
const IOwnableObject * CGHeroInstance::asOwnable() const
|
||||
{
|
||||
return this;
|
||||
|
@ -167,6 +167,7 @@ public:
|
||||
bool needsLastStack()const override;
|
||||
|
||||
ResourceSet dailyIncome() const override;
|
||||
std::vector<CreatureID> providedCreatures() const override;
|
||||
const IOwnableObject * asOwnable() const final;
|
||||
|
||||
//INativeTerrainProvider
|
||||
|
@ -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->getDwellings());
|
||||
dwellingBonus = getDwellingBonus(creatures[level].second, p->getOwnedObjects());
|
||||
}
|
||||
if(dwellingBonus)
|
||||
ret.entries.emplace_back(VLC->generaltexth->allTexts[591], dwellingBonus); // \nExternal dwellings %+d
|
||||
@ -192,15 +192,18 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CGTownInstance::getDwellingBonus(const std::vector<CreatureID>& creatureIds, const std::vector<const CGDwelling * >& dwellings) const
|
||||
int CGTownInstance::getDwellingBonus(const std::vector<CreatureID>& creatureIds, const std::vector<const CGObjectInstance * >& dwellings) const
|
||||
{
|
||||
int totalBonus = 0;
|
||||
for (const auto& dwelling : dwellings)
|
||||
{
|
||||
for (const auto& creature : dwelling->creatures)
|
||||
{
|
||||
totalBonus += vstd::contains(creatureIds, creature.second[0]) ? 1 : 0;
|
||||
}
|
||||
const auto & dwellingCreatures = dwelling->asOwnable()->providedCreatures();
|
||||
bool hasMatch = false;
|
||||
for (const auto& creature : dwellingCreatures)
|
||||
hasMatch = vstd::contains(creatureIds, creature);
|
||||
|
||||
if (hasMatch)
|
||||
totalBonus += 1;
|
||||
}
|
||||
return totalBonus;
|
||||
}
|
||||
@ -230,9 +233,9 @@ TResources CGTownInstance::dailyIncome() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
const IOwnableObject * CGTownInstance::asOwnable() const
|
||||
std::vector<CreatureID> CGTownInstance::providedCreatures() const
|
||||
{
|
||||
return this;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool CGTownInstance::hasFort() const
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#include "IMarket.h"
|
||||
#include "CGDwelling.h"
|
||||
#include "IOwnableObject.h"
|
||||
#include "../entities/faction/CFaction.h" // TODO: remove
|
||||
#include "../entities/faction/CTown.h" // TODO: remove
|
||||
|
||||
@ -48,7 +47,7 @@ struct DLL_LINKAGE GrowthInfo
|
||||
int handicapPercentage;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CGTownInstance : public CGDwelling, public IShipyard, public IMarket, public INativeTerrainProvider, public ICreatureUpgrader, public IOwnableObject
|
||||
class DLL_LINKAGE CGTownInstance : public CGDwelling, public IShipyard, public IMarket, public INativeTerrainProvider, public ICreatureUpgrader
|
||||
{
|
||||
std::string nameTextId; // name of town
|
||||
|
||||
@ -183,7 +182,7 @@ public:
|
||||
|
||||
TResources getBuildingCost(const BuildingID & buildingID) const;
|
||||
ResourceSet dailyIncome() const override;
|
||||
const IOwnableObject * asOwnable() const final;
|
||||
std::vector<CreatureID> providedCreatures() const override;
|
||||
|
||||
int spellsAtLevel(int level, bool checkGuild) const; //levels are counted from 1 (1 - 5)
|
||||
bool armedGarrison() const; //true if town has creatures in garrison or garrisoned hero
|
||||
@ -239,7 +238,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<const CGDwelling* >& dwellings) const;
|
||||
int getDwellingBonus(const std::vector<CreatureID>& creatureIds, const std::vector<const CGObjectInstance* >& dwellings) const;
|
||||
bool townEnvisagesBuilding(BuildingSubID::EBuildingSubID bid) const;
|
||||
void initializeConfigurableBuildings(vstd::RNG & rand);
|
||||
};
|
||||
|
@ -12,11 +12,19 @@
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class ResourceSet;
|
||||
class CreatureID;
|
||||
|
||||
class DLL_LINKAGE IOwnableObject
|
||||
{
|
||||
public:
|
||||
/// Fixed daily income of this object
|
||||
/// May not include random or periodical (e.g. weekly) income sources
|
||||
virtual ResourceSet dailyIncome() const = 0;
|
||||
|
||||
/// List of creatures that are provided by this building
|
||||
/// For use in town dwellings growth bonus and for portal of summoning
|
||||
virtual std::vector<CreatureID> providedCreatures() const = 0;
|
||||
|
||||
virtual ~IOwnableObject() = default;
|
||||
};
|
||||
|
||||
|
@ -132,6 +132,11 @@ const IOwnableObject * CGMine::asOwnable() const
|
||||
return this;
|
||||
}
|
||||
|
||||
std::vector<CreatureID> CGMine::providedCreatures() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
ResourceSet CGMine::dailyIncome() const
|
||||
{
|
||||
ResourceSet result;
|
||||
@ -974,6 +979,21 @@ void CGSignBottle::serializeJsonOptions(JsonSerializeFormat& handler)
|
||||
handler.serializeStruct("text", message);
|
||||
}
|
||||
|
||||
const IOwnableObject * CGGarrison::asOwnable() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
ResourceSet CGGarrison::dailyIncome() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<CreatureID> CGGarrison::providedCreatures() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
void CGGarrison::onHeroVisit (const CGHeroInstance *h) const
|
||||
{
|
||||
auto relations = cb->gameState()->getPlayerRelations(h->tempOwner, tempOwner);
|
||||
@ -1277,6 +1297,21 @@ void CGObelisk::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
|
||||
}
|
||||
}
|
||||
|
||||
const IOwnableObject * CGLighthouse::asOwnable() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
ResourceSet CGLighthouse::dailyIncome() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<CreatureID> CGLighthouse::providedCreatures() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
void CGLighthouse::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
if(h->tempOwner != tempOwner)
|
||||
|
@ -60,7 +60,7 @@ protected:
|
||||
void serializeJsonOptions(JsonSerializeFormat & handler) override;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CGGarrison : public CArmedInstance
|
||||
class DLL_LINKAGE CGGarrison : public CArmedInstance, public IOwnableObject
|
||||
{
|
||||
public:
|
||||
using CArmedInstance::CArmedInstance;
|
||||
@ -72,6 +72,10 @@ public:
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||
|
||||
const IOwnableObject * asOwnable() const final;
|
||||
ResourceSet dailyIncome() const override;
|
||||
std::vector<CreatureID> providedCreatures() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
h & static_cast<CArmedInstance&>(*this);
|
||||
@ -80,6 +84,7 @@ public:
|
||||
protected:
|
||||
void serializeJsonOptions(JsonSerializeFormat & handler) override;
|
||||
void addAntimagicGarrisonBonus();
|
||||
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CGArtifact : public CArmedInstance
|
||||
@ -180,8 +185,9 @@ public:
|
||||
ui32 defaultResProduction() const;
|
||||
ui32 getProducedQuantity() const;
|
||||
|
||||
ResourceSet dailyIncome() const override;
|
||||
const IOwnableObject * asOwnable() const final;
|
||||
ResourceSet dailyIncome() const override;
|
||||
std::vector<CreatureID> providedCreatures() const override;
|
||||
|
||||
protected:
|
||||
void serializeJsonOptions(JsonSerializeFormat & handler) override;
|
||||
@ -403,7 +409,7 @@ protected:
|
||||
void setPropertyDer(ObjProperty what, ObjPropertyID identifier) override;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CGLighthouse : public CGObjectInstance
|
||||
class DLL_LINKAGE CGLighthouse : public CGObjectInstance, public IOwnableObject
|
||||
{
|
||||
public:
|
||||
using CGObjectInstance::CGObjectInstance;
|
||||
@ -411,6 +417,10 @@ public:
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
|
||||
const IOwnableObject * asOwnable() const final;
|
||||
ResourceSet dailyIncome() const override;
|
||||
std::vector<CreatureID> providedCreatures() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h)
|
||||
{
|
||||
h & static_cast<CGObjectInstance&>(*this);
|
||||
|
@ -1943,7 +1943,7 @@ void SetObjectProperty::applyGs(CGameState *gs)
|
||||
|
||||
auto * cai = dynamic_cast<CArmedInstance *>(obj);
|
||||
|
||||
if(what == ObjProperty::OWNER)
|
||||
if(what == ObjProperty::OWNER && obj->asOwnable())
|
||||
{
|
||||
PlayerColor oldOwner = obj->getOwner();
|
||||
PlayerColor newOwner = identifier.as<PlayerColor>();
|
||||
|
@ -555,25 +555,25 @@ 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 auto &dwellings = p->getDwellings();
|
||||
if (dwellings.empty())//no dwellings - just remove
|
||||
std::set<CreatureID> availableCreatures;
|
||||
for (const auto & dwelling : p->getOwnedObjects())
|
||||
{
|
||||
sendAndApply(&ssi);
|
||||
return;
|
||||
const auto & dwellingCreatures = dwelling->asOwnable()->providedCreatures();
|
||||
availableCreatures.insert(dwellingCreatures.begin(), dwellingCreatures.end());
|
||||
}
|
||||
|
||||
auto dwelling = *RandomGeneratorUtil::nextItem(dwellings, getRandomGenerator());
|
||||
if (availableCreatures.empty())
|
||||
return;
|
||||
|
||||
// for multi-creature dwellings like Golem Factory
|
||||
auto creatureId = RandomGeneratorUtil::nextItem(dwelling->creatures, getRandomGenerator())->second[0];
|
||||
CreatureID creatureId = *RandomGeneratorUtil::nextItem(availableCreatures, getRandomGenerator());
|
||||
|
||||
if (clear)
|
||||
{
|
||||
ssi.creatures[town->town->creatures.size()].first = std::max(1, (VLC->creh->objects.at(creatureId)->getGrowth())/2);
|
||||
ssi.creatures[town->town->creatures.size()].first = std::max(1, (creatureId.toEntity(VLC)->getGrowth())/2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ssi.creatures[town->town->creatures.size()].first = VLC->creh->objects.at(creatureId)->getGrowth();
|
||||
ssi.creatures[town->town->creatures.size()].first = creatureId.toEntity(VLC)->getGrowth();
|
||||
}
|
||||
ssi.creatures[town->town->creatures.size()].second.push_back(creatureId);
|
||||
sendAndApply(&ssi);
|
||||
@ -1284,9 +1284,7 @@ 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->getDwellings().size()==1)//first dwelling captured
|
||||
if ((obj->ID == Obj::CREATURE_GENERATOR1 || obj->ID == Obj::CREATURE_GENERATOR4))
|
||||
{
|
||||
for (const CGTownInstance * t : getPlayerState(owner)->getTowns())
|
||||
{
|
||||
|
@ -147,10 +147,7 @@ ResourceSet NewTurnProcessor::generatePlayerIncome(PlayerColor playerID, bool ne
|
||||
incomeHandicapped.applyHandicap(playerSettings->handicap.percentIncome);
|
||||
|
||||
for (auto obj : state.getOwnedObjects())
|
||||
{
|
||||
if (obj->asOwnable())
|
||||
incomeHandicapped += obj->asOwnable()->dailyIncome();
|
||||
}
|
||||
|
||||
return incomeHandicapped;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user