mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-21 21:17:49 +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)
|
side(Side)
|
||||||
{
|
{
|
||||||
health.init(); //???
|
health.init(); //???
|
||||||
|
doubleWideCached = battle::CUnitState::doubleWide();
|
||||||
}
|
}
|
||||||
|
|
||||||
CStack::CStack():
|
CStack::CStack():
|
||||||
@ -55,6 +56,7 @@ CStack::CStack(const CStackBasicDescriptor * stack, const PlayerColor & O, int I
|
|||||||
side(Side)
|
side(Side)
|
||||||
{
|
{
|
||||||
health.init(); //???
|
health.init(); //???
|
||||||
|
doubleWideCached = battle::CUnitState::doubleWide();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStack::localInit(BattleInfo * battleInfo)
|
void CStack::localInit(BattleInfo * battleInfo)
|
||||||
@ -404,4 +406,30 @@ void CStack::spendMana(ServerCallback * server, const int spellCost) const
|
|||||||
server->apply(ssp);
|
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
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
27
lib/CStack.h
27
lib/CStack.h
@ -23,7 +23,7 @@ struct BattleStackAttacked;
|
|||||||
class BattleInfo;
|
class BattleInfo;
|
||||||
|
|
||||||
//Represents STACK_BATTLE nodes
|
//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:
|
private:
|
||||||
ui32 ID = -1; //unique ID of stack
|
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)
|
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:
|
public:
|
||||||
const CStackInstance * base = nullptr; //garrison slot from which stack originates (nullptr for war machines, summoned cres, etc)
|
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;
|
BattleSide unitSide() const override;
|
||||||
PlayerColor unitOwner() const override;
|
PlayerColor unitOwner() const override;
|
||||||
SlotID unitSlot() const override;
|
SlotID unitSlot() const override;
|
||||||
|
bool doubleWide() const override { return doubleWideCached;};
|
||||||
|
|
||||||
std::string getDescription() const override;
|
std::string getDescription() const override;
|
||||||
|
|
||||||
@ -119,26 +123,7 @@ public:
|
|||||||
h & army;
|
h & army;
|
||||||
h & extSlot;
|
h & extSlot;
|
||||||
|
|
||||||
if(extSlot == SlotID::COMMANDER_SLOT_PLACEHOLDER)
|
postDeserialize(army, extSlot);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ private:
|
|||||||
void reset();
|
void reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CUnitStateDetached : public CUnitState
|
class DLL_LINKAGE CUnitStateDetached final : public CUnitState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit CUnitStateDetached(const IUnitInfo * unit_, const IBonusBearer * bonus_);
|
explicit CUnitStateDetached(const IUnitInfo * unit_, const IBonusBearer * bonus_);
|
||||||
|
@ -107,24 +107,34 @@ const BattleHexArray & Unit::getHexes(BattleHex assumedPos) const
|
|||||||
return getHexes(assumedPos, doubleWide(), unitSide());
|
return getHexes(assumedPos, doubleWide(), unitSide());
|
||||||
}
|
}
|
||||||
|
|
||||||
const BattleHexArray & Unit::getHexes(BattleHex assumedPos, bool twoHex, BattleSide side)
|
BattleHexArray::ArrayOfBattleHexArrays Unit::precomputeUnitHexes(BattleSide side, bool twoHex)
|
||||||
{
|
{
|
||||||
static BattleHexArray::ArrayOfBattleHexArrays precomputed[4];
|
BattleHexArray::ArrayOfBattleHexArrays result;
|
||||||
int index = side == BattleSide::ATTACKER ? 0 : 2;
|
|
||||||
|
|
||||||
if(!precomputed[index + twoHex][assumedPos.toInt()].empty())
|
|
||||||
return precomputed[index + twoHex][assumedPos.toInt()];
|
|
||||||
|
|
||||||
// first run, compute
|
|
||||||
|
|
||||||
|
for (BattleHex assumedPos = 0; assumedPos < GameConstants::BFIELD_SIZE; ++assumedPos)
|
||||||
|
{
|
||||||
BattleHexArray hexes;
|
BattleHexArray hexes;
|
||||||
hexes.insert(assumedPos);
|
hexes.insert(assumedPos);
|
||||||
|
|
||||||
if(twoHex)
|
if(twoHex)
|
||||||
hexes.insert(occupiedHex(assumedPos, twoHex, side));
|
hexes.insert(occupiedHex(assumedPos, twoHex, side));
|
||||||
|
|
||||||
precomputed[index + twoHex][assumedPos.toInt()] = std::move(hexes);
|
result[assumedPos.toInt()] = std::move(hexes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BattleHexArray & Unit::getHexes(BattleHex assumedPos, bool twoHex, BattleSide side)
|
||||||
|
{
|
||||||
|
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;
|
||||||
return precomputed[index + twoHex][assumedPos.toInt()];
|
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
|
class DLL_LINKAGE Unit : public IUnitInfo, public spells::Caster, public virtual IBonusBearer, public ACreature
|
||||||
{
|
{
|
||||||
|
static BattleHexArray::ArrayOfBattleHexArrays precomputeUnitHexes(BattleSide side, bool twoHex);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~Unit();
|
virtual ~Unit();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user