mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-21 17:17:06 +02:00
Reduce usage of pointers to VLC entities
Final goal (of multiple PR's) is to remove all remaining pointers from serializeable game state, and replace them with either identifiers or with shared/unique pointers. CGTownInstance::town and CGHeroInstance::type members have been removed. Now this data is computed dynamically using subID member. VLC entity of a town can now be accessed via following methods: - getFactionID() returns ID of a faction - getFaction() returns pointer to a faction - getTown() returns pointer to a town VLC entity of a hero can now be accessed via following methods: - getHeroTypeID() returns ID of a hero - getHeroClassID() returns ID of a hero class - getHeroType() returns pointer to a hero - getHeroClass() returns pointer to a hero class
This commit is contained in:
parent
81f0222c68
commit
3dd4fa2528
@ -1454,7 +1454,7 @@ bool AIGateway::moveHeroToTile(int3 dst, HeroPtr h)
|
|||||||
|
|
||||||
void AIGateway::buildStructure(const CGTownInstance * t, BuildingID building)
|
void AIGateway::buildStructure(const CGTownInstance * t, BuildingID building)
|
||||||
{
|
{
|
||||||
auto name = t->town->buildings.at(building)->getNameTranslated();
|
auto name = t->getTown()->buildings.at(building)->getNameTranslated();
|
||||||
logAi->debug("Player %d will build %s in town of %s at %s", ai->playerID, name, t->getNameTranslated(), t->anchorPos().toString());
|
logAi->debug("Player %d will build %s in town of %s at %s", ai->playerID, name, t->getNameTranslated(), t->anchorPos().toString());
|
||||||
cb->buildBuilding(t, building); //just do this;
|
cb->buildBuilding(t, building); //just do this;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ std::vector<SlotInfo> ArmyManager::getBestArmy(const IBonusBearer * armyCarrier,
|
|||||||
|
|
||||||
for(auto & slot : sortedSlots)
|
for(auto & slot : sortedSlots)
|
||||||
{
|
{
|
||||||
alignmentMap[slot.creature->getFaction()] += slot.power;
|
alignmentMap[slot.creature->getFactionID()] += slot.power;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<FactionID> allowedFactions;
|
std::set<FactionID> allowedFactions;
|
||||||
@ -178,7 +178,7 @@ std::vector<SlotInfo> ArmyManager::getBestArmy(const IBonusBearer * armyCarrier,
|
|||||||
|
|
||||||
for(auto & slot : sortedSlots)
|
for(auto & slot : sortedSlots)
|
||||||
{
|
{
|
||||||
if(vstd::contains(allowedFactions, slot.creature->getFaction()))
|
if(vstd::contains(allowedFactions, slot.creature->getFactionID()))
|
||||||
{
|
{
|
||||||
auto slotID = newArmyInstance.getSlotFor(slot.creature->getId());
|
auto slotID = newArmyInstance.getSlotFor(slot.creature->getId());
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ namespace NKAI
|
|||||||
|
|
||||||
void BuildAnalyzer::updateTownDwellings(TownDevelopmentInfo & developmentInfo)
|
void BuildAnalyzer::updateTownDwellings(TownDevelopmentInfo & developmentInfo)
|
||||||
{
|
{
|
||||||
auto townInfo = developmentInfo.town->town;
|
auto townInfo = developmentInfo.town->getTown();
|
||||||
auto creatures = townInfo->creatures;
|
auto creatures = townInfo->creatures;
|
||||||
auto buildings = townInfo->getAllBuildings();
|
auto buildings = townInfo->getAllBuildings();
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ void BuildAnalyzer::updateTownDwellings(TownDevelopmentInfo & developmentInfo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int level = 0; level < developmentInfo.town->town->creatures.size(); level++)
|
for(int level = 0; level < developmentInfo.town->getTown()->creatures.size(); level++)
|
||||||
{
|
{
|
||||||
logAi->trace("Checking dwelling level %d", level);
|
logAi->trace("Checking dwelling level %d", level);
|
||||||
BuildingInfo nextToBuild = BuildingInfo();
|
BuildingInfo nextToBuild = BuildingInfo();
|
||||||
@ -82,7 +82,7 @@ void BuildAnalyzer::updateOtherBuildings(TownDevelopmentInfo & developmentInfo)
|
|||||||
{
|
{
|
||||||
for(auto & buildingID : buildingSet)
|
for(auto & buildingID : buildingSet)
|
||||||
{
|
{
|
||||||
if(!developmentInfo.town->hasBuilt(buildingID) && developmentInfo.town->town->buildings.count(buildingID))
|
if(!developmentInfo.town->hasBuilt(buildingID) && developmentInfo.town->getTown()->buildings.count(buildingID))
|
||||||
{
|
{
|
||||||
developmentInfo.addBuildingToBuild(getBuildingOrPrerequisite(developmentInfo.town, buildingID));
|
developmentInfo.addBuildingToBuild(getBuildingOrPrerequisite(developmentInfo.town, buildingID));
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ BuildingInfo BuildAnalyzer::getBuildingOrPrerequisite(
|
|||||||
bool excludeDwellingDependencies) const
|
bool excludeDwellingDependencies) const
|
||||||
{
|
{
|
||||||
BuildingID building = toBuild;
|
BuildingID building = toBuild;
|
||||||
auto townInfo = town->town;
|
auto townInfo = town->getTown();
|
||||||
|
|
||||||
const CBuilding * buildPtr = townInfo->buildings.at(building);
|
const CBuilding * buildPtr = townInfo->buildings.at(building);
|
||||||
const CCreature * creature = nullptr;
|
const CCreature * creature = nullptr;
|
||||||
@ -327,7 +327,7 @@ bool BuildAnalyzer::hasAnyBuilding(int32_t alignment, BuildingID bid) const
|
|||||||
{
|
{
|
||||||
for(auto tdi : developmentInfos)
|
for(auto tdi : developmentInfos)
|
||||||
{
|
{
|
||||||
if(tdi.town->getFaction() == alignment && tdi.town->hasBuilt(bid))
|
if(tdi.town->getFactionID() == alignment && tdi.town->hasBuilt(bid))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ float HeroManager::evaluateSecSkill(SecondarySkill skill, const CGHeroInstance *
|
|||||||
|
|
||||||
float HeroManager::evaluateSpeciality(const CGHeroInstance * hero) const
|
float HeroManager::evaluateSpeciality(const CGHeroInstance * hero) const
|
||||||
{
|
{
|
||||||
auto heroSpecial = Selector::source(BonusSource::HERO_SPECIAL, BonusSourceID(hero->type->getId()));
|
auto heroSpecial = Selector::source(BonusSource::HERO_SPECIAL, BonusSourceID(hero->getHeroTypeID()));
|
||||||
auto secondarySkillBonus = Selector::targetSourceType()(BonusSource::SECONDARY_SKILL);
|
auto secondarySkillBonus = Selector::targetSourceType()(BonusSource::SECONDARY_SKILL);
|
||||||
auto specialSecondarySkillBonuses = hero->getBonuses(heroSpecial.And(secondarySkillBonus));
|
auto specialSecondarySkillBonuses = hero->getBonuses(heroSpecial.And(secondarySkillBonus));
|
||||||
auto secondarySkillBonuses = hero->getBonuses(Selector::sourceTypeSel(BonusSource::SECONDARY_SKILL));
|
auto secondarySkillBonuses = hero->getBonuses(Selector::sourceTypeSel(BonusSource::SECONDARY_SKILL));
|
||||||
|
@ -1120,7 +1120,7 @@ public:
|
|||||||
|
|
||||||
uint64_t RewardEvaluator::getUpgradeArmyReward(const CGTownInstance * town, const BuildingInfo & bi) const
|
uint64_t RewardEvaluator::getUpgradeArmyReward(const CGTownInstance * town, const BuildingInfo & bi) const
|
||||||
{
|
{
|
||||||
if(ai->buildAnalyzer->hasAnyBuilding(town->getFaction(), bi.id))
|
if(ai->buildAnalyzer->hasAnyBuilding(town->getFactionID(), bi.id))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto creaturesToUpgrade = ai->armyManager->getTotalCreaturesAvailable(bi.baseCreatureID);
|
auto creaturesToUpgrade = ai->armyManager->getTotalCreaturesAvailable(bi.baseCreatureID);
|
||||||
|
@ -23,7 +23,7 @@ BuildThis::BuildThis(BuildingID Bid, const CGTownInstance * tid)
|
|||||||
: ElementarGoal(Goals::BUILD_STRUCTURE)
|
: ElementarGoal(Goals::BUILD_STRUCTURE)
|
||||||
{
|
{
|
||||||
buildingInfo = BuildingInfo(
|
buildingInfo = BuildingInfo(
|
||||||
tid->town->buildings.at(Bid),
|
tid->getTown()->buildings.at(Bid),
|
||||||
nullptr,
|
nullptr,
|
||||||
CreatureID::NONE,
|
CreatureID::NONE,
|
||||||
tid,
|
tid,
|
||||||
@ -52,7 +52,7 @@ void BuildThis::accept(AIGateway * ai)
|
|||||||
if(cb->canBuildStructure(town, b) == EBuildingState::ALLOWED)
|
if(cb->canBuildStructure(town, b) == EBuildingState::ALLOWED)
|
||||||
{
|
{
|
||||||
logAi->debug("Player %d will build %s in town of %s at %s",
|
logAi->debug("Player %d will build %s in town of %s at %s",
|
||||||
ai->playerID, town->town->buildings.at(b)->getNameTranslated(), town->getNameTranslated(), town->anchorPos().toString());
|
ai->playerID, town->getTown()->buildings.at(b)->getNameTranslated(), town->getNameTranslated(), town->anchorPos().toString());
|
||||||
cb->buildBuilding(town, b);
|
cb->buildBuilding(town, b);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -23,13 +23,13 @@ bool BuildingManager::tryBuildThisStructure(const CGTownInstance * t, BuildingID
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vstd::contains(t->town->buildings, building))
|
if (!vstd::contains(t->getTown()->buildings, building))
|
||||||
return false; // no such building in town
|
return false; // no such building in town
|
||||||
|
|
||||||
if (t->hasBuilt(building)) //Already built? Shouldn't happen in general
|
if (t->hasBuilt(building)) //Already built? Shouldn't happen in general
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
const CBuilding * buildPtr = t->town->buildings.at(building);
|
const CBuilding * buildPtr = t->getTown()->buildings.at(building);
|
||||||
|
|
||||||
auto toBuild = buildPtr->requirements.getFulfillmentCandidates([&](const BuildingID & buildID)
|
auto toBuild = buildPtr->requirements.getFulfillmentCandidates([&](const BuildingID & buildID)
|
||||||
{
|
{
|
||||||
@ -51,7 +51,7 @@ bool BuildingManager::tryBuildThisStructure(const CGTownInstance * t, BuildingID
|
|||||||
|
|
||||||
for (const auto & buildID : toBuild)
|
for (const auto & buildID : toBuild)
|
||||||
{
|
{
|
||||||
const CBuilding * b = t->town->buildings.at(buildID);
|
const CBuilding * b = t->getTown()->buildings.at(buildID);
|
||||||
|
|
||||||
EBuildingState canBuild = cb->canBuildStructure(t, buildID);
|
EBuildingState canBuild = cb->canBuildStructure(t, buildID);
|
||||||
if (canBuild == EBuildingState::ALLOWED)
|
if (canBuild == EBuildingState::ALLOWED)
|
||||||
@ -220,7 +220,7 @@ bool BuildingManager::getBuildingOptions(const CGTownInstance * t)
|
|||||||
|
|
||||||
//at the end, try to get and build any extra buildings with nonstandard slots (for example HotA 3rd level dwelling)
|
//at the end, try to get and build any extra buildings with nonstandard slots (for example HotA 3rd level dwelling)
|
||||||
std::vector<BuildingID> extraBuildings;
|
std::vector<BuildingID> extraBuildings;
|
||||||
for (auto buildingInfo : t->town->buildings)
|
for (auto buildingInfo : t->getTown()->buildings)
|
||||||
{
|
{
|
||||||
if (buildingInfo.first > BuildingID::DWELL_UP2_FIRST)
|
if (buildingInfo.first > BuildingID::DWELL_UP2_FIRST)
|
||||||
extraBuildings.push_back(buildingInfo.first);
|
extraBuildings.push_back(buildingInfo.first);
|
||||||
|
@ -56,7 +56,7 @@ TSubgoal BuildThis::whatToDoToAchieve()
|
|||||||
case EBuildingState::ALLOWED:
|
case EBuildingState::ALLOWED:
|
||||||
case EBuildingState::NO_RESOURCES:
|
case EBuildingState::NO_RESOURCES:
|
||||||
{
|
{
|
||||||
auto res = town->town->buildings.at(BuildingID(bid))->resources;
|
auto res = town->getTown()->buildings.at(BuildingID(bid))->resources;
|
||||||
return ai->ah->whatToDo(res, iAmElementar()); //realize immediately or gather resources
|
return ai->ah->whatToDo(res, iAmElementar()); //realize immediately or gather resources
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -88,13 +88,13 @@ TGoalVec GatherTroops::getAllPossibleSubgoals()
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto creature = VLC->creatures()->getByIndex(objid);
|
auto creature = VLC->creatures()->getByIndex(objid);
|
||||||
if(t->getFaction() == creature->getFaction()) //TODO: how to force AI to build unupgraded creatures? :O
|
if(t->getFactionID() == creature->getFactionID()) //TODO: how to force AI to build unupgraded creatures? :O
|
||||||
{
|
{
|
||||||
auto tryFindCreature = [&]() -> std::optional<std::vector<CreatureID>>
|
auto tryFindCreature = [&]() -> std::optional<std::vector<CreatureID>>
|
||||||
{
|
{
|
||||||
if(vstd::isValidIndex(t->town->creatures, creature->getLevel() - 1))
|
if(vstd::isValidIndex(t->getTown()->creatures, creature->getLevel() - 1))
|
||||||
{
|
{
|
||||||
auto itr = t->town->creatures.begin();
|
auto itr = t->getTown()->creatures.begin();
|
||||||
std::advance(itr, creature->getLevel() - 1);
|
std::advance(itr, creature->getLevel() - 1);
|
||||||
return make_optional(*itr);
|
return make_optional(*itr);
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ TGoalVec GatherTroops::getAllPossibleSubgoals()
|
|||||||
if(upgradeNumber < 0)
|
if(upgradeNumber < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
BuildingID bid(BuildingID::DWELL_FIRST + creature->getLevel() - 1 + upgradeNumber * t->town->creatures.size());
|
BuildingID bid(BuildingID::DWELL_FIRST + creature->getLevel() - 1 + upgradeNumber * t->getTown()->creatures.size());
|
||||||
if(t->hasBuilt(bid) && ai->ah->freeResources().canAfford(creature->getFullRecruitCost())) //this assumes only creatures with dwellings are assigned to faction
|
if(t->hasBuilt(bid) && ai->ah->freeResources().canAfford(creature->getFullRecruitCost())) //this assumes only creatures with dwellings are assigned to faction
|
||||||
{
|
{
|
||||||
solutions.push_back(sptr(BuyArmy(t, creature->getAIValue() * this->value).setobjid(objid)));
|
solutions.push_back(sptr(BuyArmy(t, creature->getAIValue() * this->value).setobjid(objid)));
|
||||||
|
@ -69,7 +69,7 @@ std::optional<int> MapObjectsEvaluator::getObjectValue(const CGObjectInstance *
|
|||||||
{
|
{
|
||||||
//special case handling: in-game heroes have hero ID as object subID, but when reading configs available hero object subID's are hero classes
|
//special case handling: in-game heroes have hero ID as object subID, but when reading configs available hero object subID's are hero classes
|
||||||
auto hero = dynamic_cast<const CGHeroInstance*>(obj);
|
auto hero = dynamic_cast<const CGHeroInstance*>(obj);
|
||||||
return getObjectValue(obj->ID, hero->type->heroClass->getIndex());
|
return getObjectValue(obj->ID, hero->getHeroClassID());
|
||||||
}
|
}
|
||||||
else if(obj->ID == Obj::PRISON)
|
else if(obj->ID == Obj::PRISON)
|
||||||
{
|
{
|
||||||
|
@ -1994,7 +1994,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
|||||||
|
|
||||||
void VCAI::buildStructure(const CGTownInstance * t, BuildingID building)
|
void VCAI::buildStructure(const CGTownInstance * t, BuildingID building)
|
||||||
{
|
{
|
||||||
auto name = t->town->buildings.at(building)->getNameTranslated();
|
auto name = t->getTown()->buildings.at(building)->getNameTranslated();
|
||||||
logAi->debug("Player %d will build %s in town of %s at %s", ai->playerID, name, t->getNameTranslated(), t->anchorPos().toString());
|
logAi->debug("Player %d will build %s in town of %s at %s", ai->playerID, name, t->getNameTranslated(), t->anchorPos().toString());
|
||||||
cb->buildBuilding(t, building); //just do this;
|
cb->buildBuilding(t, building); //just do this;
|
||||||
}
|
}
|
||||||
@ -2081,7 +2081,7 @@ void VCAI::tryRealize(Goals::BuildThis & g)
|
|||||||
if (cb->canBuildStructure(t, b) == EBuildingState::ALLOWED)
|
if (cb->canBuildStructure(t, b) == EBuildingState::ALLOWED)
|
||||||
{
|
{
|
||||||
logAi->debug("Player %d will build %s in town of %s at %s",
|
logAi->debug("Player %d will build %s in town of %s at %s",
|
||||||
playerID, t->town->buildings.at(b)->getNameTranslated(), t->getNameTranslated(), t->anchorPos().toString());
|
playerID, t->getTown()->buildings.at(b)->getNameTranslated(), t->getNameTranslated(), t->anchorPos().toString());
|
||||||
cb->buildBuilding(t, b);
|
cb->buildBuilding(t, b);
|
||||||
throw goalFulfilledException(sptr(g));
|
throw goalFulfilledException(sptr(g));
|
||||||
}
|
}
|
||||||
|
@ -319,7 +319,7 @@ void CCallback::recruitHero(const CGObjectInstance *townOrTavern, const CGHeroIn
|
|||||||
assert(townOrTavern);
|
assert(townOrTavern);
|
||||||
assert(hero);
|
assert(hero);
|
||||||
|
|
||||||
HireHero pack(hero->getHeroType(), townOrTavern->id, nextHero);
|
HireHero pack(hero->getHeroTypeID(), townOrTavern->id, nextHero);
|
||||||
pack.player = *player;
|
pack.player = *player;
|
||||||
sendRequest(pack);
|
sendRequest(pack);
|
||||||
}
|
}
|
||||||
|
@ -1138,7 +1138,7 @@ void CPlayerInterface::showMapObjectSelectDialog(QueryID askID, const Component
|
|||||||
const CGTownInstance * t = dynamic_cast<const CGTownInstance *>(cb->getObj(obj));
|
const CGTownInstance * t = dynamic_cast<const CGTownInstance *>(cb->getObj(obj));
|
||||||
if(t)
|
if(t)
|
||||||
{
|
{
|
||||||
auto image = GH.renderHandler().loadImage(AnimationPath::builtin("ITPA"), t->town->clientInfo.icons[t->hasFort()][false] + 2, 0, EImageBlitMode::OPAQUE);
|
auto image = GH.renderHandler().loadImage(AnimationPath::builtin("ITPA"), t->getTown()->clientInfo.icons[t->hasFort()][false] + 2, 0, EImageBlitMode::OPAQUE);
|
||||||
image->scaleTo(Point(35, 23));
|
image->scaleTo(Point(35, 23));
|
||||||
images.push_back(image);
|
images.push_back(image);
|
||||||
}
|
}
|
||||||
|
@ -453,7 +453,7 @@ void ClientCommandManager::handleTellCommand(std::istringstream& singleWordBuffe
|
|||||||
if(what == "hs")
|
if(what == "hs")
|
||||||
{
|
{
|
||||||
for(const CGHeroInstance* h : LOCPLINT->cb->getHeroesInfo())
|
for(const CGHeroInstance* h : LOCPLINT->cb->getHeroesInfo())
|
||||||
if(h->type->getIndex() == id1)
|
if(h->getHeroTypeID().getNum() == id1)
|
||||||
if(const CArtifactInstance* a = h->getArt(ArtifactPosition(id2)))
|
if(const CArtifactInstance* a = h->getArt(ArtifactPosition(id2)))
|
||||||
printCommandMessage(a->nodeName());
|
printCommandMessage(a->nodeName());
|
||||||
}
|
}
|
||||||
|
@ -671,7 +671,7 @@ void ApplyClientNetPackVisitor::visitSetHeroesInTown(SetHeroesInTown & pack)
|
|||||||
void ApplyClientNetPackVisitor::visitHeroRecruited(HeroRecruited & pack)
|
void ApplyClientNetPackVisitor::visitHeroRecruited(HeroRecruited & pack)
|
||||||
{
|
{
|
||||||
CGHeroInstance *h = gs.map->heroesOnMap.back();
|
CGHeroInstance *h = gs.map->heroesOnMap.back();
|
||||||
if(h->getHeroType() != pack.hid)
|
if(h->getHeroTypeID() != pack.hid)
|
||||||
{
|
{
|
||||||
logNetwork->error("Something wrong with hero recruited!");
|
logNetwork->error("Something wrong with hero recruited!");
|
||||||
}
|
}
|
||||||
|
@ -432,7 +432,7 @@ std::shared_ptr<CIntObject> CTownList::CTownItem::genSelection()
|
|||||||
|
|
||||||
void CTownList::CTownItem::update()
|
void CTownList::CTownItem::update()
|
||||||
{
|
{
|
||||||
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->built >= LOCPLINT->cb->getSettings().getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
|
size_t iconIndex = town->getTown()->clientInfo.icons[town->hasFort()][town->built >= LOCPLINT->cb->getSettings().getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
|
||||||
|
|
||||||
picture->setFrame(iconIndex + 2);
|
picture->setFrame(iconIndex + 2);
|
||||||
redraw();
|
redraw();
|
||||||
|
@ -389,13 +389,13 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her
|
|||||||
{
|
{
|
||||||
AnimationPath animationPath;
|
AnimationPath animationPath;
|
||||||
|
|
||||||
if(!hero->type->battleImage.empty())
|
if(!hero->getHeroType()->battleImage.empty())
|
||||||
animationPath = hero->type->battleImage;
|
animationPath = hero->getHeroType()->battleImage;
|
||||||
else
|
else
|
||||||
if(hero->gender == EHeroGender::FEMALE)
|
if(hero->gender == EHeroGender::FEMALE)
|
||||||
animationPath = hero->type->heroClass->imageBattleFemale;
|
animationPath = hero->getHeroClass()->imageBattleFemale;
|
||||||
else
|
else
|
||||||
animationPath = hero->type->heroClass->imageBattleMale;
|
animationPath = hero->getHeroClass()->imageBattleMale;
|
||||||
|
|
||||||
animation = GH.renderHandler().loadAnimation(animationPath, EImageBlitMode::ALPHA);
|
animation = GH.renderHandler().loadAnimation(animationPath, EImageBlitMode::ALPHA);
|
||||||
|
|
||||||
@ -1027,7 +1027,7 @@ void StackQueue::update()
|
|||||||
|
|
||||||
int32_t StackQueue::getSiegeShooterIconID()
|
int32_t StackQueue::getSiegeShooterIconID()
|
||||||
{
|
{
|
||||||
return owner.siegeController->getSiegedTown()->town->faction->getIndex();
|
return owner.siegeController->getSiegedTown()->getFactionID().getNum();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<uint32_t> StackQueue::getHoveredUnitIdIfAny() const
|
std::optional<uint32_t> StackQueue::getHoveredUnitIdIfAny() const
|
||||||
|
@ -58,14 +58,14 @@ ImagePath BattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisual
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string & prefix = town->town->clientInfo.siegePrefix;
|
const std::string & prefix = town->getTown()->clientInfo.siegePrefix;
|
||||||
std::string addit = std::to_string(getImageIndex());
|
std::string addit = std::to_string(getImageIndex());
|
||||||
|
|
||||||
switch(what)
|
switch(what)
|
||||||
{
|
{
|
||||||
case EWallVisual::BACKGROUND_WALL:
|
case EWallVisual::BACKGROUND_WALL:
|
||||||
{
|
{
|
||||||
auto faction = town->town->faction->getIndex();
|
auto faction = town->getFactionID();
|
||||||
|
|
||||||
if (faction == ETownType::RAMPART || faction == ETownType::NECROPOLIS || faction == ETownType::DUNGEON || faction == ETownType::STRONGHOLD)
|
if (faction == ETownType::RAMPART || faction == ETownType::NECROPOLIS || faction == ETownType::DUNGEON || faction == ETownType::STRONGHOLD)
|
||||||
return ImagePath::builtinTODO(prefix + "TPW1.BMP");
|
return ImagePath::builtinTODO(prefix + "TPW1.BMP");
|
||||||
@ -111,7 +111,7 @@ ImagePath BattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisual
|
|||||||
|
|
||||||
void BattleSiegeController::showWallPiece(Canvas & canvas, EWallVisual::EWallVisual what)
|
void BattleSiegeController::showWallPiece(Canvas & canvas, EWallVisual::EWallVisual what)
|
||||||
{
|
{
|
||||||
auto & ci = town->town->clientInfo;
|
auto & ci = town->getTown()->clientInfo;
|
||||||
auto const & pos = ci.siegePositions[what];
|
auto const & pos = ci.siegePositions[what];
|
||||||
|
|
||||||
if ( wallPieceImages[what] && pos.isValid())
|
if ( wallPieceImages[what] && pos.isValid())
|
||||||
@ -120,7 +120,7 @@ void BattleSiegeController::showWallPiece(Canvas & canvas, EWallVisual::EWallVis
|
|||||||
|
|
||||||
ImagePath BattleSiegeController::getBattleBackgroundName() const
|
ImagePath BattleSiegeController::getBattleBackgroundName() const
|
||||||
{
|
{
|
||||||
const std::string & prefix = town->town->clientInfo.siegePrefix;
|
const std::string & prefix = town->getTown()->clientInfo.siegePrefix;
|
||||||
return ImagePath::builtinTODO(prefix + "BACK.BMP");
|
return ImagePath::builtinTODO(prefix + "BACK.BMP");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,8 +130,8 @@ bool BattleSiegeController::getWallPieceExistence(EWallVisual::EWallVisual what)
|
|||||||
|
|
||||||
switch (what)
|
switch (what)
|
||||||
{
|
{
|
||||||
case EWallVisual::MOAT: return fortifications.hasMoat && town->town->clientInfo.siegePositions.at(EWallVisual::MOAT).isValid();
|
case EWallVisual::MOAT: return fortifications.hasMoat && town->getTown()->clientInfo.siegePositions.at(EWallVisual::MOAT).isValid();
|
||||||
case EWallVisual::MOAT_BANK: return fortifications.hasMoat && town->town->clientInfo.siegePositions.at(EWallVisual::MOAT_BANK).isValid();
|
case EWallVisual::MOAT_BANK: return fortifications.hasMoat && town->getTown()->clientInfo.siegePositions.at(EWallVisual::MOAT_BANK).isValid();
|
||||||
case EWallVisual::KEEP_BATTLEMENT: return fortifications.citadelHealth > 0 && owner.getBattle()->battleGetWallState(EWallPart::KEEP) != EWallState::DESTROYED;
|
case EWallVisual::KEEP_BATTLEMENT: return fortifications.citadelHealth > 0 && owner.getBattle()->battleGetWallState(EWallPart::KEEP) != EWallState::DESTROYED;
|
||||||
case EWallVisual::UPPER_BATTLEMENT: return fortifications.upperTowerHealth > 0 && owner.getBattle()->battleGetWallState(EWallPart::UPPER_TOWER) != EWallState::DESTROYED;
|
case EWallVisual::UPPER_BATTLEMENT: return fortifications.upperTowerHealth > 0 && owner.getBattle()->battleGetWallState(EWallPart::UPPER_TOWER) != EWallState::DESTROYED;
|
||||||
case EWallVisual::BOTTOM_BATTLEMENT: return fortifications.lowerTowerHealth > 0 && owner.getBattle()->battleGetWallState(EWallPart::BOTTOM_TOWER) != EWallState::DESTROYED;
|
case EWallVisual::BOTTOM_BATTLEMENT: return fortifications.lowerTowerHealth > 0 && owner.getBattle()->battleGetWallState(EWallPart::BOTTOM_TOWER) != EWallState::DESTROYED;
|
||||||
@ -218,8 +218,8 @@ Point BattleSiegeController::getTurretCreaturePosition( BattleHex position ) con
|
|||||||
if (posID != 0)
|
if (posID != 0)
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
town->town->clientInfo.siegePositions[posID].x,
|
town->getTown()->clientInfo.siegePositions[posID].x,
|
||||||
town->town->clientInfo.siegePositions[posID].y
|
town->getTown()->clientInfo.siegePositions[posID].y
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,8 +468,8 @@ void CInteractableTownTooltip::init(const CGTownInstance * town)
|
|||||||
LOCPLINT->showTavernWindow(town, nullptr, QueryID::NONE);
|
LOCPLINT->showTavernWindow(town, nullptr, QueryID::NONE);
|
||||||
}
|
}
|
||||||
}, [town]{
|
}, [town]{
|
||||||
if(!town->town->faction->getDescriptionTranslated().empty())
|
if(!town->getFaction()->getDescriptionTranslated().empty())
|
||||||
CRClickPopup::createAndPush(town->town->faction->getDescriptionTranslated());
|
CRClickPopup::createAndPush(town->getFaction()->getDescriptionTranslated());
|
||||||
});
|
});
|
||||||
fastMarket = std::make_shared<LRClickableArea>(Rect(143, 31, 30, 34), []()
|
fastMarket = std::make_shared<LRClickableArea>(Rect(143, 31, 30, 34), []()
|
||||||
{
|
{
|
||||||
@ -532,8 +532,7 @@ CreatureTooltip::CreatureTooltip(Point pos, const CGCreature * creature)
|
|||||||
{
|
{
|
||||||
OBJECT_CONSTRUCTION;
|
OBJECT_CONSTRUCTION;
|
||||||
|
|
||||||
auto creatureID = creature->getCreature();
|
int32_t creatureIconIndex = creature->getCreature()->getIconIndex();
|
||||||
int32_t creatureIconIndex = CGI->creatures()->getById(creatureID)->getIconIndex();
|
|
||||||
|
|
||||||
creatureImage = std::make_shared<CAnimImage>(AnimationPath::builtin("TWCRPORT"), creatureIconIndex);
|
creatureImage = std::make_shared<CAnimImage>(AnimationPath::builtin("TWCRPORT"), creatureIconIndex);
|
||||||
creatureImage->center(Point(parent->pos.x + parent->pos.w / 2, parent->pos.y + creatureImage->pos.h / 2 + 11));
|
creatureImage->center(Point(parent->pos.x + parent->pos.w / 2, parent->pos.y + creatureImage->pos.h / 2 + 11));
|
||||||
@ -633,7 +632,7 @@ CCreaturePic::CCreaturePic(int x, int y, const CCreature * cre, bool Big, bool A
|
|||||||
pos.x+=x;
|
pos.x+=x;
|
||||||
pos.y+=y;
|
pos.y+=y;
|
||||||
|
|
||||||
auto faction = cre->getFaction();
|
auto faction = cre->getFactionID();
|
||||||
|
|
||||||
assert(CGI->townh->size() > faction);
|
assert(CGI->townh->size() > faction);
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ CBuildingRect::CBuildingRect(CCastleBuildings * Par, const CGTownInstance * Town
|
|||||||
|
|
||||||
// special animation frame manipulation for castle shipyard with and without ship
|
// special animation frame manipulation for castle shipyard with and without ship
|
||||||
// done due to .def used in special way, not to animate building - first image is for shipyard without citadel moat, 2nd image is for including moat
|
// done due to .def used in special way, not to animate building - first image is for shipyard without citadel moat, 2nd image is for including moat
|
||||||
if(Town->town->faction->getId() == FactionID::CASTLE && Str->building &&
|
if(Town->getFactionID() == FactionID::CASTLE && Str->building &&
|
||||||
(Str->building->bid == BuildingID::SHIPYARD || Str->building->bid == BuildingID::SHIP))
|
(Str->building->bid == BuildingID::SHIPYARD || Str->building->bid == BuildingID::SHIP))
|
||||||
{
|
{
|
||||||
if(Town->hasBuilt(BuildingID::CITADEL))
|
if(Town->hasBuilt(BuildingID::CITADEL))
|
||||||
@ -107,7 +107,7 @@ const CBuilding * CBuildingRect::getBuilding()
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (str->hiddenUpgrade) // hidden upgrades, e.g. hordes - return base (dwelling for hordes)
|
if (str->hiddenUpgrade) // hidden upgrades, e.g. hordes - return base (dwelling for hordes)
|
||||||
return town->town->buildings.at(str->building->getBase());
|
return town->getTown()->buildings.at(str->building->getBase());
|
||||||
|
|
||||||
return str->building;
|
return str->building;
|
||||||
}
|
}
|
||||||
@ -156,7 +156,7 @@ void CBuildingRect::showPopupWindow(const Point & cursorPosition)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
BuildingID bid = getBuilding()->bid;
|
BuildingID bid = getBuilding()->bid;
|
||||||
const CBuilding *bld = town->town->buildings.at(bid);
|
const CBuilding *bld = town->getTown()->buildings.at(bid);
|
||||||
if (bid < BuildingID::DWELL_FIRST)
|
if (bid < BuildingID::DWELL_FIRST)
|
||||||
{
|
{
|
||||||
CRClickPopup::createAndPush(CInfoWindow::genText(bld->getNameTranslated(), bld->getDescriptionTranslated()),
|
CRClickPopup::createAndPush(CInfoWindow::genText(bld->getNameTranslated(), bld->getDescriptionTranslated()),
|
||||||
@ -235,10 +235,10 @@ std::string CBuildingRect::getSubtitle()//hover text for building
|
|||||||
int bid = getBuilding()->bid;
|
int bid = getBuilding()->bid;
|
||||||
|
|
||||||
if (bid<30)//non-dwellings - only building name
|
if (bid<30)//non-dwellings - only building name
|
||||||
return town->town->buildings.at(getBuilding()->bid)->getNameTranslated();
|
return town->getTown()->buildings.at(getBuilding()->bid)->getNameTranslated();
|
||||||
else//dwellings - recruit %creature%
|
else//dwellings - recruit %creature%
|
||||||
{
|
{
|
||||||
auto & availableCreatures = town->creatures[(bid-30)%town->town->creatures.size()].second;
|
auto & availableCreatures = town->creatures[(bid-30)%town->getTown()->creatures.size()].second;
|
||||||
if(availableCreatures.size())
|
if(availableCreatures.size())
|
||||||
{
|
{
|
||||||
int creaID = availableCreatures.back();//taking last of available creatures
|
int creaID = availableCreatures.back();//taking last of available creatures
|
||||||
@ -566,7 +566,7 @@ CCastleBuildings::CCastleBuildings(const CGTownInstance* Town):
|
|||||||
{
|
{
|
||||||
OBJECT_CONSTRUCTION;
|
OBJECT_CONSTRUCTION;
|
||||||
|
|
||||||
background = std::make_shared<CPicture>(town->town->clientInfo.townBackground);
|
background = std::make_shared<CPicture>(town->getTown()->clientInfo.townBackground);
|
||||||
background->needRefresh = true;
|
background->needRefresh = true;
|
||||||
background->getSurface()->setBlitMode(EImageBlitMode::OPAQUE);
|
background->getSurface()->setBlitMode(EImageBlitMode::OPAQUE);
|
||||||
pos.w = background->pos.w;
|
pos.w = background->pos.w;
|
||||||
@ -602,7 +602,7 @@ void CCastleBuildings::recreate()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(const CStructure * structure : town->town->clientInfo.structures)
|
for(const CStructure * structure : town->getTown()->clientInfo.structures)
|
||||||
{
|
{
|
||||||
if(!structure->building)
|
if(!structure->building)
|
||||||
{
|
{
|
||||||
@ -617,7 +617,7 @@ void CCastleBuildings::recreate()
|
|||||||
|
|
||||||
for(auto & entry : groups)
|
for(auto & entry : groups)
|
||||||
{
|
{
|
||||||
const CBuilding * build = town->town->buildings.at(entry.first);
|
const CBuilding * build = town->getTown()->buildings.at(entry.first);
|
||||||
|
|
||||||
const CStructure * toAdd = *boost::max_element(entry.second, [=](const CStructure * a, const CStructure * b)
|
const CStructure * toAdd = *boost::max_element(entry.second, [=](const CStructure * a, const CStructure * b)
|
||||||
{
|
{
|
||||||
@ -648,7 +648,7 @@ void CCastleBuildings::recreate()
|
|||||||
void CCastleBuildings::addBuilding(BuildingID building)
|
void CCastleBuildings::addBuilding(BuildingID building)
|
||||||
{
|
{
|
||||||
//FIXME: implement faster method without complete recreation of town
|
//FIXME: implement faster method without complete recreation of town
|
||||||
BuildingID base = town->town->buildings.at(building)->getBase();
|
BuildingID base = town->getTown()->buildings.at(building)->getBase();
|
||||||
|
|
||||||
recreate();
|
recreate();
|
||||||
|
|
||||||
@ -687,7 +687,7 @@ void CCastleBuildings::buildingClicked(BuildingID building)
|
|||||||
BuildingID buildingToEnter = building;
|
BuildingID buildingToEnter = building;
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
const CBuilding *b = town->town->buildings.find(buildingToEnter)->second;
|
const CBuilding *b = town->getTown()->buildings.find(buildingToEnter)->second;
|
||||||
|
|
||||||
if (buildingTryActivateCustomUI(buildingToEnter, building))
|
if (buildingTryActivateCustomUI(buildingToEnter, building))
|
||||||
return;
|
return;
|
||||||
@ -705,7 +705,7 @@ void CCastleBuildings::buildingClicked(BuildingID building)
|
|||||||
bool CCastleBuildings::buildingTryActivateCustomUI(BuildingID buildingToTest, BuildingID buildingTarget)
|
bool CCastleBuildings::buildingTryActivateCustomUI(BuildingID buildingToTest, BuildingID buildingTarget)
|
||||||
{
|
{
|
||||||
logGlobal->trace("You've clicked on %d", (int)buildingToTest.toEnum());
|
logGlobal->trace("You've clicked on %d", (int)buildingToTest.toEnum());
|
||||||
const CBuilding *b = town->town->buildings.at(buildingToTest);
|
const CBuilding *b = town->getTown()->buildings.at(buildingToTest);
|
||||||
|
|
||||||
if (town->getWarMachineInBuilding(buildingToTest).hasValue())
|
if (town->getWarMachineInBuilding(buildingToTest).hasValue())
|
||||||
{
|
{
|
||||||
@ -744,7 +744,7 @@ bool CCastleBuildings::buildingTryActivateCustomUI(BuildingID buildingToTest, Bu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (town->rewardableBuildings.count(buildingToTest) && town->town->buildings.at(buildingToTest)->manualHeroVisit)
|
if (town->rewardableBuildings.count(buildingToTest) && town->getTown()->buildings.at(buildingToTest)->manualHeroVisit)
|
||||||
{
|
{
|
||||||
enterRewardable(buildingToTest);
|
enterRewardable(buildingToTest);
|
||||||
return true;
|
return true;
|
||||||
@ -820,10 +820,10 @@ bool CCastleBuildings::buildingTryActivateCustomUI(BuildingID buildingToTest, Bu
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
case BuildingSubID::PORTAL_OF_SUMMONING:
|
case BuildingSubID::PORTAL_OF_SUMMONING:
|
||||||
if (town->creatures[town->town->creatures.size()].second.empty())//No creatures
|
if (town->creatures[town->getTown()->creatures.size()].second.empty())//No creatures
|
||||||
LOCPLINT->showInfoDialog(CGI->generaltexth->tcommands[30]);
|
LOCPLINT->showInfoDialog(CGI->generaltexth->tcommands[30]);
|
||||||
else
|
else
|
||||||
enterDwelling(town->town->creatures.size());
|
enterDwelling(town->getTown()->creatures.size());
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case BuildingSubID::BANK:
|
case BuildingSubID::BANK:
|
||||||
@ -850,7 +850,7 @@ void CCastleBuildings::enterRewardable(BuildingID building)
|
|||||||
{
|
{
|
||||||
MetaString message;
|
MetaString message;
|
||||||
message.appendTextID("core.genrltxt.273"); // only visiting heroes may visit %s
|
message.appendTextID("core.genrltxt.273"); // only visiting heroes may visit %s
|
||||||
message.replaceTextID(town->town->buildings.at(building)->getNameTextID());
|
message.replaceTextID(town->getTown()->buildings.at(building)->getNameTextID());
|
||||||
|
|
||||||
LOCPLINT->showInfoDialog(message.toString());
|
LOCPLINT->showInfoDialog(message.toString());
|
||||||
}
|
}
|
||||||
@ -868,7 +868,7 @@ void CCastleBuildings::enterBlacksmith(BuildingID building, ArtifactID artifactI
|
|||||||
const CGHeroInstance *hero = town->visitingHero;
|
const CGHeroInstance *hero = town->visitingHero;
|
||||||
if(!hero)
|
if(!hero)
|
||||||
{
|
{
|
||||||
LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[273]) % town->town->buildings.find(building)->second->getNameTranslated()));
|
LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[273]) % town->getTown()->buildings.find(building)->second->getNameTranslated()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto art = artifactID.toArtifact();
|
auto art = artifactID.toArtifact();
|
||||||
@ -897,8 +897,8 @@ void CCastleBuildings::enterBlacksmith(BuildingID building, ArtifactID artifactI
|
|||||||
|
|
||||||
void CCastleBuildings::enterBuilding(BuildingID building)
|
void CCastleBuildings::enterBuilding(BuildingID building)
|
||||||
{
|
{
|
||||||
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(ComponentType::BUILDING, BuildingTypeUniqueID(town->getFaction(), building)));
|
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(ComponentType::BUILDING, BuildingTypeUniqueID(town->getFactionID(), building)));
|
||||||
LOCPLINT->showInfoDialog( town->town->buildings.find(building)->second->getDescriptionTranslated(), comps);
|
LOCPLINT->showInfoDialog( town->getTown()->buildings.find(building)->second->getDescriptionTranslated(), comps);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCastleBuildings::enterCastleGate()
|
void CCastleBuildings::enterCastleGate()
|
||||||
@ -915,20 +915,20 @@ void CCastleBuildings::enterCastleGate()
|
|||||||
{
|
{
|
||||||
const CGTownInstance *t = Town;
|
const CGTownInstance *t = Town;
|
||||||
if (t->id != this->town->id && t->visitingHero == nullptr && //another town, empty and this is
|
if (t->id != this->town->id && t->visitingHero == nullptr && //another town, empty and this is
|
||||||
t->town->faction->getId() == town->town->faction->getId() && //the town of the same faction
|
t->getFactionID() == town->getFactionID() && //the town of the same faction
|
||||||
t->hasBuilt(BuildingSubID::CASTLE_GATE)) //and the town has a castle gate
|
t->hasBuilt(BuildingSubID::CASTLE_GATE)) //and the town has a castle gate
|
||||||
{
|
{
|
||||||
availableTowns.push_back(t->id.getNum());//add to the list
|
availableTowns.push_back(t->id.getNum());//add to the list
|
||||||
if(settings["general"]["enableUiEnhancements"].Bool())
|
if(settings["general"]["enableUiEnhancements"].Bool())
|
||||||
{
|
{
|
||||||
auto image = GH.renderHandler().loadImage(AnimationPath::builtin("ITPA"), t->town->clientInfo.icons[t->hasFort()][false] + 2, 0, EImageBlitMode::OPAQUE);
|
auto image = GH.renderHandler().loadImage(AnimationPath::builtin("ITPA"), t->getTown()->clientInfo.icons[t->hasFort()][false] + 2, 0, EImageBlitMode::OPAQUE);
|
||||||
image->scaleTo(Point(35, 23));
|
image->scaleTo(Point(35, 23));
|
||||||
images.push_back(image);
|
images.push_back(image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto gateIcon = std::make_shared<CAnimImage>(town->town->clientInfo.buildingsIcons, BuildingID::CASTLE_GATE);//will be deleted by selection window
|
auto gateIcon = std::make_shared<CAnimImage>(town->getTown()->clientInfo.buildingsIcons, BuildingID::CASTLE_GATE);//will be deleted by selection window
|
||||||
auto wnd = std::make_shared<CObjectListWindow>(availableTowns, gateIcon, CGI->generaltexth->jktexts[40],
|
auto wnd = std::make_shared<CObjectListWindow>(availableTowns, gateIcon, CGI->generaltexth->jktexts[40],
|
||||||
CGI->generaltexth->jktexts[41], std::bind (&CCastleInterface::castleTeleport, LOCPLINT->castleInt, _1), 0, images);
|
CGI->generaltexth->jktexts[41], std::bind (&CCastleInterface::castleTeleport, LOCPLINT->castleInt, _1), 0, images);
|
||||||
wnd->onPopup = [availableTowns](int index) { CRClickPopup::createAndPush(LOCPLINT->cb->getObjInstance(ObjectInstanceID(availableTowns[index])), GH.getCursorPosition()); };
|
wnd->onPopup = [availableTowns](int index) { CRClickPopup::createAndPush(LOCPLINT->cb->getObjInstance(ObjectInstanceID(availableTowns[index])), GH.getCursorPosition()); };
|
||||||
@ -940,7 +940,7 @@ void CCastleBuildings::enterDwelling(int level)
|
|||||||
if (level < 0 || level >= town->creatures.size() || town->creatures[level].second.empty())
|
if (level < 0 || level >= town->creatures.size() || town->creatures[level].second.empty())
|
||||||
{
|
{
|
||||||
assert(0);
|
assert(0);
|
||||||
logGlobal->error("Attempt to enter into invalid dwelling of level %d in town %s (%s)", level, town->getNameTranslated(), town->town->faction->getNameTranslated());
|
logGlobal->error("Attempt to enter into invalid dwelling of level %d in town %s (%s)", level, town->getNameTranslated(), town->getFaction()->getNameTranslated());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -954,8 +954,8 @@ void CCastleBuildings::enterDwelling(int level)
|
|||||||
void CCastleBuildings::enterToTheQuickRecruitmentWindow()
|
void CCastleBuildings::enterToTheQuickRecruitmentWindow()
|
||||||
{
|
{
|
||||||
const auto beginIt = town->creatures.cbegin();
|
const auto beginIt = town->creatures.cbegin();
|
||||||
const auto afterLastIt = town->creatures.size() > town->town->creatures.size()
|
const auto afterLastIt = town->creatures.size() > town->getTown()->creatures.size()
|
||||||
? std::next(beginIt, town->town->creatures.size())
|
? std::next(beginIt, town->getTown()->creatures.size())
|
||||||
: town->creatures.cend();
|
: town->creatures.cend();
|
||||||
const auto hasSomeoneToRecruit = std::any_of(beginIt, afterLastIt,
|
const auto hasSomeoneToRecruit = std::any_of(beginIt, afterLastIt,
|
||||||
[](const auto & creatureInfo) { return creatureInfo.first > 0; });
|
[](const auto & creatureInfo) { return creatureInfo.first > 0; });
|
||||||
@ -967,8 +967,8 @@ void CCastleBuildings::enterToTheQuickRecruitmentWindow()
|
|||||||
|
|
||||||
void CCastleBuildings::enterFountain(const BuildingID & building, BuildingSubID::EBuildingSubID subID, BuildingID upgrades)
|
void CCastleBuildings::enterFountain(const BuildingID & building, BuildingSubID::EBuildingSubID subID, BuildingID upgrades)
|
||||||
{
|
{
|
||||||
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(ComponentType::BUILDING, BuildingTypeUniqueID(town->getFaction(), building)));
|
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(ComponentType::BUILDING, BuildingTypeUniqueID(town->getFactionID(), building)));
|
||||||
std::string descr = town->town->buildings.find(building)->second->getDescriptionTranslated();
|
std::string descr = town->getTown()->buildings.find(building)->second->getDescriptionTranslated();
|
||||||
std::string hasNotProduced;
|
std::string hasNotProduced;
|
||||||
std::string hasProduced;
|
std::string hasProduced;
|
||||||
|
|
||||||
@ -977,10 +977,10 @@ void CCastleBuildings::enterFountain(const BuildingID & building, BuildingSubID:
|
|||||||
|
|
||||||
bool isMysticPondOrItsUpgrade = subID == BuildingSubID::MYSTIC_POND
|
bool isMysticPondOrItsUpgrade = subID == BuildingSubID::MYSTIC_POND
|
||||||
|| (upgrades != BuildingID::NONE
|
|| (upgrades != BuildingID::NONE
|
||||||
&& town->town->buildings.find(BuildingID(upgrades))->second->subId == BuildingSubID::MYSTIC_POND);
|
&& town->getTown()->buildings.find(BuildingID(upgrades))->second->subId == BuildingSubID::MYSTIC_POND);
|
||||||
|
|
||||||
if(upgrades != BuildingID::NONE)
|
if(upgrades != BuildingID::NONE)
|
||||||
descr += "\n\n"+town->town->buildings.find(BuildingID(upgrades))->second->getDescriptionTranslated();
|
descr += "\n\n"+town->getTown()->buildings.find(BuildingID(upgrades))->second->getDescriptionTranslated();
|
||||||
|
|
||||||
if(isMysticPondOrItsUpgrade) //for vanila Rampart like towns
|
if(isMysticPondOrItsUpgrade) //for vanila Rampart like towns
|
||||||
{
|
{
|
||||||
@ -1056,7 +1056,7 @@ void CCastleBuildings::enterTownHall()
|
|||||||
|
|
||||||
void CCastleBuildings::openMagesGuild()
|
void CCastleBuildings::openMagesGuild()
|
||||||
{
|
{
|
||||||
auto mageGuildBackground = LOCPLINT->castleInt->town->town->clientInfo.guildBackground;
|
auto mageGuildBackground = LOCPLINT->castleInt->town->getTown()->clientInfo.guildBackground;
|
||||||
GH.windows().createAndPushWindow<CMageGuildScreen>(LOCPLINT->castleInt, mageGuildBackground);
|
GH.windows().createAndPushWindow<CMageGuildScreen>(LOCPLINT->castleInt, mageGuildBackground);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1247,7 +1247,7 @@ CTownInfo::CTownInfo(int posX, int posY, const CGTownInstance * Town, bool townH
|
|||||||
return;//FIXME: suspicious statement, fix or comment
|
return;//FIXME: suspicious statement, fix or comment
|
||||||
picture = std::make_shared<CAnimImage>(AnimationPath::builtin("ITMCL.DEF"), town->fortLevel()-1);
|
picture = std::make_shared<CAnimImage>(AnimationPath::builtin("ITMCL.DEF"), town->fortLevel()-1);
|
||||||
}
|
}
|
||||||
building = town->town->buildings.at(BuildingID(buildID));
|
building = town->getTown()->buildings.at(BuildingID(buildID));
|
||||||
pos = picture->pos;
|
pos = picture->pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1322,7 +1322,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst
|
|||||||
recreateIcons();
|
recreateIcons();
|
||||||
if (!from)
|
if (!from)
|
||||||
adventureInt->onAudioPaused();
|
adventureInt->onAudioPaused();
|
||||||
CCS->musich->playMusicFromSet("faction", town->town->faction->getJsonKey(), true, false);
|
CCS->musich->playMusicFromSet("faction", town->getFaction()->getJsonKey(), true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
CCastleInterface::~CCastleInterface()
|
CCastleInterface::~CCastleInterface()
|
||||||
@ -1403,7 +1403,7 @@ void CCastleInterface::removeBuilding(BuildingID bid)
|
|||||||
void CCastleInterface::recreateIcons()
|
void CCastleInterface::recreateIcons()
|
||||||
{
|
{
|
||||||
OBJECT_CONSTRUCTION;
|
OBJECT_CONSTRUCTION;
|
||||||
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->built >= LOCPLINT->cb->getSettings().getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
|
size_t iconIndex = town->getTown()->clientInfo.icons[town->hasFort()][town->built >= LOCPLINT->cb->getSettings().getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
|
||||||
|
|
||||||
icon->setFrame(iconIndex);
|
icon->setFrame(iconIndex);
|
||||||
TResources townIncome = town->dailyIncome();
|
TResources townIncome = town->dailyIncome();
|
||||||
@ -1425,8 +1425,8 @@ void CCastleInterface::recreateIcons()
|
|||||||
if(town->hasBuilt(BuildingID::TAVERN))
|
if(town->hasBuilt(BuildingID::TAVERN))
|
||||||
LOCPLINT->showTavernWindow(town, nullptr, QueryID::NONE);
|
LOCPLINT->showTavernWindow(town, nullptr, QueryID::NONE);
|
||||||
}, [this]{
|
}, [this]{
|
||||||
if(!town->town->faction->getDescriptionTranslated().empty())
|
if(!town->getFaction()->getDescriptionTranslated().empty())
|
||||||
CRClickPopup::createAndPush(town->town->faction->getDescriptionTranslated());
|
CRClickPopup::createAndPush(town->getFaction()->getDescriptionTranslated());
|
||||||
});
|
});
|
||||||
|
|
||||||
creainfo.clear();
|
creainfo.clear();
|
||||||
@ -1527,7 +1527,7 @@ CHallInterface::CBuildingBox::CBuildingBox(int x, int y, const CGTownInstance *
|
|||||||
-1, -1, -1, 0, 0, 1, 2, -1, 1, 1, -1, -1
|
-1, -1, -1, 0, 0, 1, 2, -1, 1, 1, -1, -1
|
||||||
};
|
};
|
||||||
|
|
||||||
icon = std::make_shared<CAnimImage>(town->town->clientInfo.buildingsIcons, building->bid, 0, 2, 2);
|
icon = std::make_shared<CAnimImage>(town->getTown()->clientInfo.buildingsIcons, building->bid, 0, 2, 2);
|
||||||
header = std::make_shared<CAnimImage>(AnimationPath::builtin("TPTHBAR"), panelIndex[static_cast<int>(state)], 0, 1, 73);
|
header = std::make_shared<CAnimImage>(AnimationPath::builtin("TPTHBAR"), panelIndex[static_cast<int>(state)], 0, 1, 73);
|
||||||
if(iconIndex[static_cast<int>(state)] >=0)
|
if(iconIndex[static_cast<int>(state)] >=0)
|
||||||
mark = std::make_shared<CAnimImage>(AnimationPath::builtin("TPTHCHK"), iconIndex[static_cast<int>(state)], 0, 136, 56);
|
mark = std::make_shared<CAnimImage>(AnimationPath::builtin("TPTHCHK"), iconIndex[static_cast<int>(state)], 0, 136, 56);
|
||||||
@ -1569,7 +1569,7 @@ void CHallInterface::CBuildingBox::showPopupWindow(const Point & cursorPosition)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CHallInterface::CHallInterface(const CGTownInstance * Town):
|
CHallInterface::CHallInterface(const CGTownInstance * Town):
|
||||||
CWindowObject(PLAYER_COLORED | BORDERED, Town->town->clientInfo.hallBackground),
|
CWindowObject(PLAYER_COLORED | BORDERED, Town->getTown()->clientInfo.hallBackground),
|
||||||
town(Town)
|
town(Town)
|
||||||
{
|
{
|
||||||
OBJECT_CONSTRUCTION;
|
OBJECT_CONSTRUCTION;
|
||||||
@ -1581,10 +1581,10 @@ CHallInterface::CHallInterface(const CGTownInstance * Town):
|
|||||||
auto statusbarBackground = std::make_shared<CPicture>(background->getSurface(), barRect, 5, 556);
|
auto statusbarBackground = std::make_shared<CPicture>(background->getSurface(), barRect, 5, 556);
|
||||||
statusbar = CGStatusBar::create(statusbarBackground);
|
statusbar = CGStatusBar::create(statusbarBackground);
|
||||||
|
|
||||||
title = std::make_shared<CLabel>(399, 12, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, town->town->buildings.at(BuildingID(town->hallLevel()+BuildingID::VILLAGE_HALL))->getNameTranslated());
|
title = std::make_shared<CLabel>(399, 12, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, town->getTown()->buildings.at(BuildingID(town->hallLevel()+BuildingID::VILLAGE_HALL))->getNameTranslated());
|
||||||
exit = std::make_shared<CButton>(Point(748, 556), AnimationPath::builtin("TPMAGE1.DEF"), CButton::tooltip(CGI->generaltexth->hcommands[8]), [&](){close();}, EShortcut::GLOBAL_RETURN);
|
exit = std::make_shared<CButton>(Point(748, 556), AnimationPath::builtin("TPMAGE1.DEF"), CButton::tooltip(CGI->generaltexth->hcommands[8]), [&](){close();}, EShortcut::GLOBAL_RETURN);
|
||||||
|
|
||||||
auto & boxList = town->town->clientInfo.hallSlots;
|
auto & boxList = town->getTown()->clientInfo.hallSlots;
|
||||||
boxes.resize(boxList.size());
|
boxes.resize(boxList.size());
|
||||||
for(size_t row=0; row<boxList.size(); row++) //for each row
|
for(size_t row=0; row<boxList.size(); row++) //for each row
|
||||||
{
|
{
|
||||||
@ -1595,11 +1595,11 @@ CHallInterface::CHallInterface(const CGTownInstance * Town):
|
|||||||
{
|
{
|
||||||
if (!buildingID.hasValue())
|
if (!buildingID.hasValue())
|
||||||
{
|
{
|
||||||
logMod->warn("Invalid building ID found in hallSlots of town '%s'", town->town->faction->getJsonKey() );
|
logMod->warn("Invalid building ID found in hallSlots of town '%s'", town->getFaction()->getJsonKey() );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CBuilding * current = town->town->buildings.at(buildingID);
|
const CBuilding * current = town->getTown()->buildings.at(buildingID);
|
||||||
if(town->hasBuilt(buildingID))
|
if(town->hasBuilt(buildingID))
|
||||||
{
|
{
|
||||||
building = current;
|
building = current;
|
||||||
@ -1629,7 +1629,7 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin
|
|||||||
{
|
{
|
||||||
OBJECT_CONSTRUCTION;
|
OBJECT_CONSTRUCTION;
|
||||||
|
|
||||||
icon = std::make_shared<CAnimImage>(town->town->clientInfo.buildingsIcons, building->bid, 0, 125, 50);
|
icon = std::make_shared<CAnimImage>(town->getTown()->clientInfo.buildingsIcons, building->bid, 0, 125, 50);
|
||||||
auto statusbarBackground = std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26);
|
auto statusbarBackground = std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26);
|
||||||
statusbar = CGStatusBar::create(statusbarBackground);
|
statusbar = CGStatusBar::create(statusbarBackground);
|
||||||
|
|
||||||
@ -1711,7 +1711,7 @@ std::string CBuildWindow::getTextForState(EBuildingState state)
|
|||||||
{
|
{
|
||||||
auto toStr = [&](const BuildingID build) -> std::string
|
auto toStr = [&](const BuildingID build) -> std::string
|
||||||
{
|
{
|
||||||
return town->town->buildings.at(build)->getNameTranslated();
|
return town->getTown()->buildings.at(build)->getNameTranslated();
|
||||||
};
|
};
|
||||||
|
|
||||||
ret = CGI->generaltexth->allTexts[52];
|
ret = CGI->generaltexth->allTexts[52];
|
||||||
@ -1721,7 +1721,7 @@ std::string CBuildWindow::getTextForState(EBuildingState state)
|
|||||||
case EBuildingState::MISSING_BASE:
|
case EBuildingState::MISSING_BASE:
|
||||||
{
|
{
|
||||||
std::string msg = CGI->generaltexth->translate("vcmi.townHall.missingBase");
|
std::string msg = CGI->generaltexth->translate("vcmi.townHall.missingBase");
|
||||||
ret = boost::str(boost::format(msg) % town->town->buildings.at(building->upgrade)->getNameTranslated());
|
ret = boost::str(boost::format(msg) % town->getTown()->buildings.at(building->upgrade)->getNameTranslated());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1780,11 +1780,11 @@ CFortScreen::CFortScreen(const CGTownInstance * town):
|
|||||||
{
|
{
|
||||||
OBJECT_CONSTRUCTION;
|
OBJECT_CONSTRUCTION;
|
||||||
ui32 fortSize = static_cast<ui32>(town->creatures.size());
|
ui32 fortSize = static_cast<ui32>(town->creatures.size());
|
||||||
if(fortSize > town->town->creatures.size() && town->creatures.back().second.empty())
|
if(fortSize > town->getTown()->creatures.size() && town->creatures.back().second.empty())
|
||||||
fortSize--;
|
fortSize--;
|
||||||
fortSize = std::min(fortSize, static_cast<ui32>(GameConstants::CREATURES_PER_TOWN)); // for 8 creatures + portal of summoning
|
fortSize = std::min(fortSize, static_cast<ui32>(GameConstants::CREATURES_PER_TOWN)); // for 8 creatures + portal of summoning
|
||||||
|
|
||||||
const CBuilding * fortBuilding = town->town->buildings.at(BuildingID(town->fortLevel()+6));
|
const CBuilding * fortBuilding = town->getTown()->buildings.at(BuildingID(town->fortLevel()+6));
|
||||||
title = std::make_shared<CLabel>(400, 12, FONT_BIG, ETextAlignment::CENTER, Colors::WHITE, fortBuilding->getNameTranslated());
|
title = std::make_shared<CLabel>(400, 12, FONT_BIG, ETextAlignment::CENTER, Colors::WHITE, fortBuilding->getNameTranslated());
|
||||||
|
|
||||||
std::string text = boost::str(boost::format(CGI->generaltexth->fcommands[6]) % fortBuilding->getNameTranslated());
|
std::string text = boost::str(boost::format(CGI->generaltexth->fcommands[6]) % fortBuilding->getNameTranslated());
|
||||||
@ -1810,7 +1810,7 @@ CFortScreen::CFortScreen(const CGTownInstance * town):
|
|||||||
for(ui32 i=0; i<fortSize; i++)
|
for(ui32 i=0; i<fortSize; i++)
|
||||||
{
|
{
|
||||||
BuildingID buildingID;
|
BuildingID buildingID;
|
||||||
if(fortSize == town->town->creatures.size())
|
if(fortSize == town->getTown()->creatures.size())
|
||||||
{
|
{
|
||||||
BuildingID dwelling = BuildingID::getDwellingFromLevel(i, 1);
|
BuildingID dwelling = BuildingID::getDwellingFromLevel(i, 1);
|
||||||
|
|
||||||
@ -1839,7 +1839,7 @@ CFortScreen::CFortScreen(const CGTownInstance * town):
|
|||||||
ImagePath CFortScreen::getBgName(const CGTownInstance * town)
|
ImagePath CFortScreen::getBgName(const CGTownInstance * town)
|
||||||
{
|
{
|
||||||
ui32 fortSize = static_cast<ui32>(town->creatures.size());
|
ui32 fortSize = static_cast<ui32>(town->creatures.size());
|
||||||
if(fortSize > town->town->creatures.size() && town->creatures.back().second.empty())
|
if(fortSize > town->getTown()->creatures.size() && town->creatures.back().second.empty())
|
||||||
fortSize--;
|
fortSize--;
|
||||||
fortSize = std::min(fortSize, static_cast<ui32>(GameConstants::CREATURES_PER_TOWN)); // for 8 creatures + portal of summoning
|
fortSize = std::min(fortSize, static_cast<ui32>(GameConstants::CREATURES_PER_TOWN)); // for 8 creatures + portal of summoning
|
||||||
|
|
||||||
@ -1877,7 +1877,7 @@ CFortScreen::RecruitArea::RecruitArea(int posX, int posY, const CGTownInstance *
|
|||||||
|
|
||||||
if(getMyBuilding() != nullptr)
|
if(getMyBuilding() != nullptr)
|
||||||
{
|
{
|
||||||
buildingIcon = std::make_shared<CAnimImage>(town->town->clientInfo.buildingsIcons, getMyBuilding()->bid, 0, 4, 21);
|
buildingIcon = std::make_shared<CAnimImage>(town->getTown()->clientInfo.buildingsIcons, getMyBuilding()->bid, 0, 4, 21);
|
||||||
buildingName = std::make_shared<CLabel>(78, 101, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, getMyBuilding()->getNameTranslated(), 152);
|
buildingName = std::make_shared<CLabel>(78, 101, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, getMyBuilding()->getNameTranslated(), 152);
|
||||||
|
|
||||||
if(town->hasBuilt(getMyBuilding()->bid))
|
if(town->hasBuilt(getMyBuilding()->bid))
|
||||||
@ -1913,8 +1913,8 @@ const CCreature * CFortScreen::RecruitArea::getMyCreature()
|
|||||||
{
|
{
|
||||||
if(!town->creatures.at(level).second.empty()) // built
|
if(!town->creatures.at(level).second.empty()) // built
|
||||||
return town->creatures.at(level).second.back().toCreature();
|
return town->creatures.at(level).second.back().toCreature();
|
||||||
if(!town->town->creatures.at(level).empty()) // there are creatures on this level
|
if(!town->getTown()->creatures.at(level).empty()) // there are creatures on this level
|
||||||
return town->town->creatures.at(level).front().toCreature();
|
return town->getTown()->creatures.at(level).front().toCreature();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1922,17 +1922,17 @@ const CBuilding * CFortScreen::RecruitArea::getMyBuilding()
|
|||||||
{
|
{
|
||||||
BuildingID myID = BuildingID(BuildingID::getDwellingFromLevel(level, 0));
|
BuildingID myID = BuildingID(BuildingID::getDwellingFromLevel(level, 0));
|
||||||
|
|
||||||
if (level == town->town->creatures.size())
|
if (level == town->getTown()->creatures.size())
|
||||||
return town->town->getSpecialBuilding(BuildingSubID::PORTAL_OF_SUMMONING);
|
return town->getTown()->getSpecialBuilding(BuildingSubID::PORTAL_OF_SUMMONING);
|
||||||
|
|
||||||
if (!town->town->buildings.count(myID))
|
if (!town->getTown()->buildings.count(myID))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
const CBuilding * build = town->town->buildings.at(myID);
|
const CBuilding * build = town->getTown()->buildings.at(myID);
|
||||||
while (town->town->buildings.count(myID))
|
while (town->getTown()->buildings.count(myID))
|
||||||
{
|
{
|
||||||
if (town->hasBuilt(myID))
|
if (town->hasBuilt(myID))
|
||||||
build = town->town->buildings.at(myID);
|
build = town->getTown()->buildings.at(myID);
|
||||||
BuildingID::advanceDwelling(myID);
|
BuildingID::advanceDwelling(myID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1972,7 +1972,7 @@ CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner, const ImagePath & i
|
|||||||
{
|
{
|
||||||
OBJECT_CONSTRUCTION;
|
OBJECT_CONSTRUCTION;
|
||||||
|
|
||||||
window = std::make_shared<CPicture>(owner->town->town->clientInfo.guildWindow, 332, 76);
|
window = std::make_shared<CPicture>(owner->town->getTown()->clientInfo.guildWindow, 332, 76);
|
||||||
|
|
||||||
resdatabar = std::make_shared<CMinorResDataBar>();
|
resdatabar = std::make_shared<CMinorResDataBar>();
|
||||||
resdatabar->moveBy(pos.topLeft(), true);
|
resdatabar->moveBy(pos.topLeft(), true);
|
||||||
@ -2007,7 +2007,7 @@ void CMageGuildScreen::updateSpells(ObjectInstanceID tID)
|
|||||||
|
|
||||||
const CGTownInstance * town = LOCPLINT->cb->getTown(townId);
|
const CGTownInstance * town = LOCPLINT->cb->getTown(townId);
|
||||||
|
|
||||||
for(size_t i=0; i<town->town->mageLevel; i++)
|
for(size_t i=0; i<town->getTown()->mageLevel; i++)
|
||||||
{
|
{
|
||||||
size_t spellCount = town->spellsAtLevel((int)i+1,false); //spell at level with -1 hmmm?
|
size_t spellCount = town->spellsAtLevel((int)i+1,false); //spell at level with -1 hmmm?
|
||||||
for(size_t j=0; j<spellCount; j++)
|
for(size_t j=0; j<spellCount; j++)
|
||||||
|
@ -84,7 +84,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
|
|||||||
for(int m=0; m < hero->secSkills.size(); ++m)
|
for(int m=0; m < hero->secSkills.size(); ++m)
|
||||||
secSkillIcons[leftRight].push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("SECSK32"), 0, 0, 32 + 36 * m + 454 * leftRight, qeLayout ? 83 : 88));
|
secSkillIcons[leftRight].push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("SECSK32"), 0, 0, 32 + 36 * m + 454 * leftRight, qeLayout ? 83 : 88));
|
||||||
|
|
||||||
specImages[leftRight] = std::make_shared<CAnimImage>(AnimationPath::builtin("UN32"), hero->type->imageIndex, 0, 67 + 490 * leftRight, qeLayout ? 41 : 45);
|
specImages[leftRight] = std::make_shared<CAnimImage>(AnimationPath::builtin("UN32"), hero->getHeroType()->imageIndex, 0, 67 + 490 * leftRight, qeLayout ? 41 : 45);
|
||||||
|
|
||||||
expImages[leftRight] = std::make_shared<CAnimImage>(AnimationPath::builtin("PSKIL32"), 4, 0, 103 + 490 * leftRight, qeLayout ? 41 : 45);
|
expImages[leftRight] = std::make_shared<CAnimImage>(AnimationPath::builtin("PSKIL32"), 4, 0, 103 + 490 * leftRight, qeLayout ? 41 : 45);
|
||||||
expValues[leftRight] = std::make_shared<CLabel>(119 + 490 * leftRight, qeLayout ? 66 : 71, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
expValues[leftRight] = std::make_shared<CLabel>(119 + 490 * leftRight, qeLayout ? 66 : 71, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
||||||
@ -151,7 +151,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
|
|||||||
specialtyAreas[b] = std::make_shared<LRClickableAreaWText>();
|
specialtyAreas[b] = std::make_shared<LRClickableAreaWText>();
|
||||||
specialtyAreas[b]->pos = Rect(Point(pos.x + 69 + 490 * b, pos.y + (qeLayout ? 41 : 45)), Point(32, 32));
|
specialtyAreas[b]->pos = Rect(Point(pos.x + 69 + 490 * b, pos.y + (qeLayout ? 41 : 45)), Point(32, 32));
|
||||||
specialtyAreas[b]->hoverText = CGI->generaltexth->heroscrn[27];
|
specialtyAreas[b]->hoverText = CGI->generaltexth->heroscrn[27];
|
||||||
specialtyAreas[b]->text = hero->type->getSpecialtyDescriptionTranslated();
|
specialtyAreas[b]->text = hero->getHeroType()->getSpecialtyDescriptionTranslated();
|
||||||
|
|
||||||
experienceAreas[b] = std::make_shared<LRClickableAreaWText>();
|
experienceAreas[b] = std::make_shared<LRClickableAreaWText>();
|
||||||
experienceAreas[b]->pos = Rect(Point(pos.x + 105 + 490 * b, pos.y + (qeLayout ? 41 : 45)), Point(32, 32));
|
experienceAreas[b]->pos = Rect(Point(pos.x + 105 + 490 * b, pos.y + (qeLayout ? 41 : 45)), Point(32, 32));
|
||||||
|
@ -184,9 +184,9 @@ void CHeroWindow::update()
|
|||||||
name->setText(curHero->getNameTranslated());
|
name->setText(curHero->getNameTranslated());
|
||||||
title->setText((boost::format(CGI->generaltexth->allTexts[342]) % curHero->level % curHero->getClassNameTranslated()).str());
|
title->setText((boost::format(CGI->generaltexth->allTexts[342]) % curHero->level % curHero->getClassNameTranslated()).str());
|
||||||
|
|
||||||
specArea->text = curHero->type->getSpecialtyDescriptionTranslated();
|
specArea->text = curHero->getHeroType()->getSpecialtyDescriptionTranslated();
|
||||||
specImage->setFrame(curHero->type->imageIndex);
|
specImage->setFrame(curHero->getHeroType()->imageIndex);
|
||||||
specName->setText(curHero->type->getSpecialtyNameTranslated());
|
specName->setText(curHero->getHeroType()->getSpecialtyNameTranslated());
|
||||||
|
|
||||||
tacticsButton = std::make_shared<CToggleButton>(Point(539, 483), AnimationPath::builtin("hsbtns8.def"), std::make_pair(heroscrn[26], heroscrn[31]), 0, EShortcut::HERO_TOGGLE_TACTICS);
|
tacticsButton = std::make_shared<CToggleButton>(Point(539, 483), AnimationPath::builtin("hsbtns8.def"), std::make_pair(heroscrn[26], heroscrn[31]), 0, EShortcut::HERO_TOGGLE_TACTICS);
|
||||||
tacticsButton->addHoverText(EButtonState::HIGHLIGHTED, CGI->generaltexth->heroscrn[25]);
|
tacticsButton->addHoverText(EButtonState::HIGHLIGHTED, CGI->generaltexth->heroscrn[25]);
|
||||||
|
@ -300,7 +300,7 @@ int InfoBoxHeroData::getSubID()
|
|||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
case HERO_SPECIAL:
|
case HERO_SPECIAL:
|
||||||
return hero->type->getIndex();
|
return hero->getHeroTypeID().getNum();
|
||||||
case HERO_MANA:
|
case HERO_MANA:
|
||||||
case HERO_EXPERIENCE:
|
case HERO_EXPERIENCE:
|
||||||
return 0;
|
return 0;
|
||||||
@ -800,7 +800,7 @@ CTownItem::CTownItem(const CGTownInstance * Town)
|
|||||||
garr = std::make_shared<CGarrisonInt>(Point(313, 3), 4, Point(232,0), town->getUpperArmy(), town->visitingHero, true, true, CGarrisonInt::ESlotsLayout::TWO_ROWS);
|
garr = std::make_shared<CGarrisonInt>(Point(313, 3), 4, Point(232,0), town->getUpperArmy(), town->visitingHero, true, true, CGarrisonInt::ESlotsLayout::TWO_ROWS);
|
||||||
heroes = std::make_shared<HeroSlots>(town, Point(244,6), Point(475,6), garr, false);
|
heroes = std::make_shared<HeroSlots>(town, Point(244,6), Point(475,6), garr, false);
|
||||||
|
|
||||||
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->built >= LOCPLINT->cb->getSettings().getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
|
size_t iconIndex = town->getTown()->clientInfo.icons[town->hasFort()][town->built >= LOCPLINT->cb->getSettings().getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
|
||||||
|
|
||||||
picture = std::make_shared<CAnimImage>(AnimationPath::builtin("ITPT"), iconIndex, 0, 5, 6);
|
picture = std::make_shared<CAnimImage>(AnimationPath::builtin("ITPT"), iconIndex, 0, 5, 6);
|
||||||
openTown = std::make_shared<LRClickableAreaOpenTown>(Rect(5, 6, 58, 64), town);
|
openTown = std::make_shared<LRClickableAreaOpenTown>(Rect(5, 6, 58, 64), town);
|
||||||
@ -823,8 +823,8 @@ CTownItem::CTownItem(const CGTownInstance * Town)
|
|||||||
if(town->hasBuilt(BuildingID::TAVERN))
|
if(town->hasBuilt(BuildingID::TAVERN))
|
||||||
LOCPLINT->showTavernWindow(town, nullptr, QueryID::NONE);
|
LOCPLINT->showTavernWindow(town, nullptr, QueryID::NONE);
|
||||||
}, [&]{
|
}, [&]{
|
||||||
if(!town->town->faction->getDescriptionTranslated().empty())
|
if(!town->getTown()->faction->getDescriptionTranslated().empty())
|
||||||
CRClickPopup::createAndPush(town->town->faction->getDescriptionTranslated());
|
CRClickPopup::createAndPush(town->getFaction()->getDescriptionTranslated());
|
||||||
});
|
});
|
||||||
fastMarket = std::make_shared<LRClickableArea>(Rect(153, 6, 65, 64), []()
|
fastMarket = std::make_shared<LRClickableArea>(Rect(153, 6, 65, 64), []()
|
||||||
{
|
{
|
||||||
|
@ -192,7 +192,7 @@ std::string CMarketWindow::getMarketTitle(const ObjectInstanceID marketId, const
|
|||||||
{
|
{
|
||||||
for(const auto & buildingId : town->getBuildings())
|
for(const auto & buildingId : town->getBuildings())
|
||||||
{
|
{
|
||||||
if(const auto building = town->town->buildings.at(buildingId); vstd::contains(building->marketModes, mode))
|
if(const auto building = town->getTown()->buildings.at(buildingId); vstd::contains(building->marketModes, mode))
|
||||||
return building->getNameTranslated();
|
return building->getNameTranslated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -522,9 +522,9 @@ CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj, const std::func
|
|||||||
recruit->block(true);
|
recruit->block(true);
|
||||||
}
|
}
|
||||||
if(LOCPLINT->castleInt)
|
if(LOCPLINT->castleInt)
|
||||||
videoPlayer = std::make_shared<VideoWidget>(Point(70, 56), LOCPLINT->castleInt->town->town->clientInfo.tavernVideo, false);
|
videoPlayer = std::make_shared<VideoWidget>(Point(70, 56), LOCPLINT->castleInt->town->getTown()->clientInfo.tavernVideo, false);
|
||||||
else if(const auto * townObj = dynamic_cast<const CGTownInstance *>(TavernObj))
|
else if(const auto * townObj = dynamic_cast<const CGTownInstance *>(TavernObj))
|
||||||
videoPlayer = std::make_shared<VideoWidget>(Point(70, 56), townObj->town->clientInfo.tavernVideo, false);
|
videoPlayer = std::make_shared<VideoWidget>(Point(70, 56), townObj->getTown()->clientInfo.tavernVideo, false);
|
||||||
else
|
else
|
||||||
videoPlayer = std::make_shared<VideoWidget>(Point(70, 56), VideoPath::builtin("TAVERN.BIK"), false);
|
videoPlayer = std::make_shared<VideoWidget>(Point(70, 56), VideoPath::builtin("TAVERN.BIK"), false);
|
||||||
|
|
||||||
@ -548,7 +548,7 @@ void CTavernWindow::addInvite()
|
|||||||
|
|
||||||
if(!inviteableHeroes.empty())
|
if(!inviteableHeroes.empty())
|
||||||
{
|
{
|
||||||
int imageIndex = heroToInvite ? (*CGI->heroh)[heroToInvite->getHeroType()]->imageIndex : 156; // 156 => special id for random
|
int imageIndex = heroToInvite ? heroToInvite->getIconIndex() : 156; // 156 => special id for random
|
||||||
if(!heroToInvite)
|
if(!heroToInvite)
|
||||||
heroToInvite = (*RandomGeneratorUtil::nextItem(inviteableHeroes, CRandomGenerator::getDefault())).second;
|
heroToInvite = (*RandomGeneratorUtil::nextItem(inviteableHeroes, CRandomGenerator::getDefault())).second;
|
||||||
|
|
||||||
@ -563,7 +563,7 @@ void CTavernWindow::recruitb()
|
|||||||
const CGHeroInstance *toBuy = (selected ? h2 : h1)->h;
|
const CGHeroInstance *toBuy = (selected ? h2 : h1)->h;
|
||||||
const CGObjectInstance *obj = tavernObj;
|
const CGObjectInstance *obj = tavernObj;
|
||||||
|
|
||||||
LOCPLINT->cb->recruitHero(obj, toBuy, heroToInvite ? heroToInvite->getHeroType() : HeroTypeID::NONE);
|
LOCPLINT->cb->recruitHero(obj, toBuy, heroToInvite ? heroToInvite->getHeroTypeID() : HeroTypeID::NONE);
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -963,7 +963,7 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, BuildingID bu
|
|||||||
|
|
||||||
if(auto town = dynamic_cast<const CGTownInstance *>(_market))
|
if(auto town = dynamic_cast<const CGTownInstance *>(_market))
|
||||||
{
|
{
|
||||||
auto faction = town->town->faction->getId();
|
auto faction = town->getTown()->faction->getId();
|
||||||
titlePic = std::make_shared<CAnimImage>((*CGI->townh)[faction]->town->clientInfo.buildingsIcons, building);
|
titlePic = std::make_shared<CAnimImage>((*CGI->townh)[faction]->town->clientInfo.buildingsIcons, building);
|
||||||
}
|
}
|
||||||
else if(auto uni = dynamic_cast<const CGUniversity *>(_market); uni->appearance)
|
else if(auto uni = dynamic_cast<const CGUniversity *>(_market); uni->appearance)
|
||||||
|
@ -51,9 +51,9 @@ void QuickRecruitmentWindow::setCreaturePurchaseCards()
|
|||||||
{
|
{
|
||||||
int availableAmount = getAvailableCreatures();
|
int availableAmount = getAvailableCreatures();
|
||||||
Point position = Point((pos.w - 100*availableAmount - 8*(availableAmount-1))/2,64);
|
Point position = Point((pos.w - 100*availableAmount - 8*(availableAmount-1))/2,64);
|
||||||
for (int i = 0; i < town->town->creatures.size(); i++)
|
for (int i = 0; i < town->getTown()->creatures.size(); i++)
|
||||||
{
|
{
|
||||||
if(!town->town->creatures.at(i).empty() && !town->creatures.at(i).second.empty() && town->creatures[i].first)
|
if(!town->getTown()->creatures.at(i).empty() && !town->creatures.at(i).second.empty() && town->creatures[i].first)
|
||||||
{
|
{
|
||||||
cards.push_back(std::make_shared<CreaturePurchaseCard>(town->creatures[i].second, position, town->creatures[i].first, this));
|
cards.push_back(std::make_shared<CreaturePurchaseCard>(town->creatures[i].second, position, town->creatures[i].first, this));
|
||||||
position.x += 108;
|
position.x += 108;
|
||||||
@ -108,7 +108,7 @@ void QuickRecruitmentWindow::purchaseUnits()
|
|||||||
{
|
{
|
||||||
int level = 0;
|
int level = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(auto c : town->town->creatures)
|
for(auto c : town->getTown()->creatures)
|
||||||
{
|
{
|
||||||
for(auto c2 : c)
|
for(auto c2 : c)
|
||||||
if(c2 == selected->creatureOnTheCard->getId())
|
if(c2 == selected->creatureOnTheCard->getId())
|
||||||
@ -129,8 +129,8 @@ void QuickRecruitmentWindow::purchaseUnits()
|
|||||||
int QuickRecruitmentWindow::getAvailableCreatures()
|
int QuickRecruitmentWindow::getAvailableCreatures()
|
||||||
{
|
{
|
||||||
int creaturesAmount = 0;
|
int creaturesAmount = 0;
|
||||||
for (int i=0; i< town->town->creatures.size(); i++)
|
for (int i=0; i< town->getTown()->creatures.size(); i++)
|
||||||
if(!town->town->creatures.at(i).empty() && !town->creatures.at(i).second.empty() && town->creatures[i].first)
|
if(!town->getTown()->creatures.at(i).empty() && !town->creatures.at(i).second.empty() && town->creatures[i].first)
|
||||||
creaturesAmount++;
|
creaturesAmount++;
|
||||||
return creaturesAmount;
|
return creaturesAmount;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ class DLL_LINKAGE INativeTerrainProvider
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual TerrainId getNativeTerrain() const = 0;
|
virtual TerrainId getNativeTerrain() const = 0;
|
||||||
virtual FactionID getFaction() const = 0;
|
virtual FactionID getFactionID() const = 0;
|
||||||
virtual bool isNativeTerrain(TerrainId terrain) const;
|
virtual bool isNativeTerrain(TerrainId terrain) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ TerrainId AFactionMember::getNativeTerrain() const
|
|||||||
//this code is used in the CreatureTerrainLimiter::limit to setup battle bonuses
|
//this code is used in the CreatureTerrainLimiter::limit to setup battle bonuses
|
||||||
//and in the CGHeroInstance::getNativeTerrain() to setup movement bonuses or/and penalties.
|
//and in the CGHeroInstance::getNativeTerrain() to setup movement bonuses or/and penalties.
|
||||||
return getBonusBearer()->hasBonus(selectorNoTerrainPenalty, cachingStringNoTerrainPenalty)
|
return getBonusBearer()->hasBonus(selectorNoTerrainPenalty, cachingStringNoTerrainPenalty)
|
||||||
? TerrainId::ANY_TERRAIN : VLC->factions()->getById(getFaction())->getNativeTerrain();
|
? TerrainId::ANY_TERRAIN : getFactionID().toEntity(VLC)->getNativeTerrain();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t AFactionMember::magicResistance() const
|
int32_t AFactionMember::magicResistance() const
|
||||||
|
@ -117,7 +117,7 @@ int32_t CCreature::getHorde() const
|
|||||||
return hordeGrowth;
|
return hordeGrowth;
|
||||||
}
|
}
|
||||||
|
|
||||||
FactionID CCreature::getFaction() const
|
FactionID CCreature::getFactionID() const
|
||||||
{
|
{
|
||||||
return FactionID(faction);
|
return FactionID(faction);
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ public:
|
|||||||
std::string getNamePluralTextID() const override;
|
std::string getNamePluralTextID() const override;
|
||||||
std::string getNameSingularTextID() const override;
|
std::string getNameSingularTextID() const override;
|
||||||
|
|
||||||
FactionID getFaction() const override;
|
FactionID getFactionID() const override;
|
||||||
int32_t getIndex() const override;
|
int32_t getIndex() const override;
|
||||||
int32_t getIconIndex() const override;
|
int32_t getIconIndex() const override;
|
||||||
std::string getJsonKey() const override;
|
std::string getJsonKey() const override;
|
||||||
|
@ -912,10 +912,10 @@ void CStackInstance::serializeJson(JsonSerializeFormat & handler)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FactionID CStackInstance::getFaction() const
|
FactionID CStackInstance::getFactionID() const
|
||||||
{
|
{
|
||||||
if(type)
|
if(type)
|
||||||
return type->getFaction();
|
return type->getFactionID();
|
||||||
|
|
||||||
return FactionID::NEUTRAL;
|
return FactionID::NEUTRAL;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ public:
|
|||||||
//IConstBonusProvider
|
//IConstBonusProvider
|
||||||
const IBonusBearer* getBonusBearer() const override;
|
const IBonusBearer* getBonusBearer() const override;
|
||||||
//INativeTerrainProvider
|
//INativeTerrainProvider
|
||||||
FactionID getFaction() const override;
|
FactionID getFactionID() const override;
|
||||||
|
|
||||||
virtual ui64 getPower() const;
|
virtual ui64 getPower() const;
|
||||||
CCreature::CreatureQuantityId getQuantityID() const;
|
CCreature::CreatureQuantityId getQuantityID() const;
|
||||||
|
@ -381,7 +381,7 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
|
|||||||
|
|
||||||
for(const auto & creature : VLC->creh->objects)
|
for(const auto & creature : VLC->creh->objects)
|
||||||
{
|
{
|
||||||
if(creature->getFaction() == factionIndex && static_cast<int>(creature->getAIValue()) > maxAIValue)
|
if(creature->getFactionID() == factionIndex && static_cast<int>(creature->getAIValue()) > maxAIValue)
|
||||||
{
|
{
|
||||||
maxAIValue = creature->getAIValue();
|
maxAIValue = creature->getAIValue();
|
||||||
mostStrong = creature.get();
|
mostStrong = creature.get();
|
||||||
@ -575,10 +575,10 @@ EBuildingState CGameInfoCallback::canBuildStructure( const CGTownInstance *t, Bu
|
|||||||
{
|
{
|
||||||
ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", EBuildingState::TOWN_NOT_OWNED);
|
ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", EBuildingState::TOWN_NOT_OWNED);
|
||||||
|
|
||||||
if(!t->town->buildings.count(ID))
|
if(!t->getTown()->buildings.count(ID))
|
||||||
return EBuildingState::BUILDING_ERROR;
|
return EBuildingState::BUILDING_ERROR;
|
||||||
|
|
||||||
const CBuilding * building = t->town->buildings.at(ID);
|
const CBuilding * building = t->getTown()->buildings.at(ID);
|
||||||
|
|
||||||
|
|
||||||
if(t->hasBuilt(ID)) //already built
|
if(t->hasBuilt(ID)) //already built
|
||||||
|
@ -416,9 +416,9 @@ int32_t CUnitState::creatureIconIndex() const
|
|||||||
return unitType()->getIconIndex();
|
return unitType()->getIconIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
FactionID CUnitState::getFaction() const
|
FactionID CUnitState::getFactionID() const
|
||||||
{
|
{
|
||||||
return unitType()->getFaction();
|
return unitType()->getFactionID();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t CUnitState::getCasterUnitId() const
|
int32_t CUnitState::getCasterUnitId() const
|
||||||
|
@ -253,7 +253,7 @@ public:
|
|||||||
void localInit(const IUnitEnvironment * env_);
|
void localInit(const IUnitEnvironment * env_);
|
||||||
void serializeJson(JsonSerializeFormat & handler);
|
void serializeJson(JsonSerializeFormat & handler);
|
||||||
|
|
||||||
FactionID getFaction() const override;
|
FactionID getFactionID() const override;
|
||||||
|
|
||||||
void afterAttack(bool ranged, bool counter);
|
void afterAttack(bool ranged, bool counter);
|
||||||
|
|
||||||
|
@ -300,15 +300,15 @@ ILimiter::EDecision FactionLimiter::limit(const BonusLimitationContext &context)
|
|||||||
if(bearer)
|
if(bearer)
|
||||||
{
|
{
|
||||||
if(faction != FactionID::DEFAULT)
|
if(faction != FactionID::DEFAULT)
|
||||||
return bearer->getFaction() == faction ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
|
return bearer->getFactionID() == faction ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
|
||||||
|
|
||||||
switch(context.b.source)
|
switch(context.b.source)
|
||||||
{
|
{
|
||||||
case BonusSource::CREATURE_ABILITY:
|
case BonusSource::CREATURE_ABILITY:
|
||||||
return bearer->getFaction() == context.b.sid.as<CreatureID>().toCreature()->getFaction() ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
|
return bearer->getFactionID() == context.b.sid.as<CreatureID>().toCreature()->getFactionID() ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
|
||||||
|
|
||||||
case BonusSource::TOWN_STRUCTURE:
|
case BonusSource::TOWN_STRUCTURE:
|
||||||
return bearer->getFaction() == context.b.sid.as<BuildingTypeUniqueID>().getFaction() ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
|
return bearer->getFactionID() == context.b.sid.as<BuildingTypeUniqueID>().getFaction() ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
|
||||||
|
|
||||||
//TODO: other sources of bonuses
|
//TODO: other sources of bonuses
|
||||||
}
|
}
|
||||||
|
@ -351,14 +351,14 @@ void CampaignState::setCurrentMapAsConquered(std::vector<CGHeroInstance *> heroe
|
|||||||
{
|
{
|
||||||
JsonNode node = CampaignState::crossoverSerialize(hero);
|
JsonNode node = CampaignState::crossoverSerialize(hero);
|
||||||
|
|
||||||
if (reservedHeroes.count(hero->getHeroType()))
|
if (reservedHeroes.count(hero->getHeroTypeID()))
|
||||||
{
|
{
|
||||||
logGlobal->info("Hero crossover: %d (%s) exported to global pool", hero->getHeroType(), hero->getNameTranslated());
|
logGlobal->info("Hero crossover: %d (%s) exported to global pool", hero->getHeroTypeID(), hero->getNameTranslated());
|
||||||
globalHeroPool[hero->getHeroType()] = node;
|
globalHeroPool[hero->getHeroTypeID()] = node;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logGlobal->info("Hero crossover: %d (%s) exported to scenario pool", hero->getHeroType(), hero->getNameTranslated());
|
logGlobal->info("Hero crossover: %d (%s) exported to scenario pool", hero->getHeroTypeID(), hero->getNameTranslated());
|
||||||
scenarioHeroPool[*currentMap].push_back(node);
|
scenarioHeroPool[*currentMap].push_back(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ FactionID CFaction::getId() const
|
|||||||
return FactionID(index);
|
return FactionID(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
FactionID CFaction::getFaction() const
|
FactionID CFaction::getFactionID() const
|
||||||
{
|
{
|
||||||
return FactionID(index);
|
return FactionID(index);
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ class DLL_LINKAGE CFaction : public Faction
|
|||||||
|
|
||||||
FactionID index = FactionID::NEUTRAL;
|
FactionID index = FactionID::NEUTRAL;
|
||||||
|
|
||||||
FactionID getFaction() const override; //This function should not be used
|
FactionID getFactionID() const override; //This function should not be used
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TerrainId nativeTerrain;
|
TerrainId nativeTerrain;
|
||||||
|
@ -599,7 +599,7 @@ void CGameState::initHeroes()
|
|||||||
}
|
}
|
||||||
|
|
||||||
hero->initHero(getRandomGenerator());
|
hero->initHero(getRandomGenerator());
|
||||||
map->allHeroes[hero->getHeroType().getNum()] = hero;
|
map->allHeroes[hero->getHeroTypeID().getNum()] = hero;
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate boats for all heroes on water
|
// generate boats for all heroes on water
|
||||||
@ -629,20 +629,20 @@ void CGameState::initHeroes()
|
|||||||
{
|
{
|
||||||
auto * hero = dynamic_cast<CGHeroInstance*>(obj.get());
|
auto * hero = dynamic_cast<CGHeroInstance*>(obj.get());
|
||||||
hero->initHero(getRandomGenerator());
|
hero->initHero(getRandomGenerator());
|
||||||
map->allHeroes[hero->getHeroType().getNum()] = hero;
|
map->allHeroes[hero->getHeroTypeID().getNum()] = hero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<HeroTypeID> heroesToCreate = getUnusedAllowedHeroes(); //ids of heroes to be created and put into the pool
|
std::set<HeroTypeID> heroesToCreate = getUnusedAllowedHeroes(); //ids of heroes to be created and put into the pool
|
||||||
for(auto ph : map->predefinedHeroes)
|
for(auto ph : map->predefinedHeroes)
|
||||||
{
|
{
|
||||||
if(!vstd::contains(heroesToCreate, ph->getHeroType()))
|
if(!vstd::contains(heroesToCreate, ph->getHeroTypeID()))
|
||||||
continue;
|
continue;
|
||||||
ph->initHero(getRandomGenerator());
|
ph->initHero(getRandomGenerator());
|
||||||
heroesPool->addHeroToPool(ph);
|
heroesPool->addHeroToPool(ph);
|
||||||
heroesToCreate.erase(ph->type->getId());
|
heroesToCreate.erase(ph->getHeroTypeID());
|
||||||
|
|
||||||
map->allHeroes[ph->getHeroType().getNum()] = ph;
|
map->allHeroes[ph->getHeroTypeID().getNum()] = ph;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(const HeroTypeID & htype : heroesToCreate) //all not used allowed heroes go with default state into the pool
|
for(const HeroTypeID & htype : heroesToCreate) //all not used allowed heroes go with default state into the pool
|
||||||
@ -756,12 +756,12 @@ void CGameState::initTownNames()
|
|||||||
|
|
||||||
for(auto & vti : map->towns)
|
for(auto & vti : map->towns)
|
||||||
{
|
{
|
||||||
assert(vti->town);
|
assert(vti->getTown());
|
||||||
|
|
||||||
if(!vti->getNameTextID().empty())
|
if(!vti->getNameTextID().empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
FactionID faction = vti->getFaction();
|
FactionID faction = vti->getFactionID();
|
||||||
|
|
||||||
if(availableNames.empty())
|
if(availableNames.empty())
|
||||||
{
|
{
|
||||||
@ -798,8 +798,8 @@ void CGameState::initTowns()
|
|||||||
|
|
||||||
for (auto & vti : map->towns)
|
for (auto & vti : map->towns)
|
||||||
{
|
{
|
||||||
assert(vti->town);
|
assert(vti->getTown());
|
||||||
assert(vti->town->creatures.size() <= GameConstants::CREATURES_PER_TOWN);
|
assert(vti->getTown()->creatures.size() <= GameConstants::CREATURES_PER_TOWN);
|
||||||
|
|
||||||
constexpr std::array basicDwellings = { BuildingID::DWELL_FIRST, BuildingID::DWELL_LVL_2, BuildingID::DWELL_LVL_3, BuildingID::DWELL_LVL_4, BuildingID::DWELL_LVL_5, BuildingID::DWELL_LVL_6, BuildingID::DWELL_LVL_7, BuildingID::DWELL_LVL_8 };
|
constexpr std::array basicDwellings = { BuildingID::DWELL_FIRST, BuildingID::DWELL_LVL_2, BuildingID::DWELL_LVL_3, BuildingID::DWELL_LVL_4, BuildingID::DWELL_LVL_5, BuildingID::DWELL_LVL_6, BuildingID::DWELL_LVL_7, BuildingID::DWELL_LVL_8 };
|
||||||
constexpr std::array upgradedDwellings = { BuildingID::DWELL_UP_FIRST, BuildingID::DWELL_LVL_2_UP, BuildingID::DWELL_LVL_3_UP, BuildingID::DWELL_LVL_4_UP, BuildingID::DWELL_LVL_5_UP, BuildingID::DWELL_LVL_6_UP, BuildingID::DWELL_LVL_7_UP, BuildingID::DWELL_LVL_8_UP };
|
constexpr std::array upgradedDwellings = { BuildingID::DWELL_UP_FIRST, BuildingID::DWELL_LVL_2_UP, BuildingID::DWELL_LVL_3_UP, BuildingID::DWELL_LVL_4_UP, BuildingID::DWELL_LVL_5_UP, BuildingID::DWELL_LVL_6_UP, BuildingID::DWELL_LVL_7_UP, BuildingID::DWELL_LVL_8_UP };
|
||||||
@ -828,7 +828,7 @@ void CGameState::initTowns()
|
|||||||
vti->addBuilding(BuildingID::VILLAGE_HALL);
|
vti->addBuilding(BuildingID::VILLAGE_HALL);
|
||||||
|
|
||||||
//init hordes
|
//init hordes
|
||||||
for (int i = 0; i < vti->town->creatures.size(); i++)
|
for (int i = 0; i < vti->getTown()->creatures.size(); i++)
|
||||||
{
|
{
|
||||||
if(vti->hasBuilt(hordes[i])) //if we have horde for this level
|
if(vti->hasBuilt(hordes[i])) //if we have horde for this level
|
||||||
{
|
{
|
||||||
@ -894,7 +894,7 @@ void CGameState::initTowns()
|
|||||||
int sel = -1;
|
int sel = -1;
|
||||||
|
|
||||||
for(ui32 ps=0;ps<vti->possibleSpells.size();ps++)
|
for(ui32 ps=0;ps<vti->possibleSpells.size();ps++)
|
||||||
total += vti->possibleSpells[ps].toSpell()->getProbability(vti->getFaction());
|
total += vti->possibleSpells[ps].toSpell()->getProbability(vti->getFactionID());
|
||||||
|
|
||||||
if (total == 0) // remaining spells have 0 probability
|
if (total == 0) // remaining spells have 0 probability
|
||||||
break;
|
break;
|
||||||
@ -902,7 +902,7 @@ void CGameState::initTowns()
|
|||||||
auto r = getRandomGenerator().nextInt(total - 1);
|
auto r = getRandomGenerator().nextInt(total - 1);
|
||||||
for(ui32 ps=0; ps<vti->possibleSpells.size();ps++)
|
for(ui32 ps=0; ps<vti->possibleSpells.size();ps++)
|
||||||
{
|
{
|
||||||
r -= vti->possibleSpells[ps].toSpell()->getProbability(vti->getFaction());
|
r -= vti->possibleSpells[ps].toSpell()->getProbability(vti->getFactionID());
|
||||||
if(r<0)
|
if(r<0)
|
||||||
{
|
{
|
||||||
sel = ps;
|
sel = ps;
|
||||||
@ -1655,18 +1655,13 @@ std::set<HeroTypeID> CGameState::getUnusedAllowedHeroes(bool alsoIncludeNotAllow
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(auto hero : map->heroesOnMap) //heroes instances initialization
|
for(auto hero : map->heroesOnMap) //heroes instances initialization
|
||||||
{
|
ret -= hero->getHeroTypeID();
|
||||||
if(hero->type)
|
|
||||||
ret -= hero->type->getId();
|
|
||||||
else
|
|
||||||
ret -= hero->getHeroType();
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto obj : map->objects) //prisons
|
for(auto obj : map->objects) //prisons
|
||||||
{
|
{
|
||||||
auto * hero = dynamic_cast<const CGHeroInstance *>(obj.get());
|
auto * hero = dynamic_cast<const CGHeroInstance *>(obj.get());
|
||||||
if(hero && hero->ID == Obj::PRISON)
|
if(hero && hero->ID == Obj::PRISON)
|
||||||
ret -= hero->getHeroType();
|
ret -= hero->getHeroTypeID();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -1690,7 +1685,7 @@ CGHeroInstance * CGameState::getUsedHero(const HeroTypeID & hid) const
|
|||||||
auto * hero = dynamic_cast<CGHeroInstance *>(obj.get());
|
auto * hero = dynamic_cast<CGHeroInstance *>(obj.get());
|
||||||
assert(hero);
|
assert(hero);
|
||||||
|
|
||||||
if (hero->getHeroType() == hid)
|
if (hero->getHeroTypeID() == hid)
|
||||||
return hero;
|
return hero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(const CampaignTravel & tr
|
|||||||
.And(Selector::subtype()(BonusSubtypeID(g)))
|
.And(Selector::subtype()(BonusSubtypeID(g)))
|
||||||
.And(Selector::sourceType()(BonusSource::HERO_BASE_SKILL));
|
.And(Selector::sourceType()(BonusSource::HERO_BASE_SKILL));
|
||||||
|
|
||||||
hero.hero->getLocalBonus(sel)->val = hero.hero->type->heroClass->primarySkillInitial[g.getNum()];
|
hero.hero->getLocalBonus(sel)->val = hero.hero->getHeroClass()->primarySkillInitial[g.getNum()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(const CampaignTravel & tr
|
|||||||
//trimming sec skills
|
//trimming sec skills
|
||||||
for(auto & hero : campaignHeroReplacements)
|
for(auto & hero : campaignHeroReplacements)
|
||||||
{
|
{
|
||||||
hero.hero->secSkills = hero.hero->type->secSkillsInit;
|
hero.hero->secSkills = hero.hero->getHeroType()->secSkillsInit;
|
||||||
hero.hero->recreateSecondarySkillsBonuses();
|
hero.hero->recreateSecondarySkillsBonuses();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -240,7 +240,7 @@ void CGameStateCampaign::placeCampaignHeroes()
|
|||||||
|
|
||||||
for(auto & replacement : campaignHeroReplacements)
|
for(auto & replacement : campaignHeroReplacements)
|
||||||
if (replacement.heroPlaceholderId.hasValue())
|
if (replacement.heroPlaceholderId.hasValue())
|
||||||
heroesToRemove.insert(replacement.hero->getHeroType());
|
heroesToRemove.insert(replacement.hero->getHeroTypeID());
|
||||||
|
|
||||||
for(auto & heroID : heroesToRemove)
|
for(auto & heroID : heroesToRemove)
|
||||||
{
|
{
|
||||||
@ -369,8 +369,8 @@ void CGameStateCampaign::replaceHeroesPlaceholders()
|
|||||||
if(heroPlaceholder->tempOwner.isValidPlayer())
|
if(heroPlaceholder->tempOwner.isValidPlayer())
|
||||||
heroToPlace->tempOwner = heroPlaceholder->tempOwner;
|
heroToPlace->tempOwner = heroPlaceholder->tempOwner;
|
||||||
heroToPlace->setAnchorPos(heroPlaceholder->anchorPos());
|
heroToPlace->setAnchorPos(heroPlaceholder->anchorPos());
|
||||||
heroToPlace->type = heroToPlace->getHeroType().toHeroType();
|
heroToPlace->setHeroType(heroToPlace->getHeroTypeID());
|
||||||
heroToPlace->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, heroToPlace->type->heroClass->getIndex())->getTemplates().front();
|
heroToPlace->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, heroToPlace->getHeroTypeID())->getTemplates().front();
|
||||||
|
|
||||||
gameState->map->removeBlockVisTiles(heroPlaceholder, true);
|
gameState->map->removeBlockVisTiles(heroPlaceholder, true);
|
||||||
gameState->map->objects[heroPlaceholder->id.getNum()] = nullptr;
|
gameState->map->objects[heroPlaceholder->id.getNum()] = nullptr;
|
||||||
@ -563,7 +563,7 @@ void CGameStateCampaign::initHeroes()
|
|||||||
{
|
{
|
||||||
for (auto & hero : heroes)
|
for (auto & hero : heroes)
|
||||||
{
|
{
|
||||||
if (hero->getHeroType().getNum() == chosenBonus->info1)
|
if (hero->getHeroTypeID().getNum() == chosenBonus->info1)
|
||||||
{
|
{
|
||||||
giveCampaignBonusToHero(hero);
|
giveCampaignBonusToHero(hero);
|
||||||
break;
|
break;
|
||||||
@ -662,7 +662,7 @@ void CGameStateCampaign::initTowns()
|
|||||||
if(gameState->scenarioOps->campState->formatVCMI())
|
if(gameState->scenarioOps->campState->formatVCMI())
|
||||||
newBuilding = BuildingID(chosenBonus->info1);
|
newBuilding = BuildingID(chosenBonus->info1);
|
||||||
else
|
else
|
||||||
newBuilding = CBuildingHandler::campToERMU(chosenBonus->info1, town->getFaction(), town->getBuildings());
|
newBuilding = CBuildingHandler::campToERMU(chosenBonus->info1, town->getFactionID(), town->getBuildings());
|
||||||
|
|
||||||
// Build granted building & all prerequisites - e.g. Mages Guild Lvl 3 should also give Mages Guild Lvl 1 & 2
|
// Build granted building & all prerequisites - e.g. Mages Guild Lvl 3 should also give Mages Guild Lvl 1 & 2
|
||||||
while(true)
|
while(true)
|
||||||
@ -675,7 +675,7 @@ void CGameStateCampaign::initTowns()
|
|||||||
|
|
||||||
town->addBuilding(newBuilding);
|
town->addBuilding(newBuilding);
|
||||||
|
|
||||||
auto building = town->town->buildings.at(newBuilding);
|
auto building = town->getTown()->buildings.at(newBuilding);
|
||||||
newBuilding = building->upgrade;
|
newBuilding = building->upgrade;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -381,7 +381,7 @@ float Statistic::getTownBuiltRatio(const PlayerState * ps)
|
|||||||
for(const auto & t : ps->getTowns())
|
for(const auto & t : ps->getTowns())
|
||||||
{
|
{
|
||||||
built += t->getBuildings().size();
|
built += t->getBuildings().size();
|
||||||
for(const auto & b : t->town->buildings)
|
for(const auto & b : t->getTown()->buildings)
|
||||||
if(!t->forbiddenBuildings.count(b.first))
|
if(!t->forbiddenBuildings.count(b.first))
|
||||||
total += 1;
|
total += 1;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ void InfoAboutHero::initFromHero(const CGHeroInstance *h, InfoAboutHero::EInfoLe
|
|||||||
|
|
||||||
initFromArmy(h, detailed);
|
initFromArmy(h, detailed);
|
||||||
|
|
||||||
hclass = h->type->heroClass;
|
hclass = h->getHeroClass();
|
||||||
name = h->getNameTranslated();
|
name = h->getNameTranslated();
|
||||||
portraitSource = h->getPortraitSource();
|
portraitSource = h->getPortraitSource();
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ std::map<HeroTypeID, CGHeroInstance*> TavernHeroesPool::unusedHeroesFromPool() c
|
|||||||
{
|
{
|
||||||
std::map<HeroTypeID, CGHeroInstance*> pool = heroesPool;
|
std::map<HeroTypeID, CGHeroInstance*> pool = heroesPool;
|
||||||
for(const auto & slot : currentTavern)
|
for(const auto & slot : currentTavern)
|
||||||
pool.erase(slot.hero->getHeroType());
|
pool.erase(slot.hero->getHeroTypeID());
|
||||||
|
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ TavernSlotRole TavernHeroesPool::getSlotRole(HeroTypeID hero) const
|
|||||||
{
|
{
|
||||||
for (auto const & slot : currentTavern)
|
for (auto const & slot : currentTavern)
|
||||||
{
|
{
|
||||||
if (slot.hero->getHeroType() == hero)
|
if (slot.hero->getHeroTypeID() == hero)
|
||||||
return slot.role;
|
return slot.role;
|
||||||
}
|
}
|
||||||
return TavernSlotRole::NONE;
|
return TavernSlotRole::NONE;
|
||||||
@ -106,7 +106,7 @@ CGHeroInstance * TavernHeroesPool::takeHeroFromPool(HeroTypeID hero)
|
|||||||
heroesPool.erase(hero);
|
heroesPool.erase(hero);
|
||||||
|
|
||||||
vstd::erase_if(currentTavern, [&](const TavernSlot & entry){
|
vstd::erase_if(currentTavern, [&](const TavernSlot & entry){
|
||||||
return entry.hero->type->getId() == hero;
|
return entry.hero->getHeroTypeID() == hero;
|
||||||
});
|
});
|
||||||
|
|
||||||
assert(result);
|
assert(result);
|
||||||
@ -138,7 +138,7 @@ void TavernHeroesPool::onNewDay()
|
|||||||
|
|
||||||
void TavernHeroesPool::addHeroToPool(CGHeroInstance * hero)
|
void TavernHeroesPool::addHeroToPool(CGHeroInstance * hero)
|
||||||
{
|
{
|
||||||
heroesPool[hero->getHeroType()] = hero;
|
heroesPool[hero->getHeroTypeID()] = hero;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TavernHeroesPool::setAvailability(HeroTypeID hero, std::set<PlayerColor> mask)
|
void TavernHeroesPool::setAvailability(HeroTypeID hero, std::set<PlayerColor> mask)
|
||||||
|
@ -96,7 +96,6 @@ bool CTownInstanceConstructor::objectFilter(const CGObjectInstance * object, std
|
|||||||
|
|
||||||
void CTownInstanceConstructor::initializeObject(CGTownInstance * obj) const
|
void CTownInstanceConstructor::initializeObject(CGTownInstance * obj) const
|
||||||
{
|
{
|
||||||
obj->town = faction->town;
|
|
||||||
obj->tempOwner = PlayerColor::NEUTRAL;
|
obj->tempOwner = PlayerColor::NEUTRAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +143,7 @@ bool CHeroInstanceConstructor::objectFilter(const CGObjectInstance * object, std
|
|||||||
|
|
||||||
auto heroTest = [&](const HeroTypeID & id)
|
auto heroTest = [&](const HeroTypeID & id)
|
||||||
{
|
{
|
||||||
return hero->type->getId() == id;
|
return hero->getHeroTypeID() == id;
|
||||||
};
|
};
|
||||||
|
|
||||||
if(filters.count(templ->stringID))
|
if(filters.count(templ->stringID))
|
||||||
@ -154,11 +153,6 @@ bool CHeroInstanceConstructor::objectFilter(const CGObjectInstance * object, std
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHeroInstanceConstructor::initializeObject(CGHeroInstance * obj) const
|
|
||||||
{
|
|
||||||
obj->type = nullptr; //FIXME: set to valid value. somehow.
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHeroInstanceConstructor::randomizeObject(CGHeroInstance * object, vstd::RNG & rng) const
|
void CHeroInstanceConstructor::randomizeObject(CGHeroInstance * object, vstd::RNG & rng) const
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -81,7 +81,6 @@ public:
|
|||||||
const CHeroClass * heroClass = nullptr;
|
const CHeroClass * heroClass = nullptr;
|
||||||
std::map<std::string, LogicalExpression<HeroTypeID>> filters;
|
std::map<std::string, LogicalExpression<HeroTypeID>> filters;
|
||||||
|
|
||||||
void initializeObject(CGHeroInstance * object) const override;
|
|
||||||
void randomizeObject(CGHeroInstance * object, vstd::RNG & rng) const override;
|
void randomizeObject(CGHeroInstance * object, vstd::RNG & rng) const override;
|
||||||
void afterLoadFinalization() override;
|
void afterLoadFinalization() override;
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ void CArmedInstance::updateMoraleBonusFromArmy()
|
|||||||
const CStackInstance * inst = slot.second;
|
const CStackInstance * inst = slot.second;
|
||||||
const auto * creature = inst->getCreatureID().toEntity(VLC);
|
const auto * creature = inst->getCreatureID().toEntity(VLC);
|
||||||
|
|
||||||
factions.insert(creature->getFaction());
|
factions.insert(creature->getFactionID());
|
||||||
// Check for undead flag instead of faction (undead mummies are neutral)
|
// Check for undead flag instead of faction (undead mummies are neutral)
|
||||||
if (!hasUndead)
|
if (!hasUndead)
|
||||||
{
|
{
|
||||||
|
@ -45,7 +45,7 @@ std::string CGCreature::getHoverText(PlayerColor player) const
|
|||||||
else
|
else
|
||||||
ms.appendLocalString(EMetaText::ARRAY_TXT, quantityTextIndex);
|
ms.appendLocalString(EMetaText::ARRAY_TXT, quantityTextIndex);
|
||||||
ms.appendRawString(" ");
|
ms.appendRawString(" ");
|
||||||
ms.appendNamePlural(getCreature());
|
ms.appendNamePlural(getCreatureID());
|
||||||
|
|
||||||
return ms.toString();
|
return ms.toString();
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@ std::string CGCreature::getHoverText(const CGHeroInstance * hero) const
|
|||||||
MetaString ms;
|
MetaString ms;
|
||||||
ms.appendNumber(stacks.begin()->second->count);
|
ms.appendNumber(stacks.begin()->second->count);
|
||||||
ms.appendRawString(" ");
|
ms.appendRawString(" ");
|
||||||
ms.appendName(getCreature(), stacks.begin()->second->count);
|
ms.appendName(getCreatureID(), stacks.begin()->second->count);
|
||||||
return ms.toString();
|
return ms.toString();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -69,11 +69,11 @@ std::string CGCreature::getHoverText(const CGHeroInstance * hero) const
|
|||||||
std::string CGCreature::getMonsterLevelText() const
|
std::string CGCreature::getMonsterLevelText() const
|
||||||
{
|
{
|
||||||
std::string monsterLevel = VLC->generaltexth->translate("vcmi.adventureMap.monsterLevel");
|
std::string monsterLevel = VLC->generaltexth->translate("vcmi.adventureMap.monsterLevel");
|
||||||
bool isRanged = VLC->creatures()->getById(getCreature())->getBonusBearer()->hasBonusOfType(BonusType::SHOOTER);
|
bool isRanged = getCreature()->getBonusBearer()->hasBonusOfType(BonusType::SHOOTER);
|
||||||
std::string attackTypeKey = isRanged ? "vcmi.adventureMap.monsterRangedType" : "vcmi.adventureMap.monsterMeleeType";
|
std::string attackTypeKey = isRanged ? "vcmi.adventureMap.monsterRangedType" : "vcmi.adventureMap.monsterMeleeType";
|
||||||
std::string attackType = VLC->generaltexth->translate(attackTypeKey);
|
std::string attackType = VLC->generaltexth->translate(attackTypeKey);
|
||||||
boost::replace_first(monsterLevel, "%TOWN", (*VLC->townh)[VLC->creatures()->getById(getCreature())->getFaction()]->getNameTranslated());
|
boost::replace_first(monsterLevel, "%TOWN", getCreature()->getFactionID().toEntity(VLC)->getNameTranslated());
|
||||||
boost::replace_first(monsterLevel, "%LEVEL", std::to_string(VLC->creatures()->getById(getCreature())->getLevel()));
|
boost::replace_first(monsterLevel, "%LEVEL", std::to_string(getCreature()->getLevel()));
|
||||||
boost::replace_first(monsterLevel, "%ATTACK_TYPE", attackType);
|
boost::replace_first(monsterLevel, "%ATTACK_TYPE", attackType);
|
||||||
return monsterLevel;
|
return monsterLevel;
|
||||||
}
|
}
|
||||||
@ -150,7 +150,7 @@ std::string CGCreature::getPopupText(PlayerColor player) const
|
|||||||
std::vector<Component> CGCreature::getPopupComponents(PlayerColor player) const
|
std::vector<Component> CGCreature::getPopupComponents(PlayerColor player) const
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
Component(ComponentType::CREATURE, getCreature())
|
Component(ComponentType::CREATURE, getCreatureID())
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +182,7 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
BlockingDialog ynd(true,false);
|
BlockingDialog ynd(true,false);
|
||||||
ynd.player = h->tempOwner;
|
ynd.player = h->tempOwner;
|
||||||
ynd.text.appendLocalString(EMetaText::ADVOB_TXT, 86);
|
ynd.text.appendLocalString(EMetaText::ADVOB_TXT, 86);
|
||||||
ynd.text.replaceName(getCreature(), getStackCount(SlotID(0)));
|
ynd.text.replaceName(getCreatureID(), getStackCount(SlotID(0)));
|
||||||
cb->showBlockingDialog(this, &ynd);
|
cb->showBlockingDialog(this, &ynd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -197,7 +197,7 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
std::string tmp = VLC->generaltexth->advobtxt[90];
|
std::string tmp = VLC->generaltexth->advobtxt[90];
|
||||||
boost::algorithm::replace_first(tmp, "%d", std::to_string(getStackCount(SlotID(0))));
|
boost::algorithm::replace_first(tmp, "%d", std::to_string(getStackCount(SlotID(0))));
|
||||||
boost::algorithm::replace_first(tmp, "%d", std::to_string(action));
|
boost::algorithm::replace_first(tmp, "%d", std::to_string(action));
|
||||||
boost::algorithm::replace_first(tmp,"%s",VLC->creatures()->getById(getCreature())->getNamePluralTranslated());
|
boost::algorithm::replace_first(tmp,"%s",getCreature()->getNamePluralTranslated());
|
||||||
ynd.text.appendRawString(tmp);
|
ynd.text.appendRawString(tmp);
|
||||||
cb->showBlockingDialog(this, &ynd);
|
cb->showBlockingDialog(this, &ynd);
|
||||||
break;
|
break;
|
||||||
@ -205,11 +205,16 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CreatureID CGCreature::getCreature() const
|
CreatureID CGCreature::getCreatureID() const
|
||||||
{
|
{
|
||||||
return CreatureID(getObjTypeIndex().getNum());
|
return CreatureID(getObjTypeIndex().getNum());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CCreature * CGCreature::getCreature() const
|
||||||
|
{
|
||||||
|
return getCreatureID().toCreature();
|
||||||
|
}
|
||||||
|
|
||||||
void CGCreature::pickRandomObject(vstd::RNG & rand)
|
void CGCreature::pickRandomObject(vstd::RNG & rand)
|
||||||
{
|
{
|
||||||
switch(ID.toEnum())
|
switch(ID.toEnum())
|
||||||
@ -279,7 +284,7 @@ void CGCreature::initObj(vstd::RNG & rand)
|
|||||||
|
|
||||||
stacks[SlotID(0)]->setType(getCreature());
|
stacks[SlotID(0)]->setType(getCreature());
|
||||||
TQuantity &amount = stacks[SlotID(0)]->count;
|
TQuantity &amount = stacks[SlotID(0)]->count;
|
||||||
const Creature * c = VLC->creatures()->getById(getCreature());
|
const Creature * c = getCreature();
|
||||||
if(amount == 0)
|
if(amount == 0)
|
||||||
{
|
{
|
||||||
amount = rand.nextInt(c->getAdvMapAmountMin(), c->getAdvMapAmountMax());
|
amount = rand.nextInt(c->getAdvMapAmountMin(), c->getAdvMapAmountMax());
|
||||||
@ -353,8 +358,8 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
|
|||||||
|
|
||||||
for(const auto & elem : h->Slots())
|
for(const auto & elem : h->Slots())
|
||||||
{
|
{
|
||||||
bool isOurUpgrade = vstd::contains(getCreature().toCreature()->upgrades, elem.second->getCreatureID());
|
bool isOurUpgrade = vstd::contains(getCreature()->upgrades, elem.second->getCreatureID());
|
||||||
bool isOurDowngrade = vstd::contains(elem.second->type->upgrades, getCreature());
|
bool isOurDowngrade = vstd::contains(elem.second->type->upgrades, getCreatureID());
|
||||||
|
|
||||||
if(isOurUpgrade || isOurDowngrade)
|
if(isOurUpgrade || isOurDowngrade)
|
||||||
count += elem.second->count;
|
count += elem.second->count;
|
||||||
@ -380,7 +385,7 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
|
|||||||
|
|
||||||
if(diplomacy * 2 + sympathy + 1 >= character)
|
if(diplomacy * 2 + sympathy + 1 >= character)
|
||||||
{
|
{
|
||||||
int32_t recruitCost = VLC->creatures()->getById(getCreature())->getRecruitCost(EGameResID::GOLD);
|
int32_t recruitCost = getCreature()->getRecruitCost(EGameResID::GOLD);
|
||||||
int32_t stackCount = getStackCount(SlotID(0));
|
int32_t stackCount = getStackCount(SlotID(0));
|
||||||
return recruitCost * stackCount; //join for gold
|
return recruitCost * stackCount; //join for gold
|
||||||
}
|
}
|
||||||
@ -493,7 +498,7 @@ void CGCreature::flee( const CGHeroInstance * h ) const
|
|||||||
BlockingDialog ynd(true,false);
|
BlockingDialog ynd(true,false);
|
||||||
ynd.player = h->tempOwner;
|
ynd.player = h->tempOwner;
|
||||||
ynd.text.appendLocalString(EMetaText::ADVOB_TXT,91);
|
ynd.text.appendLocalString(EMetaText::ADVOB_TXT,91);
|
||||||
ynd.text.replaceName(getCreature(), getStackCount(SlotID(0)));
|
ynd.text.replaceName(getCreatureID(), getStackCount(SlotID(0)));
|
||||||
cb->showBlockingDialog(this, &ynd);
|
cb->showBlockingDialog(this, &ynd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -513,7 +518,7 @@ void CGCreature::battleFinished(const CGHeroInstance *hero, const BattleResult &
|
|||||||
{
|
{
|
||||||
//merge stacks into one
|
//merge stacks into one
|
||||||
TSlots::const_iterator i;
|
TSlots::const_iterator i;
|
||||||
const CCreature * cre = getCreature().toCreature();
|
const CCreature * cre = getCreature();
|
||||||
for(i = stacks.begin(); i != stacks.end(); i++)
|
for(i = stacks.begin(); i != stacks.end(); i++)
|
||||||
{
|
{
|
||||||
if(cre->isMyUpgrade(i->second->type))
|
if(cre->isMyUpgrade(i->second->type))
|
||||||
|
@ -49,7 +49,8 @@ public:
|
|||||||
void newTurn(vstd::RNG & rand) const override;
|
void newTurn(vstd::RNG & rand) const override;
|
||||||
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
|
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||||
void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const override;
|
void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const override;
|
||||||
CreatureID getCreature() const;
|
CreatureID getCreatureID() const;
|
||||||
|
const CCreature * getCreature() const;
|
||||||
|
|
||||||
//stack formation depends on position,
|
//stack formation depends on position,
|
||||||
bool containsUpgradedStack() const;
|
bool containsUpgradedStack() const;
|
||||||
|
@ -93,7 +93,7 @@ FactionID CGDwelling::randomizeFaction(vstd::RNG & rand)
|
|||||||
|
|
||||||
assert(linkedTown->ID == Obj::TOWN);
|
assert(linkedTown->ID == Obj::TOWN);
|
||||||
if(linkedTown->ID==Obj::TOWN)
|
if(linkedTown->ID==Obj::TOWN)
|
||||||
return linkedTown->getFaction();
|
return linkedTown->getFactionID();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!randomizationInfo->allowedFactions.empty())
|
if(!randomizationInfo->allowedFactions.empty())
|
||||||
|
@ -116,9 +116,9 @@ ui32 CGHeroInstance::getTileMovementCost(const TerrainTile & dest, const Terrain
|
|||||||
return static_cast<ui32>(ret);
|
return static_cast<ui32>(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
FactionID CGHeroInstance::getFaction() const
|
FactionID CGHeroInstance::getFactionID() const
|
||||||
{
|
{
|
||||||
return FactionID(type->heroClass->faction);
|
return getHeroClass()->faction;
|
||||||
}
|
}
|
||||||
|
|
||||||
const IBonusBearer* CGHeroInstance::getBonusBearer() const
|
const IBonusBearer* CGHeroInstance::getBonusBearer() const
|
||||||
@ -229,10 +229,10 @@ bool CGHeroInstance::canLearnSkill(const SecondarySkill & which) const
|
|||||||
if (getSecSkillLevel(which) > 0)
|
if (getSecSkillLevel(which) > 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (type->heroClass->secSkillProbability.count(which) == 0)
|
if (getHeroClass()->secSkillProbability.count(which) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (type->heroClass->secSkillProbability.at(which) == 0)
|
if (getHeroClass()->secSkillProbability.at(which) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -282,7 +282,6 @@ int CGHeroInstance::movementPointsLimitCached(bool onLand, const TurnInfo * ti)
|
|||||||
|
|
||||||
CGHeroInstance::CGHeroInstance(IGameCallback * cb)
|
CGHeroInstance::CGHeroInstance(IGameCallback * cb)
|
||||||
: CArmedInstance(cb),
|
: CArmedInstance(cb),
|
||||||
type(nullptr),
|
|
||||||
tacticFormationEnabled(false),
|
tacticFormationEnabled(false),
|
||||||
inTownGarrison(false),
|
inTownGarrison(false),
|
||||||
moveDir(4),
|
moveDir(4),
|
||||||
@ -303,14 +302,30 @@ PlayerColor CGHeroInstance::getOwner() const
|
|||||||
return tempOwner;
|
return tempOwner;
|
||||||
}
|
}
|
||||||
|
|
||||||
HeroTypeID CGHeroInstance::getHeroType() const
|
const CHeroClass * CGHeroInstance::getHeroClass() const
|
||||||
{
|
{
|
||||||
|
return getHeroType()->heroClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
HeroClassID CGHeroInstance::getHeroClassID() const
|
||||||
|
{
|
||||||
|
return getHeroType()->heroClass->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
const CHero * CGHeroInstance::getHeroType() const
|
||||||
|
{
|
||||||
|
return getHeroTypeID().toHeroType();
|
||||||
|
}
|
||||||
|
|
||||||
|
HeroTypeID CGHeroInstance::getHeroTypeID() const
|
||||||
|
{
|
||||||
|
if (ID == Obj::RANDOM_HERO)
|
||||||
|
return HeroTypeID::NONE;
|
||||||
return HeroTypeID(getObjTypeIndex().getNum());
|
return HeroTypeID(getObjTypeIndex().getNum());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGHeroInstance::setHeroType(HeroTypeID heroType)
|
void CGHeroInstance::setHeroType(HeroTypeID heroType)
|
||||||
{
|
{
|
||||||
assert(type == nullptr);
|
|
||||||
subID = heroType;
|
subID = heroType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,16 +338,14 @@ void CGHeroInstance::initHero(vstd::RNG & rand, const HeroTypeID & SUBID)
|
|||||||
void CGHeroInstance::initHero(vstd::RNG & rand)
|
void CGHeroInstance::initHero(vstd::RNG & rand)
|
||||||
{
|
{
|
||||||
assert(validTypes(true));
|
assert(validTypes(true));
|
||||||
if(!type)
|
|
||||||
type = getHeroType().toHeroType();
|
|
||||||
|
|
||||||
if (ID == Obj::HERO)
|
if (ID == Obj::HERO)
|
||||||
appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();
|
appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, getHeroClass()->getIndex())->getTemplates().front();
|
||||||
|
|
||||||
if(!vstd::contains(spells, SpellID::PRESET))
|
if(!vstd::contains(spells, SpellID::PRESET))
|
||||||
{
|
{
|
||||||
// hero starts with default spells
|
// hero starts with default spells
|
||||||
for(const auto & spellID : type->spells)
|
for(const auto & spellID : getHeroType()->spells)
|
||||||
spells.insert(spellID);
|
spells.insert(spellID);
|
||||||
}
|
}
|
||||||
else //remove placeholder
|
else //remove placeholder
|
||||||
@ -341,7 +354,7 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
|
|||||||
if(!vstd::contains(spells, SpellID::SPELLBOOK_PRESET))
|
if(!vstd::contains(spells, SpellID::SPELLBOOK_PRESET))
|
||||||
{
|
{
|
||||||
// hero starts with default spellbook presence status
|
// hero starts with default spellbook presence status
|
||||||
if(!getArt(ArtifactPosition::SPELLBOOK) && type->haveSpellBook)
|
if(!getArt(ArtifactPosition::SPELLBOOK) && getHeroType()->haveSpellBook)
|
||||||
{
|
{
|
||||||
auto artifact = ArtifactUtils::createArtifact(ArtifactID::SPELLBOOK);
|
auto artifact = ArtifactUtils::createArtifact(ArtifactID::SPELLBOOK);
|
||||||
putArtifact(ArtifactPosition::SPELLBOOK, artifact);
|
putArtifact(ArtifactPosition::SPELLBOOK, artifact);
|
||||||
@ -360,14 +373,14 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
|
|||||||
{
|
{
|
||||||
for(int g=0; g<GameConstants::PRIMARY_SKILLS; ++g)
|
for(int g=0; g<GameConstants::PRIMARY_SKILLS; ++g)
|
||||||
{
|
{
|
||||||
pushPrimSkill(static_cast<PrimarySkill>(g), type->heroClass->primarySkillInitial[g]);
|
pushPrimSkill(static_cast<PrimarySkill>(g), getHeroClass()->primarySkillInitial[g]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(secSkills.size() == 1 && secSkills[0] == std::pair<SecondarySkill,ui8>(SecondarySkill::NONE, -1)) //set secondary skills to default
|
if(secSkills.size() == 1 && secSkills[0] == std::pair<SecondarySkill,ui8>(SecondarySkill::NONE, -1)) //set secondary skills to default
|
||||||
secSkills = type->secSkillsInit;
|
secSkills = getHeroType()->secSkillsInit;
|
||||||
|
|
||||||
if (gender == EHeroGender::DEFAULT)
|
if (gender == EHeroGender::DEFAULT)
|
||||||
gender = type->gender;
|
gender = getHeroType()->gender;
|
||||||
|
|
||||||
setFormation(EArmyFormation::LOOSE);
|
setFormation(EArmyFormation::LOOSE);
|
||||||
if (!stacksCount()) //standard army//initial army
|
if (!stacksCount()) //standard army//initial army
|
||||||
@ -403,9 +416,9 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
|
|||||||
addNewBonus(bonus);
|
addNewBonus(bonus);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cb->getSettings().getBoolean(EGameSettings::MODULE_COMMANDERS) && !commander && type->heroClass->commander.hasValue())
|
if (cb->getSettings().getBoolean(EGameSettings::MODULE_COMMANDERS) && !commander && getHeroClass()->commander.hasValue())
|
||||||
{
|
{
|
||||||
commander = new CCommanderInstance(type->heroClass->commander);
|
commander = new CCommanderInstance(getHeroClass()->commander);
|
||||||
commander->setArmyObj (castToArmyObj()); //TODO: separate function for setting commanders
|
commander->setArmyObj (castToArmyObj()); //TODO: separate function for setting commanders
|
||||||
commander->giveStackExp (exp); //after our exp is set
|
commander->giveStackExp (exp); //after our exp is set
|
||||||
}
|
}
|
||||||
@ -413,7 +426,7 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
|
|||||||
skillsInfo = SecondarySkillsInfo();
|
skillsInfo = SecondarySkillsInfo();
|
||||||
|
|
||||||
//copy active (probably growing) bonuses from hero prototype to hero object
|
//copy active (probably growing) bonuses from hero prototype to hero object
|
||||||
for(const std::shared_ptr<Bonus> & b : type->specialty)
|
for(const std::shared_ptr<Bonus> & b : getHeroType()->specialty)
|
||||||
addNewBonus(b);
|
addNewBonus(b);
|
||||||
|
|
||||||
//initialize bonuses
|
//initialize bonuses
|
||||||
@ -433,14 +446,14 @@ void CGHeroInstance::initArmy(vstd::RNG & rand, IArmyDescriptor * dst)
|
|||||||
auto stacksCountChances = cb->getSettings().getVector(EGameSettings::HEROES_STARTING_STACKS_CHANCES);
|
auto stacksCountChances = cb->getSettings().getVector(EGameSettings::HEROES_STARTING_STACKS_CHANCES);
|
||||||
int stacksCountInitRandomNumber = rand.nextInt(1, 100);
|
int stacksCountInitRandomNumber = rand.nextInt(1, 100);
|
||||||
|
|
||||||
size_t maxStacksCount = std::min(stacksCountChances.size(), type->initialArmy.size());
|
size_t maxStacksCount = std::min(stacksCountChances.size(), getHeroType()->initialArmy.size());
|
||||||
|
|
||||||
for(int stackNo=0; stackNo < maxStacksCount; stackNo++)
|
for(int stackNo=0; stackNo < maxStacksCount; stackNo++)
|
||||||
{
|
{
|
||||||
if (stacksCountInitRandomNumber > stacksCountChances[stackNo])
|
if (stacksCountInitRandomNumber > stacksCountChances[stackNo])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto & stack = type->initialArmy[stackNo];
|
auto & stack = getHeroType()->initialArmy[stackNo];
|
||||||
|
|
||||||
int count = rand.nextInt(stack.minAmount, stack.maxAmount);
|
int count = rand.nextInt(stack.minAmount, stack.maxAmount);
|
||||||
|
|
||||||
@ -588,11 +601,11 @@ std::string CGHeroInstance::getMovementPointsTextIfOwner(PlayerColor player) con
|
|||||||
|
|
||||||
ui8 CGHeroInstance::maxlevelsToMagicSchool() const
|
ui8 CGHeroInstance::maxlevelsToMagicSchool() const
|
||||||
{
|
{
|
||||||
return type->heroClass->isMagicHero() ? 3 : 4;
|
return getHeroClass()->isMagicHero() ? 3 : 4;
|
||||||
}
|
}
|
||||||
ui8 CGHeroInstance::maxlevelsToWisdom() const
|
ui8 CGHeroInstance::maxlevelsToWisdom() const
|
||||||
{
|
{
|
||||||
return type->heroClass->isMagicHero() ? 3 : 6;
|
return getHeroClass()->isMagicHero() ? 3 : 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGHeroInstance::SecondarySkillsInfo::SecondarySkillsInfo():
|
CGHeroInstance::SecondarySkillsInfo::SecondarySkillsInfo():
|
||||||
@ -617,11 +630,8 @@ void CGHeroInstance::pickRandomObject(vstd::RNG & rand)
|
|||||||
{
|
{
|
||||||
ID = Obj::HERO;
|
ID = Obj::HERO;
|
||||||
subID = cb->gameState()->pickNextHeroType(getOwner());
|
subID = cb->gameState()->pickNextHeroType(getOwner());
|
||||||
type = getHeroType().toHeroType();
|
randomizeArmy(getHeroClass()->faction);
|
||||||
randomizeArmy(type->heroClass->faction);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
type = getHeroType().toHeroType();
|
|
||||||
|
|
||||||
auto oldSubID = subID;
|
auto oldSubID = subID;
|
||||||
|
|
||||||
@ -629,7 +639,7 @@ void CGHeroInstance::pickRandomObject(vstd::RNG & rand)
|
|||||||
// after setType subID used to store unique hero identify id. Check issue 2277 for details
|
// after setType subID used to store unique hero identify id. Check issue 2277 for details
|
||||||
// exclude prisons which should use appearance as set in map, via map editor or RMG
|
// exclude prisons which should use appearance as set in map, via map editor or RMG
|
||||||
if (ID != Obj::PRISON)
|
if (ID != Obj::PRISON)
|
||||||
setType(ID, type->heroClass->getIndex());
|
setType(ID, getHeroClass()->getIndex());
|
||||||
|
|
||||||
this->subID = oldSubID;
|
this->subID = oldSubID;
|
||||||
}
|
}
|
||||||
@ -1041,7 +1051,7 @@ si32 CGHeroInstance::getManaNewTurn() const
|
|||||||
|
|
||||||
BoatId CGHeroInstance::getBoatType() const
|
BoatId CGHeroInstance::getBoatType() const
|
||||||
{
|
{
|
||||||
return BoatId(VLC->townh->getById(type->heroClass->faction)->getBoatType());
|
return BoatId(VLC->townh->getById(getHeroClass()->faction)->getBoatType());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGHeroInstance::getOutOffsets(std::vector<int3> &offsets) const
|
void CGHeroInstance::getOutOffsets(std::vector<int3> &offsets) const
|
||||||
@ -1080,7 +1090,7 @@ void CGHeroInstance::pushPrimSkill( PrimarySkill which, int val )
|
|||||||
|
|
||||||
EAlignment CGHeroInstance::getAlignment() const
|
EAlignment CGHeroInstance::getAlignment() const
|
||||||
{
|
{
|
||||||
return type->heroClass->getAlignment();
|
return getHeroClass()->getAlignment();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGHeroInstance::initExp(vstd::RNG & rand)
|
void CGHeroInstance::initExp(vstd::RNG & rand)
|
||||||
@ -1104,12 +1114,12 @@ HeroTypeID CGHeroInstance::getPortraitSource() const
|
|||||||
if (customPortraitSource.isValid())
|
if (customPortraitSource.isValid())
|
||||||
return customPortraitSource;
|
return customPortraitSource;
|
||||||
else
|
else
|
||||||
return getHeroType();
|
return getHeroTypeID();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t CGHeroInstance::getIconIndex() const
|
int32_t CGHeroInstance::getIconIndex() const
|
||||||
{
|
{
|
||||||
return VLC->heroTypes()->getById(getPortraitSource())->getIconIndex();
|
return getPortraitSource().toEntity(VLC)->getIconIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CGHeroInstance::getNameTranslated() const
|
std::string CGHeroInstance::getNameTranslated() const
|
||||||
@ -1126,15 +1136,15 @@ std::string CGHeroInstance::getClassNameTextID() const
|
|||||||
{
|
{
|
||||||
if (isCampaignGem())
|
if (isCampaignGem())
|
||||||
return "core.genrltxt.735";
|
return "core.genrltxt.735";
|
||||||
return type->heroClass->getNameTextID();
|
return getHeroClass()->getNameTextID();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CGHeroInstance::getNameTextID() const
|
std::string CGHeroInstance::getNameTextID() const
|
||||||
{
|
{
|
||||||
if (!nameCustomTextId.empty())
|
if (!nameCustomTextId.empty())
|
||||||
return nameCustomTextId;
|
return nameCustomTextId;
|
||||||
if (type)
|
if (getHeroTypeID().hasValue())
|
||||||
return type->getNameTextID();
|
return getHeroType()->getNameTextID();
|
||||||
|
|
||||||
// FIXME: called by logging from some specialties (mods?) before type is set on deserialization
|
// FIXME: called by logging from some specialties (mods?) before type is set on deserialization
|
||||||
// assert(0);
|
// assert(0);
|
||||||
@ -1150,8 +1160,8 @@ std::string CGHeroInstance::getBiographyTextID() const
|
|||||||
{
|
{
|
||||||
if (!biographyCustomTextId.empty())
|
if (!biographyCustomTextId.empty())
|
||||||
return biographyCustomTextId;
|
return biographyCustomTextId;
|
||||||
if (type)
|
if (getHeroTypeID().hasValue())
|
||||||
return type->getBiographyTextID();
|
return getHeroType()->getBiographyTextID();
|
||||||
|
|
||||||
return ""; //for random hero
|
return ""; //for random hero
|
||||||
}
|
}
|
||||||
@ -1349,11 +1359,11 @@ std::vector<SecondarySkill> CGHeroInstance::getLevelUpProposedSecondarySkills(vs
|
|||||||
SecondarySkill selection;
|
SecondarySkill selection;
|
||||||
|
|
||||||
if (selectWisdom)
|
if (selectWisdom)
|
||||||
selection = type->heroClass->chooseSecSkill(intersect(options, wisdomList), rand);
|
selection = getHeroClass()->chooseSecSkill(intersect(options, wisdomList), rand);
|
||||||
else if (selectSchool)
|
else if (selectSchool)
|
||||||
selection = type->heroClass->chooseSecSkill(intersect(options, schoolList), rand);
|
selection = getHeroClass()->chooseSecSkill(intersect(options, schoolList), rand);
|
||||||
else
|
else
|
||||||
selection = type->heroClass->chooseSecSkill(options, rand);
|
selection = getHeroClass()->chooseSecSkill(options, rand);
|
||||||
|
|
||||||
skills.push_back(selection);
|
skills.push_back(selection);
|
||||||
options.erase(selection);
|
options.erase(selection);
|
||||||
@ -1384,7 +1394,7 @@ PrimarySkill CGHeroInstance::nextPrimarySkill(vstd::RNG & rand) const
|
|||||||
{
|
{
|
||||||
assert(gainsLevel());
|
assert(gainsLevel());
|
||||||
const auto isLowLevelHero = level < GameConstants::HERO_HIGH_LEVEL;
|
const auto isLowLevelHero = level < GameConstants::HERO_HIGH_LEVEL;
|
||||||
const auto & skillChances = isLowLevelHero ? type->heroClass->primarySkillLowLevel : type->heroClass->primarySkillHighLevel;
|
const auto & skillChances = isLowLevelHero ? getHeroClass()->primarySkillLowLevel : getHeroClass()->primarySkillHighLevel;
|
||||||
|
|
||||||
if (isCampaignYog())
|
if (isCampaignYog())
|
||||||
{
|
{
|
||||||
@ -1524,25 +1534,15 @@ bool CGHeroInstance::hasVisions(const CGObjectInstance * target, BonusSubtypeID
|
|||||||
std::string CGHeroInstance::getHeroTypeName() const
|
std::string CGHeroInstance::getHeroTypeName() const
|
||||||
{
|
{
|
||||||
if(ID == Obj::HERO || ID == Obj::PRISON)
|
if(ID == Obj::HERO || ID == Obj::PRISON)
|
||||||
{
|
return getHeroType()->getJsonKey();
|
||||||
if(type)
|
|
||||||
{
|
|
||||||
return type->getJsonKey();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return getHeroType().toEntity(VLC)->getJsonKey();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGHeroInstance::afterAddToMap(CMap * map)
|
void CGHeroInstance::afterAddToMap(CMap * map)
|
||||||
{
|
{
|
||||||
if(ID != Obj::PRISON)
|
if(ID != Obj::PRISON)
|
||||||
{
|
|
||||||
map->heroesOnMap.emplace_back(this);
|
map->heroesOnMap.emplace_back(this);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void CGHeroInstance::afterRemoveFromMap(CMap* map)
|
void CGHeroInstance::afterRemoveFromMap(CMap* map)
|
||||||
{
|
{
|
||||||
@ -1729,8 +1729,7 @@ void CGHeroInstance::serializeJsonOptions(JsonSerializeFormat & handler)
|
|||||||
if(!appearance)
|
if(!appearance)
|
||||||
{
|
{
|
||||||
// crossoverDeserialize
|
// crossoverDeserialize
|
||||||
type = getHeroType().toHeroType();
|
appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, getHeroClassID())->getTemplates().front();
|
||||||
appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1817,7 +1816,7 @@ bool CGHeroInstance::isCampaignYog() const
|
|||||||
if (!boost::starts_with(campaign, "DATA/YOG")) // "Birth of a Barbarian"
|
if (!boost::starts_with(campaign, "DATA/YOG")) // "Birth of a Barbarian"
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (getHeroType() != HeroTypeID::SOLMYR) // Yog (based on Solmyr)
|
if (getHeroTypeID() != HeroTypeID::SOLMYR) // Yog (based on Solmyr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -1835,7 +1834,7 @@ bool CGHeroInstance::isCampaignGem() const
|
|||||||
if (!boost::starts_with(campaign, "DATA/GEM") && !boost::starts_with(campaign, "DATA/FINAL")) // "New Beginning" and "Unholy Alliance"
|
if (!boost::starts_with(campaign, "DATA/GEM") && !boost::starts_with(campaign, "DATA/FINAL")) // "New Beginning" and "Unholy Alliance"
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (getHeroType() != HeroTypeID::GEM) // Yog (based on Solmyr)
|
if (getHeroTypeID() != HeroTypeID::GEM) // Yog (based on Solmyr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -72,7 +72,6 @@ public:
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
const CHero * type;
|
|
||||||
TExpType exp; //experience points
|
TExpType exp; //experience points
|
||||||
ui32 level; //current level of hero
|
ui32 level; //current level of hero
|
||||||
|
|
||||||
@ -171,7 +170,7 @@ public:
|
|||||||
const IOwnableObject * asOwnable() const final;
|
const IOwnableObject * asOwnable() const final;
|
||||||
|
|
||||||
//INativeTerrainProvider
|
//INativeTerrainProvider
|
||||||
FactionID getFaction() const override;
|
FactionID getFactionID() const override;
|
||||||
TerrainId getNativeTerrain() const override;
|
TerrainId getNativeTerrain() const override;
|
||||||
int getLowestCreatureSpeed() const;
|
int getLowestCreatureSpeed() const;
|
||||||
si32 manaRegain() const; //how many points of mana can hero regain "naturally" in one day
|
si32 manaRegain() const; //how many points of mana can hero regain "naturally" in one day
|
||||||
@ -235,7 +234,11 @@ public:
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
HeroTypeID getHeroType() const;
|
const CHeroClass * getHeroClass() const;
|
||||||
|
HeroClassID getHeroClassID() const;
|
||||||
|
|
||||||
|
const CHero * getHeroType() const;
|
||||||
|
HeroTypeID getHeroTypeID() const;
|
||||||
void setHeroType(HeroTypeID type);
|
void setHeroType(HeroTypeID type);
|
||||||
|
|
||||||
void initHero(vstd::RNG & rand);
|
void initHero(vstd::RNG & rand);
|
||||||
@ -352,7 +355,11 @@ public:
|
|||||||
h & skillsInfo;
|
h & skillsInfo;
|
||||||
h & visitedTown;
|
h & visitedTown;
|
||||||
h & boat;
|
h & boat;
|
||||||
h & type;
|
if (h.version < Handler::Version::REMOVE_TOWN_PTR)
|
||||||
|
{
|
||||||
|
CHero * type = nullptr;
|
||||||
|
h & type;
|
||||||
|
}
|
||||||
h & commander;
|
h & commander;
|
||||||
h & visitedObjects;
|
h & visitedObjects;
|
||||||
BONUS_TREE_DESERIALIZATION_FIX
|
BONUS_TREE_DESERIALIZATION_FIX
|
||||||
|
@ -45,7 +45,7 @@ int CGTownInstance::getSightRadius() const //returns sight distance
|
|||||||
|
|
||||||
for(const auto & bid : builtBuildings)
|
for(const auto & bid : builtBuildings)
|
||||||
{
|
{
|
||||||
auto height = town->buildings.at(bid)->height;
|
auto height = getTown()->buildings.at(bid)->height;
|
||||||
if(ret < height)
|
if(ret < height)
|
||||||
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
|
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
|
int CGTownInstance::creatureGrowth(const int & level) const
|
||||||
@ -127,7 +127,7 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
|
|||||||
{
|
{
|
||||||
GrowthInfo ret;
|
GrowthInfo ret;
|
||||||
|
|
||||||
if (level<0 || level >=town->creatures.size())
|
if (level<0 || level >=getTown()->creatures.size())
|
||||||
return ret;
|
return ret;
|
||||||
if (creatures[level].second.empty())
|
if (creatures[level].second.empty())
|
||||||
return ret; //no dwelling
|
return ret; //no dwelling
|
||||||
@ -151,11 +151,11 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
|
|||||||
else if (hasBuilt(BuildingID::CITADEL))
|
else if (hasBuilt(BuildingID::CITADEL))
|
||||||
ret.entries.emplace_back(subID, BuildingID::CITADEL, castleBonus = base / 2);
|
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))
|
if(hasBuilt(BuildingID::HORDE_1))
|
||||||
ret.entries.emplace_back(subID, BuildingID::HORDE_1, creature->getHorde());
|
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))
|
if(hasBuilt(BuildingID::HORDE_2))
|
||||||
ret.entries.emplace_back(subID, BuildingID::HORDE_2, creature->getHorde());
|
ret.entries.emplace_back(subID, BuildingID::HORDE_2, creature->getHorde());
|
||||||
|
|
||||||
@ -209,11 +209,11 @@ int CGTownInstance::getDwellingBonus(const std::vector<CreatureID>& creatureIds,
|
|||||||
TResources CGTownInstance::dailyIncome() const
|
TResources CGTownInstance::dailyIncome() const
|
||||||
{
|
{
|
||||||
TResources ret;
|
TResources ret;
|
||||||
for(const auto & p : town->buildings)
|
for(const auto & p : getTown()->buildings)
|
||||||
{
|
{
|
||||||
BuildingID buildingUpgrade;
|
BuildingID buildingUpgrade;
|
||||||
|
|
||||||
for(const auto & p2 : town->buildings)
|
for(const auto & p2 : getTown()->buildings)
|
||||||
{
|
{
|
||||||
if (p2.second->upgrade == p.first)
|
if (p2.second->upgrade == p.first)
|
||||||
{
|
{
|
||||||
@ -251,10 +251,10 @@ bool CGTownInstance::hasCapitol() const
|
|||||||
|
|
||||||
TownFortifications CGTownInstance::fortificationsLevel() const
|
TownFortifications CGTownInstance::fortificationsLevel() const
|
||||||
{
|
{
|
||||||
auto result = town->fortifications;
|
auto result = getTown()->fortifications;
|
||||||
|
|
||||||
for (auto const & buildingID : builtBuildings)
|
for (auto const & buildingID : builtBuildings)
|
||||||
result += town->buildings.at(buildingID)->fortifications;
|
result += getTown()->buildings.at(buildingID)->fortifications;
|
||||||
|
|
||||||
if (result.wallsHealth == 0)
|
if (result.wallsHealth == 0)
|
||||||
return TownFortifications();
|
return TownFortifications();
|
||||||
@ -264,7 +264,6 @@ TownFortifications CGTownInstance::fortificationsLevel() const
|
|||||||
|
|
||||||
CGTownInstance::CGTownInstance(IGameCallback *cb):
|
CGTownInstance::CGTownInstance(IGameCallback *cb):
|
||||||
CGDwelling(cb),
|
CGDwelling(cb),
|
||||||
town(nullptr),
|
|
||||||
built(0),
|
built(0),
|
||||||
destroyed(0),
|
destroyed(0),
|
||||||
identifier(0),
|
identifier(0),
|
||||||
@ -379,17 +378,17 @@ void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const
|
|||||||
|
|
||||||
std::string CGTownInstance::getObjectName() const
|
std::string CGTownInstance::getObjectName() const
|
||||||
{
|
{
|
||||||
return getNameTranslated() + ", " + town->faction->getNameTranslated();
|
return getNameTranslated() + ", " + getTown()->faction->getNameTranslated();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGTownInstance::townEnvisagesBuilding(BuildingSubID::EBuildingSubID subId) const
|
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)
|
void CGTownInstance::initializeConfigurableBuildings(vstd::RNG & rand)
|
||||||
{
|
{
|
||||||
for(const auto & kvp : town->buildings)
|
for(const auto & kvp : getTown()->buildings)
|
||||||
{
|
{
|
||||||
if(!kvp.second->rewardableObjectInfo.getParameters().isNull())
|
if(!kvp.second->rewardableObjectInfo.getParameters().isNull())
|
||||||
rewardableBuildings[kvp.first] = new TownRewardableBuildingInstance(this, kvp.second->bid, rand);
|
rewardableBuildings[kvp.first] = new TownRewardableBuildingInstance(this, kvp.second->bid, rand);
|
||||||
@ -457,8 +456,7 @@ void CGTownInstance::pickRandomObject(vstd::RNG & rand)
|
|||||||
|
|
||||||
assert(ID == Obj::TOWN); // just in case
|
assert(ID == Obj::TOWN); // just in case
|
||||||
setType(ID, subID);
|
setType(ID, subID);
|
||||||
town = (*VLC->townh)[getFaction()]->town;
|
randomizeArmy(getFactionID());
|
||||||
randomizeArmy(getFaction());
|
|
||||||
updateAppearance();
|
updateAppearance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,19 +465,19 @@ void CGTownInstance::initObj(vstd::RNG & rand) ///initialize town structures
|
|||||||
blockVisit = true;
|
blockVisit = true;
|
||||||
|
|
||||||
if(townEnvisagesBuilding(BuildingSubID::PORTAL_OF_SUMMONING)) //Dungeon for example
|
if(townEnvisagesBuilding(BuildingSubID::PORTAL_OF_SUMMONING)) //Dungeon for example
|
||||||
creatures.resize(town->creatures.size() + 1);
|
creatures.resize(getTown()->creatures.size() + 1);
|
||||||
else
|
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));
|
BuildingID buildID = BuildingID(BuildingID::getDwellingFromLevel(level, 0));
|
||||||
int upgradeNum = 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)
|
if (hasBuilt(buildID) && getTown()->creatures.at(level).size() > upgradeNum)
|
||||||
creatures[level].second.push_back(town->creatures[level][upgradeNum]);
|
creatures[level].second.push_back(getTown()->creatures[level][upgradeNum]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
initializeConfigurableBuildings(rand);
|
initializeConfigurableBuildings(rand);
|
||||||
@ -623,9 +621,9 @@ void CGTownInstance::removeCapitols(const PlayerColor & owner) const
|
|||||||
if (hasCapitol()) // search if there's an older capitol
|
if (hasCapitol()) // search if there's an older capitol
|
||||||
{
|
{
|
||||||
PlayerState* state = cb->gameState()->getPlayerState(owner); //get all towns owned by player
|
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;
|
RazeStructures rs;
|
||||||
rs.tid = id;
|
rs.tid = id;
|
||||||
@ -648,7 +646,7 @@ void CGTownInstance::clearArmy() const
|
|||||||
|
|
||||||
BoatId CGTownInstance::getBoatType() const
|
BoatId CGTownInstance::getBoatType() const
|
||||||
{
|
{
|
||||||
return town->faction->boatType;
|
return getTown()->faction->boatType;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CGTownInstance::getMarketEfficiency() const
|
int CGTownInstance::getMarketEfficiency() const
|
||||||
@ -703,7 +701,7 @@ void CGTownInstance::updateAppearance()
|
|||||||
|
|
||||||
std::string CGTownInstance::nodeName() const
|
std::string CGTownInstance::nodeName() const
|
||||||
{
|
{
|
||||||
return "Town (" + (town ? town->faction->getNameTranslated() : "unknown") + ") of " + getNameTranslated();
|
return "Town (" + getTown()->faction->getNameTranslated() + ") of " + getNameTranslated();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGTownInstance::deserializationFix()
|
void CGTownInstance::deserializationFix()
|
||||||
@ -752,7 +750,7 @@ void CGTownInstance::recreateBuildingsBonuses()
|
|||||||
|
|
||||||
for(const auto & upgradeID : builtBuildings)
|
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)
|
if (upgrade->getBase() == bid && upgrade->upgradeReplacesBonuses)
|
||||||
bonusesReplacedByUpgrade = true;
|
bonusesReplacedByUpgrade = true;
|
||||||
}
|
}
|
||||||
@ -761,7 +759,7 @@ void CGTownInstance::recreateBuildingsBonuses()
|
|||||||
if (bonusesReplacedByUpgrade)
|
if (bonusesReplacedByUpgrade)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto building = town->buildings.at(bid);
|
auto building = getTown()->buildings.at(bid);
|
||||||
|
|
||||||
if(building->buildingBonuses.empty())
|
if(building->buildingBonuses.empty())
|
||||||
continue;
|
continue;
|
||||||
@ -828,21 +826,6 @@ bool CGTownInstance::armedGarrison() const
|
|||||||
return !stacks.empty() || garrisonHero;
|
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
|
int CGTownInstance::getTownLevel() const
|
||||||
{
|
{
|
||||||
// count all buildings that are not upgrades
|
// count all buildings that are not upgrades
|
||||||
@ -850,7 +833,7 @@ int CGTownInstance::getTownLevel() const
|
|||||||
|
|
||||||
for(const auto & bid : builtBuildings)
|
for(const auto & bid : builtBuildings)
|
||||||
{
|
{
|
||||||
if(town->buildings.at(bid)->upgrade == BuildingID::NONE)
|
if(getTown()->buildings.at(bid)->upgrade == BuildingID::NONE)
|
||||||
level++;
|
level++;
|
||||||
}
|
}
|
||||||
return level;
|
return level;
|
||||||
@ -892,7 +875,7 @@ bool CGTownInstance::hasBuilt(BuildingSubID::EBuildingSubID buildingID) const
|
|||||||
{
|
{
|
||||||
for(const auto & bid : builtBuildings)
|
for(const auto & bid : builtBuildings)
|
||||||
{
|
{
|
||||||
if(town->buildings.at(bid)->subId == buildingID)
|
if(getTown()->buildings.at(bid)->subId == buildingID)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -905,7 +888,7 @@ bool CGTownInstance::hasBuilt(const BuildingID & buildingID) const
|
|||||||
|
|
||||||
bool CGTownInstance::hasBuilt(const BuildingID & buildingID, FactionID townID) 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 hasBuilt(buildingID);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -923,7 +906,7 @@ std::set<EMarketMode> CGTownInstance::availableModes() const
|
|||||||
std::set<EMarketMode> result;
|
std::set<EMarketMode> result;
|
||||||
for (const auto & buildingID : builtBuildings)
|
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());
|
result.insert(buildingPtr->marketModes.begin(), buildingPtr->marketModes.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -950,8 +933,8 @@ std::set<BuildingID> CGTownInstance::getBuildings() const
|
|||||||
|
|
||||||
TResources CGTownInstance::getBuildingCost(const BuildingID & buildingID) const
|
TResources CGTownInstance::getBuildingCost(const BuildingID & buildingID) const
|
||||||
{
|
{
|
||||||
if (vstd::contains(town->buildings, buildingID))
|
if (vstd::contains(getTown()->buildings, buildingID))
|
||||||
return town->buildings.at(buildingID)->resources;
|
return getTown()->buildings.at(buildingID)->resources;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logGlobal->error("Town %s at %s has no possible building %d!", getNameTranslated(), anchorPos().toString(), buildingID.toEnum());
|
logGlobal->error("Town %s at %s has no possible building %d!", getNameTranslated(), anchorPos().toString(), buildingID.toEnum());
|
||||||
@ -962,7 +945,7 @@ TResources CGTownInstance::getBuildingCost(const BuildingID & buildingID) const
|
|||||||
|
|
||||||
CBuilding::TRequired CGTownInstance::genBuildingRequirements(const BuildingID & buildID, bool deep) 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
|
//TODO: find better solution to prevent infinite loops
|
||||||
std::set<BuildingID> processed;
|
std::set<BuildingID> processed;
|
||||||
@ -970,13 +953,13 @@ CBuilding::TRequired CGTownInstance::genBuildingRequirements(const BuildingID &
|
|||||||
std::function<CBuilding::TRequired::Variant(const BuildingID &)> dependTest =
|
std::function<CBuilding::TRequired::Variant(const BuildingID &)> dependTest =
|
||||||
[&](const BuildingID & id) -> CBuilding::TRequired::Variant
|
[&](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());
|
logMod->error("Invalid building ID %d in building dependencies!", id.getNum());
|
||||||
return CBuilding::TRequired::OperatorAll();
|
return CBuilding::TRequired::OperatorAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
const CBuilding * build = town->buildings.at(id);
|
const CBuilding * build = getTown()->buildings.at(id);
|
||||||
CBuilding::TRequired::OperatorAll requirements;
|
CBuilding::TRequired::OperatorAll requirements;
|
||||||
|
|
||||||
if (!hasBuilt(id))
|
if (!hasBuilt(id))
|
||||||
@ -1001,7 +984,7 @@ CBuilding::TRequired CGTownInstance::genBuildingRequirements(const BuildingID &
|
|||||||
CBuilding::TRequired::OperatorAll requirements;
|
CBuilding::TRequired::OperatorAll requirements;
|
||||||
if (building->upgrade != BuildingID::NONE)
|
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));
|
requirements.expressions.push_back(dependTest(upgr->bid));
|
||||||
processed.clear();
|
processed.clear();
|
||||||
@ -1151,14 +1134,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
|
TerrainId CGTownInstance::getNativeTerrain() const
|
||||||
{
|
{
|
||||||
return town->faction->getNativeTerrain();
|
return getTown()->faction->getNativeTerrain();
|
||||||
}
|
}
|
||||||
|
|
||||||
ArtifactID CGTownInstance::getWarMachineInBuilding(BuildingID building) const
|
ArtifactID CGTownInstance::getWarMachineInBuilding(BuildingID building) const
|
||||||
@ -1166,21 +1162,21 @@ ArtifactID CGTownInstance::getWarMachineInBuilding(BuildingID building) const
|
|||||||
if (builtBuildings.count(building) == 0)
|
if (builtBuildings.count(building) == 0)
|
||||||
return ArtifactID::NONE;
|
return ArtifactID::NONE;
|
||||||
|
|
||||||
if (building == BuildingID::BLACKSMITH && town->warMachineDeprecated.hasValue())
|
if (building == BuildingID::BLACKSMITH && getTown()->warMachineDeprecated.hasValue())
|
||||||
return town->warMachineDeprecated.toCreature()->warMachine;
|
return getTown()->warMachineDeprecated.toCreature()->warMachine;
|
||||||
|
|
||||||
return town->buildings.at(building)->warMachine;
|
return getTown()->buildings.at(building)->warMachine;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGTownInstance::isWarMachineAvailable(ArtifactID warMachine) const
|
bool CGTownInstance::isWarMachineAvailable(ArtifactID warMachine) const
|
||||||
{
|
{
|
||||||
for (auto const & buildingID : builtBuildings)
|
for (auto const & buildingID : builtBuildings)
|
||||||
if (town->buildings.at(buildingID)->warMachine == warMachine)
|
if (getTown()->buildings.at(buildingID)->warMachine == warMachine)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (builtBuildings.count(BuildingID::BLACKSMITH) &&
|
if (builtBuildings.count(BuildingID::BLACKSMITH) &&
|
||||||
town->warMachineDeprecated.hasValue() &&
|
getTown()->warMachineDeprecated.hasValue() &&
|
||||||
town->warMachineDeprecated.toCreature()->warMachine == warMachine)
|
getTown()->warMachineDeprecated.toCreature()->warMachine == warMachine)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1200,7 +1196,7 @@ GrowthInfo::Entry::Entry(int subID, const BuildingID & building, int _count): co
|
|||||||
{
|
{
|
||||||
MetaString formatter;
|
MetaString formatter;
|
||||||
formatter.appendRawString("%s %+d");
|
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);
|
formatter.replacePositiveNumber(count);
|
||||||
|
|
||||||
description = formatter.toString();
|
description = formatter.toString();
|
||||||
|
@ -50,6 +50,7 @@ struct DLL_LINKAGE GrowthInfo
|
|||||||
|
|
||||||
class DLL_LINKAGE CGTownInstance : public CGDwelling, public IShipyard, public IMarket, public INativeTerrainProvider, public ICreatureUpgrader
|
class DLL_LINKAGE CGTownInstance : public CGDwelling, public IShipyard, public IMarket, public INativeTerrainProvider, public ICreatureUpgrader
|
||||||
{
|
{
|
||||||
|
friend class CTownInstanceConstructor;
|
||||||
std::string nameTextId; // name of town
|
std::string nameTextId; // name of town
|
||||||
|
|
||||||
std::map<BuildingID, TownRewardableBuildingInstance*> convertOldBuildings(std::vector<TownRewardableBuildingInstance*> oldVector);
|
std::map<BuildingID, TownRewardableBuildingInstance*> convertOldBuildings(std::vector<TownRewardableBuildingInstance*> oldVector);
|
||||||
@ -59,7 +60,6 @@ public:
|
|||||||
enum EFortLevel {NONE = 0, FORT = 1, CITADEL = 2, CASTLE = 3};
|
enum EFortLevel {NONE = 0, FORT = 1, CITADEL = 2, CASTLE = 3};
|
||||||
|
|
||||||
CTownAndVisitingHero townAndVis;
|
CTownAndVisitingHero townAndVis;
|
||||||
const CTown * town;
|
|
||||||
si32 built; //how many buildings has been built this turn
|
si32 built; //how many buildings has been built this turn
|
||||||
si32 destroyed; //how many buildings has been destroyed this turn
|
si32 destroyed; //how many buildings has been destroyed this turn
|
||||||
ConstTransitivePtr<CGHeroInstance> garrisonHero, visitingHero;
|
ConstTransitivePtr<CGHeroInstance> garrisonHero, visitingHero;
|
||||||
@ -112,16 +112,21 @@ public:
|
|||||||
rewardableBuildings = convertOldBuildings(oldVector);
|
rewardableBuildings = convertOldBuildings(oldVector);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h.saving)
|
if (h.version < Handler::Version::REMOVE_TOWN_PTR)
|
||||||
{
|
{
|
||||||
CFaction * faction = town ? town->faction : nullptr;
|
CTown * town = nullptr;
|
||||||
h & faction;
|
|
||||||
}
|
if (h.saving)
|
||||||
else
|
{
|
||||||
{
|
CFaction * faction = town ? town->faction : nullptr;
|
||||||
CFaction * faction = nullptr;
|
h & faction;
|
||||||
h & faction;
|
}
|
||||||
town = faction ? faction->town : nullptr;
|
else
|
||||||
|
{
|
||||||
|
CFaction * faction = nullptr;
|
||||||
|
h & faction;
|
||||||
|
town = faction ? faction->town : nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h & townAndVis;
|
h & townAndVis;
|
||||||
@ -213,9 +218,10 @@ public:
|
|||||||
DamageRange getKeepDamageRange() const;
|
DamageRange getKeepDamageRange() const;
|
||||||
|
|
||||||
const CTown * getTown() const;
|
const CTown * getTown() const;
|
||||||
|
const CFaction * getFaction() const;
|
||||||
|
|
||||||
/// INativeTerrainProvider
|
/// INativeTerrainProvider
|
||||||
FactionID getFaction() const override;
|
FactionID getFactionID() const override;
|
||||||
TerrainId getNativeTerrain() const override;
|
TerrainId getNativeTerrain() const override;
|
||||||
|
|
||||||
/// Returns ID of war machine that is produced by specified building or NONE if this is not built or if building does not produce war machines
|
/// Returns ID of war machine that is produced by specified building or NONE if this is not built or if building does not produce war machines
|
||||||
|
@ -431,7 +431,7 @@ void CGSeerHut::setObjToKill()
|
|||||||
|
|
||||||
if(getCreatureToKill(true))
|
if(getCreatureToKill(true))
|
||||||
{
|
{
|
||||||
quest->stackToKill = getCreatureToKill(false)->getCreature();
|
quest->stackToKill = getCreatureToKill(false)->getCreatureID();
|
||||||
assert(quest->stackToKill != CreatureID::NONE);
|
assert(quest->stackToKill != CreatureID::NONE);
|
||||||
quest->stackDirection = checkDirection();
|
quest->stackDirection = checkDirection();
|
||||||
}
|
}
|
||||||
|
@ -73,14 +73,14 @@ TownRewardableBuildingInstance::TownRewardableBuildingInstance(CGTownInstance *
|
|||||||
|
|
||||||
void TownRewardableBuildingInstance::initObj(vstd::RNG & rand)
|
void TownRewardableBuildingInstance::initObj(vstd::RNG & rand)
|
||||||
{
|
{
|
||||||
assert(town && town->town);
|
assert(town && town->getTown());
|
||||||
configuration = generateConfiguration(rand);
|
configuration = generateConfiguration(rand);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rewardable::Configuration TownRewardableBuildingInstance::generateConfiguration(vstd::RNG & rand) const
|
Rewardable::Configuration TownRewardableBuildingInstance::generateConfiguration(vstd::RNG & rand) const
|
||||||
{
|
{
|
||||||
Rewardable::Configuration result;
|
Rewardable::Configuration result;
|
||||||
auto building = town->town->buildings.at(getBuildingType());
|
auto building = town->getTown()->buildings.at(getBuildingType());
|
||||||
|
|
||||||
building->rewardableObjectInfo.configureObject(result, rand, cb);
|
building->rewardableObjectInfo.configureObject(result, rand, cb);
|
||||||
for(auto & rewardInfo : result.info)
|
for(auto & rewardInfo : result.info)
|
||||||
|
@ -302,7 +302,7 @@ void CMap::calculateGuardingGreaturePositions()
|
|||||||
CGHeroInstance * CMap::getHero(HeroTypeID heroID)
|
CGHeroInstance * CMap::getHero(HeroTypeID heroID)
|
||||||
{
|
{
|
||||||
for(auto & elem : heroesOnMap)
|
for(auto & elem : heroesOnMap)
|
||||||
if(elem->getHeroType() == heroID)
|
if(elem->getHeroTypeID() == heroID)
|
||||||
return elem;
|
return elem;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -896,7 +896,7 @@ void CMapLoaderH3M::readPredefinedHeroes()
|
|||||||
}
|
}
|
||||||
map->predefinedHeroes.emplace_back(hero);
|
map->predefinedHeroes.emplace_back(hero);
|
||||||
|
|
||||||
logGlobal->debug("Map '%s': Hero predefined in map: %s", mapName, VLC->heroh->getById(hero->getHeroType())->getJsonKey());
|
logGlobal->debug("Map '%s': Hero predefined in map: %s", mapName, hero->getHeroType()->getJsonKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -913,7 +913,7 @@ void CMapLoaderH3M::loadArtifactsOfHero(CGHeroInstance * hero)
|
|||||||
|
|
||||||
if(!hero->artifactsWorn.empty() || !hero->artifactsInBackpack.empty())
|
if(!hero->artifactsWorn.empty() || !hero->artifactsInBackpack.empty())
|
||||||
{
|
{
|
||||||
logGlobal->debug("Hero %d at %s has set artifacts twice (in map properties and on adventure map instance). Using the latter set...", hero->getHeroType().getNum(), hero->anchorPos().toString());
|
logGlobal->debug("Hero %d at %s has set artifacts twice (in map properties and on adventure map instance). Using the latter set...", hero->getHeroTypeID().getNum(), hero->anchorPos().toString());
|
||||||
|
|
||||||
hero->artifactsInBackpack.clear();
|
hero->artifactsInBackpack.clear();
|
||||||
while(!hero->artifactsWorn.empty())
|
while(!hero->artifactsWorn.empty())
|
||||||
@ -1778,7 +1778,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
|
|||||||
|
|
||||||
for(auto & elem : map->disposedHeroes)
|
for(auto & elem : map->disposedHeroes)
|
||||||
{
|
{
|
||||||
if(elem.heroId == object->getHeroType())
|
if(elem.heroId == object->getHeroTypeID())
|
||||||
{
|
{
|
||||||
object->nameCustomTextId = elem.name;
|
object->nameCustomTextId = elem.name;
|
||||||
object->customPortraitSource = elem.portrait;
|
object->customPortraitSource = elem.portrait;
|
||||||
@ -1788,7 +1788,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
|
|||||||
|
|
||||||
bool hasName = reader->readBool();
|
bool hasName = reader->readBool();
|
||||||
if(hasName)
|
if(hasName)
|
||||||
object->nameCustomTextId = readLocalizedString(TextIdentifier("heroes", object->getHeroType().getNum(), "name"));
|
object->nameCustomTextId = readLocalizedString(TextIdentifier("heroes", object->getHeroTypeID().getNum(), "name"));
|
||||||
|
|
||||||
if(features.levelSOD)
|
if(features.levelSOD)
|
||||||
{
|
{
|
||||||
@ -1891,7 +1891,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
|
|||||||
auto ps = object->getAllBonuses(Selector::type()(BonusType::PRIMARY_SKILL).And(Selector::sourceType()(BonusSource::HERO_BASE_SKILL)), nullptr);
|
auto ps = object->getAllBonuses(Selector::type()(BonusType::PRIMARY_SKILL).And(Selector::sourceType()(BonusSource::HERO_BASE_SKILL)), nullptr);
|
||||||
if(ps->size())
|
if(ps->size())
|
||||||
{
|
{
|
||||||
logGlobal->debug("Hero %s has set primary skills twice (in map properties and on adventure map instance). Using the latter set...", object->getHeroType().getNum() );
|
logGlobal->debug("Hero %s has set primary skills twice (in map properties and on adventure map instance). Using the latter set...", object->getHeroTypeID().getNum() );
|
||||||
for(const auto & b : *ps)
|
for(const auto & b : *ps)
|
||||||
object->removeBonus(b);
|
object->removeBonus(b);
|
||||||
}
|
}
|
||||||
@ -1904,7 +1904,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (object->subID != MapObjectSubID())
|
if (object->subID != MapObjectSubID())
|
||||||
logGlobal->debug("Map '%s': Hero on map: %s at %s, owned by %s", mapName, VLC->heroh->getById(object->getHeroType())->getJsonKey(), mapPosition.toString(), object->getOwner().toString());
|
logGlobal->debug("Map '%s': Hero on map: %s at %s, owned by %s", mapName, object->getHeroType()->getJsonKey(), mapPosition.toString(), object->getOwner().toString());
|
||||||
else
|
else
|
||||||
logGlobal->debug("Map '%s': Hero on map: (random) at %s, owned by %s", mapName, mapPosition.toString(), object->getOwner().toString());
|
logGlobal->debug("Map '%s': Hero on map: (random) at %s, owned by %s", mapName, mapPosition.toString(), object->getOwner().toString());
|
||||||
|
|
||||||
|
@ -436,10 +436,8 @@ void CMapFormatJson::serializePlayerInfo(JsonSerializeFormat & handler)
|
|||||||
if(hero->ID == Obj::HERO)
|
if(hero->ID == Obj::HERO)
|
||||||
{
|
{
|
||||||
std::string temp;
|
std::string temp;
|
||||||
if(hero->type)
|
if(hero->getHeroTypeID().hasValue())
|
||||||
temp = hero->type->getJsonKey();
|
temp = hero->getHeroType()->getJsonKey();
|
||||||
else
|
|
||||||
temp = hero->getHeroType().toEntity(VLC)->getJsonKey();
|
|
||||||
|
|
||||||
handler.serializeString("type", temp);
|
handler.serializeString("type", temp);
|
||||||
}
|
}
|
||||||
@ -1154,10 +1152,10 @@ void CMapLoaderJson::readObjects()
|
|||||||
|
|
||||||
auto * hero = dynamic_cast<const CGHeroInstance *>(object.get());
|
auto * hero = dynamic_cast<const CGHeroInstance *>(object.get());
|
||||||
|
|
||||||
if (debugHeroesOnMap.count(hero->getHeroType()))
|
if (debugHeroesOnMap.count(hero->getHeroTypeID()))
|
||||||
logGlobal->error("Hero is already on the map at %s", hero->visitablePos().toString());
|
logGlobal->error("Hero is already on the map at %s", hero->visitablePos().toString());
|
||||||
|
|
||||||
debugHeroesOnMap.insert(hero->getHeroType());
|
debugHeroesOnMap.insert(hero->getHeroTypeID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1355,7 +1355,7 @@ void NewStructures::applyGs(CGameState *gs)
|
|||||||
|
|
||||||
for(const auto & id : bid)
|
for(const auto & id : bid)
|
||||||
{
|
{
|
||||||
assert(t->town->buildings.at(id) != nullptr);
|
assert(t->getTown()->buildings.at(id) != nullptr);
|
||||||
t->addBuilding(id);
|
t->addBuilding(id);
|
||||||
}
|
}
|
||||||
t->updateAppearance();
|
t->updateAppearance();
|
||||||
@ -1470,7 +1470,7 @@ void GiveHero::applyGs(CGameState *gs)
|
|||||||
|
|
||||||
auto oldVisitablePos = h->visitablePos();
|
auto oldVisitablePos = h->visitablePos();
|
||||||
gs->map->removeBlockVisTiles(h,true);
|
gs->map->removeBlockVisTiles(h,true);
|
||||||
h->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, h->type->heroClass->getIndex())->getTemplates().front();
|
h->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, h->getHeroClassID().getNum())->getTemplates().front();
|
||||||
|
|
||||||
h->setOwner(player);
|
h->setOwner(player);
|
||||||
h->setMovementPoints(h->movementPointsLimit(true));
|
h->setMovementPoints(h->movementPointsLimit(true));
|
||||||
|
@ -292,7 +292,7 @@ TeleporterTilesVector CPathfinderHelper::getTeleportExits(const PathNodeInfo & s
|
|||||||
{
|
{
|
||||||
auto * town = dynamic_cast<const CGTownInstance *>(source.nodeObject);
|
auto * town = dynamic_cast<const CGTownInstance *>(source.nodeObject);
|
||||||
assert(town);
|
assert(town);
|
||||||
if (town && town->getFaction() == FactionID::INFERNO)
|
if (town && town->getFactionID() == FactionID::INFERNO)
|
||||||
{
|
{
|
||||||
/// TODO: Find way to reuse CPlayerSpecificInfoCallback::getTownsInfo
|
/// TODO: Find way to reuse CPlayerSpecificInfoCallback::getTownsInfo
|
||||||
/// This may be handy if we allow to use teleportation to friendly towns
|
/// This may be handy if we allow to use teleportation to friendly towns
|
||||||
|
@ -173,10 +173,10 @@ bool Rewardable::Limiter::heroAllowed(const CGHeroInstance * hero) const
|
|||||||
if(!players.empty() && !vstd::contains(players, hero->getOwner()))
|
if(!players.empty() && !vstd::contains(players, hero->getOwner()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!heroes.empty() && !vstd::contains(heroes, hero->type->getId()))
|
if(!heroes.empty() && !vstd::contains(heroes, hero->getHeroTypeID()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!heroClasses.empty() && !vstd::contains(heroClasses, hero->type->heroClass->getId()))
|
if(!heroClasses.empty() && !vstd::contains(heroClasses, hero->getHeroClassID()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
@ -733,7 +733,7 @@ CGCreature * ObjectManager::chooseGuard(si32 strength, bool zoneGuard)
|
|||||||
continue;
|
continue;
|
||||||
if(!cre->getAIValue()) //bug #2681
|
if(!cre->getAIValue()) //bug #2681
|
||||||
continue;
|
continue;
|
||||||
if(!vstd::contains(zone.getMonsterTypes(), cre->getFaction()))
|
if(!vstd::contains(zone.getMonsterTypes(), cre->getFactionID()))
|
||||||
continue;
|
continue;
|
||||||
if((static_cast<si32>(cre->getAIValue() * (cre->ammMin + cre->ammMax) / 2) < strength) && (strength < static_cast<si32>(cre->getAIValue()) * 100)) //at least one full monster. size between average size of given stack and 100
|
if((static_cast<si32>(cre->getAIValue() * (cre->ammMin + cre->ammMax) / 2) < strength) && (strength < static_cast<si32>(cre->getAIValue()) * 100)) //at least one full monster. size between average size of given stack and 100
|
||||||
{
|
{
|
||||||
|
@ -90,7 +90,7 @@ void TownPlacer::placeTowns(ObjectManager & manager)
|
|||||||
|
|
||||||
totalTowns++;
|
totalTowns++;
|
||||||
//register MAIN town of zone only
|
//register MAIN town of zone only
|
||||||
map.registerZone(town->getFaction());
|
map.registerZone(town->getFactionID());
|
||||||
|
|
||||||
if(player.isValidPlayer()) //configure info for owning player
|
if(player.isValidPlayer()) //configure info for owning player
|
||||||
{
|
{
|
||||||
@ -213,7 +213,7 @@ void TownPlacer::addNewTowns(int count, bool hasFort, const PlayerColor & player
|
|||||||
{
|
{
|
||||||
//FIXME: discovered bug with small zones - getPos is close to map boarder and we have outOfMap exception
|
//FIXME: discovered bug with small zones - getPos is close to map boarder and we have outOfMap exception
|
||||||
//register MAIN town of zone
|
//register MAIN town of zone
|
||||||
map.registerZone(town->getFaction());
|
map.registerZone(town->getFactionID());
|
||||||
//first town in zone goes in the middle
|
//first town in zone goes in the middle
|
||||||
placeMainTown(manager, *town);
|
placeMainTown(manager, *town);
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ void TreasurePlacer::process()
|
|||||||
// Add all native creatures
|
// Add all native creatures
|
||||||
for(auto const & cre : VLC->creh->objects)
|
for(auto const & cre : VLC->creh->objects)
|
||||||
{
|
{
|
||||||
if(!cre->special && cre->getFaction() == zone.getTownType())
|
if(!cre->special && cre->getFactionID() == zone.getTownType())
|
||||||
{
|
{
|
||||||
creatures.push_back(cre.get());
|
creatures.push_back(cre.get());
|
||||||
}
|
}
|
||||||
@ -192,7 +192,7 @@ void TreasurePlacer::addPrisons()
|
|||||||
{
|
{
|
||||||
// Hero can be used again
|
// Hero can be used again
|
||||||
auto* hero = dynamic_cast<CGHeroInstance*>(obj);
|
auto* hero = dynamic_cast<CGHeroInstance*>(obj);
|
||||||
prisonHeroPlacer->restoreDrawnHero(hero->getHeroType());
|
prisonHeroPlacer->restoreDrawnHero(hero->getHeroTypeID());
|
||||||
};
|
};
|
||||||
|
|
||||||
oi.setTemplates(Obj::PRISON, 0, zone.getTerrainType());
|
oi.setTemplates(Obj::PRISON, 0, zone.getTerrainType());
|
||||||
@ -236,9 +236,9 @@ void TreasurePlacer::addDwellings()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto * cre = creatures.front();
|
const auto * cre = creatures.front();
|
||||||
if(cre->getFaction() == zone.getTownType())
|
if(cre->getFactionID() == zone.getTownType())
|
||||||
{
|
{
|
||||||
auto nativeZonesCount = static_cast<float>(map.getZoneCount(cre->getFaction()));
|
auto nativeZonesCount = static_cast<float>(map.getZoneCount(cre->getFactionID()));
|
||||||
ObjectInfo oi(dwellingType, secondaryID);
|
ObjectInfo oi(dwellingType, secondaryID);
|
||||||
setBasicProperties(oi, CompoundMapObjectID(dwellingType, secondaryID));
|
setBasicProperties(oi, CompoundMapObjectID(dwellingType, secondaryID));
|
||||||
|
|
||||||
@ -375,7 +375,7 @@ void TreasurePlacer::addPandoraBoxesWithCreatures()
|
|||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
oi.setTemplates(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
|
oi.setTemplates(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
|
||||||
oi.value = static_cast<ui32>(creature->getAIValue() * creaturesAmount * (1 + static_cast<float>(map.getZoneCount(creature->getFaction())) / map.getTotalZoneCount()));
|
oi.value = static_cast<ui32>(creature->getAIValue() * creaturesAmount * (1 + static_cast<float>(map.getZoneCount(creature->getFactionID())) / map.getTotalZoneCount()));
|
||||||
oi.probability = 3;
|
oi.probability = 3;
|
||||||
if(!oi.templates.empty())
|
if(!oi.templates.empty())
|
||||||
addObjectToRandomPool(oi);
|
addObjectToRandomPool(oi);
|
||||||
@ -555,7 +555,7 @@ void TreasurePlacer::addSeerHuts()
|
|||||||
oi.destroyObject = destroyObject;
|
oi.destroyObject = destroyObject;
|
||||||
oi.probability = 3;
|
oi.probability = 3;
|
||||||
oi.setTemplates(Obj::SEER_HUT, randomAppearance, zone.getTerrainType());
|
oi.setTemplates(Obj::SEER_HUT, randomAppearance, zone.getTerrainType());
|
||||||
oi.value = static_cast<ui32>(((2 * (creature->getAIValue()) * creaturesAmount * (1 + static_cast<float>(map.getZoneCount(creature->getFaction())) / map.getTotalZoneCount())) - 4000) / 3);
|
oi.value = static_cast<ui32>(((2 * (creature->getAIValue()) * creaturesAmount * (1 + static_cast<float>(map.getZoneCount(creature->getFactionID())) / map.getTotalZoneCount())) - 4000) / 3);
|
||||||
if (oi.value > zone.getMaxTreasureValue())
|
if (oi.value > zone.getMaxTreasureValue())
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -26,7 +26,7 @@ void CSerializer::addStdVecItems(CGameState *gs, LibClasses *lib)
|
|||||||
registerVectoredType<CGObjectInstance, ObjectInstanceID>(&gs->map->objects,
|
registerVectoredType<CGObjectInstance, ObjectInstanceID>(&gs->map->objects,
|
||||||
[](const CGObjectInstance &obj){ return obj.id; });
|
[](const CGObjectInstance &obj){ return obj.id; });
|
||||||
registerVectoredType<CGHeroInstance, HeroTypeID>(&gs->map->allHeroes,
|
registerVectoredType<CGHeroInstance, HeroTypeID>(&gs->map->allHeroes,
|
||||||
[](const CGHeroInstance &h){ return h.type->getId(); });
|
[](const CGHeroInstance &h){ return h.getHeroType()->getId(); });
|
||||||
registerVectoredType<CArtifactInstance, ArtifactInstanceID>(&gs->map->artInstances,
|
registerVectoredType<CArtifactInstance, ArtifactInstanceID>(&gs->map->artInstances,
|
||||||
[](const CArtifactInstance &artInst){ return artInst.getId(); });
|
[](const CArtifactInstance &artInst){ return artInst.getId(); });
|
||||||
registerVectoredType<CQuest, si32>(&gs->map->quests,
|
registerVectoredType<CQuest, si32>(&gs->map->quests,
|
||||||
|
@ -63,6 +63,7 @@ enum class ESerializationVersion : int32_t
|
|||||||
REGION_LABEL, // 864 - labels for campaign regions
|
REGION_LABEL, // 864 - labels for campaign regions
|
||||||
SPELL_RESEARCH, // 865 - spell research
|
SPELL_RESEARCH, // 865 - spell research
|
||||||
LOCAL_PLAYER_STATE_DATA, // 866 - player state contains arbitrary client-side data
|
LOCAL_PLAYER_STATE_DATA, // 866 - player state contains arbitrary client-side data
|
||||||
|
REMOVE_TOWN_PTR, // 867 - removed pointer to CTown from CGTownInstance
|
||||||
|
|
||||||
CURRENT = LOCAL_PLAYER_STATE_DATA
|
CURRENT = REMOVE_TOWN_PTR
|
||||||
};
|
};
|
||||||
|
@ -88,7 +88,7 @@ void Moat::convertBonus(const Mechanics * m, std::vector<Bonus> & converted) con
|
|||||||
|
|
||||||
if(m->battle()->battleGetDefendedTown() && m->battle()->battleGetFortifications().hasMoat)
|
if(m->battle()->battleGetDefendedTown() && m->battle()->battleGetFortifications().hasMoat)
|
||||||
{
|
{
|
||||||
nb.sid = BonusSourceID(m->battle()->battleGetDefendedTown()->town->buildings.at(BuildingID::CITADEL)->getUniqueTypeID());
|
nb.sid = BonusSourceID(m->battle()->battleGetDefendedTown()->getTown()->buildings.at(BuildingID::CITADEL)->getUniqueTypeID());
|
||||||
nb.source = BonusSource::TOWN_STRUCTURE;
|
nb.source = BonusSource::TOWN_STRUCTURE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -79,7 +79,7 @@ bool Summon::applicable(Problem & problem, const Mechanics * m) const
|
|||||||
|
|
||||||
text.replaceNamePlural(elemental->creatureId());
|
text.replaceNamePlural(elemental->creatureId());
|
||||||
|
|
||||||
if(caster->type->gender == EHeroGender::FEMALE)
|
if(caster->gender == EHeroGender::FEMALE)
|
||||||
text.replaceLocalString(EMetaText::GENERAL_TXT, 540);
|
text.replaceLocalString(EMetaText::GENERAL_TXT, 540);
|
||||||
else
|
else
|
||||||
text.replaceLocalString(EMetaText::GENERAL_TXT, 539);
|
text.replaceLocalString(EMetaText::GENERAL_TXT, 539);
|
||||||
|
@ -138,25 +138,11 @@ void Initializer::initialize(CGHeroInstance * o)
|
|||||||
o->subID = 0;
|
o->subID = 0;
|
||||||
o->tempOwner = PlayerColor::NEUTRAL;
|
o->tempOwner = PlayerColor::NEUTRAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(o->ID == Obj::HERO)
|
if(o->getHeroTypeID().hasValue())
|
||||||
{
|
{
|
||||||
for(auto const & t : VLC->heroh->objects)
|
o->gender = o->getHeroType()->gender;
|
||||||
{
|
o->randomizeArmy(o->getFactionID());
|
||||||
if(t->heroClass->getId() == HeroClassID(o->subID))
|
|
||||||
{
|
|
||||||
o->type = t.get();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(o->type)
|
|
||||||
{
|
|
||||||
// o->type = VLC->heroh->objects.at(o->subID);
|
|
||||||
|
|
||||||
o->gender = o->type->gender;
|
|
||||||
o->randomizeArmy(o->type->heroClass->faction);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,7 +290,7 @@ void Inspector::updateProperties(CGHeroInstance * o)
|
|||||||
auto isPrison = o->ID == Obj::PRISON;
|
auto isPrison = o->ID == Obj::PRISON;
|
||||||
addProperty("Owner", o->tempOwner, new OwnerDelegate(controller, isPrison), isPrison); //field is not editable for prison
|
addProperty("Owner", o->tempOwner, new OwnerDelegate(controller, isPrison), isPrison); //field is not editable for prison
|
||||||
addProperty<int>("Experience", o->exp, false);
|
addProperty<int>("Experience", o->exp, false);
|
||||||
addProperty("Hero class", o->type ? o->type->heroClass->getNameTranslated() : "", true);
|
addProperty("Hero class", o->getHeroClassID().hasValue() ? o->getHeroClass()->getNameTranslated() : "", true);
|
||||||
|
|
||||||
{ //Gender
|
{ //Gender
|
||||||
auto * delegate = new InspectorDelegate;
|
auto * delegate = new InspectorDelegate;
|
||||||
@ -319,20 +305,20 @@ void Inspector::updateProperties(CGHeroInstance * o)
|
|||||||
addProperty("Skills", PropertyEditorPlaceholder(), delegate, false);
|
addProperty("Skills", PropertyEditorPlaceholder(), delegate, false);
|
||||||
addProperty("Spells", PropertyEditorPlaceholder(), new HeroSpellDelegate(*o), false);
|
addProperty("Spells", PropertyEditorPlaceholder(), new HeroSpellDelegate(*o), false);
|
||||||
|
|
||||||
if(o->type || o->ID == Obj::PRISON)
|
if(o->getHeroTypeID().hasValue() || o->ID == Obj::PRISON)
|
||||||
{ //Hero type
|
{ //Hero type
|
||||||
auto * delegate = new InspectorDelegate;
|
auto * delegate = new InspectorDelegate;
|
||||||
for(int i = 0; i < VLC->heroh->objects.size(); ++i)
|
for(const auto & heroPtr : VLC->heroh->objects)
|
||||||
{
|
{
|
||||||
if(controller.map()->allowedHeroes.count(HeroTypeID(i)) != 0)
|
if(controller.map()->allowedHeroes.count(heroPtr->getId()) != 0)
|
||||||
{
|
{
|
||||||
if(o->ID == Obj::PRISON || (o->type && VLC->heroh->objects[i]->heroClass->getIndex() == o->type->heroClass->getIndex()))
|
if(o->ID == Obj::PRISON || heroPtr->heroClass->getIndex() == o->getHeroClassID())
|
||||||
{
|
{
|
||||||
delegate->options.push_back({QObject::tr(VLC->heroh->objects[i]->getNameTranslated().c_str()), QVariant::fromValue(VLC->heroh->objects[i]->getId().getNum())});
|
delegate->options.push_back({QObject::tr(heroPtr->getNameTranslated().c_str()), QVariant::fromValue(heroPtr->getIndex())});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addProperty("Hero type", o->type ? o->type->getNameTranslated() : "", delegate, false);
|
addProperty("Hero type", o->getHeroTypeID().hasValue() ? o->getHeroType()->getNameTranslated() : "", delegate, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -706,13 +692,10 @@ void Inspector::setProperty(CGHeroInstance * o, const QString & key, const QVari
|
|||||||
for(auto const & t : VLC->heroh->objects)
|
for(auto const & t : VLC->heroh->objects)
|
||||||
{
|
{
|
||||||
if(t->getId() == value.toInt())
|
if(t->getId() == value.toInt())
|
||||||
{
|
|
||||||
o->subID = value.toInt();
|
o->subID = value.toInt();
|
||||||
o->type = t.get();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
o->gender = o->type->gender;
|
o->gender = o->getHeroType()->gender;
|
||||||
o->randomizeArmy(o->type->heroClass->faction);
|
o->randomizeArmy(o->getHeroType()->heroClass->faction);
|
||||||
updateProperties(); //updating other properties after change
|
updateProperties(); //updating other properties after change
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,7 +331,7 @@ void TownBuildingsDelegate::setEditorData(QWidget *editor, const QModelIndex &in
|
|||||||
{
|
{
|
||||||
if(auto * ed = qobject_cast<TownBuildingsWidget *>(editor))
|
if(auto * ed = qobject_cast<TownBuildingsWidget *>(editor))
|
||||||
{
|
{
|
||||||
auto * ctown = town.town;
|
auto * ctown = town.getTown();
|
||||||
if(!ctown)
|
if(!ctown)
|
||||||
ctown = VLC->townh->randomTown;
|
ctown = VLC->townh->randomTown;
|
||||||
if(!ctown)
|
if(!ctown)
|
||||||
|
@ -100,7 +100,7 @@ void TownEventDialog::initResources()
|
|||||||
|
|
||||||
void TownEventDialog::initBuildings()
|
void TownEventDialog::initBuildings()
|
||||||
{
|
{
|
||||||
auto * ctown = town.town;
|
auto * ctown = town.getTown();
|
||||||
if (!ctown)
|
if (!ctown)
|
||||||
ctown = VLC->townh->randomTown;
|
ctown = VLC->townh->randomTown;
|
||||||
if (!ctown)
|
if (!ctown)
|
||||||
@ -156,7 +156,7 @@ QStandardItem * TownEventDialog::addBuilding(const CTown& ctown, BuildingID buil
|
|||||||
void TownEventDialog::initCreatures()
|
void TownEventDialog::initCreatures()
|
||||||
{
|
{
|
||||||
auto creatures = params.value("creatures").toList();
|
auto creatures = params.value("creatures").toList();
|
||||||
auto * ctown = town.town;
|
auto * ctown = town.getTown();
|
||||||
if (!ctown)
|
if (!ctown)
|
||||||
ui->creaturesTable->setRowCount(GameConstants::CREATURES_PER_TOWN);
|
ui->creaturesTable->setRowCount(GameConstants::CREATURES_PER_TOWN);
|
||||||
else
|
else
|
||||||
|
@ -138,7 +138,7 @@ void MapController::repairMap(CMap * map) const
|
|||||||
|
|
||||||
// FIXME: How about custom scenarios where defeated hero cannot be hired again?
|
// FIXME: How about custom scenarios where defeated hero cannot be hired again?
|
||||||
|
|
||||||
map->allowedHeroes.insert(nih->getHeroType());
|
map->allowedHeroes.insert(nih->getHeroTypeID());
|
||||||
|
|
||||||
auto const & type = VLC->heroh->objects[nih->subID];
|
auto const & type = VLC->heroh->objects[nih->subID];
|
||||||
assert(type->heroClass);
|
assert(type->heroClass);
|
||||||
@ -154,10 +154,6 @@ void MapController::repairMap(CMap * map) const
|
|||||||
nih->subTypeName = "prison";
|
nih->subTypeName = "prison";
|
||||||
nih->subID = 0;
|
nih->subID = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(obj->ID != Obj::RANDOM_HERO)
|
|
||||||
nih->type = type.get();
|
|
||||||
|
|
||||||
if(nih->ID == Obj::HERO) //not prison
|
if(nih->ID == Obj::HERO) //not prison
|
||||||
nih->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();
|
nih->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();
|
||||||
//fix spellbook
|
//fix spellbook
|
||||||
|
@ -77,12 +77,10 @@ PlayerParams::PlayerParams(MapController & ctrl, int playerId, QWidget *parent)
|
|||||||
{
|
{
|
||||||
if(auto town = dynamic_cast<CGTownInstance*>(controller.map()->objects[i].get()))
|
if(auto town = dynamic_cast<CGTownInstance*>(controller.map()->objects[i].get()))
|
||||||
{
|
{
|
||||||
auto * ctown = town->town;
|
auto * ctown = town->getTown();
|
||||||
if(!ctown)
|
if(!ctown)
|
||||||
{
|
|
||||||
ctown = VLC->townh->randomTown;
|
ctown = VLC->townh->randomTown;
|
||||||
town->town = ctown;
|
|
||||||
}
|
|
||||||
if(ctown && town->getOwner().getNum() == playerColor)
|
if(ctown && town->getOwner().getNum() == playerColor)
|
||||||
{
|
{
|
||||||
if(playerInfo.hasMainTown && playerInfo.posOfMainTown == town->pos)
|
if(playerInfo.hasMainTown && playerInfo.posOfMainTown == town->pos)
|
||||||
|
@ -122,13 +122,13 @@ std::set<Validator::Issue> Validator::validate(const CMap * map)
|
|||||||
|
|
||||||
++amountOfHeroes[ins->getOwner()];
|
++amountOfHeroes[ins->getOwner()];
|
||||||
}
|
}
|
||||||
if(ins->type)
|
if(ins->getHeroTypeID().hasValue())
|
||||||
{
|
{
|
||||||
if(map->allowedHeroes.count(ins->getHeroType()) == 0)
|
if(map->allowedHeroes.count(ins->getHeroTypeID()) == 0)
|
||||||
issues.insert({ tr("Hero %1 is prohibited by map settings").arg(ins->type->getNameTranslated().c_str()), false });
|
issues.insert({ tr("Hero %1 is prohibited by map settings").arg(ins->getHeroType()->getNameTranslated().c_str()), false });
|
||||||
|
|
||||||
if(!allHeroesOnMap.insert(ins->type).second)
|
if(!allHeroesOnMap.insert(ins->getHeroType()).second)
|
||||||
issues.insert({ tr("Hero %1 has duplicate on map").arg(ins->type->getNameTranslated().c_str()), false });
|
issues.insert({ tr("Hero %1 has duplicate on map").arg(ins->getHeroType()->getNameTranslated().c_str()), false });
|
||||||
}
|
}
|
||||||
else if(ins->ID != Obj::RANDOM_HERO)
|
else if(ins->ID != Obj::RANDOM_HERO)
|
||||||
issues.insert({ tr("Hero %1 has an empty type and must be removed").arg(ins->instanceName.c_str()), true });
|
issues.insert({ tr("Hero %1 has an empty type and must be removed").arg(ins->instanceName.c_str()), true });
|
||||||
|
@ -46,7 +46,7 @@ const std::vector<CreatureProxy::CustomRegType> CreatureProxy::REGISTER_CUSTOM =
|
|||||||
{"getLevel", LuaMethodWrapper<Creature, decltype(&Creature::getLevel), &Creature::getLevel>::invoke, false},
|
{"getLevel", LuaMethodWrapper<Creature, decltype(&Creature::getLevel), &Creature::getLevel>::invoke, false},
|
||||||
{"getGrowth", LuaMethodWrapper<Creature, decltype(&Creature::getGrowth), &Creature::getGrowth>::invoke, false},
|
{"getGrowth", LuaMethodWrapper<Creature, decltype(&Creature::getGrowth), &Creature::getGrowth>::invoke, false},
|
||||||
{"getHorde", LuaMethodWrapper<Creature, decltype(&Creature::getHorde), &Creature::getHorde>::invoke, false},
|
{"getHorde", LuaMethodWrapper<Creature, decltype(&Creature::getHorde), &Creature::getHorde>::invoke, false},
|
||||||
{"getFaction", LuaMethodWrapper<Creature, decltype(&Creature::getFaction), &Creature::getFaction>::invoke, false},
|
{"getFactionID", LuaMethodWrapper<Creature, decltype(&Creature::getFactionID), &Creature::getFactionID>::invoke, false},
|
||||||
|
|
||||||
{"getBaseAttack", LuaMethodWrapper<Creature, decltype(&Creature::getBaseAttack), &Creature::getBaseAttack>::invoke, false},
|
{"getBaseAttack", LuaMethodWrapper<Creature, decltype(&Creature::getBaseAttack), &Creature::getBaseAttack>::invoke, false},
|
||||||
{"getBaseDefense", LuaMethodWrapper<Creature, decltype(&Creature::getBaseDefense), &Creature::getBaseDefense>::invoke, false},
|
{"getBaseDefense", LuaMethodWrapper<Creature, decltype(&Creature::getBaseDefense), &Creature::getBaseDefense>::invoke, false},
|
||||||
|
@ -162,7 +162,7 @@ void CGameHandler::levelUpHero(const CGHeroInstance * hero)
|
|||||||
hlu.player = hero->tempOwner;
|
hlu.player = hero->tempOwner;
|
||||||
hlu.heroId = hero->id;
|
hlu.heroId = hero->id;
|
||||||
hlu.primskill = primarySkill;
|
hlu.primskill = primarySkill;
|
||||||
hlu.skills = hero->getLevelUpProposedSecondarySkills(heroPool->getHeroSkillsRandomGenerator(hero->getHeroType()));
|
hlu.skills = hero->getLevelUpProposedSecondarySkills(heroPool->getHeroSkillsRandomGenerator(hero->getHeroTypeID()));
|
||||||
|
|
||||||
if (hlu.skills.size() == 0)
|
if (hlu.skills.size() == 0)
|
||||||
{
|
{
|
||||||
@ -553,7 +553,7 @@ void CGameHandler::init(StartInfo *si, Load::ProgressAccumulator & progressTrack
|
|||||||
for (auto & elem : gs->map->allHeroes)
|
for (auto & elem : gs->map->allHeroes)
|
||||||
{
|
{
|
||||||
if(elem)
|
if(elem)
|
||||||
heroPool->getHeroSkillsRandomGenerator(elem->getHeroType()); // init RMG seed
|
heroPool->getHeroSkillsRandomGenerator(elem->getHeroTypeID()); // init RMG seed
|
||||||
}
|
}
|
||||||
|
|
||||||
reinitScripting();
|
reinitScripting();
|
||||||
@ -569,12 +569,12 @@ void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=fa
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (forced || town->creatures.at(town->town->creatures.size()).second.empty())//we need to change creature
|
if (forced || town->creatures.at(town->getTown()->creatures.size()).second.empty())//we need to change creature
|
||||||
{
|
{
|
||||||
SetAvailableCreatures ssi;
|
SetAvailableCreatures ssi;
|
||||||
ssi.tid = town->id;
|
ssi.tid = town->id;
|
||||||
ssi.creatures = town->creatures;
|
ssi.creatures = town->creatures;
|
||||||
ssi.creatures[town->town->creatures.size()].second.clear();//remove old one
|
ssi.creatures[town->getTown()->creatures.size()].second.clear();//remove old one
|
||||||
|
|
||||||
std::set<CreatureID> availableCreatures;
|
std::set<CreatureID> availableCreatures;
|
||||||
for (const auto & dwelling : p->getOwnedObjects())
|
for (const auto & dwelling : p->getOwnedObjects())
|
||||||
@ -590,13 +590,13 @@ void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=fa
|
|||||||
|
|
||||||
if (clear)
|
if (clear)
|
||||||
{
|
{
|
||||||
ssi.creatures[town->town->creatures.size()].first = std::max(1, (creatureId.toEntity(VLC)->getGrowth())/2);
|
ssi.creatures[town->getTown()->creatures.size()].first = std::max(1, (creatureId.toEntity(VLC)->getGrowth())/2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ssi.creatures[town->town->creatures.size()].first = creatureId.toEntity(VLC)->getGrowth();
|
ssi.creatures[town->getTown()->creatures.size()].first = creatureId.toEntity(VLC)->getGrowth();
|
||||||
}
|
}
|
||||||
ssi.creatures[town->town->creatures.size()].second.push_back(creatureId);
|
ssi.creatures[town->getTown()->creatures.size()].second.push_back(creatureId);
|
||||||
sendAndApply(ssi);
|
sendAndApply(ssi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -657,7 +657,7 @@ void CGameHandler::onNewTurn()
|
|||||||
PlayerColor player = t->tempOwner;
|
PlayerColor player = t->tempOwner;
|
||||||
|
|
||||||
if(t->hasBuilt(BuildingID::GRAIL)
|
if(t->hasBuilt(BuildingID::GRAIL)
|
||||||
&& t->town->buildings.at(BuildingID::GRAIL)->height == CBuilding::HEIGHT_SKYSHIP)
|
&& t->getTown()->buildings.at(BuildingID::GRAIL)->height == CBuilding::HEIGHT_SKYSHIP)
|
||||||
{
|
{
|
||||||
// Skyship, probably easier to handle same as Veil of darkness
|
// Skyship, probably easier to handle same as Veil of darkness
|
||||||
// do it every new day before veils
|
// do it every new day before veils
|
||||||
@ -1048,7 +1048,7 @@ bool CGameHandler::teleportHero(ObjectInstanceID hid, ObjectInstanceID dstid, ui
|
|||||||
if (((h->getOwner() != t->getOwner())
|
if (((h->getOwner() != t->getOwner())
|
||||||
&& complain("Cannot teleport hero to another player"))
|
&& complain("Cannot teleport hero to another player"))
|
||||||
|
|
||||||
|| (from->town->faction->getId() != t->town->faction->getId()
|
|| (from->getFactionID() != t->getFactionID()
|
||||||
&& complain("Source town and destination town should belong to the same faction"))
|
&& complain("Source town and destination town should belong to the same faction"))
|
||||||
|
|
||||||
|| ((!from || !from->hasBuilt(BuildingSubID::CASTLE_GATE))
|
|| ((!from || !from->hasBuilt(BuildingSubID::CASTLE_GATE))
|
||||||
@ -1212,7 +1212,7 @@ void CGameHandler::visitCastleObjects(const CGTownInstance * t, std::vector<cons
|
|||||||
|
|
||||||
for (auto & building : t->rewardableBuildings)
|
for (auto & building : t->rewardableBuildings)
|
||||||
{
|
{
|
||||||
if (!t->town->buildings.at(building.first)->manualHeroVisit && t->hasBuilt(building.first))
|
if (!t->getTown()->buildings.at(building.first)->manualHeroVisit && t->hasBuilt(building.first))
|
||||||
buildingsToVisit.push_back(building.first);
|
buildingsToVisit.push_back(building.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2036,12 +2036,12 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
|
|||||||
const CGTownInstance * t = getTown(tid);
|
const CGTownInstance * t = getTown(tid);
|
||||||
if(!t)
|
if(!t)
|
||||||
COMPLAIN_RETF("No such town (ID=%s)!", tid);
|
COMPLAIN_RETF("No such town (ID=%s)!", tid);
|
||||||
if(!t->town->buildings.count(requestedID))
|
if(!t->getTown()->buildings.count(requestedID))
|
||||||
COMPLAIN_RETF("Town of faction %s does not have info about building ID=%s!", t->town->faction->getNameTranslated() % requestedID);
|
COMPLAIN_RETF("Town of faction %s does not have info about building ID=%s!", t->getFaction()->getNameTranslated() % requestedID);
|
||||||
if(t->hasBuilt(requestedID))
|
if(t->hasBuilt(requestedID))
|
||||||
COMPLAIN_RETF("Building %s is already built in %s", t->town->buildings.at(requestedID)->getNameTranslated() % t->getNameTranslated());
|
COMPLAIN_RETF("Building %s is already built in %s", t->getTown()->buildings.at(requestedID)->getNameTranslated() % t->getNameTranslated());
|
||||||
|
|
||||||
const CBuilding * requestedBuilding = t->town->buildings.at(requestedID);
|
const CBuilding * requestedBuilding = t->getTown()->buildings.at(requestedID);
|
||||||
|
|
||||||
//Vector with future list of built building and buildings in auto-mode that are not yet built.
|
//Vector with future list of built building and buildings in auto-mode that are not yet built.
|
||||||
std::vector<const CBuilding*> remainingAutoBuildings;
|
std::vector<const CBuilding*> remainingAutoBuildings;
|
||||||
@ -2081,7 +2081,7 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
|
|||||||
int level = BuildingID::getLevelFromDwelling(buildingID);
|
int level = BuildingID::getLevelFromDwelling(buildingID);
|
||||||
int upgradeNumber = BuildingID::getUpgradedFromDwelling(buildingID);
|
int upgradeNumber = BuildingID::getUpgradedFromDwelling(buildingID);
|
||||||
|
|
||||||
if(upgradeNumber >= t->town->creatures.at(level).size())
|
if(upgradeNumber >= t->getTown()->creatures.at(level).size())
|
||||||
{
|
{
|
||||||
complain(boost::str(boost::format("Error encountered when building dwelling (bid=%s):"
|
complain(boost::str(boost::format("Error encountered when building dwelling (bid=%s):"
|
||||||
"no creature found (upgrade number %d, level %d!")
|
"no creature found (upgrade number %d, level %d!")
|
||||||
@ -2089,7 +2089,7 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CCreature * crea = t->town->creatures.at(level).at(upgradeNumber).toCreature();
|
const CCreature * crea = t->getTown()->creatures.at(level).at(upgradeNumber).toCreature();
|
||||||
|
|
||||||
SetAvailableCreatures ssi;
|
SetAvailableCreatures ssi;
|
||||||
ssi.tid = t->id;
|
ssi.tid = t->id;
|
||||||
@ -2099,7 +2099,7 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
|
|||||||
ssi.creatures[level].second.push_back(crea->getId());
|
ssi.creatures[level].second.push_back(crea->getId());
|
||||||
sendAndApply(ssi);
|
sendAndApply(ssi);
|
||||||
}
|
}
|
||||||
if(t->town->buildings.at(buildingID)->subId == BuildingSubID::PORTAL_OF_SUMMONING)
|
if(t->getTown()->buildings.at(buildingID)->subId == BuildingSubID::PORTAL_OF_SUMMONING)
|
||||||
{
|
{
|
||||||
setPortalDwelling(t);
|
setPortalDwelling(t);
|
||||||
}
|
}
|
||||||
@ -2110,9 +2110,9 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
|
|||||||
{
|
{
|
||||||
auto isMageGuild = (buildingID <= BuildingID::MAGES_GUILD_5 && buildingID >= BuildingID::MAGES_GUILD_1);
|
auto isMageGuild = (buildingID <= BuildingID::MAGES_GUILD_5 && buildingID >= BuildingID::MAGES_GUILD_1);
|
||||||
auto isLibrary = isMageGuild ? false
|
auto isLibrary = isMageGuild ? false
|
||||||
: t->town->buildings.at(buildingID)->subId == BuildingSubID::EBuildingSubID::LIBRARY;
|
: t->getTown()->buildings.at(buildingID)->subId == BuildingSubID::EBuildingSubID::LIBRARY;
|
||||||
|
|
||||||
if(isMageGuild || isLibrary || (t->getFaction() == ETownType::CONFLUX && buildingID == BuildingID::GRAIL))
|
if(isMageGuild || isLibrary || (t->getFactionID() == ETownType::CONFLUX && buildingID == BuildingID::GRAIL))
|
||||||
{
|
{
|
||||||
if(t->visitingHero)
|
if(t->visitingHero)
|
||||||
giveSpells(t,t->visitingHero);
|
giveSpells(t,t->visitingHero);
|
||||||
@ -2128,7 +2128,7 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
|
|||||||
};
|
};
|
||||||
|
|
||||||
//Init the vectors
|
//Init the vectors
|
||||||
for(auto & build : t->town->buildings)
|
for(auto & build : t->getTown()->buildings)
|
||||||
{
|
{
|
||||||
if(t->hasBuilt(build.first))
|
if(t->hasBuilt(build.first))
|
||||||
{
|
{
|
||||||
@ -2212,7 +2212,7 @@ bool CGameHandler::visitTownBuilding(ObjectInstanceID tid, BuildingID bid)
|
|||||||
if(!t->hasBuilt(bid))
|
if(!t->hasBuilt(bid))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto subID = t->town->buildings.at(bid)->subId;
|
auto subID = t->getTown()->buildings.at(bid)->subId;
|
||||||
|
|
||||||
if(subID == BuildingSubID::EBuildingSubID::BANK)
|
if(subID == BuildingSubID::EBuildingSubID::BANK)
|
||||||
{
|
{
|
||||||
@ -2224,7 +2224,7 @@ bool CGameHandler::visitTownBuilding(ObjectInstanceID tid, BuildingID bid)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t->rewardableBuildings.count(bid) && t->visitingHero && t->town->buildings.at(bid)->manualHeroVisit)
|
if (t->rewardableBuildings.count(bid) && t->visitingHero && t->getTown()->buildings.at(bid)->manualHeroVisit)
|
||||||
{
|
{
|
||||||
std::vector<BuildingID> buildingsToVisit;
|
std::vector<BuildingID> buildingsToVisit;
|
||||||
std::vector<const CGHeroInstance*> visitors;
|
std::vector<const CGHeroInstance*> visitors;
|
||||||
|
@ -47,8 +47,8 @@ TavernHeroSlot HeroPoolProcessor::selectSlotForRole(const PlayerColor & player,
|
|||||||
// try to find "better" slot to overwrite
|
// try to find "better" slot to overwrite
|
||||||
// we want to avoid overwriting retreated heroes when tavern still has slot with random hero
|
// we want to avoid overwriting retreated heroes when tavern still has slot with random hero
|
||||||
// as well as avoid overwriting surrendered heroes if we can overwrite retreated hero
|
// as well as avoid overwriting surrendered heroes if we can overwrite retreated hero
|
||||||
auto roleLeft = heroesPool->getSlotRole(heroes[0]->getHeroType());
|
auto roleLeft = heroesPool->getSlotRole(heroes[0]->getHeroTypeID());
|
||||||
auto roleRight = heroesPool->getSlotRole(heroes[1]->getHeroType());
|
auto roleRight = heroesPool->getSlotRole(heroes[1]->getHeroTypeID());
|
||||||
|
|
||||||
if (roleLeft > roleRight)
|
if (roleLeft > roleRight)
|
||||||
return TavernHeroSlot::RANDOM;
|
return TavernHeroSlot::RANDOM;
|
||||||
@ -70,7 +70,7 @@ void HeroPoolProcessor::onHeroSurrendered(const PlayerColor & color, const CGHer
|
|||||||
|
|
||||||
sah.slotID = selectSlotForRole(color, sah.roleID);
|
sah.slotID = selectSlotForRole(color, sah.roleID);
|
||||||
sah.player = color;
|
sah.player = color;
|
||||||
sah.hid = hero->getHeroType();
|
sah.hid = hero->getHeroTypeID();
|
||||||
sah.replenishPoints = false;
|
sah.replenishPoints = false;
|
||||||
gameHandler->sendAndApply(sah);
|
gameHandler->sendAndApply(sah);
|
||||||
}
|
}
|
||||||
@ -82,9 +82,9 @@ void HeroPoolProcessor::onHeroEscaped(const PlayerColor & color, const CGHeroIns
|
|||||||
|
|
||||||
sah.slotID = selectSlotForRole(color, sah.roleID);
|
sah.slotID = selectSlotForRole(color, sah.roleID);
|
||||||
sah.player = color;
|
sah.player = color;
|
||||||
sah.hid = hero->getHeroType();
|
sah.hid = hero->getHeroTypeID();
|
||||||
sah.army.clearSlots();
|
sah.army.clearSlots();
|
||||||
sah.army.setCreature(SlotID(0), hero->type->initialArmy.at(0).creature, 1);
|
sah.army.setCreature(SlotID(0), hero->getHeroType()->initialArmy.at(0).creature, 1);
|
||||||
sah.replenishPoints = false;
|
sah.replenishPoints = false;
|
||||||
|
|
||||||
gameHandler->sendAndApply(sah);
|
gameHandler->sendAndApply(sah);
|
||||||
@ -112,7 +112,7 @@ void HeroPoolProcessor::selectNewHeroForSlot(const PlayerColor & color, TavernHe
|
|||||||
|
|
||||||
if (newHero)
|
if (newHero)
|
||||||
{
|
{
|
||||||
sah.hid = newHero->getHeroType();
|
sah.hid = newHero->getHeroTypeID();
|
||||||
|
|
||||||
if (giveArmy)
|
if (giveArmy)
|
||||||
{
|
{
|
||||||
@ -123,7 +123,7 @@ void HeroPoolProcessor::selectNewHeroForSlot(const PlayerColor & color, TavernHe
|
|||||||
{
|
{
|
||||||
sah.roleID = TavernSlotRole::SINGLE_UNIT;
|
sah.roleID = TavernSlotRole::SINGLE_UNIT;
|
||||||
sah.army.clearSlots();
|
sah.army.clearSlots();
|
||||||
sah.army.setCreature(SlotID(0), newHero->type->initialArmy[0].creature, 1);
|
sah.army.setCreature(SlotID(0), newHero->getHeroType()->initialArmy[0].creature, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -208,7 +208,7 @@ bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTy
|
|||||||
|
|
||||||
for(const auto & hero : recruitableHeroes)
|
for(const auto & hero : recruitableHeroes)
|
||||||
{
|
{
|
||||||
if(hero->getHeroType() == heroToRecruit)
|
if(hero->getHeroTypeID() == heroToRecruit)
|
||||||
recruitedHero = hero;
|
recruitedHero = hero;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +221,7 @@ bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTy
|
|||||||
|
|
||||||
HeroRecruited hr;
|
HeroRecruited hr;
|
||||||
hr.tid = mapObject->id;
|
hr.tid = mapObject->id;
|
||||||
hr.hid = recruitedHero->getHeroType();
|
hr.hid = recruitedHero->getHeroTypeID();
|
||||||
hr.player = player;
|
hr.player = player;
|
||||||
hr.tile = recruitedHero->convertFromVisitablePos(targetPos );
|
hr.tile = recruitedHero->convertFromVisitablePos(targetPos );
|
||||||
if(gameHandler->getTile(targetPos)->isWater() && !recruitedHero->boat)
|
if(gameHandler->getTile(targetPos)->isWater() && !recruitedHero->boat)
|
||||||
@ -258,14 +258,14 @@ std::vector<const CHeroClass *> HeroPoolProcessor::findAvailableClassesFor(const
|
|||||||
|
|
||||||
for(const auto & elem : heroesPool->unusedHeroesFromPool())
|
for(const auto & elem : heroesPool->unusedHeroesFromPool())
|
||||||
{
|
{
|
||||||
if (vstd::contains(result, elem.second->type->heroClass))
|
if (vstd::contains(result, elem.second->getHeroClass()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool heroAvailable = heroesPool->isHeroAvailableFor(elem.first, player);
|
bool heroAvailable = heroesPool->isHeroAvailableFor(elem.first, player);
|
||||||
bool heroClassBanned = elem.second->type->heroClass->tavernProbability(factionID) == 0;
|
bool heroClassBanned = elem.second->getHeroClass()->tavernProbability(factionID) == 0;
|
||||||
|
|
||||||
if(heroAvailable && !heroClassBanned)
|
if(heroAvailable && !heroClassBanned)
|
||||||
result.push_back(elem.second->type->heroClass);
|
result.push_back(elem.second->getHeroClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -282,7 +282,7 @@ std::vector<CGHeroInstance *> HeroPoolProcessor::findAvailableHeroesFor(const Pl
|
|||||||
assert(!vstd::contains(result, elem.second));
|
assert(!vstd::contains(result, elem.second));
|
||||||
|
|
||||||
bool heroAvailable = heroesPool->isHeroAvailableFor(elem.first, player);
|
bool heroAvailable = heroesPool->isHeroAvailableFor(elem.first, player);
|
||||||
bool heroClassMatches = elem.second->type->heroClass == heroClass;
|
bool heroClassMatches = elem.second->getHeroClass() == heroClass;
|
||||||
|
|
||||||
if(heroAvailable && heroClassMatches)
|
if(heroAvailable && heroClassMatches)
|
||||||
result.push_back(elem.second);
|
result.push_back(elem.second);
|
||||||
@ -318,7 +318,7 @@ const CHeroClass * HeroPoolProcessor::pickClassFor(bool isNative, const PlayerCo
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool hasSameClass = vstd::contains_if(currentTavern, [&](const CGHeroInstance * hero){
|
bool hasSameClass = vstd::contains_if(currentTavern, [&](const CGHeroInstance * hero){
|
||||||
return hero->type->heroClass == heroClass;
|
return hero->getHeroClass() == heroClass;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (hasSameClass)
|
if (hasSameClass)
|
||||||
|
@ -95,10 +95,10 @@ void NewTurnProcessor::handleTownEvents(const CGTownInstance * town)
|
|||||||
// 1. Building exists in town (don't attempt to build Lvl 5 guild in Fortress
|
// 1. Building exists in town (don't attempt to build Lvl 5 guild in Fortress
|
||||||
// 2. Building was not built yet
|
// 2. Building was not built yet
|
||||||
// othervice, silently ignore / skip it
|
// othervice, silently ignore / skip it
|
||||||
if (town->town->buildings.count(i) && !town->hasBuilt(i))
|
if (town->getTown()->buildings.count(i) && !town->hasBuilt(i))
|
||||||
{
|
{
|
||||||
gameHandler->buildStructure(town->id, i, true);
|
gameHandler->buildStructure(town->id, i, true);
|
||||||
iw.components.emplace_back(ComponentType::BUILDING, BuildingTypeUniqueID(town->getFaction(), i));
|
iw.components.emplace_back(ComponentType::BUILDING, BuildingTypeUniqueID(town->getFactionID(), i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,7 +246,7 @@ SetAvailableCreatures NewTurnProcessor::generateTownGrowth(const CGTownInstance
|
|||||||
sac.tid = t->id;
|
sac.tid = t->id;
|
||||||
sac.creatures = t->creatures;
|
sac.creatures = t->creatures;
|
||||||
|
|
||||||
for (int k=0; k < t->town->creatures.size(); k++)
|
for (int k=0; k < t->getTown()->creatures.size(); k++)
|
||||||
{
|
{
|
||||||
if (t->creatures.at(k).second.empty())
|
if (t->creatures.at(k).second.empty())
|
||||||
continue;
|
continue;
|
||||||
@ -345,7 +345,7 @@ void NewTurnProcessor::updateNeutralTownGarrison(const CGTownInstance * t, int c
|
|||||||
{
|
{
|
||||||
const auto * creature = slot.second->type;
|
const auto * creature = slot.second->type;
|
||||||
|
|
||||||
if (creature->getFaction() != t->getFaction())
|
if (creature->getFactionID() != t->getFactionID())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (creature->getLevel() != tierToGrow)
|
if (creature->getLevel() != tierToGrow)
|
||||||
@ -518,7 +518,7 @@ std::tuple<EWeekType, CreatureID> NewTurnProcessor::pickWeekType(bool newMonth)
|
|||||||
{
|
{
|
||||||
newMonster.second = VLC->creh->pickRandomMonster(gameHandler->getRandomGenerator());
|
newMonster.second = VLC->creh->pickRandomMonster(gameHandler->getRandomGenerator());
|
||||||
} while (VLC->creh->objects[newMonster.second] &&
|
} while (VLC->creh->objects[newMonster.second] &&
|
||||||
(*VLC->townh)[VLC->creatures()->getById(newMonster.second)->getFaction()]->town == nullptr); // find first non neutral creature
|
(*VLC->townh)[VLC->creatures()->getById(newMonster.second)->getFactionID()]->town == nullptr); // find first non neutral creature
|
||||||
|
|
||||||
return { EWeekType::BONUS_GROWTH, newMonster.second};
|
return { EWeekType::BONUS_GROWTH, newMonster.second};
|
||||||
}
|
}
|
||||||
|
@ -370,7 +370,7 @@ void PlayerMessageProcessor::cheatBuildTown(PlayerColor player, const CGTownInst
|
|||||||
if (!town)
|
if (!town)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (auto & build : town->town->buildings)
|
for (auto & build : town->getTown()->buildings)
|
||||||
{
|
{
|
||||||
if (!town->hasBuilt(build.first)
|
if (!town->hasBuilt(build.first)
|
||||||
&& !build.second->getNameTranslated().empty()
|
&& !build.second->getNameTranslated().empty()
|
||||||
|
@ -100,7 +100,7 @@ TEST_F(CCreatureTest, DISABLED_JsonUpdate)
|
|||||||
|
|
||||||
EXPECT_EQ(subject->getFightValue(), 2420);
|
EXPECT_EQ(subject->getFightValue(), 2420);
|
||||||
EXPECT_EQ(subject->getLevel(), 6);
|
EXPECT_EQ(subject->getLevel(), 6);
|
||||||
EXPECT_EQ(subject->getFaction().getNum(), 55);
|
EXPECT_EQ(subject->getFactionID().getNum(), 55);
|
||||||
EXPECT_TRUE(subject->isDoubleWide());
|
EXPECT_TRUE(subject->isDoubleWide());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ public:
|
|||||||
MOCK_CONST_METHOD0(getLevel, int32_t());
|
MOCK_CONST_METHOD0(getLevel, int32_t());
|
||||||
MOCK_CONST_METHOD0(getGrowth, int32_t());
|
MOCK_CONST_METHOD0(getGrowth, int32_t());
|
||||||
MOCK_CONST_METHOD0(getHorde, int32_t());
|
MOCK_CONST_METHOD0(getHorde, int32_t());
|
||||||
MOCK_CONST_METHOD0(getFaction, FactionID());
|
MOCK_CONST_METHOD0(getFactionID, FactionID());
|
||||||
|
|
||||||
MOCK_CONST_METHOD0(getBaseAttack, int32_t());
|
MOCK_CONST_METHOD0(getBaseAttack, int32_t());
|
||||||
MOCK_CONST_METHOD0(getBaseDefense, int32_t());
|
MOCK_CONST_METHOD0(getBaseDefense, int32_t());
|
||||||
|
@ -82,7 +82,7 @@ public:
|
|||||||
MOCK_CONST_METHOD1(willMove, bool(int));
|
MOCK_CONST_METHOD1(willMove, bool(int));
|
||||||
MOCK_CONST_METHOD1(waited, bool(int));
|
MOCK_CONST_METHOD1(waited, bool(int));
|
||||||
|
|
||||||
MOCK_CONST_METHOD0(getFaction, FactionID());
|
MOCK_CONST_METHOD0(getFactionID, FactionID());
|
||||||
|
|
||||||
MOCK_CONST_METHOD1(battleQueuePhase, battle::BattlePhases::Type(int));
|
MOCK_CONST_METHOD1(battleQueuePhase, battle::BattlePhases::Type(int));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user