1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-27 12:22:45 +02:00

Feature: Opposite Side Limiter. Added: Old saves support.

This commit is contained in:
Dmitry Orlov 2021-08-19 01:45:28 +03:00
parent 25d9ea1ddf
commit 2a39c401b8
10 changed files with 89 additions and 57 deletions

View File

@ -392,6 +392,20 @@ void CCreature::fillWarMachine()
warMachine = ArtifactID::NONE; //this creature is not artifact 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() CCreatureHandler::CCreatureHandler()
: expAfterUpgrade(0) : expAfterUpgrade(0)
{ {

View File

@ -223,12 +223,17 @@ public:
{ {
fillWarMachine(); fillWarMachine();
} }
if(version < 801 && !h.saving) // Opposite bonuses are introduced
{
updateOppositeBonuses();
}
} }
CCreature(); CCreature();
private: private:
void fillWarMachine(); void fillWarMachine();
void updateOppositeBonuses();
}; };
class DLL_LINKAGE CCreatureHandler : public CHandlerBase<CreatureID, Creature, CCreature, CreatureService> class DLL_LINKAGE CCreatureHandler : public CHandlerBase<CreatureID, Creature, CCreature, CreatureService>

View File

@ -102,7 +102,7 @@ public:
private: private:
void copyOppositeBonusesFromCreature(const CCreature * creature); void copyOppositeBonusesFromCreature(const CCreature * creature);
STRONG_INLINE void removeOppositeBonuses(); inline void removeOppositeBonuses();
}; };
class DLL_LINKAGE CCommanderInstance : public CStackInstance class DLL_LINKAGE CCommanderInstance : public CStackInstance

View File

@ -2336,6 +2336,52 @@ std::shared_ptr<Bonus> Bonus::addUpdater(TUpdaterPtr Updater)
return this->shared_from_this(); 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() IUpdater::~IUpdater()
{ {
} }

View File

@ -455,6 +455,10 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>
{ {
h & updater; h & updater;
} }
if(version < 801 && !h.saving) //Opposite Side bonuses are introduced
{
updateOppositeBonuses();
}
} }
template <typename Ptr> 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> 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> addPropagator(TPropagatorPtr Propagator); //returns this for convenient chain-calls
std::shared_ptr<Bonus> addUpdater(TUpdaterPtr Updater); //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); DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus);

View File

@ -751,38 +751,6 @@ std::shared_ptr<Bonus> JsonUtils::parseBuildingBonus(const JsonNode &ability, Bu
return b; 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) bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b)
{ {
const JsonNode *value; const JsonNode *value;
@ -878,16 +846,7 @@ bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b)
break; break;
} }
} }
if(b->effectRange == Bonus::ONLY_ENEMY_ARMY) b->updateOppositeBonuses();
{
createBattlePropagator(b);
createOppositeLimiter(b);
}
else if(b->limiter && dynamic_cast<OppositeSideLimiter *>(b->limiter.get()))
{
createBattlePropagator(b);
b->effectRange = Bonus::ONLY_ENEMY_ARMY;
}
return true; return true;
} }

View File

@ -352,7 +352,7 @@ public:
void afterAddToMap(CMap * map) override; void afterAddToMap(CMap * map) override;
static void reset(); static void reset();
STRONG_INLINE bool isBattleOutsideTown(const CGHeroInstance * defendingHero) const inline bool isBattleOutsideTown(const CGHeroInstance * defendingHero) const
{ {
return defendingHero && garrisonHero && defendingHero != garrisonHero; return defendingHero && garrisonHero && defendingHero != garrisonHero;
} }

View File

@ -12,7 +12,7 @@
#include "../ConstTransitivePtr.h" #include "../ConstTransitivePtr.h"
#include "../GameConstants.h" #include "../GameConstants.h"
const ui32 SERIALIZATION_VERSION = 800; const ui32 SERIALIZATION_VERSION = 801;
const ui32 MINIMAL_SERIALIZATION_VERSION = 753; const ui32 MINIMAL_SERIALIZATION_VERSION = 753;
const std::string SAVEGAME_MAGIC = "VCMISVG"; const std::string SAVEGAME_MAGIC = "VCMISVG";