mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-17 20:58:07 +02:00
Optimize Unit::getHexes method
This commit is contained in:
parent
5375d61d1b
commit
3b35c679ce
@ -35,6 +35,7 @@ CStack::CStack(const CStackInstance * Base, const PlayerColor & O, int I, Battle
|
||||
side(Side)
|
||||
{
|
||||
health.init(); //???
|
||||
doubleWideCached = battle::CUnitState::doubleWide();
|
||||
}
|
||||
|
||||
CStack::CStack():
|
||||
@ -55,6 +56,7 @@ CStack::CStack(const CStackBasicDescriptor * stack, const PlayerColor & O, int I
|
||||
side(Side)
|
||||
{
|
||||
health.init(); //???
|
||||
doubleWideCached = battle::CUnitState::doubleWide();
|
||||
}
|
||||
|
||||
void CStack::localInit(BattleInfo * battleInfo)
|
||||
@ -404,4 +406,30 @@ void CStack::spendMana(ServerCallback * server, const int spellCost) const
|
||||
server->apply(ssp);
|
||||
}
|
||||
|
||||
void CStack::postDeserialize(const CArmedInstance * army, const SlotID & extSlot)
|
||||
{
|
||||
if(extSlot == SlotID::COMMANDER_SLOT_PLACEHOLDER)
|
||||
{
|
||||
const auto * hero = dynamic_cast<const CGHeroInstance *>(army);
|
||||
assert(hero);
|
||||
base = hero->commander;
|
||||
}
|
||||
else if(slot == SlotID::SUMMONED_SLOT_PLACEHOLDER || slot == SlotID::ARROW_TOWERS_SLOT || slot == SlotID::WAR_MACHINES_SLOT)
|
||||
{
|
||||
//no external slot possible, so no base stack
|
||||
base = nullptr;
|
||||
}
|
||||
else if(!army || extSlot == SlotID() || !army->hasStackAtSlot(extSlot))
|
||||
{
|
||||
base = nullptr;
|
||||
logGlobal->warn("%s doesn't have a base stack!", typeID.toEntity(VLC)->getNameSingularTranslated());
|
||||
}
|
||||
else
|
||||
{
|
||||
base = &army->getStack(extSlot);
|
||||
}
|
||||
|
||||
doubleWideCached = battle::CUnitState::doubleWide();
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
29
lib/CStack.h
29
lib/CStack.h
@ -23,7 +23,7 @@ struct BattleStackAttacked;
|
||||
class BattleInfo;
|
||||
|
||||
//Represents STACK_BATTLE nodes
|
||||
class DLL_LINKAGE CStack : public CBonusSystemNode, public battle::CUnitState, public battle::IUnitEnvironment
|
||||
class DLL_LINKAGE CStack final : public CBonusSystemNode, public battle::CUnitState, public battle::IUnitEnvironment
|
||||
{
|
||||
private:
|
||||
ui32 ID = -1; //unique ID of stack
|
||||
@ -36,6 +36,9 @@ private:
|
||||
|
||||
SlotID slot; //slot - position in garrison (may be 255 for neutrals/called creatures)
|
||||
|
||||
bool doubleWideCached = false;
|
||||
|
||||
void postDeserialize(const CArmedInstance * army, const SlotID & extSlot);
|
||||
public:
|
||||
const CStackInstance * base = nullptr; //garrison slot from which stack originates (nullptr for war machines, summoned cres, etc)
|
||||
|
||||
@ -77,6 +80,7 @@ public:
|
||||
BattleSide unitSide() const override;
|
||||
PlayerColor unitOwner() const override;
|
||||
SlotID unitSlot() const override;
|
||||
bool doubleWide() const override { return doubleWideCached;};
|
||||
|
||||
std::string getDescription() const override;
|
||||
|
||||
@ -119,26 +123,7 @@ public:
|
||||
h & army;
|
||||
h & extSlot;
|
||||
|
||||
if(extSlot == SlotID::COMMANDER_SLOT_PLACEHOLDER)
|
||||
{
|
||||
const auto * hero = dynamic_cast<const CGHeroInstance *>(army);
|
||||
assert(hero);
|
||||
base = hero->commander;
|
||||
}
|
||||
else if(slot == SlotID::SUMMONED_SLOT_PLACEHOLDER || slot == SlotID::ARROW_TOWERS_SLOT || slot == SlotID::WAR_MACHINES_SLOT)
|
||||
{
|
||||
//no external slot possible, so no base stack
|
||||
base = nullptr;
|
||||
}
|
||||
else if(!army || extSlot == SlotID() || !army->hasStackAtSlot(extSlot))
|
||||
{
|
||||
base = nullptr;
|
||||
logGlobal->warn("%s doesn't have a base stack!", typeID.toEntity(VLC)->getNameSingularTranslated());
|
||||
}
|
||||
else
|
||||
{
|
||||
base = &army->getStack(extSlot);
|
||||
}
|
||||
postDeserialize(army, extSlot);
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,4 +131,4 @@ private:
|
||||
const BattleInfo * battle; //do not serialize
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -269,7 +269,7 @@ private:
|
||||
void reset();
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CUnitStateDetached : public CUnitState
|
||||
class DLL_LINKAGE CUnitStateDetached final : public CUnitState
|
||||
{
|
||||
public:
|
||||
explicit CUnitStateDetached(const IUnitInfo * unit_, const IBonusBearer * bonus_);
|
||||
|
@ -107,24 +107,34 @@ const BattleHexArray & Unit::getHexes(BattleHex assumedPos) const
|
||||
return getHexes(assumedPos, doubleWide(), unitSide());
|
||||
}
|
||||
|
||||
BattleHexArray::ArrayOfBattleHexArrays Unit::precomputeUnitHexes(BattleSide side, bool twoHex)
|
||||
{
|
||||
BattleHexArray::ArrayOfBattleHexArrays result;
|
||||
|
||||
for (BattleHex assumedPos = 0; assumedPos < GameConstants::BFIELD_SIZE; ++assumedPos)
|
||||
{
|
||||
BattleHexArray hexes;
|
||||
hexes.insert(assumedPos);
|
||||
|
||||
if(twoHex)
|
||||
hexes.insert(occupiedHex(assumedPos, twoHex, side));
|
||||
|
||||
result[assumedPos.toInt()] = std::move(hexes);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const BattleHexArray & Unit::getHexes(BattleHex assumedPos, bool twoHex, BattleSide side)
|
||||
{
|
||||
static BattleHexArray::ArrayOfBattleHexArrays precomputed[4];
|
||||
static const std::array<BattleHexArray::ArrayOfBattleHexArrays, 4> precomputed = {
|
||||
precomputeUnitHexes(BattleSide::ATTACKER, false),
|
||||
precomputeUnitHexes(BattleSide::ATTACKER, true),
|
||||
precomputeUnitHexes(BattleSide::DEFENDER, false),
|
||||
precomputeUnitHexes(BattleSide::DEFENDER, true),
|
||||
};
|
||||
|
||||
int index = side == BattleSide::ATTACKER ? 0 : 2;
|
||||
|
||||
if(!precomputed[index + twoHex][assumedPos.toInt()].empty())
|
||||
return precomputed[index + twoHex][assumedPos.toInt()];
|
||||
|
||||
// first run, compute
|
||||
|
||||
BattleHexArray hexes;
|
||||
hexes.insert(assumedPos);
|
||||
|
||||
if(twoHex)
|
||||
hexes.insert(occupiedHex(assumedPos, twoHex, side));
|
||||
|
||||
precomputed[index + twoHex][assumedPos.toInt()] = std::move(hexes);
|
||||
|
||||
return precomputed[index + twoHex][assumedPos.toInt()];
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,8 @@ class CUnitState;
|
||||
|
||||
class DLL_LINKAGE Unit : public IUnitInfo, public spells::Caster, public virtual IBonusBearer, public ACreature
|
||||
{
|
||||
static BattleHexArray::ArrayOfBattleHexArrays precomputeUnitHexes(BattleSide side, bool twoHex);
|
||||
|
||||
public:
|
||||
virtual ~Unit();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user