1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-21 00:19:29 +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
}
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)
{

View File

@ -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>

View File

@ -102,7 +102,7 @@ public:
private:
void copyOppositeBonusesFromCreature(const CCreature * creature);
STRONG_INLINE void removeOppositeBonuses();
inline void removeOppositeBonuses();
};
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();
}
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()
{
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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";