1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-21 17:17:06 +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())
{
if(!stack.second->type)
if(!stack.second->getType())
continue;
auto duplicatingSlot = recruiter->getSlotFor(stack.second->type);
auto duplicatingSlot = recruiter->getSlotFor(stack.second->getCreature());
if(duplicatingSlot != stack.first)
{

View File

@ -312,7 +312,7 @@ int getDuplicatingSlots(const CArmedInstance * army)
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++;
}
@ -387,7 +387,7 @@ bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObject
{
for(auto slot : h->Slots())
{
if(slot.second->type->hasUpgrades())
if(slot.second->getType()->hasUpgrades())
return true; //TODO: check price?
}
return false;

View File

@ -90,7 +90,7 @@ std::vector<SlotInfo> ArmyManager::getSortedSlots(const CCreatureSet * target, c
{
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];
slotInfp.creature = cre;

View File

@ -155,10 +155,10 @@ uint64_t getCreatureBankArmyReward(const CGObjectInstance * target, const CGHero
for (auto c : creatures)
{
//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)
{
result += (c.data.type->getAIValue() * c.data.count) * c.chance;
result += (c.data.getType()->getAIValue() * c.data.count) * c.chance;
}
/*else
{

View File

@ -36,7 +36,7 @@ std::vector<SlotInfo> ArmyManager::getSortedSlots(const CCreatureSet * target, c
{
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];
slotInfp.creature = cre;

View File

@ -162,7 +162,7 @@ TGoalVec CompleteQuest::missionArmy() const
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;

View File

@ -2818,7 +2818,7 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj)
{
for(auto slot : h->Slots())
{
if(slot.second->type->hasUpgrades())
if(slot.second->getType()->hasUpgrades())
return true; //TODO: check price?
}
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();
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 exchangeMode = stackExists && owner->upperArmy() && owner->lowerArmy();
bool hasOtherEmptySlots = exchangeMode && otherArmy->getFreeSlot() != SlotID();
@ -398,7 +398,7 @@ void CGarrisonSlot::update()
{
addUsedEvents(LCLICK | SHOW_POPUP | GESTURE | HOVER);
myStack = getObj()->getStackPtr(ID);
creature = myStack ? myStack->type : nullptr;
creature = myStack ? myStack->getCreature() : nullptr;
}
else
{
@ -426,7 +426,7 @@ CGarrisonSlot::CGarrisonSlot(CGarrisonInt * Owner, int x, int y, SlotID IID, EGa
: ID(IID),
owner(Owner),
myStack(creature_),
creature(creature_ ? creature_->type : nullptr),
creature(creature_ ? creature_->getCreature() : nullptr),
upg(Upg)
{
OBJECT_CONSTRUCTION;

View File

@ -280,7 +280,7 @@ void CArmyTooltip::init(const InfoAboutArmy &army)
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;
if(army.army.isDetailed)

View File

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

View File

@ -1056,7 +1056,7 @@ CGarrisonWindow::CGarrisonWindow(const CArmedInstance * up, const CGHeroInstance
if(up->Slots().size() > 0)
{
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
{

View File

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

View File

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

View File

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

View File

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

View File

@ -345,10 +345,10 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
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();
mostStrong = elem.second.type;
maxAIValue = elem.second.getCreature()->getAIValue();
mostStrong = elem.second.getCreature();
}
}
@ -357,7 +357,7 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
else
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
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),
base(Base),
ID(I),
type(Base->type),
type(Base->getCreature()),
baseAmount(Base->count),
owner(O),
slot(S),
@ -48,7 +48,7 @@ CStack::CStack():
CStack::CStack(const CStackBasicDescriptor * stack, const PlayerColor & O, int I, BattleSide Side, const SlotID & S):
CBonusSystemNode(STACK_BATTLE),
ID(I),
type(stack->type),
type(stack->getCreature()),
baseAmount(stack->count),
owner(O),
slot(S),

View File

@ -75,7 +75,7 @@ static const CCreature * retrieveCreature(const CBonusSystemNode *node)
default:
const CStackInstance * csi = retrieveStackInstance(node);
if(csi)
return csi->type;
return csi->getCreature();
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 ret;
const CCreature *base = stack.type;
const CCreature *base = stack.getCreature();
if (stack.armyObj->ID == Obj::HERO)
{
@ -1571,7 +1571,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
{
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())
{
bestCre = toCmp;

View File

@ -26,7 +26,7 @@ ArmyDescriptor::ArmyDescriptor(const CArmedInstance *army, bool detailed)
if(detailed)
(*this)[elem.first] = *elem.second;
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)
{
for(const auto & elem : *this)
ret += elem.second.type->getAIValue() * elem.second.count;
ret += elem.second.getType()->getAIValue() * elem.second.count;
}
else
{
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);
}

View File

@ -485,13 +485,13 @@ VCMI_LIB_NAMESPACE_BEGIN
else
logMod->warn("Failed to select suitable random creature!");
stack.type = pickedCreature.toCreature();
stack.setType(pickedCreature.toCreature());
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
{
stack.type = RandomGeneratorUtil::nextItem(stack.type->upgrades, rng)->toCreature();
stack.setType(RandomGeneratorUtil::nextItem(stack.getCreature()->upgrades, rng)->toCreature());
}
}
return stack;

View File

@ -102,7 +102,7 @@ void DwellingInstanceConstructor::randomizeObject(CGDwelling * dwelling, vstd::R
JsonRandom::Variables 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

View File

@ -94,7 +94,7 @@ void CBank::setConfig(const BankConfig & config)
clearSlots(); // remove all stacks, if any
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
}
@ -190,8 +190,8 @@ void CBank::doVisit(const CGHeroInstance * hero) const
iw.text.appendLocalString(EMetaText::ADVOB_TXT, 34);
const auto * strongest = boost::range::max_element(bankConfig->guards, [](const CStackBasicDescriptor & a, const CStackBasicDescriptor & b)
{
return a.type->getFightValue() < b.type->getFightValue();
})->type;
return a.getType()->getFightValue() < b.getType()->getFightValue();
})->getType();
iw.text.replaceNamePlural(strongest->getId());
iw.text.replaceRawString(loot.buildList());
@ -244,7 +244,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const
CCreatureSet ourArmy;
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())

View File

@ -359,7 +359,7 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
for(const auto & elem : h->Slots())
{
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)
count += elem.second->count;
@ -480,7 +480,7 @@ void CGCreature::fight( const CGHeroInstance *h ) const
if (containsUpgradedStack()) //upgrade
{
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())
{
auto it = RandomGeneratorUtil::nextItem(upgrades, cb->gameState()->getRandomGenerator());
@ -521,7 +521,7 @@ void CGCreature::battleFinished(const CGHeroInstance *hero, const BattleResult &
const CCreature * cre = getCreature();
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
}
@ -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)
i = stacks.end();
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
break;
else

View File

@ -1806,14 +1806,14 @@ bool CGHeroInstance::isMissionCritical() 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)
{
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.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)
{
if (vstd::contains(dwelling.second, stack.type->getId())) //Dwelling with our creature
if (vstd::contains(dwelling.second, stack.getId())) //Dwelling with our creature
{
for(const auto & upgrID : dwelling.second)
{
if(vstd::contains(stack.type->upgrades, upgrID)) //possible upgrade
if(vstd::contains(stack.getCreature()->upgrades, upgrID)) //possible upgrade
{
info.newID.push_back(upgrID);
info.cost.push_back(upgrID.toCreature()->getFullRecruitCost() - stack.type->getFullRecruitCost());
info.cost.push_back(upgrID.toCreature()->getFullRecruitCost() - stack.getType()->getFullRecruitCost());
}
}
}

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)
{
if(it->second->type == cre->type)
if(it->second->getType() == cre->getType())
{
count += it->second->count;
slotsCount++;

View File

@ -1152,7 +1152,7 @@ void CGSirens::onHeroVisit( const CGHeroInstance * h ) const
if(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
{
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);
int costModifier = upgradeCostPercentage[index];
@ -1326,10 +1326,10 @@ void HillFort::fillUpgradeInfo(UpgradeInfo & info, const CStackInstance &stack)
if (costModifier < 0)
return; // upgrade not allowed
for(const auto & nid : stack.type->upgrades)
for(const auto & nid : stack.getCreature()->upgrades)
{
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);
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();
}
break;

View File

@ -185,7 +185,7 @@ void Rewardable::Interface::grantRewardAfterLevelup(const Rewardable::VisitInfo
for(const auto & change : info.reward.creaturesChange)
{
if (heroStack->type->getId() == change.first)
if (heroStack->getId() == change.first)
{
StackLocation location(hero, slot.first);
cb->changeStackType(location, change.second.toCreature());
@ -199,7 +199,7 @@ void Rewardable::Interface::grantRewardAfterLevelup(const Rewardable::VisitInfo
{
CCreatureSet 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
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())
{
const CStackInstance * heroStack = slot.second;
if (heroStack->type == reqStack.type)
if (heroStack->getType() == reqStack.getType())
count += heroStack->count;
}
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);
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)
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)
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++)
{

View File

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

View File

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

View File

@ -459,7 +459,7 @@ void RewardsWidget::loadCurrentVisitInfo(int index)
}
for(auto & i : vinfo.reward.creatures)
{
int index = i.type->getIndex();
int index = i.getType()->getIndex();
ui->rCreatureId->setCurrentIndex(index);
ui->rCreatureAmount->setValue(i.count);
onCreatureAdd(ui->rCreatures, ui->rCreatureId, ui->rCreatureAmount);
@ -527,7 +527,7 @@ void RewardsWidget::loadCurrentVisitInfo(int index)
}
for(auto & i : vinfo.limiter.creatures)
{
int index = i.type->getIndex();
int index = i.getType()->getIndex();
ui->lCreatureId->setCurrentIndex(index);
ui->lCreatureAmount->setValue(i.count);
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
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);
@ -1160,7 +1160,7 @@ void CGameHandler::takeCreatures(ObjectInstanceID objid, const std::vector<CStac
bool foundSth = false;
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
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
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())
{
//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 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
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!");
}
int crid = hero->getStack(slot[i]).type->getId();
int crid = hero->getStack(slot[i]).getId();
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
{
SlotID pos = dst->getSlotFor(i->second->type);
SlotID pos = dst->getSlotFor(i->second->getCreature());
if (pos.validSlot())
{
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();
// Give raised units to winner and show dialog, if any were raised,
// 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())
{
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;

View File

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