|
BattleInfo * BattleInfo::setupBattle(
...
auto handleWarMachine= [&](int side, ArtifactPosition artslot, BattleHex hex)
{
const CArtifactInstance * warMachineArt = heroes[side]->getArt(artslot);
if(nullptr != warMachineArt)
{
CreatureID cre = warMachineArt->artType->warMachine;
if(cre != CreatureID::NONE)
stacks.push_back(curB->generateNewStack(CStackBasicDescriptor(cre, 1), side, SlotID::WAR_MACHINES_SLOT, hex));
}
};
...
}
CStack * BattleInfo::generateNewStack(const CStackBasicDescriptor & base, ui8 side, SlotID slot, BattleHex position) const
{
int stackID = getIdForNewStack();
PlayerColor owner = sides[side].color;
auto ret = new CStack(&base, owner, stackID, side, slot);
ret->position = position;
ret->state.insert(EBattleStackState::ALIVE); //alive state indication
return ret;
}
---
In CCreatureSet.cpp:
CStackBasicDescriptor::CStackBasicDescriptor(CreatureID id, TQuantity Count)
: type (VLC->creh->creatures[id]), count(Count)
{
}
---
CStack::CStack(const CStackBasicDescriptor * stack, PlayerColor O, int I, ui8 Side, SlotID S):
base(nullptr), ID(I), owner(O), slot(S), side(Side),
counterAttacks(this), shots(this), casts(this), health(this), cloneID(-1),
position()
{
type = stack->type;
baseAmount = stack->count;
health.init(); //???
setNodeType(STACK_BATTLE);
}
---
In HeroBonus.cpp:
int CCreatureTypeLimiter::limit(const BonusLimitationContext &context) const
{
const CCreature *c = retrieveCreature(&context.node);
if(!c)
return true;
return c != creature && (!includeUpgrades || !creature->isMyUpgrade(c));
//drop bonus if it's not our creature and (we don`t check upgrades or its not our upgrade)
}
const CCreature * retrieveCreature(const CBonusSystemNode *node)
{
switch(node->getNodeType())
{
case CBonusSystemNode::CREATURE:
return (static_cast<const CCreature *>(node));
default:
const CStackInstance *csi = retreiveStackInstance(node);
if(csi)
return csi->type;
return nullptr;
}
}
const CStackInstance * retreiveStackInstance(const CBonusSystemNode *node)
{
switch(node->getNodeType())
{
case CBonusSystemNode::STACK_INSTANCE:
return (static_cast<const CStackInstance *>(node));
case CBonusSystemNode::STACK_BATTLE:
return (static_cast<const CStack*>(node))->base;
default:
return nullptr;
}
} |
|
|
Looks like war machines stacks are created with base = nullptr, which is what retrieveStackInstance returns, and hence retrieveCreature as well.
As a result, CCreatureTypeLimiter::limit will return true, stopping propagation. |
|
(0007249)
|
hkoehler
|
2017-09-02 02:46
(edited on: 2017-09-02 06:32) |
|
Problem is that retrieveCreature shouldn't depend on retrieveStackInstance, as it only requires creature type, not creature instance, and there are stacks without instances (e.g. war machines). Creature type is stored in type, so no need to use base->type.
Fix:
const CCreature * retrieveCreature(const CBonusSystemNode *node)
{
switch(node->getNodeType())
{
case CBonusSystemNode::CREATURE:
return (static_cast<const CCreature *>(node));
case CBonusSystemNode::STACK_BATTLE:
return (static_cast<const CStack*>(node))->type;
default:
const CStackInstance *csi = retreiveStackInstance(node);
if(csi)
return csi->type;
return nullptr;
}
}
|
|