mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Feature: Opposite Side Limiter. Added: Old saves support.
This commit is contained in:
parent
25d9ea1ddf
commit
2a39c401b8
@ -392,6 +392,20 @@ void CCreature::fillWarMachine()
|
||||
warMachine = ArtifactID::NONE; //this creature is not artifact
|
||||
}
|
||||
|
||||
void CCreature::updateOppositeBonuses()
|
||||
{
|
||||
auto & bonusList = getExportedBonusList();
|
||||
for(auto & bonus : bonusList)
|
||||
{
|
||||
if(bonus->effectRange == Bonus::ONLY_ENEMY_ARMY //Opposite Side bonuses should not be exported from CREATURE node.
|
||||
|| (bonus->propagator && bonus->propagator->getPropagatorType() == CBonusSystemNode::BATTLE))
|
||||
{
|
||||
bonus->effectRange == Bonus::ONLY_ENEMY_ARMY;
|
||||
bonus->propagator.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CCreatureHandler::CCreatureHandler()
|
||||
: expAfterUpgrade(0)
|
||||
{
|
||||
|
@ -223,12 +223,17 @@ public:
|
||||
{
|
||||
fillWarMachine();
|
||||
}
|
||||
if(version < 801 && !h.saving) // Opposite bonuses are introduced
|
||||
{
|
||||
updateOppositeBonuses();
|
||||
}
|
||||
}
|
||||
|
||||
CCreature();
|
||||
|
||||
private:
|
||||
void fillWarMachine();
|
||||
void updateOppositeBonuses();
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CCreatureHandler : public CHandlerBase<CreatureID, Creature, CCreature, CreatureService>
|
||||
|
@ -102,7 +102,7 @@ public:
|
||||
|
||||
private:
|
||||
void copyOppositeBonusesFromCreature(const CCreature * creature);
|
||||
STRONG_INLINE void removeOppositeBonuses();
|
||||
inline void removeOppositeBonuses();
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CCommanderInstance : public CStackInstance
|
||||
|
@ -833,7 +833,7 @@ std::shared_ptr<const Bonus> IBonusBearer::getBonus(const CSelector &selector) c
|
||||
|
||||
const CStack * retrieveStackBattle(const CBonusSystemNode * node)
|
||||
{
|
||||
switch (node->getNodeType())
|
||||
switch(node->getNodeType())
|
||||
{
|
||||
case CBonusSystemNode::STACK_BATTLE:
|
||||
return static_cast<const CStack*>(node);
|
||||
@ -844,7 +844,7 @@ const CStack * retrieveStackBattle(const CBonusSystemNode * node)
|
||||
|
||||
const CStackInstance * retrieveStackInstance(const CBonusSystemNode * node)
|
||||
{
|
||||
switch (node->getNodeType())
|
||||
switch(node->getNodeType())
|
||||
{
|
||||
case CBonusSystemNode::STACK_INSTANCE:
|
||||
return (static_cast<const CStackInstance *>(node));
|
||||
@ -857,15 +857,15 @@ const CStackInstance * retrieveStackInstance(const CBonusSystemNode * node)
|
||||
|
||||
PlayerColor CBonusSystemNode::retrieveNodeOwner(const CBonusSystemNode * node)
|
||||
{
|
||||
if (!node)
|
||||
if(!node)
|
||||
return PlayerColor::CANNOT_DETERMINE;
|
||||
|
||||
const CStack * stack = retrieveStackBattle(node);
|
||||
if (stack)
|
||||
if(stack)
|
||||
return stack->owner;
|
||||
|
||||
const CStackInstance * csi = retrieveStackInstance(node);
|
||||
if (csi && csi->armyObj)
|
||||
if(csi && csi->armyObj)
|
||||
return csi->armyObj->getOwner();
|
||||
|
||||
return PlayerColor::NEUTRAL;
|
||||
@ -1377,10 +1377,10 @@ void CBonusSystemNode::removedRedDescendant(CBonusSystemNode *descendant)
|
||||
TNodes redParents;
|
||||
getRedAncestors(redParents); //get all red parents recursively
|
||||
|
||||
for (auto parent : redParents)
|
||||
for(auto parent : redParents)
|
||||
{
|
||||
for (auto b : parent->exportedBonuses)
|
||||
if (b->propagator)
|
||||
for(auto b : parent->exportedBonuses)
|
||||
if(b->propagator)
|
||||
descendant->unpropagateBonus(b);
|
||||
}
|
||||
}
|
||||
@ -2336,6 +2336,52 @@ std::shared_ptr<Bonus> Bonus::addUpdater(TUpdaterPtr Updater)
|
||||
return this->shared_from_this();
|
||||
}
|
||||
|
||||
void Bonus::createOppositeLimiter()
|
||||
{
|
||||
if(limiter)
|
||||
{
|
||||
if(!dynamic_cast<OppositeSideLimiter *>(limiter.get()))
|
||||
{
|
||||
logMod->error("Wrong Limiter will be ignored: The 'ONLY_ENEMY_ARMY' effectRange is only compatible with the 'OPPOSITE_SIDE' limiter.");
|
||||
limiter.reset(new OppositeSideLimiter());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
limiter = std::make_shared<OppositeSideLimiter>();
|
||||
}
|
||||
}
|
||||
|
||||
void Bonus::createBattlePropagator()
|
||||
{
|
||||
if(propagator)
|
||||
{
|
||||
if(propagator->getPropagatorType() != CBonusSystemNode::BATTLE)
|
||||
{
|
||||
logMod->error("Wrong Propagator will be ignored: The 'ONLY_ENEMY_ARMY' effectRange is only compatible with the 'BATTLE_WIDE' propagator.");
|
||||
propagator.reset(new CPropagatorNodeType(CBonusSystemNode::BATTLE));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
propagator = std::make_shared<CPropagatorNodeType>(CBonusSystemNode::BATTLE);
|
||||
}
|
||||
}
|
||||
|
||||
void Bonus::updateOppositeBonuses()
|
||||
{
|
||||
if(effectRange == Bonus::ONLY_ENEMY_ARMY)
|
||||
{
|
||||
createBattlePropagator();
|
||||
createOppositeLimiter();
|
||||
}
|
||||
else if(limiter && dynamic_cast<OppositeSideLimiter *>(limiter.get()))
|
||||
{
|
||||
createBattlePropagator();
|
||||
effectRange = Bonus::ONLY_ENEMY_ARMY;
|
||||
}
|
||||
}
|
||||
|
||||
IUpdater::~IUpdater()
|
||||
{
|
||||
}
|
||||
|
@ -455,6 +455,10 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>
|
||||
{
|
||||
h & updater;
|
||||
}
|
||||
if(version < 801 && !h.saving) //Opposite Side bonuses are introduced
|
||||
{
|
||||
updateOppositeBonuses();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Ptr>
|
||||
@ -522,6 +526,10 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>
|
||||
std::shared_ptr<Bonus> addLimiter(TLimiterPtr Limiter); //returns this for convenient chain-calls
|
||||
std::shared_ptr<Bonus> addPropagator(TPropagatorPtr Propagator); //returns this for convenient chain-calls
|
||||
std::shared_ptr<Bonus> addUpdater(TUpdaterPtr Updater); //returns this for convenient chain-calls
|
||||
|
||||
inline void createOppositeLimiter();
|
||||
inline void createBattlePropagator();
|
||||
void updateOppositeBonuses();
|
||||
};
|
||||
|
||||
DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus);
|
||||
|
@ -751,38 +751,6 @@ std::shared_ptr<Bonus> JsonUtils::parseBuildingBonus(const JsonNode &ability, Bu
|
||||
return b;
|
||||
}
|
||||
|
||||
inline void createOppositeLimiter(Bonus * b)
|
||||
{
|
||||
if(b->limiter)
|
||||
{
|
||||
if(!dynamic_cast<OppositeSideLimiter *>(b->limiter.get()))
|
||||
{
|
||||
logMod->error("Wrong Limiter will be ignored: The 'ONLY_ENEMY_ARMY' effectRange is only compatible with the 'OPPOSITE_SIDE' limiter.");
|
||||
b->limiter.reset(new OppositeSideLimiter());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
b->limiter = std::make_shared<OppositeSideLimiter>();
|
||||
}
|
||||
}
|
||||
|
||||
inline void createBattlePropagator(Bonus * b)
|
||||
{
|
||||
if(b->propagator)
|
||||
{
|
||||
if(b->propagator->getPropagatorType() != CBonusSystemNode::BATTLE)
|
||||
{
|
||||
logMod->error("Wrong Propagator will be ignored: The 'ONLY_ENEMY_ARMY' effectRange is only compatible with the 'BATTLE_WIDE' propagator.");
|
||||
b->propagator.reset(new CPropagatorNodeType(CBonusSystemNode::BATTLE));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
b->propagator = std::make_shared<CPropagatorNodeType>(CBonusSystemNode::BATTLE);
|
||||
}
|
||||
}
|
||||
|
||||
bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b)
|
||||
{
|
||||
const JsonNode *value;
|
||||
@ -878,16 +846,7 @@ bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(b->effectRange == Bonus::ONLY_ENEMY_ARMY)
|
||||
{
|
||||
createBattlePropagator(b);
|
||||
createOppositeLimiter(b);
|
||||
}
|
||||
else if(b->limiter && dynamic_cast<OppositeSideLimiter *>(b->limiter.get()))
|
||||
{
|
||||
createBattlePropagator(b);
|
||||
b->effectRange = Bonus::ONLY_ENEMY_ARMY;
|
||||
}
|
||||
b->updateOppositeBonuses();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1089,9 +1089,9 @@ CBonusSystemNode * CGHeroInstance::whereShouldBeAttachedOnSiege(CGameState * gs)
|
||||
|
||||
CBonusSystemNode * CGHeroInstance::whereShouldBeAttached(CGameState * gs)
|
||||
{
|
||||
if (visitedTown)
|
||||
if(visitedTown)
|
||||
{
|
||||
if (inTownGarrison)
|
||||
if(inTownGarrison)
|
||||
return visitedTown;
|
||||
else
|
||||
return &visitedTown->townAndVis;
|
||||
|
@ -352,7 +352,7 @@ public:
|
||||
void afterAddToMap(CMap * map) override;
|
||||
static void reset();
|
||||
|
||||
STRONG_INLINE bool isBattleOutsideTown(const CGHeroInstance * defendingHero) const
|
||||
inline bool isBattleOutsideTown(const CGHeroInstance * defendingHero) const
|
||||
{
|
||||
return defendingHero && garrisonHero && defendingHero != garrisonHero;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "../ConstTransitivePtr.h"
|
||||
#include "../GameConstants.h"
|
||||
|
||||
const ui32 SERIALIZATION_VERSION = 800;
|
||||
const ui32 SERIALIZATION_VERSION = 801;
|
||||
const ui32 MINIMAL_SERIALIZATION_VERSION = 753;
|
||||
const std::string SAVEGAME_MAGIC = "VCMISVG";
|
||||
|
||||
|
@ -904,9 +904,9 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance * heroAttacker, con
|
||||
garrisonSwapOnSiege(heroDefender->visitedTown->id); //return defending visitor from garrison to its rightful place
|
||||
}
|
||||
//give exp
|
||||
if (battleResult.data->exp[0] && heroAttacker && battleResult.get()->winner == BattleSide::ATTACKER)
|
||||
if(battleResult.data->exp[0] && heroAttacker && battleResult.get()->winner == BattleSide::ATTACKER)
|
||||
changePrimSkill(heroAttacker, PrimarySkill::EXPERIENCE, battleResult.data->exp[0]);
|
||||
else if (battleResult.data->exp[1] && heroDefender && battleResult.get()->winner == BattleSide::DEFENDER)
|
||||
else if(battleResult.data->exp[1] && heroDefender && battleResult.get()->winner == BattleSide::DEFENDER)
|
||||
changePrimSkill(heroDefender, PrimarySkill::EXPERIENCE, battleResult.data->exp[1]);
|
||||
|
||||
queries.popIfTop(battleQuery);
|
||||
|
Loading…
Reference in New Issue
Block a user