mirror of
https://github.com/vcmi/vcmi.git
synced 2025-09-16 09:26:28 +02:00
Merge branch 'develop' into timed_events_objects_removal
This commit is contained in:
@@ -45,7 +45,7 @@ int CGTownInstance::getSightRadius() const //returns sight distance
|
||||
|
||||
for(const auto & bid : builtBuildings)
|
||||
{
|
||||
auto height = town->buildings.at(bid)->height;
|
||||
auto height = getTown()->buildings.at(bid)->height;
|
||||
if(ret < height)
|
||||
ret = height;
|
||||
}
|
||||
@@ -115,7 +115,7 @@ int CGTownInstance::mageGuildLevel() const
|
||||
|
||||
int CGTownInstance::getHordeLevel(const int & HID) const//HID - 0 or 1; returns creature level or -1 if that horde structure is not present
|
||||
{
|
||||
return town->hordeLvl.at(HID);
|
||||
return getTown()->hordeLvl.at(HID);
|
||||
}
|
||||
|
||||
int CGTownInstance::creatureGrowth(const int & level) const
|
||||
@@ -127,7 +127,7 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
|
||||
{
|
||||
GrowthInfo ret;
|
||||
|
||||
if (level<0 || level >=town->creatures.size())
|
||||
if (level<0 || level >=getTown()->creatures.size())
|
||||
return ret;
|
||||
if (creatures[level].second.empty())
|
||||
return ret; //no dwelling
|
||||
@@ -151,11 +151,11 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
|
||||
else if (hasBuilt(BuildingID::CITADEL))
|
||||
ret.entries.emplace_back(subID, BuildingID::CITADEL, castleBonus = base / 2);
|
||||
|
||||
if(town->hordeLvl.at(0) == level)//horde 1
|
||||
if(getTown()->hordeLvl.at(0) == level)//horde 1
|
||||
if(hasBuilt(BuildingID::HORDE_1))
|
||||
ret.entries.emplace_back(subID, BuildingID::HORDE_1, creature->getHorde());
|
||||
|
||||
if(town->hordeLvl.at(1) == level)//horde 2
|
||||
if(getTown()->hordeLvl.at(1) == level)//horde 2
|
||||
if(hasBuilt(BuildingID::HORDE_2))
|
||||
ret.entries.emplace_back(subID, BuildingID::HORDE_2, creature->getHorde());
|
||||
|
||||
@@ -166,7 +166,7 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
|
||||
const auto growth = b->val * (base + castleBonus) / 100;
|
||||
if (growth)
|
||||
{
|
||||
ret.entries.emplace_back(growth, b->Description(growth));
|
||||
ret.entries.emplace_back(growth, b->Description(cb, growth));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
|
||||
// Note: bonus uses 1-based levels (Pikeman is level 1), town list uses 0-based (Pikeman in 0-th creatures entry)
|
||||
TConstBonusListPtr bonuses = getBonuses(Selector::typeSubtype(BonusType::CREATURE_GROWTH, BonusCustomSubtype::creatureLevel(level+1)));
|
||||
for(const auto & b : *bonuses)
|
||||
ret.entries.emplace_back(b->val, b->Description());
|
||||
ret.entries.emplace_back(b->val, b->Description(cb));
|
||||
|
||||
int dwellingBonus = 0;
|
||||
if(const PlayerState *p = cb->getPlayerState(tempOwner, false))
|
||||
@@ -209,11 +209,11 @@ int CGTownInstance::getDwellingBonus(const std::vector<CreatureID>& creatureIds,
|
||||
TResources CGTownInstance::dailyIncome() const
|
||||
{
|
||||
TResources ret;
|
||||
for(const auto & p : town->buildings)
|
||||
for(const auto & p : getTown()->buildings)
|
||||
{
|
||||
BuildingID buildingUpgrade;
|
||||
|
||||
for(const auto & p2 : town->buildings)
|
||||
for(const auto & p2 : getTown()->buildings)
|
||||
{
|
||||
if (p2.second->upgrade == p.first)
|
||||
{
|
||||
@@ -251,10 +251,10 @@ bool CGTownInstance::hasCapitol() const
|
||||
|
||||
TownFortifications CGTownInstance::fortificationsLevel() const
|
||||
{
|
||||
auto result = town->fortifications;
|
||||
auto result = getTown()->fortifications;
|
||||
|
||||
for (auto const & buildingID : builtBuildings)
|
||||
result += town->buildings.at(buildingID)->fortifications;
|
||||
result += getTown()->buildings.at(buildingID)->fortifications;
|
||||
|
||||
if (result.wallsHealth == 0)
|
||||
return TownFortifications();
|
||||
@@ -264,11 +264,13 @@ TownFortifications CGTownInstance::fortificationsLevel() const
|
||||
|
||||
CGTownInstance::CGTownInstance(IGameCallback *cb):
|
||||
CGDwelling(cb),
|
||||
town(nullptr),
|
||||
built(0),
|
||||
destroyed(0),
|
||||
identifier(0),
|
||||
alignmentToPlayer(PlayerColor::NEUTRAL)
|
||||
alignmentToPlayer(PlayerColor::NEUTRAL),
|
||||
spellResearchCounterDay(0),
|
||||
spellResearchAcceptedCounter(0),
|
||||
spellResearchAllowed(true)
|
||||
{
|
||||
this->setNodeType(CBonusSystemNode::TOWN);
|
||||
}
|
||||
@@ -347,7 +349,7 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
|
||||
scp.heroid = h->id;
|
||||
scp.which = SetCommanderProperty::ALIVE;
|
||||
scp.amount = 1;
|
||||
cb->sendAndApply(&scp);
|
||||
cb->sendAndApply(scp);
|
||||
}
|
||||
cb->heroVisitCastle(this, h);
|
||||
// TODO(vmarkovtsev): implement payment for rising the commander
|
||||
@@ -376,17 +378,17 @@ void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const
|
||||
|
||||
std::string CGTownInstance::getObjectName() const
|
||||
{
|
||||
return getNameTranslated() + ", " + (ID == Obj::RANDOM_TOWN ? "Random town" : getFaction().toEntity(VLC)->getNameTranslated());
|
||||
return getNameTranslated() + ", " + (ID == Obj::RANDOM_TOWN ? "Random town" : getTown()->faction->getNameTranslated());
|
||||
}
|
||||
|
||||
bool CGTownInstance::townEnvisagesBuilding(BuildingSubID::EBuildingSubID subId) const
|
||||
{
|
||||
return town->getBuildingType(subId) != BuildingID::NONE;
|
||||
return getTown()->getBuildingType(subId) != BuildingID::NONE;
|
||||
}
|
||||
|
||||
void CGTownInstance::initializeConfigurableBuildings(vstd::RNG & rand)
|
||||
{
|
||||
for(const auto & kvp : town->buildings)
|
||||
for(const auto & kvp : getTown()->buildings)
|
||||
{
|
||||
if(!kvp.second->rewardableObjectInfo.getParameters().isNull())
|
||||
rewardableBuildings[kvp.first] = new TownRewardableBuildingInstance(this, kvp.second->bid, rand);
|
||||
@@ -454,8 +456,7 @@ void CGTownInstance::pickRandomObject(vstd::RNG & rand)
|
||||
|
||||
assert(ID == Obj::TOWN); // just in case
|
||||
setType(ID, subID);
|
||||
town = (*VLC->townh)[getFaction()]->town;
|
||||
randomizeArmy(getFaction());
|
||||
randomizeArmy(getFactionID());
|
||||
updateAppearance();
|
||||
}
|
||||
|
||||
@@ -464,19 +465,19 @@ void CGTownInstance::initObj(vstd::RNG & rand) ///initialize town structures
|
||||
blockVisit = true;
|
||||
|
||||
if(townEnvisagesBuilding(BuildingSubID::PORTAL_OF_SUMMONING)) //Dungeon for example
|
||||
creatures.resize(town->creatures.size() + 1);
|
||||
creatures.resize(getTown()->creatures.size() + 1);
|
||||
else
|
||||
creatures.resize(town->creatures.size());
|
||||
creatures.resize(getTown()->creatures.size());
|
||||
|
||||
for (int level = 0; level < town->creatures.size(); level++)
|
||||
for (int level = 0; level < getTown()->creatures.size(); level++)
|
||||
{
|
||||
BuildingID buildID = BuildingID(BuildingID::getDwellingFromLevel(level, 0));
|
||||
int upgradeNum = 0;
|
||||
|
||||
for (; town->buildings.count(buildID); upgradeNum++, BuildingID::advanceDwelling(buildID))
|
||||
for (; getTown()->buildings.count(buildID); upgradeNum++, BuildingID::advanceDwelling(buildID))
|
||||
{
|
||||
if (hasBuilt(buildID) && town->creatures.at(level).size() > upgradeNum)
|
||||
creatures[level].second.push_back(town->creatures[level][upgradeNum]);
|
||||
if (hasBuilt(buildID) && getTown()->creatures.at(level).size() > upgradeNum)
|
||||
creatures[level].second.push_back(getTown()->creatures[level][upgradeNum]);
|
||||
}
|
||||
}
|
||||
initializeConfigurableBuildings(rand);
|
||||
@@ -620,15 +621,15 @@ 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 (const auto & town : state->getTowns())
|
||||
for (const auto & otherTown : state->getTowns())
|
||||
{
|
||||
if (town != this && town->hasCapitol())
|
||||
if (otherTown != this && otherTown->hasCapitol())
|
||||
{
|
||||
RazeStructures rs;
|
||||
rs.tid = id;
|
||||
rs.bid.insert(BuildingID::CAPITOL);
|
||||
rs.destroyed = destroyed;
|
||||
cb->sendAndApply(&rs);
|
||||
cb->sendAndApply(rs);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -645,7 +646,7 @@ void CGTownInstance::clearArmy() const
|
||||
|
||||
BoatId CGTownInstance::getBoatType() const
|
||||
{
|
||||
return town->faction->boatType;
|
||||
return getTown()->faction->boatType;
|
||||
}
|
||||
|
||||
int CGTownInstance::getMarketEfficiency() const
|
||||
@@ -669,11 +670,9 @@ std::vector<TradeItemBuy> CGTownInstance::availableItemsIds(EMarketMode mode) co
|
||||
if(mode == EMarketMode::RESOURCE_ARTIFACT)
|
||||
{
|
||||
std::vector<TradeItemBuy> ret;
|
||||
for(const CArtifact *a : cb->gameState()->map->townMerchantArtifacts)
|
||||
if(a)
|
||||
ret.push_back(a->getId());
|
||||
else
|
||||
ret.push_back(ArtifactID{});
|
||||
for(const ArtifactID a : cb->gameState()->map->townMerchantArtifacts)
|
||||
ret.push_back(a);
|
||||
|
||||
return ret;
|
||||
}
|
||||
else if ( mode == EMarketMode::RESOURCE_SKILL )
|
||||
@@ -691,7 +690,7 @@ ObjectInstanceID CGTownInstance::getObjInstanceID() const
|
||||
|
||||
void CGTownInstance::updateAppearance()
|
||||
{
|
||||
auto terrain = cb->gameState()->getTile(visitablePos())->terType->getId();
|
||||
auto terrain = cb->gameState()->getTile(visitablePos())->getTerrainID();
|
||||
//FIXME: not the best way to do this
|
||||
auto app = getObjectHandler()->getOverride(terrain, this);
|
||||
if (app)
|
||||
@@ -700,7 +699,7 @@ void CGTownInstance::updateAppearance()
|
||||
|
||||
std::string CGTownInstance::nodeName() const
|
||||
{
|
||||
return "Town (" + (town ? town->faction->getNameTranslated() : "unknown") + ") of " + getNameTranslated();
|
||||
return "Town (" + getTown()->faction->getNameTranslated() + ") of " + getNameTranslated();
|
||||
}
|
||||
|
||||
void CGTownInstance::deserializationFix()
|
||||
@@ -749,7 +748,7 @@ void CGTownInstance::recreateBuildingsBonuses()
|
||||
|
||||
for(const auto & upgradeID : builtBuildings)
|
||||
{
|
||||
const auto & upgrade = town->buildings.at(upgradeID);
|
||||
const auto & upgrade = getTown()->buildings.at(upgradeID);
|
||||
if (upgrade->getBase() == bid && upgrade->upgradeReplacesBonuses)
|
||||
bonusesReplacedByUpgrade = true;
|
||||
}
|
||||
@@ -758,7 +757,7 @@ void CGTownInstance::recreateBuildingsBonuses()
|
||||
if (bonusesReplacedByUpgrade)
|
||||
continue;
|
||||
|
||||
auto building = town->buildings.at(bid);
|
||||
auto building = getTown()->buildings.at(bid);
|
||||
|
||||
if(building->buildingBonuses.empty())
|
||||
continue;
|
||||
@@ -825,21 +824,6 @@ bool CGTownInstance::armedGarrison() const
|
||||
return !stacks.empty() || garrisonHero;
|
||||
}
|
||||
|
||||
const CTown * CGTownInstance::getTown() const
|
||||
{
|
||||
if(ID == Obj::RANDOM_TOWN)
|
||||
return VLC->townh->randomTown;
|
||||
else
|
||||
{
|
||||
if(nullptr == town)
|
||||
{
|
||||
return (*VLC->townh)[getFaction()]->town;
|
||||
}
|
||||
else
|
||||
return town;
|
||||
}
|
||||
}
|
||||
|
||||
int CGTownInstance::getTownLevel() const
|
||||
{
|
||||
// count all buildings that are not upgrades
|
||||
@@ -847,7 +831,7 @@ int CGTownInstance::getTownLevel() const
|
||||
|
||||
for(const auto & bid : builtBuildings)
|
||||
{
|
||||
if(town->buildings.at(bid)->upgrade == BuildingID::NONE)
|
||||
if(getTown()->buildings.at(bid)->upgrade == BuildingID::NONE)
|
||||
level++;
|
||||
}
|
||||
return level;
|
||||
@@ -889,7 +873,7 @@ bool CGTownInstance::hasBuilt(BuildingSubID::EBuildingSubID buildingID) const
|
||||
{
|
||||
for(const auto & bid : builtBuildings)
|
||||
{
|
||||
if(town->buildings.at(bid)->subId == buildingID)
|
||||
if(getTown()->buildings.at(bid)->subId == buildingID)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -902,7 +886,7 @@ bool CGTownInstance::hasBuilt(const BuildingID & buildingID) const
|
||||
|
||||
bool CGTownInstance::hasBuilt(const BuildingID & buildingID, FactionID townID) const
|
||||
{
|
||||
if (townID == town->faction->getId() || townID == FactionID::ANY)
|
||||
if (townID == getTown()->faction->getId() || townID == FactionID::ANY)
|
||||
return hasBuilt(buildingID);
|
||||
return false;
|
||||
}
|
||||
@@ -920,7 +904,7 @@ std::set<EMarketMode> CGTownInstance::availableModes() const
|
||||
std::set<EMarketMode> result;
|
||||
for (const auto & buildingID : builtBuildings)
|
||||
{
|
||||
const auto * buildingPtr = town->buildings.at(buildingID).get();
|
||||
const auto * buildingPtr = getTown()->buildings.at(buildingID).get();
|
||||
result.insert(buildingPtr->marketModes.begin(), buildingPtr->marketModes.end());
|
||||
}
|
||||
|
||||
@@ -947,11 +931,11 @@ std::set<BuildingID> CGTownInstance::getBuildings() const
|
||||
|
||||
TResources CGTownInstance::getBuildingCost(const BuildingID & buildingID) const
|
||||
{
|
||||
if (vstd::contains(town->buildings, buildingID))
|
||||
return town->buildings.at(buildingID)->resources;
|
||||
if (vstd::contains(getTown()->buildings, buildingID))
|
||||
return getTown()->buildings.at(buildingID)->resources;
|
||||
else
|
||||
{
|
||||
logGlobal->error("Town %s at %s has no possible building %d!", getNameTranslated(), pos.toString(), buildingID.toEnum());
|
||||
logGlobal->error("Town %s at %s has no possible building %d!", getNameTranslated(), anchorPos().toString(), buildingID.toEnum());
|
||||
return TResources();
|
||||
}
|
||||
|
||||
@@ -959,7 +943,7 @@ TResources CGTownInstance::getBuildingCost(const BuildingID & buildingID) const
|
||||
|
||||
CBuilding::TRequired CGTownInstance::genBuildingRequirements(const BuildingID & buildID, bool deep) const
|
||||
{
|
||||
const CBuilding * building = town->buildings.at(buildID);
|
||||
const CBuilding * building = getTown()->buildings.at(buildID);
|
||||
|
||||
//TODO: find better solution to prevent infinite loops
|
||||
std::set<BuildingID> processed;
|
||||
@@ -967,13 +951,13 @@ CBuilding::TRequired CGTownInstance::genBuildingRequirements(const BuildingID &
|
||||
std::function<CBuilding::TRequired::Variant(const BuildingID &)> dependTest =
|
||||
[&](const BuildingID & id) -> CBuilding::TRequired::Variant
|
||||
{
|
||||
if (town->buildings.count(id) == 0)
|
||||
if (getTown()->buildings.count(id) == 0)
|
||||
{
|
||||
logMod->error("Invalid building ID %d in building dependencies!", id.getNum());
|
||||
return CBuilding::TRequired::OperatorAll();
|
||||
}
|
||||
|
||||
const CBuilding * build = town->buildings.at(id);
|
||||
const CBuilding * build = getTown()->buildings.at(id);
|
||||
CBuilding::TRequired::OperatorAll requirements;
|
||||
|
||||
if (!hasBuilt(id))
|
||||
@@ -998,7 +982,7 @@ CBuilding::TRequired CGTownInstance::genBuildingRequirements(const BuildingID &
|
||||
CBuilding::TRequired::OperatorAll requirements;
|
||||
if (building->upgrade != BuildingID::NONE)
|
||||
{
|
||||
const CBuilding * upgr = town->buildings.at(building->upgrade);
|
||||
const CBuilding * upgr = getTown()->buildings.at(building->upgrade);
|
||||
|
||||
requirements.expressions.push_back(dependTest(upgr->bid));
|
||||
processed.clear();
|
||||
@@ -1148,14 +1132,27 @@ void CGTownInstance::serializeJsonOptions(JsonSerializeFormat & handler)
|
||||
}
|
||||
}
|
||||
|
||||
FactionID CGTownInstance::getFaction() const
|
||||
const CFaction * CGTownInstance::getFaction() const
|
||||
{
|
||||
return FactionID(subID.getNum());
|
||||
return getFactionID().toFaction();
|
||||
}
|
||||
|
||||
const CTown * CGTownInstance::getTown() const
|
||||
{
|
||||
if(ID == Obj::RANDOM_TOWN)
|
||||
return VLC->townh->randomTown;
|
||||
|
||||
return getFaction()->town;
|
||||
}
|
||||
|
||||
FactionID CGTownInstance::getFactionID() const
|
||||
{
|
||||
return FactionID(subID.getNum());
|
||||
}
|
||||
|
||||
TerrainId CGTownInstance::getNativeTerrain() const
|
||||
{
|
||||
return town->faction->getNativeTerrain();
|
||||
return getTown()->faction->getNativeTerrain();
|
||||
}
|
||||
|
||||
ArtifactID CGTownInstance::getWarMachineInBuilding(BuildingID building) const
|
||||
@@ -1163,21 +1160,21 @@ ArtifactID CGTownInstance::getWarMachineInBuilding(BuildingID building) const
|
||||
if (builtBuildings.count(building) == 0)
|
||||
return ArtifactID::NONE;
|
||||
|
||||
if (building == BuildingID::BLACKSMITH && town->warMachineDeprecated.hasValue())
|
||||
return town->warMachineDeprecated.toCreature()->warMachine;
|
||||
if (building == BuildingID::BLACKSMITH && getTown()->warMachineDeprecated.hasValue())
|
||||
return getTown()->warMachineDeprecated.toCreature()->warMachine;
|
||||
|
||||
return town->buildings.at(building)->warMachine;
|
||||
return getTown()->buildings.at(building)->warMachine;
|
||||
}
|
||||
|
||||
bool CGTownInstance::isWarMachineAvailable(ArtifactID warMachine) const
|
||||
{
|
||||
for (auto const & buildingID : builtBuildings)
|
||||
if (town->buildings.at(buildingID)->warMachine == warMachine)
|
||||
if (getTown()->buildings.at(buildingID)->warMachine == warMachine)
|
||||
return true;
|
||||
|
||||
if (builtBuildings.count(BuildingID::BLACKSMITH) &&
|
||||
town->warMachineDeprecated.hasValue() &&
|
||||
town->warMachineDeprecated.toCreature()->warMachine == warMachine)
|
||||
getTown()->warMachineDeprecated.hasValue() &&
|
||||
getTown()->warMachineDeprecated.toCreature()->warMachine == warMachine)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -1197,7 +1194,7 @@ GrowthInfo::Entry::Entry(int subID, const BuildingID & building, int _count): co
|
||||
{
|
||||
MetaString formatter;
|
||||
formatter.appendRawString("%s %+d");
|
||||
formatter.replaceRawString((*VLC->townh)[subID]->town->buildings.at(building)->getNameTranslated());
|
||||
formatter.replaceRawString(FactionID(subID).toFaction()->town->buildings.at(building)->getNameTranslated());
|
||||
formatter.replacePositiveNumber(count);
|
||||
|
||||
description = formatter.toString();
|
||||
@@ -1228,14 +1225,14 @@ void CGTownInstance::fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &s
|
||||
{
|
||||
for(const CGTownInstance::TCreaturesSet::value_type & dwelling : creatures)
|
||||
{
|
||||
if (vstd::contains(dwelling.second, stack.type->getId())) //Dwelling with our creature
|
||||
if (vstd::contains(dwelling.second, stack.getId())) //Dwelling with our creature
|
||||
{
|
||||
for(const auto & upgrID : dwelling.second)
|
||||
{
|
||||
if(vstd::contains(stack.type->upgrades, upgrID)) //possible upgrade
|
||||
if(vstd::contains(stack.getCreature()->upgrades, upgrID)) //possible upgrade
|
||||
{
|
||||
info.newID.push_back(upgrID);
|
||||
info.cost.push_back(upgrID.toCreature()->getFullRecruitCost() - stack.type->getFullRecruitCost());
|
||||
info.cost.push_back(upgrID.toCreature()->getFullRecruitCost() - stack.getType()->getFullRecruitCost());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user