mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-13 01:20:34 +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:
@ -78,7 +78,7 @@ void CArmedInstance::updateMoraleBonusFromArmy()
|
||||
const CStackInstance * inst = slot.second;
|
||||
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)
|
||||
if (!hasUndead)
|
||||
{
|
||||
|
@ -45,7 +45,7 @@ std::string CGCreature::getHoverText(PlayerColor player) const
|
||||
else
|
||||
ms.appendLocalString(EMetaText::ARRAY_TXT, quantityTextIndex);
|
||||
ms.appendRawString(" ");
|
||||
ms.appendNamePlural(getCreature());
|
||||
ms.appendNamePlural(getCreatureID());
|
||||
|
||||
return ms.toString();
|
||||
}
|
||||
@ -57,7 +57,7 @@ std::string CGCreature::getHoverText(const CGHeroInstance * hero) const
|
||||
MetaString ms;
|
||||
ms.appendNumber(stacks.begin()->second->count);
|
||||
ms.appendRawString(" ");
|
||||
ms.appendName(getCreature(), stacks.begin()->second->count);
|
||||
ms.appendName(getCreatureID(), stacks.begin()->second->count);
|
||||
return ms.toString();
|
||||
}
|
||||
else
|
||||
@ -69,11 +69,11 @@ std::string CGCreature::getHoverText(const CGHeroInstance * hero) const
|
||||
std::string CGCreature::getMonsterLevelText() const
|
||||
{
|
||||
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 attackType = VLC->generaltexth->translate(attackTypeKey);
|
||||
boost::replace_first(monsterLevel, "%TOWN", (*VLC->townh)[VLC->creatures()->getById(getCreature())->getFaction()]->getNameTranslated());
|
||||
boost::replace_first(monsterLevel, "%LEVEL", std::to_string(VLC->creatures()->getById(getCreature())->getLevel()));
|
||||
boost::replace_first(monsterLevel, "%TOWN", getCreature()->getFactionID().toEntity(VLC)->getNameTranslated());
|
||||
boost::replace_first(monsterLevel, "%LEVEL", std::to_string(getCreature()->getLevel()));
|
||||
boost::replace_first(monsterLevel, "%ATTACK_TYPE", attackType);
|
||||
return monsterLevel;
|
||||
}
|
||||
@ -150,7 +150,7 @@ std::string CGCreature::getPopupText(PlayerColor player) const
|
||||
std::vector<Component> CGCreature::getPopupComponents(PlayerColor player) const
|
||||
{
|
||||
return {
|
||||
Component(ComponentType::CREATURE, getCreature())
|
||||
Component(ComponentType::CREATURE, getCreatureID())
|
||||
};
|
||||
}
|
||||
|
||||
@ -182,7 +182,7 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
|
||||
BlockingDialog ynd(true,false);
|
||||
ynd.player = h->tempOwner;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
@ -197,7 +197,7 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
|
||||
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(action));
|
||||
boost::algorithm::replace_first(tmp,"%s",VLC->creatures()->getById(getCreature())->getNamePluralTranslated());
|
||||
boost::algorithm::replace_first(tmp,"%s",getCreature()->getNamePluralTranslated());
|
||||
ynd.text.appendRawString(tmp);
|
||||
cb->showBlockingDialog(this, &ynd);
|
||||
break;
|
||||
@ -205,11 +205,16 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
|
||||
}
|
||||
}
|
||||
|
||||
CreatureID CGCreature::getCreature() const
|
||||
CreatureID CGCreature::getCreatureID() const
|
||||
{
|
||||
return CreatureID(getObjTypeIndex().getNum());
|
||||
}
|
||||
|
||||
const CCreature * CGCreature::getCreature() const
|
||||
{
|
||||
return getCreatureID().toCreature();
|
||||
}
|
||||
|
||||
void CGCreature::pickRandomObject(vstd::RNG & rand)
|
||||
{
|
||||
switch(ID.toEnum())
|
||||
@ -279,7 +284,7 @@ void CGCreature::initObj(vstd::RNG & rand)
|
||||
|
||||
stacks[SlotID(0)]->setType(getCreature());
|
||||
TQuantity &amount = stacks[SlotID(0)]->count;
|
||||
const Creature * c = VLC->creatures()->getById(getCreature());
|
||||
const Creature * c = getCreature();
|
||||
if(amount == 0)
|
||||
{
|
||||
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())
|
||||
{
|
||||
bool isOurUpgrade = vstd::contains(getCreature().toCreature()->upgrades, elem.second->getCreatureID());
|
||||
bool isOurDowngrade = vstd::contains(elem.second->type->upgrades, getCreature());
|
||||
bool isOurUpgrade = vstd::contains(getCreature()->upgrades, elem.second->getCreatureID());
|
||||
bool isOurDowngrade = vstd::contains(elem.second->type->upgrades, getCreatureID());
|
||||
|
||||
if(isOurUpgrade || isOurDowngrade)
|
||||
count += elem.second->count;
|
||||
@ -380,7 +385,7 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
|
||||
|
||||
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));
|
||||
return recruitCost * stackCount; //join for gold
|
||||
}
|
||||
@ -493,7 +498,7 @@ void CGCreature::flee( const CGHeroInstance * h ) const
|
||||
BlockingDialog ynd(true,false);
|
||||
ynd.player = h->tempOwner;
|
||||
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);
|
||||
}
|
||||
|
||||
@ -513,7 +518,7 @@ void CGCreature::battleFinished(const CGHeroInstance *hero, const BattleResult &
|
||||
{
|
||||
//merge stacks into one
|
||||
TSlots::const_iterator i;
|
||||
const CCreature * cre = getCreature().toCreature();
|
||||
const CCreature * cre = getCreature();
|
||||
for(i = stacks.begin(); i != stacks.end(); i++)
|
||||
{
|
||||
if(cre->isMyUpgrade(i->second->type))
|
||||
|
@ -49,7 +49,8 @@ public:
|
||||
void newTurn(vstd::RNG & rand) const override;
|
||||
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) 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,
|
||||
bool containsUpgradedStack() const;
|
||||
|
@ -93,7 +93,7 @@ FactionID CGDwelling::randomizeFaction(vstd::RNG & rand)
|
||||
|
||||
assert(linkedTown->ID == Obj::TOWN);
|
||||
if(linkedTown->ID==Obj::TOWN)
|
||||
return linkedTown->getFaction();
|
||||
return linkedTown->getFactionID();
|
||||
}
|
||||
|
||||
if(!randomizationInfo->allowedFactions.empty())
|
||||
|
@ -116,9 +116,9 @@ ui32 CGHeroInstance::getTileMovementCost(const TerrainTile & dest, const Terrain
|
||||
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
|
||||
@ -229,10 +229,10 @@ bool CGHeroInstance::canLearnSkill(const SecondarySkill & which) const
|
||||
if (getSecSkillLevel(which) > 0)
|
||||
return false;
|
||||
|
||||
if (type->heroClass->secSkillProbability.count(which) == 0)
|
||||
if (getHeroClass()->secSkillProbability.count(which) == 0)
|
||||
return false;
|
||||
|
||||
if (type->heroClass->secSkillProbability.at(which) == 0)
|
||||
if (getHeroClass()->secSkillProbability.at(which) == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -282,7 +282,6 @@ int CGHeroInstance::movementPointsLimitCached(bool onLand, const TurnInfo * ti)
|
||||
|
||||
CGHeroInstance::CGHeroInstance(IGameCallback * cb)
|
||||
: CArmedInstance(cb),
|
||||
type(nullptr),
|
||||
tacticFormationEnabled(false),
|
||||
inTownGarrison(false),
|
||||
moveDir(4),
|
||||
@ -303,14 +302,30 @@ PlayerColor CGHeroInstance::getOwner() const
|
||||
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());
|
||||
}
|
||||
|
||||
void CGHeroInstance::setHeroType(HeroTypeID heroType)
|
||||
{
|
||||
assert(type == nullptr);
|
||||
subID = heroType;
|
||||
}
|
||||
|
||||
@ -323,16 +338,14 @@ void CGHeroInstance::initHero(vstd::RNG & rand, const HeroTypeID & SUBID)
|
||||
void CGHeroInstance::initHero(vstd::RNG & rand)
|
||||
{
|
||||
assert(validTypes(true));
|
||||
if(!type)
|
||||
type = getHeroType().toHeroType();
|
||||
|
||||
|
||||
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))
|
||||
{
|
||||
// hero starts with default spells
|
||||
for(const auto & spellID : type->spells)
|
||||
for(const auto & spellID : getHeroType()->spells)
|
||||
spells.insert(spellID);
|
||||
}
|
||||
else //remove placeholder
|
||||
@ -341,7 +354,7 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
|
||||
if(!vstd::contains(spells, SpellID::SPELLBOOK_PRESET))
|
||||
{
|
||||
// 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);
|
||||
putArtifact(ArtifactPosition::SPELLBOOK, artifact);
|
||||
@ -360,14 +373,14 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
|
||||
{
|
||||
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
|
||||
secSkills = type->secSkillsInit;
|
||||
secSkills = getHeroType()->secSkillsInit;
|
||||
|
||||
if (gender == EHeroGender::DEFAULT)
|
||||
gender = type->gender;
|
||||
gender = getHeroType()->gender;
|
||||
|
||||
setFormation(EArmyFormation::LOOSE);
|
||||
if (!stacksCount()) //standard army//initial army
|
||||
@ -403,9 +416,9 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
|
||||
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->giveStackExp (exp); //after our exp is set
|
||||
}
|
||||
@ -413,7 +426,7 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
|
||||
skillsInfo = SecondarySkillsInfo();
|
||||
|
||||
//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);
|
||||
|
||||
//initialize bonuses
|
||||
@ -433,14 +446,14 @@ void CGHeroInstance::initArmy(vstd::RNG & rand, IArmyDescriptor * dst)
|
||||
auto stacksCountChances = cb->getSettings().getVector(EGameSettings::HEROES_STARTING_STACKS_CHANCES);
|
||||
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++)
|
||||
{
|
||||
if (stacksCountInitRandomNumber > stacksCountChances[stackNo])
|
||||
continue;
|
||||
|
||||
auto & stack = type->initialArmy[stackNo];
|
||||
auto & stack = getHeroType()->initialArmy[stackNo];
|
||||
|
||||
int count = rand.nextInt(stack.minAmount, stack.maxAmount);
|
||||
|
||||
@ -588,11 +601,11 @@ std::string CGHeroInstance::getMovementPointsTextIfOwner(PlayerColor player) con
|
||||
|
||||
ui8 CGHeroInstance::maxlevelsToMagicSchool() const
|
||||
{
|
||||
return type->heroClass->isMagicHero() ? 3 : 4;
|
||||
return getHeroClass()->isMagicHero() ? 3 : 4;
|
||||
}
|
||||
ui8 CGHeroInstance::maxlevelsToWisdom() const
|
||||
{
|
||||
return type->heroClass->isMagicHero() ? 3 : 6;
|
||||
return getHeroClass()->isMagicHero() ? 3 : 6;
|
||||
}
|
||||
|
||||
CGHeroInstance::SecondarySkillsInfo::SecondarySkillsInfo():
|
||||
@ -617,11 +630,8 @@ void CGHeroInstance::pickRandomObject(vstd::RNG & rand)
|
||||
{
|
||||
ID = Obj::HERO;
|
||||
subID = cb->gameState()->pickNextHeroType(getOwner());
|
||||
type = getHeroType().toHeroType();
|
||||
randomizeArmy(type->heroClass->faction);
|
||||
randomizeArmy(getHeroClass()->faction);
|
||||
}
|
||||
else
|
||||
type = getHeroType().toHeroType();
|
||||
|
||||
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
|
||||
// exclude prisons which should use appearance as set in map, via map editor or RMG
|
||||
if (ID != Obj::PRISON)
|
||||
setType(ID, type->heroClass->getIndex());
|
||||
setType(ID, getHeroClass()->getIndex());
|
||||
|
||||
this->subID = oldSubID;
|
||||
}
|
||||
@ -1041,7 +1051,7 @@ si32 CGHeroInstance::getManaNewTurn() 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
|
||||
@ -1080,7 +1090,7 @@ void CGHeroInstance::pushPrimSkill( PrimarySkill which, int val )
|
||||
|
||||
EAlignment CGHeroInstance::getAlignment() const
|
||||
{
|
||||
return type->heroClass->getAlignment();
|
||||
return getHeroClass()->getAlignment();
|
||||
}
|
||||
|
||||
void CGHeroInstance::initExp(vstd::RNG & rand)
|
||||
@ -1104,12 +1114,12 @@ HeroTypeID CGHeroInstance::getPortraitSource() const
|
||||
if (customPortraitSource.isValid())
|
||||
return customPortraitSource;
|
||||
else
|
||||
return getHeroType();
|
||||
return getHeroTypeID();
|
||||
}
|
||||
|
||||
int32_t CGHeroInstance::getIconIndex() const
|
||||
{
|
||||
return VLC->heroTypes()->getById(getPortraitSource())->getIconIndex();
|
||||
return getPortraitSource().toEntity(VLC)->getIconIndex();
|
||||
}
|
||||
|
||||
std::string CGHeroInstance::getNameTranslated() const
|
||||
@ -1126,15 +1136,15 @@ std::string CGHeroInstance::getClassNameTextID() const
|
||||
{
|
||||
if (isCampaignGem())
|
||||
return "core.genrltxt.735";
|
||||
return type->heroClass->getNameTextID();
|
||||
return getHeroClass()->getNameTextID();
|
||||
}
|
||||
|
||||
std::string CGHeroInstance::getNameTextID() const
|
||||
{
|
||||
if (!nameCustomTextId.empty())
|
||||
return nameCustomTextId;
|
||||
if (type)
|
||||
return type->getNameTextID();
|
||||
if (getHeroTypeID().hasValue())
|
||||
return getHeroType()->getNameTextID();
|
||||
|
||||
// FIXME: called by logging from some specialties (mods?) before type is set on deserialization
|
||||
// assert(0);
|
||||
@ -1150,8 +1160,8 @@ std::string CGHeroInstance::getBiographyTextID() const
|
||||
{
|
||||
if (!biographyCustomTextId.empty())
|
||||
return biographyCustomTextId;
|
||||
if (type)
|
||||
return type->getBiographyTextID();
|
||||
if (getHeroTypeID().hasValue())
|
||||
return getHeroType()->getBiographyTextID();
|
||||
|
||||
return ""; //for random hero
|
||||
}
|
||||
@ -1349,11 +1359,11 @@ std::vector<SecondarySkill> CGHeroInstance::getLevelUpProposedSecondarySkills(vs
|
||||
SecondarySkill selection;
|
||||
|
||||
if (selectWisdom)
|
||||
selection = type->heroClass->chooseSecSkill(intersect(options, wisdomList), rand);
|
||||
selection = getHeroClass()->chooseSecSkill(intersect(options, wisdomList), rand);
|
||||
else if (selectSchool)
|
||||
selection = type->heroClass->chooseSecSkill(intersect(options, schoolList), rand);
|
||||
selection = getHeroClass()->chooseSecSkill(intersect(options, schoolList), rand);
|
||||
else
|
||||
selection = type->heroClass->chooseSecSkill(options, rand);
|
||||
selection = getHeroClass()->chooseSecSkill(options, rand);
|
||||
|
||||
skills.push_back(selection);
|
||||
options.erase(selection);
|
||||
@ -1384,7 +1394,7 @@ PrimarySkill CGHeroInstance::nextPrimarySkill(vstd::RNG & rand) const
|
||||
{
|
||||
assert(gainsLevel());
|
||||
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())
|
||||
{
|
||||
@ -1524,25 +1534,15 @@ bool CGHeroInstance::hasVisions(const CGObjectInstance * target, BonusSubtypeID
|
||||
std::string CGHeroInstance::getHeroTypeName() const
|
||||
{
|
||||
if(ID == Obj::HERO || ID == Obj::PRISON)
|
||||
{
|
||||
if(type)
|
||||
{
|
||||
return type->getJsonKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
return getHeroType().toEntity(VLC)->getJsonKey();
|
||||
}
|
||||
}
|
||||
return getHeroType()->getJsonKey();
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void CGHeroInstance::afterAddToMap(CMap * map)
|
||||
{
|
||||
if(ID != Obj::PRISON)
|
||||
{
|
||||
map->heroesOnMap.emplace_back(this);
|
||||
}
|
||||
}
|
||||
void CGHeroInstance::afterRemoveFromMap(CMap* map)
|
||||
{
|
||||
@ -1729,8 +1729,7 @@ void CGHeroInstance::serializeJsonOptions(JsonSerializeFormat & handler)
|
||||
if(!appearance)
|
||||
{
|
||||
// crossoverDeserialize
|
||||
type = getHeroType().toHeroType();
|
||||
appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();
|
||||
appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, getHeroClassID())->getTemplates().front();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1817,7 +1816,7 @@ bool CGHeroInstance::isCampaignYog() const
|
||||
if (!boost::starts_with(campaign, "DATA/YOG")) // "Birth of a Barbarian"
|
||||
return false;
|
||||
|
||||
if (getHeroType() != HeroTypeID::SOLMYR) // Yog (based on Solmyr)
|
||||
if (getHeroTypeID() != HeroTypeID::SOLMYR) // Yog (based on Solmyr)
|
||||
return false;
|
||||
|
||||
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"
|
||||
return false;
|
||||
|
||||
if (getHeroType() != HeroTypeID::GEM) // Yog (based on Solmyr)
|
||||
if (getHeroTypeID() != HeroTypeID::GEM) // Yog (based on Solmyr)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -72,7 +72,6 @@ public:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const CHero * type;
|
||||
TExpType exp; //experience points
|
||||
ui32 level; //current level of hero
|
||||
|
||||
@ -171,7 +170,7 @@ public:
|
||||
const IOwnableObject * asOwnable() const final;
|
||||
|
||||
//INativeTerrainProvider
|
||||
FactionID getFaction() const override;
|
||||
FactionID getFactionID() const override;
|
||||
TerrainId getNativeTerrain() const override;
|
||||
int getLowestCreatureSpeed() const;
|
||||
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 initHero(vstd::RNG & rand);
|
||||
@ -352,7 +355,11 @@ public:
|
||||
h & skillsInfo;
|
||||
h & visitedTown;
|
||||
h & boat;
|
||||
h & type;
|
||||
if (h.version < Handler::Version::REMOVE_TOWN_PTR)
|
||||
{
|
||||
CHero * type = nullptr;
|
||||
h & type;
|
||||
}
|
||||
h & commander;
|
||||
h & visitedObjects;
|
||||
BONUS_TREE_DESERIALIZATION_FIX
|
||||
|
@ -45,7 +45,7 @@ int CGTownInstance::getSightRadius() const //returns sight distance
|
||||
|
||||
for(const auto & bid : builtBuildings)
|
||||
{
|
||||
auto height = town->buildings.at(bid)->height;
|
||||
auto height = getTown()->buildings.at(bid)->height;
|
||||
if(ret < height)
|
||||
ret = height;
|
||||
}
|
||||
@ -115,7 +115,7 @@ int CGTownInstance::mageGuildLevel() const
|
||||
|
||||
int CGTownInstance::getHordeLevel(const int & HID) const//HID - 0 or 1; returns creature level or -1 if that horde structure is not present
|
||||
{
|
||||
return town->hordeLvl.at(HID);
|
||||
return getTown()->hordeLvl.at(HID);
|
||||
}
|
||||
|
||||
int CGTownInstance::creatureGrowth(const int & level) const
|
||||
@ -127,7 +127,7 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
|
||||
{
|
||||
GrowthInfo ret;
|
||||
|
||||
if (level<0 || level >=town->creatures.size())
|
||||
if (level<0 || level >=getTown()->creatures.size())
|
||||
return ret;
|
||||
if (creatures[level].second.empty())
|
||||
return ret; //no dwelling
|
||||
@ -151,11 +151,11 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
|
||||
else if (hasBuilt(BuildingID::CITADEL))
|
||||
ret.entries.emplace_back(subID, BuildingID::CITADEL, castleBonus = base / 2);
|
||||
|
||||
if(town->hordeLvl.at(0) == level)//horde 1
|
||||
if(getTown()->hordeLvl.at(0) == level)//horde 1
|
||||
if(hasBuilt(BuildingID::HORDE_1))
|
||||
ret.entries.emplace_back(subID, BuildingID::HORDE_1, creature->getHorde());
|
||||
|
||||
if(town->hordeLvl.at(1) == level)//horde 2
|
||||
if(getTown()->hordeLvl.at(1) == level)//horde 2
|
||||
if(hasBuilt(BuildingID::HORDE_2))
|
||||
ret.entries.emplace_back(subID, BuildingID::HORDE_2, creature->getHorde());
|
||||
|
||||
@ -209,11 +209,11 @@ int CGTownInstance::getDwellingBonus(const std::vector<CreatureID>& creatureIds,
|
||||
TResources CGTownInstance::dailyIncome() const
|
||||
{
|
||||
TResources ret;
|
||||
for(const auto & p : town->buildings)
|
||||
for(const auto & p : getTown()->buildings)
|
||||
{
|
||||
BuildingID buildingUpgrade;
|
||||
|
||||
for(const auto & p2 : town->buildings)
|
||||
for(const auto & p2 : getTown()->buildings)
|
||||
{
|
||||
if (p2.second->upgrade == p.first)
|
||||
{
|
||||
@ -251,10 +251,10 @@ bool CGTownInstance::hasCapitol() const
|
||||
|
||||
TownFortifications CGTownInstance::fortificationsLevel() const
|
||||
{
|
||||
auto result = town->fortifications;
|
||||
auto result = getTown()->fortifications;
|
||||
|
||||
for (auto const & buildingID : builtBuildings)
|
||||
result += town->buildings.at(buildingID)->fortifications;
|
||||
result += getTown()->buildings.at(buildingID)->fortifications;
|
||||
|
||||
if (result.wallsHealth == 0)
|
||||
return TownFortifications();
|
||||
@ -264,7 +264,6 @@ TownFortifications CGTownInstance::fortificationsLevel() const
|
||||
|
||||
CGTownInstance::CGTownInstance(IGameCallback *cb):
|
||||
CGDwelling(cb),
|
||||
town(nullptr),
|
||||
built(0),
|
||||
destroyed(0),
|
||||
identifier(0),
|
||||
@ -379,17 +378,17 @@ void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const
|
||||
|
||||
std::string CGTownInstance::getObjectName() const
|
||||
{
|
||||
return getNameTranslated() + ", " + town->faction->getNameTranslated();
|
||||
return getNameTranslated() + ", " + getTown()->faction->getNameTranslated();
|
||||
}
|
||||
|
||||
bool CGTownInstance::townEnvisagesBuilding(BuildingSubID::EBuildingSubID subId) const
|
||||
{
|
||||
return town->getBuildingType(subId) != BuildingID::NONE;
|
||||
return getTown()->getBuildingType(subId) != BuildingID::NONE;
|
||||
}
|
||||
|
||||
void CGTownInstance::initializeConfigurableBuildings(vstd::RNG & rand)
|
||||
{
|
||||
for(const auto & kvp : town->buildings)
|
||||
for(const auto & kvp : getTown()->buildings)
|
||||
{
|
||||
if(!kvp.second->rewardableObjectInfo.getParameters().isNull())
|
||||
rewardableBuildings[kvp.first] = new TownRewardableBuildingInstance(this, kvp.second->bid, rand);
|
||||
@ -457,8 +456,7 @@ void CGTownInstance::pickRandomObject(vstd::RNG & rand)
|
||||
|
||||
assert(ID == Obj::TOWN); // just in case
|
||||
setType(ID, subID);
|
||||
town = (*VLC->townh)[getFaction()]->town;
|
||||
randomizeArmy(getFaction());
|
||||
randomizeArmy(getFactionID());
|
||||
updateAppearance();
|
||||
}
|
||||
|
||||
@ -467,19 +465,19 @@ void CGTownInstance::initObj(vstd::RNG & rand) ///initialize town structures
|
||||
blockVisit = true;
|
||||
|
||||
if(townEnvisagesBuilding(BuildingSubID::PORTAL_OF_SUMMONING)) //Dungeon for example
|
||||
creatures.resize(town->creatures.size() + 1);
|
||||
creatures.resize(getTown()->creatures.size() + 1);
|
||||
else
|
||||
creatures.resize(town->creatures.size());
|
||||
creatures.resize(getTown()->creatures.size());
|
||||
|
||||
for (int level = 0; level < town->creatures.size(); level++)
|
||||
for (int level = 0; level < getTown()->creatures.size(); level++)
|
||||
{
|
||||
BuildingID buildID = BuildingID(BuildingID::getDwellingFromLevel(level, 0));
|
||||
int upgradeNum = 0;
|
||||
|
||||
for (; town->buildings.count(buildID); upgradeNum++, BuildingID::advanceDwelling(buildID))
|
||||
for (; getTown()->buildings.count(buildID); upgradeNum++, BuildingID::advanceDwelling(buildID))
|
||||
{
|
||||
if (hasBuilt(buildID) && town->creatures.at(level).size() > upgradeNum)
|
||||
creatures[level].second.push_back(town->creatures[level][upgradeNum]);
|
||||
if (hasBuilt(buildID) && getTown()->creatures.at(level).size() > upgradeNum)
|
||||
creatures[level].second.push_back(getTown()->creatures[level][upgradeNum]);
|
||||
}
|
||||
}
|
||||
initializeConfigurableBuildings(rand);
|
||||
@ -623,9 +621,9 @@ void CGTownInstance::removeCapitols(const PlayerColor & owner) const
|
||||
if (hasCapitol()) // search if there's an older capitol
|
||||
{
|
||||
PlayerState* state = cb->gameState()->getPlayerState(owner); //get all towns owned by player
|
||||
for (const auto & town : state->getTowns())
|
||||
for (const auto & otherTown : state->getTowns())
|
||||
{
|
||||
if (town != this && town->hasCapitol())
|
||||
if (otherTown != this && otherTown->hasCapitol())
|
||||
{
|
||||
RazeStructures rs;
|
||||
rs.tid = id;
|
||||
@ -648,7 +646,7 @@ void CGTownInstance::clearArmy() const
|
||||
|
||||
BoatId CGTownInstance::getBoatType() const
|
||||
{
|
||||
return town->faction->boatType;
|
||||
return getTown()->faction->boatType;
|
||||
}
|
||||
|
||||
int CGTownInstance::getMarketEfficiency() const
|
||||
@ -703,7 +701,7 @@ void CGTownInstance::updateAppearance()
|
||||
|
||||
std::string CGTownInstance::nodeName() const
|
||||
{
|
||||
return "Town (" + (town ? town->faction->getNameTranslated() : "unknown") + ") of " + getNameTranslated();
|
||||
return "Town (" + getTown()->faction->getNameTranslated() + ") of " + getNameTranslated();
|
||||
}
|
||||
|
||||
void CGTownInstance::deserializationFix()
|
||||
@ -752,7 +750,7 @@ void CGTownInstance::recreateBuildingsBonuses()
|
||||
|
||||
for(const auto & upgradeID : builtBuildings)
|
||||
{
|
||||
const auto & upgrade = town->buildings.at(upgradeID);
|
||||
const auto & upgrade = getTown()->buildings.at(upgradeID);
|
||||
if (upgrade->getBase() == bid && upgrade->upgradeReplacesBonuses)
|
||||
bonusesReplacedByUpgrade = true;
|
||||
}
|
||||
@ -761,7 +759,7 @@ void CGTownInstance::recreateBuildingsBonuses()
|
||||
if (bonusesReplacedByUpgrade)
|
||||
continue;
|
||||
|
||||
auto building = town->buildings.at(bid);
|
||||
auto building = getTown()->buildings.at(bid);
|
||||
|
||||
if(building->buildingBonuses.empty())
|
||||
continue;
|
||||
@ -828,21 +826,6 @@ bool CGTownInstance::armedGarrison() const
|
||||
return !stacks.empty() || garrisonHero;
|
||||
}
|
||||
|
||||
const CTown * CGTownInstance::getTown() const
|
||||
{
|
||||
if(ID == Obj::RANDOM_TOWN)
|
||||
return VLC->townh->randomTown;
|
||||
else
|
||||
{
|
||||
if(nullptr == town)
|
||||
{
|
||||
return (*VLC->townh)[getFaction()]->town;
|
||||
}
|
||||
else
|
||||
return town;
|
||||
}
|
||||
}
|
||||
|
||||
int CGTownInstance::getTownLevel() const
|
||||
{
|
||||
// count all buildings that are not upgrades
|
||||
@ -850,7 +833,7 @@ int CGTownInstance::getTownLevel() const
|
||||
|
||||
for(const auto & bid : builtBuildings)
|
||||
{
|
||||
if(town->buildings.at(bid)->upgrade == BuildingID::NONE)
|
||||
if(getTown()->buildings.at(bid)->upgrade == BuildingID::NONE)
|
||||
level++;
|
||||
}
|
||||
return level;
|
||||
@ -892,7 +875,7 @@ bool CGTownInstance::hasBuilt(BuildingSubID::EBuildingSubID buildingID) const
|
||||
{
|
||||
for(const auto & bid : builtBuildings)
|
||||
{
|
||||
if(town->buildings.at(bid)->subId == buildingID)
|
||||
if(getTown()->buildings.at(bid)->subId == buildingID)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -905,7 +888,7 @@ bool CGTownInstance::hasBuilt(const BuildingID & buildingID) const
|
||||
|
||||
bool CGTownInstance::hasBuilt(const BuildingID & buildingID, FactionID townID) const
|
||||
{
|
||||
if (townID == town->faction->getId() || townID == FactionID::ANY)
|
||||
if (townID == getTown()->faction->getId() || townID == FactionID::ANY)
|
||||
return hasBuilt(buildingID);
|
||||
return false;
|
||||
}
|
||||
@ -923,7 +906,7 @@ std::set<EMarketMode> CGTownInstance::availableModes() const
|
||||
std::set<EMarketMode> result;
|
||||
for (const auto & buildingID : builtBuildings)
|
||||
{
|
||||
const auto * buildingPtr = town->buildings.at(buildingID).get();
|
||||
const auto * buildingPtr = getTown()->buildings.at(buildingID).get();
|
||||
result.insert(buildingPtr->marketModes.begin(), buildingPtr->marketModes.end());
|
||||
}
|
||||
|
||||
@ -950,8 +933,8 @@ std::set<BuildingID> CGTownInstance::getBuildings() const
|
||||
|
||||
TResources CGTownInstance::getBuildingCost(const BuildingID & buildingID) const
|
||||
{
|
||||
if (vstd::contains(town->buildings, buildingID))
|
||||
return town->buildings.at(buildingID)->resources;
|
||||
if (vstd::contains(getTown()->buildings, buildingID))
|
||||
return getTown()->buildings.at(buildingID)->resources;
|
||||
else
|
||||
{
|
||||
logGlobal->error("Town %s at %s has no possible building %d!", getNameTranslated(), 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
|
||||
{
|
||||
const CBuilding * building = town->buildings.at(buildID);
|
||||
const CBuilding * building = getTown()->buildings.at(buildID);
|
||||
|
||||
//TODO: find better solution to prevent infinite loops
|
||||
std::set<BuildingID> processed;
|
||||
@ -970,13 +953,13 @@ CBuilding::TRequired CGTownInstance::genBuildingRequirements(const BuildingID &
|
||||
std::function<CBuilding::TRequired::Variant(const BuildingID &)> dependTest =
|
||||
[&](const BuildingID & id) -> CBuilding::TRequired::Variant
|
||||
{
|
||||
if (town->buildings.count(id) == 0)
|
||||
if (getTown()->buildings.count(id) == 0)
|
||||
{
|
||||
logMod->error("Invalid building ID %d in building dependencies!", id.getNum());
|
||||
return CBuilding::TRequired::OperatorAll();
|
||||
}
|
||||
|
||||
const CBuilding * build = town->buildings.at(id);
|
||||
const CBuilding * build = getTown()->buildings.at(id);
|
||||
CBuilding::TRequired::OperatorAll requirements;
|
||||
|
||||
if (!hasBuilt(id))
|
||||
@ -1001,7 +984,7 @@ CBuilding::TRequired CGTownInstance::genBuildingRequirements(const BuildingID &
|
||||
CBuilding::TRequired::OperatorAll requirements;
|
||||
if (building->upgrade != BuildingID::NONE)
|
||||
{
|
||||
const CBuilding * upgr = town->buildings.at(building->upgrade);
|
||||
const CBuilding * upgr = getTown()->buildings.at(building->upgrade);
|
||||
|
||||
requirements.expressions.push_back(dependTest(upgr->bid));
|
||||
processed.clear();
|
||||
@ -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
|
||||
{
|
||||
return town->faction->getNativeTerrain();
|
||||
return getTown()->faction->getNativeTerrain();
|
||||
}
|
||||
|
||||
ArtifactID CGTownInstance::getWarMachineInBuilding(BuildingID building) const
|
||||
@ -1166,21 +1162,21 @@ ArtifactID CGTownInstance::getWarMachineInBuilding(BuildingID building) const
|
||||
if (builtBuildings.count(building) == 0)
|
||||
return ArtifactID::NONE;
|
||||
|
||||
if (building == BuildingID::BLACKSMITH && town->warMachineDeprecated.hasValue())
|
||||
return town->warMachineDeprecated.toCreature()->warMachine;
|
||||
if (building == BuildingID::BLACKSMITH && getTown()->warMachineDeprecated.hasValue())
|
||||
return getTown()->warMachineDeprecated.toCreature()->warMachine;
|
||||
|
||||
return town->buildings.at(building)->warMachine;
|
||||
return getTown()->buildings.at(building)->warMachine;
|
||||
}
|
||||
|
||||
bool CGTownInstance::isWarMachineAvailable(ArtifactID warMachine) const
|
||||
{
|
||||
for (auto const & buildingID : builtBuildings)
|
||||
if (town->buildings.at(buildingID)->warMachine == warMachine)
|
||||
if (getTown()->buildings.at(buildingID)->warMachine == warMachine)
|
||||
return true;
|
||||
|
||||
if (builtBuildings.count(BuildingID::BLACKSMITH) &&
|
||||
town->warMachineDeprecated.hasValue() &&
|
||||
town->warMachineDeprecated.toCreature()->warMachine == warMachine)
|
||||
getTown()->warMachineDeprecated.hasValue() &&
|
||||
getTown()->warMachineDeprecated.toCreature()->warMachine == warMachine)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -1200,7 +1196,7 @@ GrowthInfo::Entry::Entry(int subID, const BuildingID & building, int _count): co
|
||||
{
|
||||
MetaString formatter;
|
||||
formatter.appendRawString("%s %+d");
|
||||
formatter.replaceRawString((*VLC->townh)[subID]->town->buildings.at(building)->getNameTranslated());
|
||||
formatter.replaceRawString(FactionID(subID).toFaction()->town->buildings.at(building)->getNameTranslated());
|
||||
formatter.replacePositiveNumber(count);
|
||||
|
||||
description = formatter.toString();
|
||||
|
@ -50,6 +50,7 @@ struct DLL_LINKAGE GrowthInfo
|
||||
|
||||
class DLL_LINKAGE CGTownInstance : public CGDwelling, public IShipyard, public IMarket, public INativeTerrainProvider, public ICreatureUpgrader
|
||||
{
|
||||
friend class CTownInstanceConstructor;
|
||||
std::string nameTextId; // name of town
|
||||
|
||||
std::map<BuildingID, TownRewardableBuildingInstance*> convertOldBuildings(std::vector<TownRewardableBuildingInstance*> oldVector);
|
||||
@ -59,7 +60,6 @@ public:
|
||||
enum EFortLevel {NONE = 0, FORT = 1, CITADEL = 2, CASTLE = 3};
|
||||
|
||||
CTownAndVisitingHero townAndVis;
|
||||
const CTown * town;
|
||||
si32 built; //how many buildings has been built this turn
|
||||
si32 destroyed; //how many buildings has been destroyed this turn
|
||||
ConstTransitivePtr<CGHeroInstance> garrisonHero, visitingHero;
|
||||
@ -112,16 +112,21 @@ public:
|
||||
rewardableBuildings = convertOldBuildings(oldVector);
|
||||
}
|
||||
|
||||
if (h.saving)
|
||||
if (h.version < Handler::Version::REMOVE_TOWN_PTR)
|
||||
{
|
||||
CFaction * faction = town ? town->faction : nullptr;
|
||||
h & faction;
|
||||
}
|
||||
else
|
||||
{
|
||||
CFaction * faction = nullptr;
|
||||
h & faction;
|
||||
town = faction ? faction->town : nullptr;
|
||||
CTown * town = nullptr;
|
||||
|
||||
if (h.saving)
|
||||
{
|
||||
CFaction * faction = town ? town->faction : nullptr;
|
||||
h & faction;
|
||||
}
|
||||
else
|
||||
{
|
||||
CFaction * faction = nullptr;
|
||||
h & faction;
|
||||
town = faction ? faction->town : nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
h & townAndVis;
|
||||
@ -213,9 +218,10 @@ public:
|
||||
DamageRange getKeepDamageRange() const;
|
||||
|
||||
const CTown * getTown() const;
|
||||
const CFaction * getFaction() const;
|
||||
|
||||
/// INativeTerrainProvider
|
||||
FactionID getFaction() const override;
|
||||
FactionID getFactionID() 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
|
||||
|
@ -431,7 +431,7 @@ void CGSeerHut::setObjToKill()
|
||||
|
||||
if(getCreatureToKill(true))
|
||||
{
|
||||
quest->stackToKill = getCreatureToKill(false)->getCreature();
|
||||
quest->stackToKill = getCreatureToKill(false)->getCreatureID();
|
||||
assert(quest->stackToKill != CreatureID::NONE);
|
||||
quest->stackDirection = checkDirection();
|
||||
}
|
||||
|
@ -73,14 +73,14 @@ TownRewardableBuildingInstance::TownRewardableBuildingInstance(CGTownInstance *
|
||||
|
||||
void TownRewardableBuildingInstance::initObj(vstd::RNG & rand)
|
||||
{
|
||||
assert(town && town->town);
|
||||
assert(town && town->getTown());
|
||||
configuration = generateConfiguration(rand);
|
||||
}
|
||||
|
||||
Rewardable::Configuration TownRewardableBuildingInstance::generateConfiguration(vstd::RNG & rand) const
|
||||
{
|
||||
Rewardable::Configuration result;
|
||||
auto building = town->town->buildings.at(getBuildingType());
|
||||
auto building = town->getTown()->buildings.at(getBuildingType());
|
||||
|
||||
building->rewardableObjectInfo.configureObject(result, rand, cb);
|
||||
for(auto & rewardInfo : result.info)
|
||||
|
Reference in New Issue
Block a user