1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-11 11:31:52 +02:00

Removed pointer to VLC entity from CStackBasicDescriptor

This commit is contained in:
Ivan Savenko 2024-10-12 16:02:35 +00:00
parent c98ac01e7a
commit d3af9f1c67
38 changed files with 140 additions and 160 deletions

View File

@ -1129,10 +1129,10 @@ void AIGateway::recruitCreatures(const CGDwelling * d, const CArmedInstance * re
{ {
for(auto stack : recruiter->Slots()) for(auto stack : recruiter->Slots())
{ {
if(!stack.second->type) if(!stack.second->getType())
continue; continue;
auto duplicatingSlot = recruiter->getSlotFor(stack.second->type); auto duplicatingSlot = recruiter->getSlotFor(stack.second->getCreature());
if(duplicatingSlot != stack.first) if(duplicatingSlot != stack.first)
{ {

View File

@ -312,7 +312,7 @@ int getDuplicatingSlots(const CArmedInstance * army)
for(auto stack : army->Slots()) for(auto stack : army->Slots())
{ {
if(stack.second->type && army->getSlotFor(stack.second->type) != stack.first) if(stack.second->getCreature() && army->getSlotFor(stack.second->getCreature()) != stack.first)
duplicatingSlots++; duplicatingSlots++;
} }
@ -387,7 +387,7 @@ bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObject
{ {
for(auto slot : h->Slots()) for(auto slot : h->Slots())
{ {
if(slot.second->type->hasUpgrades()) if(slot.second->getType()->hasUpgrades())
return true; //TODO: check price? return true; //TODO: check price?
} }
return false; return false;

View File

@ -90,7 +90,7 @@ std::vector<SlotInfo> ArmyManager::getSortedSlots(const CCreatureSet * target, c
{ {
for(auto & i : armyPtr->Slots()) for(auto & i : armyPtr->Slots())
{ {
auto cre = dynamic_cast<const CCreature*>(i.second->type); auto cre = dynamic_cast<const CCreature*>(i.second->getType());
auto & slotInfp = creToPower[cre]; auto & slotInfp = creToPower[cre];
slotInfp.creature = cre; slotInfp.creature = cre;

View File

@ -155,10 +155,10 @@ uint64_t getCreatureBankArmyReward(const CGObjectInstance * target, const CGHero
for (auto c : creatures) for (auto c : creatures)
{ {
//Only if hero has slot for this creature in the army //Only if hero has slot for this creature in the army
auto ccre = dynamic_cast<const CCreature*>(c.data.type); auto ccre = dynamic_cast<const CCreature*>(c.data.getType());
if (hero->getSlotFor(ccre).validSlot() || duplicatingSlots > 0) if (hero->getSlotFor(ccre).validSlot() || duplicatingSlots > 0)
{ {
result += (c.data.type->getAIValue() * c.data.count) * c.chance; result += (c.data.getType()->getAIValue() * c.data.count) * c.chance;
} }
/*else /*else
{ {

View File

@ -36,7 +36,7 @@ std::vector<SlotInfo> ArmyManager::getSortedSlots(const CCreatureSet * target, c
{ {
for(auto & i : armyPtr->Slots()) for(auto & i : armyPtr->Slots())
{ {
auto cre = dynamic_cast<const CCreature*>(i.second->type); auto cre = dynamic_cast<const CCreature*>(i.second->getType());
auto & slotInfp = creToPower[cre]; auto & slotInfp = creToPower[cre];
slotInfp.creature = cre; slotInfp.creature = cre;

View File

@ -162,7 +162,7 @@ TGoalVec CompleteQuest::missionArmy() const
for(auto creature : q.quest->mission.creatures) for(auto creature : q.quest->mission.creatures)
{ {
solutions.push_back(sptr(GatherTroops(creature.type->getId(), creature.count))); solutions.push_back(sptr(GatherTroops(creature.getId(), creature.count)));
} }
return solutions; return solutions;

View File

@ -2818,7 +2818,7 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj)
{ {
for(auto slot : h->Slots()) for(auto slot : h->Slots())
{ {
if(slot.second->type->hasUpgrades()) if(slot.second->getType()->hasUpgrades())
return true; //TODO: check price? return true; //TODO: check price?
} }
return false; return false;

View File

@ -373,7 +373,7 @@ void CGarrisonSlot::gesture(bool on, const Point & initialPosition, const Point
const auto * otherArmy = upg == EGarrisonType::UPPER ? owner->lowerArmy() : owner->upperArmy(); const auto * otherArmy = upg == EGarrisonType::UPPER ? owner->lowerArmy() : owner->upperArmy();
bool stackExists = myStack != nullptr; bool stackExists = myStack != nullptr;
bool hasSameUnit = stackExists && !owner->army(upg)->getCreatureSlots(myStack->type, ID).empty(); bool hasSameUnit = stackExists && !owner->army(upg)->getCreatureSlots(myStack->getCreature(), ID).empty();
bool hasOwnEmptySlots = stackExists && owner->army(upg)->getFreeSlot() != SlotID(); bool hasOwnEmptySlots = stackExists && owner->army(upg)->getFreeSlot() != SlotID();
bool exchangeMode = stackExists && owner->upperArmy() && owner->lowerArmy(); bool exchangeMode = stackExists && owner->upperArmy() && owner->lowerArmy();
bool hasOtherEmptySlots = exchangeMode && otherArmy->getFreeSlot() != SlotID(); bool hasOtherEmptySlots = exchangeMode && otherArmy->getFreeSlot() != SlotID();
@ -398,7 +398,7 @@ void CGarrisonSlot::update()
{ {
addUsedEvents(LCLICK | SHOW_POPUP | GESTURE | HOVER); addUsedEvents(LCLICK | SHOW_POPUP | GESTURE | HOVER);
myStack = getObj()->getStackPtr(ID); myStack = getObj()->getStackPtr(ID);
creature = myStack ? myStack->type : nullptr; creature = myStack ? myStack->getCreature() : nullptr;
} }
else else
{ {
@ -426,7 +426,7 @@ CGarrisonSlot::CGarrisonSlot(CGarrisonInt * Owner, int x, int y, SlotID IID, EGa
: ID(IID), : ID(IID),
owner(Owner), owner(Owner),
myStack(creature_), myStack(creature_),
creature(creature_ ? creature_->type : nullptr), creature(creature_ ? creature_->getCreature() : nullptr),
upg(Upg) upg(Upg)
{ {
OBJECT_CONSTRUCTION; OBJECT_CONSTRUCTION;

View File

@ -280,7 +280,7 @@ void CArmyTooltip::init(const InfoAboutArmy &army)
continue; continue;
} }
icons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("CPRSMALL"), slot.second.type->getIconIndex(), 0, slotsPos[slot.first.getNum()].x, slotsPos[slot.first.getNum()].y)); icons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("CPRSMALL"), slot.second.getType()->getIconIndex(), 0, slotsPos[slot.first.getNum()].x, slotsPos[slot.first.getNum()].y));
std::string subtitle; std::string subtitle;
if(army.army.isDetailed) if(army.army.isDetailed)

View File

@ -89,7 +89,7 @@ public:
std::string getName() const std::string getName() const
{ {
if(commander) if(commander)
return commander->type->getNameSingularTranslated(); return commander->getType()->getNameSingularTranslated();
else else
return creature->getNamePluralTranslated(); return creature->getNamePluralTranslated();
} }
@ -695,7 +695,7 @@ CStackWindow::CStackWindow(const CStackInstance * stack, bool popup)
info(new UnitView()) info(new UnitView())
{ {
info->stackNode = stack; info->stackNode = stack;
info->creature = stack->type; info->creature = stack->getCreature();
info->creatureCount = stack->count; info->creatureCount = stack->count;
info->popupWindow = popup; info->popupWindow = popup;
info->owner = dynamic_cast<const CGHeroInstance *> (stack->armyObj); info->owner = dynamic_cast<const CGHeroInstance *> (stack->armyObj);
@ -707,7 +707,7 @@ CStackWindow::CStackWindow(const CStackInstance * stack, std::function<void()> d
info(new UnitView()) info(new UnitView())
{ {
info->stackNode = stack; info->stackNode = stack;
info->creature = stack->type; info->creature = stack->getCreature();
info->creatureCount = stack->count; info->creatureCount = stack->count;
info->upgradeInfo = std::make_optional(UnitView::StackUpgradeInfo()); info->upgradeInfo = std::make_optional(UnitView::StackUpgradeInfo());
@ -724,7 +724,7 @@ CStackWindow::CStackWindow(const CCommanderInstance * commander, bool popup)
info(new UnitView()) info(new UnitView())
{ {
info->stackNode = commander; info->stackNode = commander;
info->creature = commander->type; info->creature = commander->getCreature();
info->commander = commander; info->commander = commander;
info->creatureCount = 1; info->creatureCount = 1;
info->popupWindow = popup; info->popupWindow = popup;
@ -737,7 +737,7 @@ CStackWindow::CStackWindow(const CCommanderInstance * commander, std::vector<ui3
info(new UnitView()) info(new UnitView())
{ {
info->stackNode = commander; info->stackNode = commander;
info->creature = commander->type; info->creature = commander->getCreature();
info->commander = commander; info->commander = commander;
info->creatureCount = 1; info->creatureCount = 1;
info->levelupInfo = std::make_optional(UnitView::CommanderLevelInfo()); info->levelupInfo = std::make_optional(UnitView::CommanderLevelInfo());
@ -869,7 +869,7 @@ std::string CStackWindow::generateStackExpDescription()
const CStackInstance * stack = info->stackNode; const CStackInstance * stack = info->stackNode;
const CCreature * creature = info->creature; const CCreature * creature = info->creature;
int tier = stack->type->getLevel(); int tier = stack->getType()->getLevel();
int rank = stack->getExpRank(); int rank = stack->getExpRank();
if (!vstd::iswithin(tier, 1, 7)) if (!vstd::iswithin(tier, 1, 7))
tier = 0; tier = 0;

View File

@ -1056,7 +1056,7 @@ CGarrisonWindow::CGarrisonWindow(const CArmedInstance * up, const CGHeroInstance
if(up->Slots().size() > 0) if(up->Slots().size() > 0)
{ {
titleText = CGI->generaltexth->allTexts[35]; titleText = CGI->generaltexth->allTexts[35];
boost::algorithm::replace_first(titleText, "%s", up->Slots().begin()->second->type->getNamePluralTranslated()); boost::algorithm::replace_first(titleText, "%s", up->Slots().begin()->second->getType()->getNamePluralTranslated());
} }
else else
{ {

View File

@ -343,11 +343,6 @@ bool CCreature::isMyUpgrade(const CCreature *anotherCre) const
return vstd::contains(upgrades, anotherCre->getId()); return vstd::contains(upgrades, anotherCre->getId());
} }
bool CCreature::valid() const
{
return this == (*VLC->creh)[idNumber];
}
std::string CCreature::nodeName() const std::string CCreature::nodeName() const
{ {
return "\"" + getNamePluralTextID() + "\""; return "\"" + getNamePluralTextID() + "\"";

View File

@ -166,8 +166,6 @@ public:
static int estimateCreatureCount(ui32 countID); //reverse version of above function, returns middle of range static int estimateCreatureCount(ui32 countID); //reverse version of above function, returns middle of range
bool isMyUpgrade(const CCreature *anotherCre) const; bool isMyUpgrade(const CCreature *anotherCre) const;
bool valid() const;
void addBonus(int val, BonusType type); void addBonus(int val, BonusType type);
void addBonus(int val, BonusType type, BonusSubtypeID subtype); void addBonus(int val, BonusType type, BonusSubtypeID subtype);
std::string nodeName() const override; std::string nodeName() const override;

View File

@ -48,7 +48,7 @@ const CCreature * CCreatureSet::getCreature(const SlotID & slot) const
{ {
auto i = stacks.find(slot); auto i = stacks.find(slot);
if (i != stacks.end()) if (i != stacks.end())
return i->second->type; return i->second->getCreature();
else else
return nullptr; return nullptr;
} }
@ -84,11 +84,10 @@ SlotID CCreatureSet::getSlotFor(const CreatureID & creature, ui32 slotsAmount) c
SlotID CCreatureSet::getSlotFor(const CCreature *c, ui32 slotsAmount) const SlotID CCreatureSet::getSlotFor(const CCreature *c, ui32 slotsAmount) const
{ {
assert(c && c->valid()); assert(c);
for(const auto & elem : stacks) for(const auto & elem : stacks)
{ {
assert(elem.second->type->valid()); if(elem.second->getType() == c)
if(elem.second->type == c)
{ {
return elem.first; //if there is already such creature we return its slot id return elem.first; //if there is already such creature we return its slot id
} }
@ -98,18 +97,16 @@ SlotID CCreatureSet::getSlotFor(const CCreature *c, ui32 slotsAmount) const
bool CCreatureSet::hasCreatureSlots(const CCreature * c, const SlotID & exclude) const bool CCreatureSet::hasCreatureSlots(const CCreature * c, const SlotID & exclude) const
{ {
assert(c && c->valid()); assert(c);
for(const auto & elem : stacks) // elem is const for(const auto & elem : stacks) // elem is const
{ {
if(elem.first == exclude) // Check slot if(elem.first == exclude) // Check slot
continue; continue;
if(!elem.second || !elem.second->type) // Check creature if(!elem.second || !elem.second->getType()) // Check creature
continue; continue;
assert(elem.second->type->valid()); if(elem.second->getType() == c)
if(elem.second->type == c)
return true; return true;
} }
return false; return false;
@ -117,7 +114,7 @@ bool CCreatureSet::hasCreatureSlots(const CCreature * c, const SlotID & exclude)
std::vector<SlotID> CCreatureSet::getCreatureSlots(const CCreature * c, const SlotID & exclude, TQuantity ignoreAmount) const std::vector<SlotID> CCreatureSet::getCreatureSlots(const CCreature * c, const SlotID & exclude, TQuantity ignoreAmount) const
{ {
assert(c && c->valid()); assert(c);
std::vector<SlotID> result; std::vector<SlotID> result;
for(const auto & elem : stacks) for(const auto & elem : stacks)
@ -125,13 +122,12 @@ std::vector<SlotID> CCreatureSet::getCreatureSlots(const CCreature * c, const Sl
if(elem.first == exclude) if(elem.first == exclude)
continue; continue;
if(!elem.second || !elem.second->type || elem.second->type != c) if(!elem.second || !elem.second->getType() || elem.second->getType() != c)
continue; continue;
if(elem.second->count == ignoreAmount || elem.second->count < 1) if(elem.second->count == ignoreAmount || elem.second->count < 1)
continue; continue;
assert(elem.second->type->valid());
result.push_back(elem.first); result.push_back(elem.first);
} }
return result; return result;
@ -139,13 +135,13 @@ std::vector<SlotID> CCreatureSet::getCreatureSlots(const CCreature * c, const Sl
bool CCreatureSet::isCreatureBalanced(const CCreature * c, TQuantity ignoreAmount) const bool CCreatureSet::isCreatureBalanced(const CCreature * c, TQuantity ignoreAmount) const
{ {
assert(c && c->valid()); assert(c);
TQuantity max = 0; TQuantity max = 0;
auto min = std::numeric_limits<TQuantity>::max(); auto min = std::numeric_limits<TQuantity>::max();
for(const auto & elem : stacks) for(const auto & elem : stacks)
{ {
if(!elem.second || !elem.second->type || elem.second->type != c) if(!elem.second || !elem.second->getType() || elem.second->getType() != c)
continue; continue;
const auto count = elem.second->count; const auto count = elem.second->count;
@ -153,7 +149,6 @@ bool CCreatureSet::isCreatureBalanced(const CCreature * c, TQuantity ignoreAmoun
if(count == ignoreAmount || count < 1) if(count == ignoreAmount || count < 1)
continue; continue;
assert(elem.second->type->valid());
if(count > max) if(count > max)
max = count; max = count;
@ -214,7 +209,7 @@ TMapCreatureSlot CCreatureSet::getCreatureMap() const
// https://www.cplusplus.com/reference/map/map/key_comp/ // https://www.cplusplus.com/reference/map/map/key_comp/
for(const auto & pair : stacks) for(const auto & pair : stacks)
{ {
const auto * creature = pair.second->type; const auto * creature = pair.second->getCreature();
auto slot = pair.first; auto slot = pair.first;
auto lb = creatureMap.lower_bound(creature); auto lb = creatureMap.lower_bound(creature);
@ -234,7 +229,7 @@ TCreatureQueue CCreatureSet::getCreatureQueue(const SlotID & exclude) const
{ {
if(pair.first == exclude) if(pair.first == exclude)
continue; continue;
creatureQueue.push(std::make_pair(pair.second->type, pair.first)); creatureQueue.push(std::make_pair(pair.second->getCreature(), pair.first));
} }
return creatureQueue; return creatureQueue;
} }
@ -262,10 +257,10 @@ bool CCreatureSet::mergeableStacks(std::pair<SlotID, SlotID> & out, const SlotID
//try to match creature to our preferred stack //try to match creature to our preferred stack
if(preferable.validSlot() && vstd::contains(stacks, preferable)) if(preferable.validSlot() && vstd::contains(stacks, preferable))
{ {
const CCreature *cr = stacks.find(preferable)->second->type; const CCreature *cr = stacks.find(preferable)->second->getCreature();
for(const auto & elem : stacks) for(const auto & elem : stacks)
{ {
if(cr == elem.second->type && elem.first != preferable) if(cr == elem.second->getType() && elem.first != preferable)
{ {
out.first = preferable; out.first = preferable;
out.second = elem.first; out.second = elem.first;
@ -278,7 +273,7 @@ bool CCreatureSet::mergeableStacks(std::pair<SlotID, SlotID> & out, const SlotID
{ {
for(const auto & elem : stacks) for(const auto & elem : stacks)
{ {
if(stack.second->type == elem.second->type && stack.first != elem.first) if(stack.second->getType() == elem.second->getType() && stack.first != elem.first)
{ {
out.first = stack.first; out.first = stack.first;
out.second = elem.first; out.second = elem.first;
@ -328,7 +323,7 @@ void CCreatureSet::addToSlot(const SlotID & slot, CStackInstance * stack, bool a
{ {
putStack(slot, stack); putStack(slot, stack);
} }
else if(allowMerging && stack->type == getCreature(slot)) else if(allowMerging && stack->getType() == getCreature(slot))
{ {
joinStack(slot, stack); joinStack(slot, stack);
} }
@ -514,7 +509,7 @@ void CCreatureSet::putStack(const SlotID & slot, CStackInstance * stack)
void CCreatureSet::joinStack(const SlotID & slot, CStackInstance * stack) void CCreatureSet::joinStack(const SlotID & slot, CStackInstance * stack)
{ {
[[maybe_unused]] const CCreature *c = getCreature(slot); [[maybe_unused]] const CCreature *c = getCreature(slot);
assert(c == stack->type); assert(c == stack->getType());
assert(c); assert(c);
//TODO move stuff //TODO move stuff
@ -577,9 +572,9 @@ bool CCreatureSet::canBeMergedWith(const CCreatureSet &cs, bool allowMergingStac
std::set<const CCreature*> cresToAdd; std::set<const CCreature*> cresToAdd;
for(const auto & elem : cs.stacks) for(const auto & elem : cs.stacks)
{ {
SlotID dest = getSlotFor(elem.second->type); SlotID dest = getSlotFor(elem.second->getCreature());
if(!dest.validSlot() || hasStackAtSlot(dest)) if(!dest.validSlot() || hasStackAtSlot(dest))
cresToAdd.insert(elem.second->type); cresToAdd.insert(elem.second->getCreature());
} }
return cresToAdd.size() <= freeSlots; return cresToAdd.size() <= freeSlots;
} }
@ -590,13 +585,13 @@ bool CCreatureSet::canBeMergedWith(const CCreatureSet &cs, bool allowMergingStac
//get types of creatures that need their own slot //get types of creatures that need their own slot
for(const auto & elem : cs.stacks) for(const auto & elem : cs.stacks)
if ((j = cres.getSlotFor(elem.second->type)).validSlot()) if ((j = cres.getSlotFor(elem.second->getCreature())).validSlot())
cres.addToSlot(j, elem.second->type->getId(), 1, true); //merge if possible cres.addToSlot(j, elem.second->getId(), 1, true); //merge if possible
//cres.addToSlot(elem.first, elem.second->type->getId(), 1, true); //cres.addToSlot(elem.first, elem.second->type->getId(), 1, true);
for(const auto & elem : stacks) for(const auto & elem : stacks)
{ {
if ((j = cres.getSlotFor(elem.second->type)).validSlot()) if ((j = cres.getSlotFor(elem.second->getCreature())).validSlot())
cres.addToSlot(j, elem.second->type->getId(), 1, true); //merge if possible cres.addToSlot(j, elem.second->getId(), 1, true); //merge if possible
else else
return false; //no place found return false; //no place found
} }
@ -693,7 +688,7 @@ void CStackInstance::init()
{ {
experience = 0; experience = 0;
count = 0; count = 0;
type = nullptr; setType(nullptr);
_armyObj = nullptr; _armyObj = nullptr;
setNodeType(STACK_INSTANCE); setNodeType(STACK_INSTANCE);
} }
@ -707,7 +702,7 @@ int CStackInstance::getExpRank() const
{ {
if (!VLC->engineSettings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE)) if (!VLC->engineSettings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE))
return 0; return 0;
int tier = type->getLevel(); int tier = getType()->getLevel();
if (vstd::iswithin(tier, 1, 7)) if (vstd::iswithin(tier, 1, 7))
{ {
for(int i = static_cast<int>(VLC->creh->expRanks[tier].size()) - 2; i > -1; --i) //sic! for(int i = static_cast<int>(VLC->creh->expRanks[tier].size()) - 2; i > -1; --i) //sic!
@ -730,12 +725,12 @@ int CStackInstance::getExpRank() const
int CStackInstance::getLevel() const int CStackInstance::getLevel() const
{ {
return std::max(1, static_cast<int>(type->getLevel())); return std::max(1, static_cast<int>(getType()->getLevel()));
} }
void CStackInstance::giveStackExp(TExpType exp) void CStackInstance::giveStackExp(TExpType exp)
{ {
int level = type->getLevel(); int level = getType()->getLevel();
if (!vstd::iswithin(level, 1, 7)) if (!vstd::iswithin(level, 1, 7))
level = 0; level = 0;
@ -756,17 +751,17 @@ void CStackInstance::setType(const CreatureID & creID)
void CStackInstance::setType(const CCreature *c) void CStackInstance::setType(const CCreature *c)
{ {
if(type) if(getCreature())
{ {
detachFromSource(*type); detachFromSource(*getCreature());
if (type->isMyUpgrade(c) && VLC->engineSettings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE)) if (getCreature()->isMyUpgrade(c) && VLC->engineSettings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE))
experience = static_cast<TExpType>(experience * VLC->creh->expAfterUpgrade / 100.0); experience = static_cast<TExpType>(experience * VLC->creh->expAfterUpgrade / 100.0);
} }
CStackBasicDescriptor::setType(c); CStackBasicDescriptor::setType(c);
if(type) if(getCreature())
attachToSource(*type); attachToSource(*getCreature());
} }
std::string CStackInstance::bonusToString(const std::shared_ptr<Bonus>& bonus, bool description) const std::string CStackInstance::bonusToString(const std::shared_ptr<Bonus>& bonus, bool description) const
{ {
@ -808,7 +803,7 @@ bool CStackInstance::valid(bool allowUnrandomized) const
{ {
if(!randomStack) if(!randomStack)
{ {
return (type && type == type->getId().toEntity(VLC)); return (getType() && getType() == getId().toEntity(VLC));
} }
else else
return allowUnrandomized; return allowUnrandomized;
@ -818,8 +813,8 @@ std::string CStackInstance::nodeName() const
{ {
std::ostringstream oss; std::ostringstream oss;
oss << "Stack of " << count << " of "; oss << "Stack of " << count << " of ";
if(type) if(getType())
oss << type->getNamePluralTextID(); oss << getType()->getNamePluralTextID();
else else
oss << "[UNDEFINED TYPE]"; oss << "[UNDEFINED TYPE]";
@ -841,21 +836,21 @@ void CStackInstance::deserializationFix()
CreatureID CStackInstance::getCreatureID() const CreatureID CStackInstance::getCreatureID() const
{ {
if(type) if(getType())
return type->getId(); return getType()->getId();
else else
return CreatureID::NONE; return CreatureID::NONE;
} }
std::string CStackInstance::getName() const std::string CStackInstance::getName() const
{ {
return (count > 1) ? type->getNamePluralTranslated() : type->getNameSingularTranslated(); return (count > 1) ? getType()->getNamePluralTranslated() : getType()->getNameSingularTranslated();
} }
ui64 CStackInstance::getPower() const ui64 CStackInstance::getPower() const
{ {
assert(type); assert(getType());
return static_cast<ui64>(type->getAIValue()) * count; return static_cast<ui64>(getType()->getAIValue()) * count;
} }
ArtBearer::ArtBearer CStackInstance::bearerType() const ArtBearer::ArtBearer CStackInstance::bearerType() const
@ -899,7 +894,7 @@ void CStackInstance::serializeJson(JsonSerializeFormat & handler)
else else
{ {
//type set by CStackBasicDescriptor::serializeJson //type set by CStackBasicDescriptor::serializeJson
if(type == nullptr) if(getType() == nullptr)
{ {
uint8_t level = 0; uint8_t level = 0;
uint8_t upgrade = 0; uint8_t upgrade = 0;
@ -914,8 +909,8 @@ void CStackInstance::serializeJson(JsonSerializeFormat & handler)
FactionID CStackInstance::getFactionID() const FactionID CStackInstance::getFactionID() const
{ {
if(type) if(getType())
return type->getFactionID(); return getType()->getFactionID();
return FactionID::NEUTRAL; return FactionID::NEUTRAL;
} }
@ -943,7 +938,7 @@ void CCommanderInstance::init()
experience = 0; experience = 0;
level = 1; level = 1;
count = 1; count = 1;
type = nullptr; setType(nullptr);
_armyObj = nullptr; _armyObj = nullptr;
setNodeType (CBonusSystemNode::COMMANDER); setNodeType (CBonusSystemNode::COMMANDER);
secondarySkills.resize (ECommander::SPELL_POWER + 1); secondarySkills.resize (ECommander::SPELL_POWER + 1);
@ -998,24 +993,29 @@ bool CCommanderInstance::gainsLevel() const
CStackBasicDescriptor::CStackBasicDescriptor() = default; CStackBasicDescriptor::CStackBasicDescriptor() = default;
CStackBasicDescriptor::CStackBasicDescriptor(const CreatureID & id, TQuantity Count): CStackBasicDescriptor::CStackBasicDescriptor(const CreatureID & id, TQuantity Count):
type(id.toCreature()), typeID(id),
count(Count) count(Count)
{ {
} }
CStackBasicDescriptor::CStackBasicDescriptor(const CCreature *c, TQuantity Count) CStackBasicDescriptor::CStackBasicDescriptor(const CCreature *c, TQuantity Count)
: type(c), count(Count) : typeID(c ? c->getId() : CreatureID()), count(Count)
{ {
} }
const CCreature * CStackBasicDescriptor::getCreature() const
{
return typeID.toCreature();
}
const Creature * CStackBasicDescriptor::getType() const const Creature * CStackBasicDescriptor::getType() const
{ {
return type; return typeID.toEntity(VLC);
} }
CreatureID CStackBasicDescriptor::getId() const CreatureID CStackBasicDescriptor::getId() const
{ {
return type->getId(); return typeID;
} }
TQuantity CStackBasicDescriptor::getCount() const TQuantity CStackBasicDescriptor::getCount() const
@ -1023,18 +1023,14 @@ TQuantity CStackBasicDescriptor::getCount() const
return count; return count;
} }
void CStackBasicDescriptor::setType(const CCreature * c) void CStackBasicDescriptor::setType(const CCreature * c)
{ {
type = c; typeID = c ? c->getId() : CreatureID();
} }
bool operator== (const CStackBasicDescriptor & l, const CStackBasicDescriptor & r) bool operator== (const CStackBasicDescriptor & l, const CStackBasicDescriptor & r)
{ {
return (!l.type && !r.type) return l.typeID == r.typeID && l.count == r.count;
|| (l.type && r.type
&& l.type->getId() == r.type->getId()
&& l.count == r.count);
} }
void CStackBasicDescriptor::serializeJson(JsonSerializeFormat & handler) void CStackBasicDescriptor::serializeJson(JsonSerializeFormat & handler)
@ -1043,9 +1039,9 @@ void CStackBasicDescriptor::serializeJson(JsonSerializeFormat & handler)
if(handler.saving) if(handler.saving)
{ {
if(type) if(typeID.hasValue())
{ {
std::string typeName = type->getJsonKey(); std::string typeName = typeID.toEntity(VLC)->getJsonKey();
handler.serializeString("type", typeName); handler.serializeString("type", typeName);
} }
} }

View File

@ -31,8 +31,8 @@ class JsonSerializeFormat;
class DLL_LINKAGE CStackBasicDescriptor class DLL_LINKAGE CStackBasicDescriptor
{ {
CreatureID typeID;
public: public:
const CCreature *type = nullptr;
TQuantity count = -1; //exact quantity or quantity ID from CCreature::getQuantityID when getting info about enemy army TQuantity count = -1; //exact quantity or quantity ID from CCreature::getQuantityID when getting info about enemy army
CStackBasicDescriptor(); CStackBasicDescriptor();
@ -41,29 +41,20 @@ public:
virtual ~CStackBasicDescriptor() = default; virtual ~CStackBasicDescriptor() = default;
const Creature * getType() const; const Creature * getType() const;
const CCreature * getCreature() const;
CreatureID getId() const; CreatureID getId() const;
TQuantity getCount() const; TQuantity getCount() const;
virtual void setType(const CCreature * c); virtual void setType(const CCreature * c);
friend bool operator== (const CStackBasicDescriptor & l, const CStackBasicDescriptor & r); friend bool operator== (const CStackBasicDescriptor & l, const CStackBasicDescriptor & r);
template <typename Handler> void serialize(Handler &h) template <typename Handler> void serialize(Handler &h)
{ {
if(h.saving) h & typeID;
{ if(!h.saving)
auto idNumber = type ? type->getId() : CreatureID(CreatureID::NONE); setType(typeID.toCreature());
h & idNumber;
}
else
{
CreatureID idNumber;
h & idNumber;
if(idNumber != CreatureID::NONE)
setType(dynamic_cast<const CCreature*>(VLC->creatures()->getById(idNumber)));
else
type = nullptr;
}
h & count; h & count;
} }

View File

@ -345,10 +345,10 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
for(auto & elem : info.army) for(auto & elem : info.army)
{ {
if(static_cast<int>(elem.second.type->getAIValue()) > maxAIValue) if(static_cast<int>(elem.second.getCreature()->getAIValue()) > maxAIValue)
{ {
maxAIValue = elem.second.type->getAIValue(); maxAIValue = elem.second.getCreature()->getAIValue();
mostStrong = elem.second.type; mostStrong = elem.second.getCreature();
} }
} }
@ -357,7 +357,7 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
else else
for(auto & elem : info.army) for(auto & elem : info.army)
{ {
elem.second.type = mostStrong; elem.second.setType(mostStrong);
} }
}; };
@ -390,7 +390,7 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
if(nullptr != mostStrong) //possible, faction may have no creatures at all if(nullptr != mostStrong) //possible, faction may have no creatures at all
for(auto & elem : info.army) for(auto & elem : info.army)
elem.second.type = mostStrong; elem.second.setType(mostStrong);
}; };

View File

@ -28,7 +28,7 @@ CStack::CStack(const CStackInstance * Base, const PlayerColor & O, int I, Battle
CBonusSystemNode(STACK_BATTLE), CBonusSystemNode(STACK_BATTLE),
base(Base), base(Base),
ID(I), ID(I),
type(Base->type), type(Base->getCreature()),
baseAmount(Base->count), baseAmount(Base->count),
owner(O), owner(O),
slot(S), slot(S),
@ -48,7 +48,7 @@ CStack::CStack():
CStack::CStack(const CStackBasicDescriptor * stack, const PlayerColor & O, int I, BattleSide Side, const SlotID & S): CStack::CStack(const CStackBasicDescriptor * stack, const PlayerColor & O, int I, BattleSide Side, const SlotID & S):
CBonusSystemNode(STACK_BATTLE), CBonusSystemNode(STACK_BATTLE),
ID(I), ID(I),
type(stack->type), type(stack->getCreature()),
baseAmount(stack->count), baseAmount(stack->count),
owner(O), owner(O),
slot(S), slot(S),

View File

@ -75,7 +75,7 @@ static const CCreature * retrieveCreature(const CBonusSystemNode *node)
default: default:
const CStackInstance * csi = retrieveStackInstance(node); const CStackInstance * csi = retrieveStackInstance(node);
if(csi) if(csi)
return csi->type; return csi->getCreature();
return nullptr; return nullptr;
} }
} }

View File

@ -1091,7 +1091,7 @@ void CGameState::fillUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, Upg
UpgradeInfo CGameState::fillUpgradeInfo(const CStackInstance &stack) const UpgradeInfo CGameState::fillUpgradeInfo(const CStackInstance &stack) const
{ {
UpgradeInfo ret; UpgradeInfo ret;
const CCreature *base = stack.type; const CCreature *base = stack.getCreature();
if (stack.armyObj->ID == Obj::HERO) if (stack.armyObj->ID == Obj::HERO)
{ {
@ -1571,7 +1571,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
{ {
for(const auto & it : elem->Slots()) for(const auto & it : elem->Slots())
{ {
CreatureID toCmp = it.second->type->getId(); //ID of creature we should compare with the best one CreatureID toCmp = it.second->getId(); //ID of creature we should compare with the best one
if(bestCre == CreatureID::NONE || bestCre.toEntity(VLC)->getAIValue() < toCmp.toEntity(VLC)->getAIValue()) if(bestCre == CreatureID::NONE || bestCre.toEntity(VLC)->getAIValue() < toCmp.toEntity(VLC)->getAIValue())
{ {
bestCre = toCmp; bestCre = toCmp;

View File

@ -26,7 +26,7 @@ ArmyDescriptor::ArmyDescriptor(const CArmedInstance *army, bool detailed)
if(detailed) if(detailed)
(*this)[elem.first] = *elem.second; (*this)[elem.first] = *elem.second;
else else
(*this)[elem.first] = CStackBasicDescriptor(elem.second->type, (int)elem.second->getQuantityID()); (*this)[elem.first] = CStackBasicDescriptor(elem.second->getCreature(), (int)elem.second->getQuantityID());
} }
} }
@ -42,12 +42,12 @@ int ArmyDescriptor::getStrength() const
if(isDetailed) if(isDetailed)
{ {
for(const auto & elem : *this) for(const auto & elem : *this)
ret += elem.second.type->getAIValue() * elem.second.count; ret += elem.second.getType()->getAIValue() * elem.second.count;
} }
else else
{ {
for(const auto & elem : *this) for(const auto & elem : *this)
ret += elem.second.type->getAIValue() * CCreature::estimateCreatureCount(elem.second.count); ret += elem.second.getType()->getAIValue() * CCreature::estimateCreatureCount(elem.second.count);
} }
return static_cast<int>(ret); return static_cast<int>(ret);
} }

View File

@ -485,13 +485,13 @@ VCMI_LIB_NAMESPACE_BEGIN
else else
logMod->warn("Failed to select suitable random creature!"); logMod->warn("Failed to select suitable random creature!");
stack.type = pickedCreature.toCreature(); stack.setType(pickedCreature.toCreature());
stack.count = loadValue(value, rng, variables); stack.count = loadValue(value, rng, variables);
if (!value["upgradeChance"].isNull() && !stack.type->upgrades.empty()) if (!value["upgradeChance"].isNull() && !stack.getCreature()->upgrades.empty())
{ {
if (int(value["upgradeChance"].Float()) > rng.nextInt(99)) // select random upgrade if (int(value["upgradeChance"].Float()) > rng.nextInt(99)) // select random upgrade
{ {
stack.type = RandomGeneratorUtil::nextItem(stack.type->upgrades, rng)->toCreature(); stack.setType(RandomGeneratorUtil::nextItem(stack.getCreature()->upgrades, rng)->toCreature());
} }
} }
return stack; return stack;

View File

@ -102,7 +102,7 @@ void DwellingInstanceConstructor::randomizeObject(CGDwelling * dwelling, vstd::R
JsonRandom::Variables emptyVariables; JsonRandom::Variables emptyVariables;
for(auto & stack : randomizer.loadCreatures(guards, rng, emptyVariables)) for(auto & stack : randomizer.loadCreatures(guards, rng, emptyVariables))
{ {
dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(stack.type->getId(), stack.count)); dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(stack.getId(), stack.count));
} }
} }
else //default condition - creatures are of level 5 or higher else //default condition - creatures are of level 5 or higher

View File

@ -94,7 +94,7 @@ void CBank::setConfig(const BankConfig & config)
clearSlots(); // remove all stacks, if any clearSlots(); // remove all stacks, if any
for(const auto & stack : config.guards) for(const auto & stack : config.guards)
setCreature (SlotID(stacksCount()), stack.type->getId(), stack.count); setCreature (SlotID(stacksCount()), stack.getId(), stack.count);
daycounter = 1; //yes, 1 since "today" daycounter won't be incremented daycounter = 1; //yes, 1 since "today" daycounter won't be incremented
} }
@ -190,8 +190,8 @@ void CBank::doVisit(const CGHeroInstance * hero) const
iw.text.appendLocalString(EMetaText::ADVOB_TXT, 34); iw.text.appendLocalString(EMetaText::ADVOB_TXT, 34);
const auto * strongest = boost::range::max_element(bankConfig->guards, [](const CStackBasicDescriptor & a, const CStackBasicDescriptor & b) const auto * strongest = boost::range::max_element(bankConfig->guards, [](const CStackBasicDescriptor & a, const CStackBasicDescriptor & b)
{ {
return a.type->getFightValue() < b.type->getFightValue(); return a.getType()->getFightValue() < b.getType()->getFightValue();
})->type; })->getType();
iw.text.replaceNamePlural(strongest->getId()); iw.text.replaceNamePlural(strongest->getId());
iw.text.replaceRawString(loot.buildList()); iw.text.replaceRawString(loot.buildList());
@ -244,7 +244,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
CCreatureSet ourArmy; CCreatureSet ourArmy;
for(const auto & slot : bankConfig->creatures) for(const auto & slot : bankConfig->creatures)
{ {
ourArmy.addToSlot(ourArmy.getSlotFor(slot.type->getId()), slot.type->getId(), slot.count); ourArmy.addToSlot(ourArmy.getSlotFor(slot.getId()), slot.getId(), slot.count);
} }
for(const auto & elem : ourArmy.Slots()) for(const auto & elem : ourArmy.Slots())

View File

@ -359,7 +359,7 @@ 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()->upgrades, elem.second->getCreatureID()); bool isOurUpgrade = vstd::contains(getCreature()->upgrades, elem.second->getCreatureID());
bool isOurDowngrade = vstd::contains(elem.second->type->upgrades, getCreatureID()); bool isOurDowngrade = vstd::contains(elem.second->getCreature()->upgrades, getCreatureID());
if(isOurUpgrade || isOurDowngrade) if(isOurUpgrade || isOurDowngrade)
count += elem.second->count; count += elem.second->count;
@ -480,7 +480,7 @@ void CGCreature::fight( const CGHeroInstance *h ) const
if (containsUpgradedStack()) //upgrade if (containsUpgradedStack()) //upgrade
{ {
SlotID slotID = SlotID(static_cast<si32>(std::floor(static_cast<float>(stacks.size()) / 2.0f))); SlotID slotID = SlotID(static_cast<si32>(std::floor(static_cast<float>(stacks.size()) / 2.0f)));
const auto & upgrades = getStack(slotID).type->upgrades; const auto & upgrades = getStack(slotID).getCreature()->upgrades;
if(!upgrades.empty()) if(!upgrades.empty())
{ {
auto it = RandomGeneratorUtil::nextItem(upgrades, cb->gameState()->getRandomGenerator()); auto it = RandomGeneratorUtil::nextItem(upgrades, cb->gameState()->getRandomGenerator());
@ -521,7 +521,7 @@ void CGCreature::battleFinished(const CGHeroInstance *hero, const BattleResult &
const CCreature * cre = getCreature(); 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->getCreature()))
{ {
cb->changeStackType(StackLocation(this, i->first), cre); //un-upgrade creatures cb->changeStackType(StackLocation(this, i->first), cre); //un-upgrade creatures
} }
@ -536,7 +536,7 @@ void CGCreature::battleFinished(const CGHeroInstance *hero, const BattleResult &
// TODO it's either overcomplicated (if we assume there'll be only one stack) or buggy (if we allow multiple stacks... but that'll also cause troubles elsewhere) // TODO it's either overcomplicated (if we assume there'll be only one stack) or buggy (if we allow multiple stacks... but that'll also cause troubles elsewhere)
i = stacks.end(); i = stacks.end();
i--; i--;
SlotID slot = getSlotFor(i->second->type); SlotID slot = getSlotFor(i->second->getCreature());
if(slot == i->first) //no reason to move stack to its own slot if(slot == i->first) //no reason to move stack to its own slot
break; break;
else else

View File

@ -1806,14 +1806,14 @@ bool CGHeroInstance::isMissionCritical() const
void CGHeroInstance::fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack) const void CGHeroInstance::fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack) const
{ {
TConstBonusListPtr lista = getBonuses(Selector::typeSubtype(BonusType::SPECIAL_UPGRADE, BonusSubtypeID(stack.type->getId()))); TConstBonusListPtr lista = getBonuses(Selector::typeSubtype(BonusType::SPECIAL_UPGRADE, BonusSubtypeID(stack.getId())));
for(const auto & it : *lista) for(const auto & it : *lista)
{ {
auto nid = CreatureID(it->additionalInfo[0]); auto nid = CreatureID(it->additionalInfo[0]);
if (nid != stack.type->getId()) //in very specific case the upgrade is available by default (?) if (nid != stack.getId()) //in very specific case the upgrade is available by default (?)
{ {
info.newID.push_back(nid); info.newID.push_back(nid);
info.cost.push_back(nid.toCreature()->getFullRecruitCost() - stack.type->getFullRecruitCost()); info.cost.push_back(nid.toCreature()->getFullRecruitCost() - stack.getType()->getFullRecruitCost());
} }
} }
} }

View File

@ -1227,14 +1227,14 @@ void CGTownInstance::fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &s
{ {
for(const CGTownInstance::TCreaturesSet::value_type & dwelling : creatures) for(const CGTownInstance::TCreaturesSet::value_type & dwelling : creatures)
{ {
if (vstd::contains(dwelling.second, stack.type->getId())) //Dwelling with our creature if (vstd::contains(dwelling.second, stack.getId())) //Dwelling with our creature
{ {
for(const auto & upgrID : dwelling.second) for(const auto & upgrID : dwelling.second)
{ {
if(vstd::contains(stack.type->upgrades, upgrID)) //possible upgrade if(vstd::contains(stack.getCreature()->upgrades, upgrID)) //possible upgrade
{ {
info.newID.push_back(upgrID); info.newID.push_back(upgrID);
info.cost.push_back(upgrID.toCreature()->getFullRecruitCost() - stack.type->getFullRecruitCost()); info.cost.push_back(upgrID.toCreature()->getFullRecruitCost() - stack.getType()->getFullRecruitCost());
} }
} }
} }

View File

@ -110,7 +110,7 @@ bool CQuest::checkMissionArmy(const CQuest * q, const CCreatureSet * army)
{ {
for(count = 0, it = army->Slots().begin(); it != army->Slots().end(); ++it) for(count = 0, it = army->Slots().begin(); it != army->Slots().end(); ++it)
{ {
if(it->second->type == cre->type) if(it->second->getType() == cre->getType())
{ {
count += it->second->count; count += it->second->count;
slotsCount++; slotsCount++;

View File

@ -1152,7 +1152,7 @@ void CGSirens::onHeroVisit( const CGHeroInstance * h ) const
if(drown) if(drown)
{ {
cb->changeStackCount(StackLocation(h, i->first), -drown); cb->changeStackCount(StackLocation(h, i->first), -drown);
xp += drown * i->second->type->getMaxHealth(); xp += drown * i->second->getType()->getMaxHealth();
} }
} }
@ -1318,7 +1318,7 @@ void HillFort::onHeroVisit(const CGHeroInstance * h) const
void HillFort::fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack) const void HillFort::fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack) const
{ {
int32_t level = stack.type->getLevel(); int32_t level = stack.getType()->getLevel();
int32_t index = std::clamp<int32_t>(level - 1, 0, upgradeCostPercentage.size() - 1); int32_t index = std::clamp<int32_t>(level - 1, 0, upgradeCostPercentage.size() - 1);
int costModifier = upgradeCostPercentage[index]; int costModifier = upgradeCostPercentage[index];
@ -1326,10 +1326,10 @@ void HillFort::fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack)
if (costModifier < 0) if (costModifier < 0)
return; // upgrade not allowed return; // upgrade not allowed
for(const auto & nid : stack.type->upgrades) for(const auto & nid : stack.getCreature()->upgrades)
{ {
info.newID.push_back(nid); info.newID.push_back(nid);
info.cost.push_back((nid.toCreature()->getFullRecruitCost() - stack.type->getFullRecruitCost()) * costModifier / 100); info.cost.push_back((nid.toCreature()->getFullRecruitCost() - stack.getType()->getFullRecruitCost()) * costModifier / 100);
} }
} }

View File

@ -2116,7 +2116,7 @@ EQuestMission CMapLoaderH3M::readQuest(IQuestObject * guard, const int3 & positi
guard->quest->mission.creatures.resize(typeNumber); guard->quest->mission.creatures.resize(typeNumber);
for(size_t hh = 0; hh < typeNumber; ++hh) for(size_t hh = 0; hh < typeNumber; ++hh)
{ {
guard->quest->mission.creatures[hh].type = reader->readCreature().toCreature(); guard->quest->mission.creatures[hh].setType(reader->readCreature().toCreature());
guard->quest->mission.creatures[hh].count = reader->readUInt16(); guard->quest->mission.creatures[hh].count = reader->readUInt16();
} }
break; break;

View File

@ -185,7 +185,7 @@ void Rewardable::Interface::grantRewardAfterLevelup(const Rewardable::VisitInfo
for(const auto & change : info.reward.creaturesChange) for(const auto & change : info.reward.creaturesChange)
{ {
if (heroStack->type->getId() == change.first) if (heroStack->getId() == change.first)
{ {
StackLocation location(hero, slot.first); StackLocation location(hero, slot.first);
cb->changeStackType(location, change.second.toCreature()); cb->changeStackType(location, change.second.toCreature());
@ -199,7 +199,7 @@ void Rewardable::Interface::grantRewardAfterLevelup(const Rewardable::VisitInfo
{ {
CCreatureSet creatures; CCreatureSet creatures;
for(const auto & crea : info.reward.creatures) for(const auto & crea : info.reward.creatures)
creatures.addToSlot(creatures.getFreeSlot(), new CStackInstance(crea.type, crea.count)); creatures.addToSlot(creatures.getFreeSlot(), new CStackInstance(crea.getCreature(), crea.count));
if(auto * army = dynamic_cast<const CArmedInstance*>(this)) //TODO: to fix that, CArmedInstance must be split on map instance part and interface part if(auto * army = dynamic_cast<const CArmedInstance*>(this)) //TODO: to fix that, CArmedInstance must be split on map instance part and interface part
cb->giveCreatures(army, hero, creatures, false); cb->giveCreatures(army, hero, creatures, false);

View File

@ -84,7 +84,7 @@ bool Rewardable::Limiter::heroAllowed(const CGHeroInstance * hero) const
for(const auto & slot : hero->Slots()) for(const auto & slot : hero->Slots())
{ {
const CStackInstance * heroStack = slot.second; const CStackInstance * heroStack = slot.second;
if (heroStack->type == reqStack.type) if (heroStack->getType() == reqStack.getType())
count += heroStack->count; count += heroStack->count;
} }
if (count < reqStack.count) //not enough creatures of this kind if (count < reqStack.count) //not enough creatures of this kind
@ -233,7 +233,7 @@ void Rewardable::Limiter::loadComponents(std::vector<Component> & comps,
comps.emplace_back(ComponentType::SPELL, entry); comps.emplace_back(ComponentType::SPELL, entry);
for(const auto & entry : creatures) for(const auto & entry : creatures)
comps.emplace_back(ComponentType::CREATURE, entry.type->getId(), entry.count); comps.emplace_back(ComponentType::CREATURE, entry.getId(), entry.count);
for(const auto & entry : players) for(const auto & entry : players)
comps.emplace_back(ComponentType::FLAG, entry); comps.emplace_back(ComponentType::FLAG, entry);

View File

@ -121,7 +121,7 @@ void Rewardable::Reward::loadComponents(std::vector<Component> & comps, const CG
} }
for(const auto & entry : creatures) for(const auto & entry : creatures)
comps.emplace_back(ComponentType::CREATURE, entry.type->getId(), entry.count); comps.emplace_back(ComponentType::CREATURE, entry.getId(), entry.count);
for (size_t i=0; i<resources.size(); i++) for (size_t i=0; i<resources.size(); i++)
{ {

View File

@ -438,7 +438,7 @@ void MetaString::replaceName(const CreatureID & id, TQuantity count) //adds sing
void MetaString::replaceName(const CStackBasicDescriptor & stack) void MetaString::replaceName(const CStackBasicDescriptor & stack)
{ {
replaceName(stack.type->getId(), stack.count); replaceName(stack.getId(), stack.count);
} }
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END

View File

@ -169,7 +169,7 @@ void QuestWidget::obtainData()
} }
for(auto & i : quest.mission.creatures) for(auto & i : quest.mission.creatures)
{ {
int index = i.type->getIndex(); int index = i.getType()->getIndex();
ui->lCreatureId->setCurrentIndex(index); ui->lCreatureId->setCurrentIndex(index);
ui->lCreatureAmount->setValue(i.count); ui->lCreatureAmount->setValue(i.count);
onCreatureAdd(ui->lCreatures, ui->lCreatureId, ui->lCreatureAmount); onCreatureAdd(ui->lCreatures, ui->lCreatureId, ui->lCreatureAmount);

View File

@ -459,7 +459,7 @@ void RewardsWidget::loadCurrentVisitInfo(int index)
} }
for(auto & i : vinfo.reward.creatures) for(auto & i : vinfo.reward.creatures)
{ {
int index = i.type->getIndex(); int index = i.getType()->getIndex();
ui->rCreatureId->setCurrentIndex(index); ui->rCreatureId->setCurrentIndex(index);
ui->rCreatureAmount->setValue(i.count); ui->rCreatureAmount->setValue(i.count);
onCreatureAdd(ui->rCreatures, ui->rCreatureId, ui->rCreatureAmount); onCreatureAdd(ui->rCreatures, ui->rCreatureId, ui->rCreatureAmount);
@ -527,7 +527,7 @@ void RewardsWidget::loadCurrentVisitInfo(int index)
} }
for(auto & i : vinfo.limiter.creatures) for(auto & i : vinfo.limiter.creatures)
{ {
int index = i.type->getIndex(); int index = i.getType()->getIndex();
ui->lCreatureId->setCurrentIndex(index); ui->lCreatureId->setCurrentIndex(index);
ui->lCreatureAmount->setValue(i.count); ui->lCreatureAmount->setValue(i.count);
onCreatureAdd(ui->lCreatures, ui->lCreatureId, ui->lCreatureAmount); onCreatureAdd(ui->lCreatures, ui->lCreatureId, ui->lCreatureAmount);

View File

@ -1139,7 +1139,7 @@ void CGameHandler::giveCreatures(const CArmedInstance *obj, const CGHeroInstance
//first we move creatures to give to make them army of object-source //first we move creatures to give to make them army of object-source
for (auto & elem : creatures.Slots()) for (auto & elem : creatures.Slots())
{ {
addToSlot(StackLocation(obj, obj->getSlotFor(elem.second->type)), elem.second->type, elem.second->count); addToSlot(StackLocation(obj, obj->getSlotFor(elem.second->getCreature())), elem.second->getCreature(), elem.second->count);
} }
tryJoiningArmy(obj, h, remove, true); tryJoiningArmy(obj, h, remove, true);
@ -1160,7 +1160,7 @@ void CGameHandler::takeCreatures(ObjectInstanceID objid, const std::vector<CStac
bool foundSth = false; bool foundSth = false;
for (auto i = obj->Slots().begin(); i != obj->Slots().end(); i++) for (auto i = obj->Slots().begin(); i != obj->Slots().end(); i++)
{ {
if (i->second->type == sbd.type) if (i->second->getType() == sbd.getType())
{ {
TQuantity take = std::min(sbd.count - collected, i->second->count); //collect as much cres as we can TQuantity take = std::min(sbd.count - collected, i->second->count); //collect as much cres as we can
changeStackCount(StackLocation(obj, i->first), -take, false); changeStackCount(StackLocation(obj, i->first), -take, false);
@ -2455,7 +2455,7 @@ void CGameHandler::moveArmy(const CArmedInstance *src, const CArmedInstance *dst
auto i = src->Slots().begin(); //iterator to stack to move auto i = src->Slots().begin(); //iterator to stack to move
StackLocation sl(src, i->first); //location of stack to move StackLocation sl(src, i->first); //location of stack to move
SlotID pos = dst->getSlotFor(i->second->type); SlotID pos = dst->getSlotFor(i->second->getCreature());
if (!pos.validSlot()) if (!pos.validSlot())
{ {
//try to merge two other stacks to make place //try to merge two other stacks to make place
@ -3137,7 +3137,7 @@ bool CGameHandler::sellCreatures(ui32 count, const IMarket *market, const CGHero
int b1; //base quantities for trade int b1; //base quantities for trade
int b2; int b2;
market->getOffer(s.type->getId(), resourceID, b1, b2, EMarketMode::CREATURE_RESOURCE); market->getOffer(s.getId(), resourceID, b1, b2, EMarketMode::CREATURE_RESOURCE);
int units = count / b1; //how many base quantities we trade int units = count / b1; //how many base quantities we trade
if (count%b1) //all offered units of resource should be used, if not -> somewhere in calculations must be an error if (count%b1) //all offered units of resource should be used, if not -> somewhere in calculations must be an error
@ -3648,7 +3648,7 @@ bool CGameHandler::sacrificeCreatures(const IMarket * market, const CGHeroInstan
COMPLAIN_RET("Cannot sacrifice last creature!"); COMPLAIN_RET("Cannot sacrifice last creature!");
} }
int crid = hero->getStack(slot[i]).type->getId(); int crid = hero->getStack(slot[i]).getId();
changeStackCount(StackLocation(hero, slot[i]), -(TQuantity)count[i]); changeStackCount(StackLocation(hero, slot[i]), -(TQuantity)count[i]);
@ -3801,7 +3801,7 @@ void CGameHandler::tryJoiningArmy(const CArmedInstance *src, const CArmedInstanc
{ {
for (auto i = src->stacks.begin(); i != src->stacks.end(); i++)//while there are unmoved creatures for (auto i = src->stacks.begin(); i != src->stacks.end(); i++)//while there are unmoved creatures
{ {
SlotID pos = dst->getSlotFor(i->second->type); SlotID pos = dst->getSlotFor(i->second->getCreature());
if (pos.validSlot()) if (pos.validSlot())
{ {
moveStack(StackLocation(src, i->first), StackLocation(dst, pos)); moveStack(StackLocation(src, i->first), StackLocation(dst, pos));

View File

@ -556,12 +556,12 @@ void BattleResultProcessor::battleAfterLevelUp(const BattleID & battleID, const
const CStackBasicDescriptor raisedStack = finishingBattle->winnerHero ? finishingBattle->winnerHero->calculateNecromancy(result) : CStackBasicDescriptor(); const CStackBasicDescriptor raisedStack = finishingBattle->winnerHero ? finishingBattle->winnerHero->calculateNecromancy(result) : CStackBasicDescriptor();
// Give raised units to winner and show dialog, if any were raised, // Give raised units to winner and show dialog, if any were raised,
// units will be given after casualties are taken // units will be given after casualties are taken
const SlotID necroSlot = raisedStack.type ? finishingBattle->winnerHero->getSlotFor(raisedStack.type) : SlotID(); const SlotID necroSlot = raisedStack.getCreature() ? finishingBattle->winnerHero->getSlotFor(raisedStack.getCreature()) : SlotID();
if (necroSlot != SlotID() && !finishingBattle->isDraw()) if (necroSlot != SlotID() && !finishingBattle->isDraw())
{ {
finishingBattle->winnerHero->showNecromancyDialog(raisedStack, gameHandler->getRandomGenerator()); finishingBattle->winnerHero->showNecromancyDialog(raisedStack, gameHandler->getRandomGenerator());
gameHandler->addToSlot(StackLocation(finishingBattle->winnerHero, necroSlot), raisedStack.type, raisedStack.count); gameHandler->addToSlot(StackLocation(finishingBattle->winnerHero, necroSlot), raisedStack.getCreature(), raisedStack.count);
} }
BattleResultsApplied resultsApplied; BattleResultsApplied resultsApplied;

View File

@ -345,7 +345,7 @@ void NewTurnProcessor::updateNeutralTownGarrison(const CGTownInstance * t, int c
// Check if town garrison already has unit of specified tier // Check if town garrison already has unit of specified tier
for(const auto & slot : t->Slots()) for(const auto & slot : t->Slots())
{ {
const auto * creature = slot.second->type; const auto * creature = slot.second->getCreature();
if (creature->getFactionID() != t->getFactionID()) if (creature->getFactionID() != t->getFactionID())
continue; continue;