1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

vcmi: modernize lib/spells/effects

This commit is contained in:
Konstantin 2023-02-07 01:40:01 +03:00
parent cb3723b54c
commit e82cc56ddb
34 changed files with 154 additions and 355 deletions

View File

@ -32,17 +32,9 @@ namespace effects
VCMI_REGISTER_SPELL_EFFECT(Catapult, EFFECT_NAME); VCMI_REGISTER_SPELL_EFFECT(Catapult, EFFECT_NAME);
Catapult::Catapult()
: LocationEffect(),
targetsToAttack(0)
{
}
Catapult::~Catapult() = default;
bool Catapult::applicable(Problem & problem, const Mechanics * m) const bool Catapult::applicable(Problem & problem, const Mechanics * m) const
{ {
auto town = m->battle()->battleGetDefendedTown(); const auto *town = m->battle()->battleGetDefendedTown();
if(nullptr == town) if(nullptr == town)
{ {
@ -113,7 +105,7 @@ void Catapult::apply(ServerCallback * server, const Mechanics * m, const EffectT
if (attackInfo == ca.attackedParts.end()) // new part if (attackInfo == ca.attackedParts.end()) // new part
{ {
CatapultAttack::AttackInfo newInfo; CatapultAttack::AttackInfo newInfo{};
newInfo.damageDealt = 1; newInfo.damageDealt = 1;
newInfo.attackedPart = target; newInfo.attackedPart = target;
newInfo.destinationTile = m->battle()->wallPartToBattleHex(target); newInfo.destinationTile = m->battle()->wallPartToBattleHex(target);

View File

@ -22,16 +22,13 @@ namespace effects
class Catapult : public LocationEffect class Catapult : public LocationEffect
{ {
public: public:
Catapult();
virtual ~Catapult();
bool applicable(Problem & problem, const Mechanics * m) const override; bool applicable(Problem & problem, const Mechanics * m) const override;
void apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const override; void apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const override;
protected: protected:
void serializeJsonEffect(JsonSerializeFormat & handler) override; void serializeJsonEffect(JsonSerializeFormat & handler) override;
private: private:
int targetsToAttack; int targetsToAttack = 0;
}; };
} }

View File

@ -28,14 +28,6 @@ namespace effects
VCMI_REGISTER_SPELL_EFFECT(Clone, EFFECT_NAME); VCMI_REGISTER_SPELL_EFFECT(Clone, EFFECT_NAME);
Clone::Clone()
: UnitEffect(),
maxTier(0)
{
}
Clone::~Clone() = default;
void Clone::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const void Clone::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const
{ {
for(const Destination & dest : target) for(const Destination & dest : target)
@ -80,7 +72,7 @@ void Clone::apply(ServerCallback * server, const Mechanics * m, const EffectTarg
BattleUnitsChanged cloneFlags; BattleUnitsChanged cloneFlags;
auto cloneUnit = m->battle()->battleGetUnitByID(unitId); const auto *cloneUnit = m->battle()->battleGetUnitByID(unitId);
if(!cloneUnit) if(!cloneUnit)
{ {
@ -105,7 +97,7 @@ void Clone::apply(ServerCallback * server, const Mechanics * m, const EffectTarg
lifeTimeMarker.turnsRemain = m->getEffectDuration(); lifeTimeMarker.turnsRemain = m->getEffectDuration();
std::vector<Bonus> buffer; std::vector<Bonus> buffer;
buffer.push_back(lifeTimeMarker); buffer.push_back(lifeTimeMarker);
sse.toAdd.push_back(std::make_pair(unitId, buffer)); sse.toAdd.emplace_back(unitId, buffer);
server->apply(&sse); server->apply(&sse);
} }
} }

View File

@ -22,9 +22,6 @@ namespace effects
class Clone : public UnitEffect class Clone : public UnitEffect
{ {
public: public:
Clone();
virtual ~Clone();
void apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const override; void apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const override;
protected: protected:
bool isReceptive(const Mechanics * m, const battle::Unit * s) const override; bool isReceptive(const Mechanics * m, const battle::Unit * s) const override;
@ -32,7 +29,7 @@ protected:
void serializeJsonUnitEffect(JsonSerializeFormat & handler) override final; void serializeJsonUnitEffect(JsonSerializeFormat & handler) override final;
private: private:
int maxTier; int maxTier = 0;
}; };
} }

View File

@ -31,15 +31,6 @@ namespace effects
VCMI_REGISTER_SPELL_EFFECT(Damage, EFFECT_NAME); VCMI_REGISTER_SPELL_EFFECT(Damage, EFFECT_NAME);
Damage::Damage()
: UnitEffect(),
killByPercentage(false),
killByCount(false)
{
}
Damage::~Damage() = default;
void Damage::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const void Damage::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const
{ {
StacksInjured stacksInjured; StacksInjured stacksInjured;
@ -52,7 +43,7 @@ void Damage::apply(ServerCallback * server, const Mechanics * m, const EffectTar
uint32_t killed = 0; uint32_t killed = 0;
bool multiple = false; bool multiple = false;
for(auto & t : target) for(const auto & t : target)
{ {
const battle::Unit * unit = t.unitValue; const battle::Unit * unit = t.unitValue;
if(unit && unit->alive()) if(unit && unit->alive())

View File

@ -24,9 +24,6 @@ namespace effects
class Damage : public UnitEffect class Damage : public UnitEffect
{ {
public: public:
Damage();
virtual ~Damage();
void apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const override; void apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const override;
protected: protected:
@ -39,8 +36,8 @@ protected:
virtual void describeEffect(std::vector<MetaString> & log, const Mechanics * m, const battle::Unit * firstTarget, uint32_t kills, int64_t damage, bool multiple) const; virtual void describeEffect(std::vector<MetaString> & log, const Mechanics * m, const battle::Unit * firstTarget, uint32_t kills, int64_t damage, bool multiple) const;
private: private:
bool killByPercentage; bool killByPercentage = false;
bool killByCount; bool killByCount = false;
}; };
} }

View File

@ -28,15 +28,6 @@ namespace effects
VCMI_REGISTER_SPELL_EFFECT(DemonSummon, EFFECT_NAME); VCMI_REGISTER_SPELL_EFFECT(DemonSummon, EFFECT_NAME);
DemonSummon::DemonSummon()
: UnitEffect()
, creature(0)
, permanent(false)
{
}
DemonSummon::~DemonSummon() = default;
void DemonSummon::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const void DemonSummon::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const
{ {
BattleUnitsChanged pack; BattleUnitsChanged pack;
@ -60,7 +51,7 @@ void DemonSummon::apply(ServerCallback * server, const Mechanics * m, const Effe
break; break;
} }
auto creatureType = creature.toCreature(m->creatures()); const auto *creatureType = creature.toCreature(m->creatures());
int32_t deadCount = targetStack->unitBaseAmount(); int32_t deadCount = targetStack->unitBaseAmount();
int32_t deadTotalHealth = targetStack->getTotalHealth(); int32_t deadTotalHealth = targetStack->getTotalHealth();
@ -110,7 +101,7 @@ bool DemonSummon::isValidTarget(const Mechanics * m, const battle::Unit * s) con
if (s->isGhost()) if (s->isGhost())
return false; return false;
auto creatureType = creature.toCreature(m->creatures()); const auto *creatureType = creature.toCreature(m->creatures());
if (s->getTotalHealth() < creatureType->getMaxHealth()) if (s->getTotalHealth() < creatureType->getMaxHealth())
return false; return false;

View File

@ -23,9 +23,6 @@ namespace effects
class DemonSummon : public UnitEffect class DemonSummon : public UnitEffect
{ {
public: public:
DemonSummon();
virtual ~DemonSummon();
void apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const override; void apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const override;
protected: protected:
bool isValidTarget(const Mechanics * m, const battle::Unit * s) const override; bool isValidTarget(const Mechanics * m, const battle::Unit * s) const override;
@ -33,9 +30,9 @@ protected:
void serializeJsonUnitEffect(JsonSerializeFormat & handler) override final; void serializeJsonUnitEffect(JsonSerializeFormat & handler) override final;
private: private:
CreatureID creature; CreatureID creature = CreatureID(0);
bool permanent; bool permanent = false;
}; };
} }

View File

@ -32,21 +32,13 @@ namespace effects
VCMI_REGISTER_SPELL_EFFECT(Dispel, EFFECT_NAME); VCMI_REGISTER_SPELL_EFFECT(Dispel, EFFECT_NAME);
Dispel::Dispel()
: UnitEffect()
{
}
Dispel::~Dispel() = default;
void Dispel::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const void Dispel::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const
{ {
const bool describe = server->describeChanges(); const bool describe = server->describeChanges();
SetStackEffect sse; SetStackEffect sse;
BattleLogMessage blm; BattleLogMessage blm;
for(auto & t : target) for(const auto & t : target)
{ {
const battle::Unit * unit = t.unitValue; const battle::Unit * unit = t.unitValue;
if(unit) if(unit)
@ -63,11 +55,11 @@ void Dispel::apply(ServerCallback * server, const Mechanics * m, const EffectTar
std::vector<Bonus> buffer; std::vector<Bonus> buffer;
auto bl = getBonuses(m, unit); auto bl = getBonuses(m, unit);
for(auto item : *bl) for(const auto& item : *bl)
buffer.emplace_back(*item); buffer.emplace_back(*item);
if(!buffer.empty()) if(!buffer.empty())
sse.toRemove.push_back(std::make_pair(unit->unitId(), buffer)); sse.toRemove.emplace_back(unit->unitId(), buffer);
} }
} }

View File

@ -27,9 +27,6 @@ namespace effects
class Dispel : public UnitEffect class Dispel : public UnitEffect
{ {
public: public:
Dispel();
virtual ~Dispel();
void apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const override; void apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const override;
protected: protected:

View File

@ -21,15 +21,6 @@ namespace spells
namespace effects namespace effects
{ {
Effect::Effect()
: indirect(false),
optional(false)
{
}
Effect::~Effect() = default;
bool Effect::applicable(Problem & problem, const Mechanics * m) const bool Effect::applicable(Problem & problem, const Mechanics * m) const
{ {
return true; return true;
@ -49,7 +40,7 @@ void Effect::serializeJson(JsonSerializeFormat & handler)
std::shared_ptr<Effect> Effect::create(const Registry * registry, const std::string & type) std::shared_ptr<Effect> Effect::create(const Registry * registry, const std::string & type)
{ {
auto factory = registry->find(type); const auto *factory = registry->find(type);
if(factory) if(factory)
{ {

View File

@ -43,13 +43,12 @@ using TargetType = spells::AimType;
class DLL_LINKAGE Effect class DLL_LINKAGE Effect
{ {
public: public:
bool indirect; bool indirect = false;
bool optional; bool optional = false;
std::string name; std::string name;
Effect(); virtual ~Effect() = default; //Required for child classes
virtual ~Effect();
// TODO: document me // TODO: document me
virtual void adjustTargetTypes(std::vector<TargetType> & types) const = 0; virtual void adjustTargetTypes(std::vector<TargetType> & types) const = 0;

View File

@ -29,7 +29,7 @@ Effects::Effects() = default;
Effects::~Effects() = default; Effects::~Effects() = default;
void Effects::add(const std::string & name, std::shared_ptr<Effect> effect, const int level) void Effects::add(const std::string & name, const std::shared_ptr<Effect>& effect, const int level)
{ {
effect->name = name; effect->name = name;
data.at(level)[name] = effect; data.at(level)[name] = effect;
@ -97,7 +97,7 @@ bool Effects::applicable(Problem & problem, const Mechanics * m, const Target &
void Effects::forEachEffect(const int level, const std::function<void(const Effect *, bool &)> & callback) const void Effects::forEachEffect(const int level, const std::function<void(const Effect *, bool &)> & callback) const
{ {
bool stop = false; bool stop = false;
for(auto one : data.at(level)) for(const auto& one : data.at(level))
{ {
callback(one.second.get(), stop); callback(one.second.get(), stop);
if(stop) if(stop)
@ -138,7 +138,7 @@ void Effects::serializeJson(const Registry * registry, JsonSerializeFormat & han
const JsonNode & effectMap = handler.getCurrent(); const JsonNode & effectMap = handler.getCurrent();
for(auto & p : effectMap.Struct()) for(const auto & p : effectMap.Struct())
{ {
const std::string & name = p.first; const std::string & name = p.first;

View File

@ -33,7 +33,7 @@ public:
Effects(); Effects();
virtual ~Effects(); virtual ~Effects();
void add(const std::string & name, std::shared_ptr<Effect> effect, const int level); void add(const std::string & name, const std::shared_ptr<Effect>& effect, const int level);
bool applicable(Problem & problem, const Mechanics * m) const; bool applicable(Problem & problem, const Mechanics * m) const;
bool applicable(Problem & problem, const Mechanics * m, const Target & aimPoint, const Target & spellTarget) const; bool applicable(Problem & problem, const Mechanics * m, const Target & aimPoint, const Target & spellTarget) const;

View File

@ -31,17 +31,6 @@ namespace effects
VCMI_REGISTER_SPELL_EFFECT(Heal, EFFECT_NAME); VCMI_REGISTER_SPELL_EFFECT(Heal, EFFECT_NAME);
Heal::Heal()
: UnitEffect(),
healLevel(EHealLevel::HEAL),
healPower(EHealPower::PERMANENT),
minFullUnits(0)
{
}
Heal::~Heal() = default;
void Heal::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const void Heal::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const
{ {
apply(m->getEffectValue(), server, m, target); apply(m->getEffectValue(), server, m, target);
@ -117,7 +106,7 @@ void Heal::serializeJsonUnitEffect(JsonSerializeFormat & handler)
void Heal::prepareHealEffect(int64_t value, BattleUnitsChanged & pack, BattleLogMessage & logMessage, RNG & rng, const Mechanics * m, const EffectTarget & target) const void Heal::prepareHealEffect(int64_t value, BattleUnitsChanged & pack, BattleLogMessage & logMessage, RNG & rng, const Mechanics * m, const EffectTarget & target) const
{ {
for(auto & oneTarget : target) for(const auto & oneTarget : target)
{ {
const battle::Unit * unit = oneTarget.unitValue; const battle::Unit * unit = oneTarget.unitValue;

View File

@ -26,9 +26,6 @@ namespace effects
class Heal : public UnitEffect class Heal : public UnitEffect
{ {
public: public:
Heal();
virtual ~Heal();
void apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const override; void apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const override;
protected: protected:
@ -38,10 +35,10 @@ protected:
void serializeJsonUnitEffect(JsonSerializeFormat & handler) override final; void serializeJsonUnitEffect(JsonSerializeFormat & handler) override final;
private: private:
EHealLevel healLevel; EHealLevel healLevel = EHealLevel::HEAL;
EHealPower healPower; EHealPower healPower = EHealPower::PERMANENT;
int32_t minFullUnits; int32_t minFullUnits = 0;
void prepareHealEffect(int64_t value, BattleUnitsChanged & pack, BattleLogMessage & logMessage, RNG & rng, const Mechanics * m, const EffectTarget & target) const; void prepareHealEffect(int64_t value, BattleUnitsChanged & pack, BattleLogMessage & logMessage, RNG & rng, const Mechanics * m, const EffectTarget & target) const;
}; };

View File

@ -19,13 +19,6 @@ namespace spells
namespace effects namespace effects
{ {
LocationEffect::LocationEffect()
: Effect()
{
}
LocationEffect::~LocationEffect() = default;
void LocationEffect::adjustTargetTypes(std::vector<TargetType> & types) const void LocationEffect::adjustTargetTypes(std::vector<TargetType> & types) const
{ {
@ -33,7 +26,7 @@ void LocationEffect::adjustTargetTypes(std::vector<TargetType> & types) const
void LocationEffect::adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const void LocationEffect::adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const
{ {
for(auto & destnation : spellTarget) for(const auto & destnation : spellTarget)
hexes.insert(destnation.hexValue); hexes.insert(destnation.hexValue);
} }

View File

@ -23,9 +23,6 @@ namespace effects
class LocationEffect : public Effect class LocationEffect : public Effect
{ {
public: public:
LocationEffect();
virtual ~LocationEffect();
void adjustTargetTypes(std::vector<TargetType> & types) const override; void adjustTargetTypes(std::vector<TargetType> & types) const override;
void adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const override; void adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const override;

View File

@ -30,27 +30,9 @@ namespace effects
VCMI_REGISTER_SPELL_EFFECT(Obstacle, EFFECT_NAME); VCMI_REGISTER_SPELL_EFFECT(Obstacle, EFFECT_NAME);
ObstacleSideOptions::ObstacleSideOptions() using RelativeShape = std::vector<std::vector<BattleHex::EDir>>;
: shape(),
range()
{
}
void ObstacleSideOptions::serializeJson(JsonSerializeFormat & handler) static void serializeRelativeShape(JsonSerializeFormat & handler, const std::string & fieldName, RelativeShape & value)
{
serializeRelativeShape(handler, "shape", shape);
serializeRelativeShape(handler, "range", range);
handler.serializeString("appearSound", appearSound);
handler.serializeString("appearAnimation", appearAnimation);
handler.serializeString("triggerSound", triggerSound);
handler.serializeString("triggerAnimation", triggerAnimation);
handler.serializeString("animation", animation);
handler.serializeInt("offsetY", offsetY);
}
void ObstacleSideOptions::serializeRelativeShape(JsonSerializeFormat & handler, const std::string & fieldName, RelativeShape & value)
{ {
static const std::vector<std::string> EDirMap = static const std::vector<std::string> EDirMap =
{ {
@ -102,19 +84,19 @@ void ObstacleSideOptions::serializeRelativeShape(JsonSerializeFormat & handler,
} }
} }
Obstacle::Obstacle() void ObstacleSideOptions::serializeJson(JsonSerializeFormat & handler)
: LocationEffect(),
hidden(false),
passable(false),
trigger(false),
trap(false),
removeOnTrigger(false),
patchCount(1),
turnsRemaining(-1)
{ {
} serializeRelativeShape(handler, "shape", shape);
serializeRelativeShape(handler, "range", range);
Obstacle::~Obstacle() = default; handler.serializeString("appearSound", appearSound);
handler.serializeString("appearAnimation", appearAnimation);
handler.serializeString("triggerSound", triggerSound);
handler.serializeString("triggerAnimation", triggerAnimation);
handler.serializeString("animation", animation);
handler.serializeInt("offsetY", offsetY);
}
void Obstacle::adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const void Obstacle::adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const
{ {
@ -124,7 +106,7 @@ void Obstacle::adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics
for(auto & destination : effectTarget) for(auto & destination : effectTarget)
{ {
for(auto & trasformation : options.shape) for(const auto & trasformation : options.shape)
{ {
BattleHex hex = destination.hexValue; BattleHex hex = destination.hexValue;
@ -154,7 +136,7 @@ bool Obstacle::applicable(Problem & problem, const Mechanics * m, const EffectTa
for(const auto & destination : target) for(const auto & destination : target)
{ {
for(auto & trasformation : options.shape) for(const auto & trasformation : options.shape)
{ {
BattleHex hex = destination.hexValue; BattleHex hex = destination.hexValue;
for(auto direction : trasformation) for(auto direction : trasformation)
@ -177,9 +159,9 @@ EffectTarget Obstacle::transformTarget(const Mechanics * m, const Target & aimPo
if(!m->isMassive()) if(!m->isMassive())
{ {
for(auto & spellDestination : spellTarget) for(const auto & spellDestination : spellTarget)
{ {
for(auto & rangeShape : options.range) for(const auto & rangeShape : options.range)
{ {
BattleHex hex = spellDestination.hexValue; BattleHex hex = spellDestination.hexValue;
@ -330,7 +312,7 @@ void Obstacle::placeObstacles(ServerCallback * server, const Mechanics * m, cons
obstacle.customSize.clear(); obstacle.customSize.clear();
obstacle.customSize.reserve(options.shape.size()); obstacle.customSize.reserve(options.shape.size());
for(auto & shape : options.shape) for(const auto & shape : options.shape)
{ {
BattleHex hex = destination.hexValue; BattleHex hex = destination.hexValue;

View File

@ -35,22 +35,14 @@ public:
std::string triggerAnimation; std::string triggerAnimation;
std::string animation; std::string animation;
int offsetY; int offsetY = 0;
ObstacleSideOptions();
void serializeJson(JsonSerializeFormat & handler); void serializeJson(JsonSerializeFormat & handler);
private:
void serializeRelativeShape(JsonSerializeFormat & handler, const std::string & fieldName, RelativeShape & value);
}; };
class Obstacle : public LocationEffect class Obstacle : public LocationEffect
{ {
public: public:
Obstacle();
virtual ~Obstacle();
void adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const override; void adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const override;
bool applicable(Problem & problem, const Mechanics * m) const override; bool applicable(Problem & problem, const Mechanics * m) const override;
@ -64,13 +56,13 @@ protected:
void serializeJsonEffect(JsonSerializeFormat & handler) override; void serializeJsonEffect(JsonSerializeFormat & handler) override;
private: private:
bool hidden; bool hidden = false;
bool passable; bool passable = false;
bool trigger; bool trigger = false;
bool trap; bool trap = false;
bool removeOnTrigger; bool removeOnTrigger = false;
int32_t patchCount;//random patches to place, only for massive spells int32_t patchCount = 1;//random patches to place, only for massive spells
int32_t turnsRemaining; int32_t turnsRemaining = -1;
std::array<ObstacleSideOptions, 2> sideOptions; std::array<ObstacleSideOptions, 2> sideOptions;

View File

@ -23,9 +23,6 @@ namespace detail
class RegistryImpl : public Registry class RegistryImpl : public Registry
{ {
public: public:
RegistryImpl() = default;
~RegistryImpl() = default;
const IEffectFactory * find(const std::string & name) const override const IEffectFactory * find(const std::string & name) const override
{ {
auto iter = data.find(name); auto iter = data.find(name);
@ -46,10 +43,6 @@ private:
} }
Registry::Registry() = default;
Registry::~Registry() = default;
Registry * GlobalRegistry::get() Registry * GlobalRegistry::get()
{ {
static std::unique_ptr<Registry> Instance = std::make_unique<detail::RegistryImpl>(); static std::unique_ptr<Registry> Instance = std::make_unique<detail::RegistryImpl>();

View File

@ -40,8 +40,7 @@ class DLL_LINKAGE Registry
public: public:
using FactoryPtr = std::shared_ptr<IEffectFactory>; using FactoryPtr = std::shared_ptr<IEffectFactory>;
Registry(); virtual ~Registry() = default; //Required for child classes
virtual ~Registry();
virtual const IEffectFactory * find(const std::string & name) const = 0; virtual const IEffectFactory * find(const std::string & name) const = 0;
virtual void add(const std::string & name, FactoryPtr item) = 0; virtual void add(const std::string & name, FactoryPtr item) = 0;
}; };

View File

@ -31,16 +31,6 @@ namespace effects
VCMI_REGISTER_SPELL_EFFECT(RemoveObstacle, EFFECT_NAME); VCMI_REGISTER_SPELL_EFFECT(RemoveObstacle, EFFECT_NAME);
RemoveObstacle::RemoveObstacle()
: LocationEffect(),
removeAbsolute(false),
removeUsual(false),
removeAllSpells(false)
{
}
RemoveObstacle::~RemoveObstacle() = default;
bool RemoveObstacle::applicable(Problem & problem, const Mechanics * m) const bool RemoveObstacle::applicable(Problem & problem, const Mechanics * m) const
{ {
if (getTargets(m, EffectTarget(), true).empty()) if (getTargets(m, EffectTarget(), true).empty())
@ -80,7 +70,7 @@ bool RemoveObstacle::canRemove(const CObstacleInstance * obstacle) const
return true; return true;
if(removeUsual && obstacle->obstacleType == CObstacleInstance::USUAL) if(removeUsual && obstacle->obstacleType == CObstacleInstance::USUAL)
return true; return true;
auto spellObstacle = dynamic_cast<const SpellCreatedObstacle *>(obstacle); const auto *spellObstacle = dynamic_cast<const SpellCreatedObstacle *>(obstacle);
if(removeAllSpells && spellObstacle) if(removeAllSpells && spellObstacle)
return true; return true;

View File

@ -27,9 +27,6 @@ namespace effects
class RemoveObstacle : public LocationEffect class RemoveObstacle : public LocationEffect
{ {
public: public:
RemoveObstacle();
virtual ~RemoveObstacle();
bool applicable(Problem & problem, const Mechanics * m) const override; bool applicable(Problem & problem, const Mechanics * m) const override;
bool applicable(Problem & problem, const Mechanics * m, const EffectTarget & target) const override; bool applicable(Problem & problem, const Mechanics * m, const EffectTarget & target) const override;
@ -39,9 +36,9 @@ protected:
void serializeJsonEffect(JsonSerializeFormat & handler) override; void serializeJsonEffect(JsonSerializeFormat & handler) override;
private: private:
bool removeAbsolute; bool removeAbsolute = false;
bool removeUsual; bool removeUsual = false;
bool removeAllSpells; bool removeAllSpells = false;
std::set<SpellID> removeSpells; std::set<SpellID> removeSpells;

View File

@ -31,14 +31,6 @@ namespace effects
VCMI_REGISTER_SPELL_EFFECT(Sacrifice, EFFECT_NAME); VCMI_REGISTER_SPELL_EFFECT(Sacrifice, EFFECT_NAME);
Sacrifice::Sacrifice()
: Heal()
{
}
Sacrifice::~Sacrifice() = default;
void Sacrifice::adjustTargetTypes(std::vector<TargetType> & types) const void Sacrifice::adjustTargetTypes(std::vector<TargetType> & types) const
{ {
if(!types.empty()) if(!types.empty())
@ -109,7 +101,7 @@ bool Sacrifice::applicable(Problem & problem, const Mechanics * m, const EffectT
if(target.size() == 2) if(target.size() == 2)
{ {
auto victim = target.at(1).unitValue; const auto *victim = target.at(1).unitValue;
if(!victim) if(!victim)
return false; return false;
@ -160,7 +152,7 @@ EffectTarget Sacrifice::transformTarget(const Mechanics * m, const Target & aimP
//add victim //add victim
if(aimPoint.size() >= 2) if(aimPoint.size() >= 2)
{ {
auto victim = aimPoint.at(1).unitValue; const auto *victim = aimPoint.at(1).unitValue;
if(victim && getStackFilter(m, false, victim) && isReceptive(m, victim)) if(victim && getStackFilter(m, false, victim) && isReceptive(m, victim))
res.emplace_back(victim); res.emplace_back(victim);
} }
@ -168,7 +160,7 @@ EffectTarget Sacrifice::transformTarget(const Mechanics * m, const Target & aimP
return res; return res;
} }
int64_t Sacrifice::calculateHealEffectValue(const Mechanics * m, const battle::Unit * victim) const int64_t Sacrifice::calculateHealEffectValue(const Mechanics * m, const battle::Unit * victim)
{ {
return (m->getEffectPower() + victim->MaxHealth() + m->calculateRawEffectValue(0, 1)) * victim->getCount(); return (m->getEffectPower() + victim->MaxHealth() + m->calculateRawEffectValue(0, 1)) * victim->getCount();
} }

View File

@ -22,9 +22,6 @@ namespace effects
class Sacrifice : public Heal class Sacrifice : public Heal
{ {
public: public:
Sacrifice();
virtual ~Sacrifice();
void adjustTargetTypes(std::vector<TargetType> & types) const override; void adjustTargetTypes(std::vector<TargetType> & types) const override;
bool applicable(Problem & problem, const Mechanics * m) const override; bool applicable(Problem & problem, const Mechanics * m) const override;
@ -38,7 +35,7 @@ protected:
bool isValidTarget(const Mechanics * m, const battle::Unit * unit) const override; bool isValidTarget(const Mechanics * m, const battle::Unit * unit) const override;
private: private:
int64_t calculateHealEffectValue(const Mechanics * m, const battle::Unit * victim ) const; static int64_t calculateHealEffectValue(const Mechanics * m, const battle::Unit * victim);
}; };
} }

View File

@ -34,18 +34,6 @@ namespace effects
VCMI_REGISTER_SPELL_EFFECT(Summon, EFFECT_NAME); VCMI_REGISTER_SPELL_EFFECT(Summon, EFFECT_NAME);
Summon::Summon()
: Effect(),
creature(),
permanent(false),
exclusive(true),
summonByHealth(false),
summonSameUnit(false)
{
}
Summon::~Summon() = default;
void Summon::adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const void Summon::adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const
{ {
//no hexes affected //no hexes affected
@ -72,12 +60,12 @@ bool Summon::applicable(Problem & problem, const Mechanics * m) const
if(!otherSummoned.empty()) if(!otherSummoned.empty())
{ {
auto elemental = otherSummoned.front(); const auto *elemental = otherSummoned.front();
MetaString text; MetaString text;
text.addTxt(MetaString::GENERAL_TXT, 538); text.addTxt(MetaString::GENERAL_TXT, 538);
auto caster = dynamic_cast<const CGHeroInstance *>(m->caster); const auto *caster = dynamic_cast<const CGHeroInstance *>(m->caster);
if(caster) if(caster)
{ {
text.addReplacement(caster->getNameTranslated()); text.addReplacement(caster->getNameTranslated());
@ -105,7 +93,7 @@ void Summon::apply(ServerCallback * server, const Mechanics * m, const EffectTar
BattleUnitsChanged pack; BattleUnitsChanged pack;
for(auto & dest : target) for(const auto & dest : target)
{ {
if(dest.unitValue) if(dest.unitValue)
{ {
@ -122,7 +110,7 @@ void Summon::apply(ServerCallback * server, const Mechanics * m, const EffectTar
if(summonByHealth) if(summonByHealth)
{ {
auto creatureType = creature.toCreature(m->creatures()); const auto *creatureType = creature.toCreature(m->creatures());
auto creatureMaxHealth = creatureType->getMaxHealth(); auto creatureMaxHealth = creatureType->getMaxHealth();
amount = static_cast<int32_t>(valueWithBonus / creatureMaxHealth); amount = static_cast<int32_t>(valueWithBonus / creatureMaxHealth);
} }

View File

@ -23,9 +23,6 @@ namespace effects
class Summon : public Effect class Summon : public Effect
{ {
public: public:
Summon();
virtual ~Summon();
void adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const override; void adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const override;
void adjustTargetTypes(std::vector<TargetType> & types) const override; void adjustTargetTypes(std::vector<TargetType> & types) const override;
@ -43,10 +40,10 @@ protected:
private: private:
CreatureID creature; CreatureID creature;
bool permanent; bool permanent = false;
bool exclusive; bool exclusive = true;
bool summonByHealth; bool summonByHealth = false;
bool summonSameUnit; bool summonSameUnit = false;
}; };
} }

View File

@ -11,7 +11,6 @@
#include "Teleport.h" #include "Teleport.h"
#include "Registry.h" #include "Registry.h"
#include "Registry.h"
#include "../ISpellMechanics.h" #include "../ISpellMechanics.h"
#include "../../NetPacks.h" #include "../../NetPacks.h"
#include "../../battle/CBattleInfoCallback.h" #include "../../battle/CBattleInfoCallback.h"
@ -29,12 +28,6 @@ namespace effects
{ {
VCMI_REGISTER_SPELL_EFFECT(Teleport, EFFECT_NAME); VCMI_REGISTER_SPELL_EFFECT(Teleport, EFFECT_NAME);
Teleport::Teleport()
: UnitEffect()
{
}
Teleport::~Teleport() = default;
void Teleport::adjustTargetTypes(std::vector<TargetType> & types) const void Teleport::adjustTargetTypes(std::vector<TargetType> & types) const
{ {
@ -71,7 +64,7 @@ void Teleport::apply(ServerCallback * server, const Mechanics * m, const EffectT
return; return;
} }
auto targetUnit = target[0].unitValue; const auto *targetUnit = target[0].unitValue;
if(nullptr == targetUnit) if(nullptr == targetUnit)
{ {
server->complain("No unit to teleport"); server->complain("No unit to teleport");

View File

@ -24,9 +24,6 @@ namespace effects
class Teleport : public UnitEffect class Teleport : public UnitEffect
{ {
public: public:
Teleport();
virtual ~Teleport();
void adjustTargetTypes(std::vector<TargetType> & types) const override; void adjustTargetTypes(std::vector<TargetType> & types) const override;
bool applicable(Problem & problem, const Mechanics * m) const override; bool applicable(Problem & problem, const Mechanics * m) const override;

View File

@ -29,14 +29,73 @@ namespace effects
VCMI_REGISTER_SPELL_EFFECT(Timed, EFFECT_NAME); VCMI_REGISTER_SPELL_EFFECT(Timed, EFFECT_NAME);
Timed::Timed() static void describeEffect(std::vector<MetaString> & log, const Mechanics * m, const std::vector<Bonus> & bonuses, const battle::Unit * target)
: UnitEffect(),
cumulative(false),
bonus()
{ {
} auto addLogLine = [&](const int32_t baseTextID, const boost::logic::tribool & plural)
{
MetaString line;
target->addText(line, MetaString::GENERAL_TXT, baseTextID, plural);
target->addNameReplacement(line, plural);
log.push_back(std::move(line));
};
Timed::~Timed() = default; if(m->getSpellIndex() == SpellID::DISEASE)
{
addLogLine(553, boost::logic::indeterminate);
return;
}
for(const auto & bonus : bonuses)
{
switch(bonus.type)
{
case Bonus::NOT_ACTIVE:
{
switch(bonus.subtype)
{
case SpellID::STONE_GAZE:
addLogLine(558, boost::logic::indeterminate);
return;
case SpellID::PARALYZE:
addLogLine(563, boost::logic::indeterminate);
return;
default:
break;
}
}
break;
case Bonus::POISON:
addLogLine(561, boost::logic::indeterminate);
return;
case Bonus::BIND_EFFECT:
addLogLine(-560, true);
return;
case Bonus::STACK_HEALTH:
{
if(bonus.val < 0)
{
BonusList unitHealth = *target->getBonuses(Selector::type()(Bonus::STACK_HEALTH));
auto oldHealth = unitHealth.totalValue();
unitHealth.push_back(std::make_shared<Bonus>(bonus));
auto newHealth = unitHealth.totalValue();
//"The %s shrivel with age, and lose %d hit points."
MetaString line;
target->addText(line, MetaString::GENERAL_TXT, 551);
target->addNameReplacement(line);
line.addReplacement(oldHealth - newHealth);
log.push_back(std::move(line));
return;
}
}
break;
default:
break;
}
}
}
void Timed::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const void Timed::apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const
{ {
@ -50,7 +109,7 @@ void Timed::apply(ServerCallback * server, const Mechanics * m, const EffectTarg
std::shared_ptr<const Bonus> addedValueBonus = nullptr; std::shared_ptr<const Bonus> addedValueBonus = nullptr;
std::shared_ptr<const Bonus> fixedValueBonus = nullptr; std::shared_ptr<const Bonus> fixedValueBonus = nullptr;
auto casterHero = dynamic_cast<const CGHeroInstance *>(m->caster); const auto *casterHero = dynamic_cast<const CGHeroInstance *>(m->caster);
if(casterHero) if(casterHero)
{ {
peculiarBonus = casterHero->getBonusLocalFirst(Selector::typeSubtype(Bonus::SPECIAL_PECULIAR_ENCHANT, m->getSpellIndex())); peculiarBonus = casterHero->getBonusLocalFirst(Selector::typeSubtype(Bonus::SPECIAL_PECULIAR_ENCHANT, m->getSpellIndex()));
@ -62,7 +121,7 @@ void Timed::apply(ServerCallback * server, const Mechanics * m, const EffectTarg
SetStackEffect sse; SetStackEffect sse;
BattleLogMessage blm; BattleLogMessage blm;
for(auto & t : target) for(const auto & t : target)
{ {
std::vector<Bonus> buffer; std::vector<Bonus> buffer;
std::copy(converted.begin(), converted.end(), std::back_inserter(buffer)); std::copy(converted.begin(), converted.end(), std::back_inserter(buffer));
@ -147,9 +206,9 @@ void Timed::apply(ServerCallback * server, const Mechanics * m, const EffectTarg
} }
if(cumulative) if(cumulative)
sse.toAdd.push_back(std::make_pair(affected->unitId(), buffer)); sse.toAdd.emplace_back(affected->unitId(), buffer);
else else
sse.toUpdate.push_back(std::make_pair(affected->unitId(), buffer)); sse.toUpdate.emplace_back(affected->unitId(), buffer);
} }
if(!(sse.toAdd.empty() && sse.toUpdate.empty())) if(!(sse.toAdd.empty() && sse.toUpdate.empty()))
@ -163,7 +222,7 @@ void Timed::convertBonus(const Mechanics * m, int32_t & duration, std::vector<Bo
{ {
int32_t maxDuration = 0; int32_t maxDuration = 0;
for(const std::shared_ptr<Bonus> & b : bonus) for(const auto & b : bonus)
{ {
Bonus nb(*b); Bonus nb(*b);
@ -189,74 +248,6 @@ void Timed::convertBonus(const Mechanics * m, int32_t & duration, std::vector<Bo
duration = maxDuration; duration = maxDuration;
} }
void Timed::describeEffect(std::vector<MetaString> & log, const Mechanics * m, const std::vector<Bonus> & bonuses, const battle::Unit * target) const
{
auto addLogLine = [&](const int32_t baseTextID, const boost::logic::tribool & plural)
{
MetaString line;
target->addText(line, MetaString::GENERAL_TXT, baseTextID, plural);
target->addNameReplacement(line, plural);
log.push_back(std::move(line));
};
if(m->getSpellIndex() == SpellID::DISEASE)
{
addLogLine(553, boost::logic::indeterminate);
return;
}
for(const auto & bonus : bonuses)
{
switch(bonus.type)
{
case Bonus::NOT_ACTIVE:
{
switch(bonus.subtype)
{
case SpellID::STONE_GAZE:
addLogLine(558, boost::logic::indeterminate);
return;
case SpellID::PARALYZE:
addLogLine(563, boost::logic::indeterminate);
return;
default:
break;
}
}
break;
case Bonus::POISON:
addLogLine(561, boost::logic::indeterminate);
return;
case Bonus::BIND_EFFECT:
addLogLine(-560, true);
return;
case Bonus::STACK_HEALTH:
{
if(bonus.val < 0)
{
BonusList unitHealth = *target->getBonuses(Selector::type()(Bonus::STACK_HEALTH));
auto oldHealth = unitHealth.totalValue();
unitHealth.push_back(std::make_shared<Bonus>(bonus));
auto newHealth = unitHealth.totalValue();
//"The %s shrivel with age, and lose %d hit points."
MetaString line;
target->addText(line, MetaString::GENERAL_TXT, 551);
target->addNameReplacement(line);
line.addReplacement(oldHealth - newHealth);
log.push_back(std::move(line));
return;
}
}
break;
default:
break;
}
}
}
void Timed::serializeJsonUnitEffect(JsonSerializeFormat & handler) void Timed::serializeJsonUnitEffect(JsonSerializeFormat & handler)
{ {
assert(!handler.saving); assert(!handler.saving);

View File

@ -26,12 +26,9 @@ namespace effects
class Timed : public UnitEffect class Timed : public UnitEffect
{ {
public: public:
bool cumulative; bool cumulative = false;
std::vector<std::shared_ptr<Bonus>> bonus; std::vector<std::shared_ptr<Bonus>> bonus;
Timed();
virtual ~Timed();
void apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const override; void apply(ServerCallback * server, const Mechanics * m, const EffectTarget & target) const override;
protected: protected:
@ -39,8 +36,6 @@ protected:
private: private:
void convertBonus(const Mechanics * m, int32_t & duration, std::vector<Bonus> & converted) const; void convertBonus(const Mechanics * m, int32_t & duration, std::vector<Bonus> & converted) const;
void describeEffect(std::vector<MetaString> & log, const Mechanics * m, const std::vector<Bonus> & bonuses, const battle::Unit * target) const;
}; };
} }

View File

@ -25,16 +25,6 @@ namespace spells
namespace effects namespace effects
{ {
UnitEffect::UnitEffect()
: Effect(),
chainLength(0),
chainFactor(0.0),
ignoreImmunity(false)
{
}
UnitEffect::~UnitEffect() = default;
void UnitEffect::adjustTargetTypes(std::vector<TargetType> & types) const void UnitEffect::adjustTargetTypes(std::vector<TargetType> & types) const
{ {
@ -42,7 +32,7 @@ void UnitEffect::adjustTargetTypes(std::vector<TargetType> & types) const
void UnitEffect::adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const void UnitEffect::adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const
{ {
for(auto & destnation : spellTarget) for(const auto & destnation : spellTarget)
hexes.insert(destnation.hexValue); hexes.insert(destnation.hexValue);
} }
@ -72,7 +62,7 @@ bool UnitEffect::applicable(Problem & problem, const Mechanics * m, const Effect
//stack effect is applicable if it affects at least one smart target //stack effect is applicable if it affects at least one smart target
//assume target correctly transformed, just reapply smart filter //assume target correctly transformed, just reapply smart filter
for(auto & item : target) for(const auto & item : target)
if(item.unitValue) if(item.unitValue)
if(getStackFilter(m, true, item.unitValue)) if(getStackFilter(m, true, item.unitValue))
return true; return true;
@ -127,7 +117,7 @@ EffectTarget UnitEffect::transformTargetByRange(const Mechanics * m, const Targe
{ {
//ignore spellTarget and add all stacks //ignore spellTarget and add all stacks
auto units = m->battle()->battleGetUnitsIf(mainFilter); auto units = m->battle()->battleGetUnitsIf(mainFilter);
for(auto unit : units) for(const auto *unit : units)
targets.insert(unit); targets.insert(unit);
} }
else else
@ -152,7 +142,7 @@ EffectTarget UnitEffect::transformTargetByRange(const Mechanics * m, const Targe
auto units = m->battle()->battleGetUnitsIf(predicate); auto units = m->battle()->battleGetUnitsIf(predicate);
for(auto unit : units) for(const auto *unit : units)
{ {
if(unit->alive()) if(unit->alive())
{ {
@ -188,7 +178,7 @@ EffectTarget UnitEffect::transformTargetByRange(const Mechanics * m, const Targe
EffectTarget effectTarget; EffectTarget effectTarget;
for(auto s : targets) for(const auto *s : targets)
effectTarget.push_back(Destination(s)); effectTarget.push_back(Destination(s));
return effectTarget; return effectTarget;
@ -217,7 +207,7 @@ EffectTarget UnitEffect::transformTargetByChain(const Mechanics * m, const Targe
return isValidTarget(m, unit); return isValidTarget(m, unit);
}); });
for(auto unit : possibleTargets) for(const auto *unit : possibleTargets)
{ {
for(auto hex : battle::Unit::getHexes(unit->getPosition(), unit->doubleWide(), unit->unitSide())) for(auto hex : battle::Unit::getHexes(unit->getPosition(), unit->doubleWide(), unit->unitSide()))
possibleHexes.insert(hex); possibleHexes.insert(hex);
@ -228,7 +218,7 @@ EffectTarget UnitEffect::transformTargetByChain(const Mechanics * m, const Targe
for(int32_t targetIndex = 0; targetIndex < chainLength; ++targetIndex) for(int32_t targetIndex = 0; targetIndex < chainLength; ++targetIndex)
{ {
auto unit = m->battle()->battleGetUnitByPos(destHex, true); const auto *unit = m->battle()->battleGetUnitByPos(destHex, true);
if(!unit) if(!unit)
break; break;

View File

@ -22,9 +22,6 @@ namespace effects
class UnitEffect : public Effect class UnitEffect : public Effect
{ {
public: public:
UnitEffect();
virtual ~UnitEffect();
void adjustTargetTypes(std::vector<TargetType> & types) const override; void adjustTargetTypes(std::vector<TargetType> & types) const override;
void adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const override; void adjustAffectedHexes(std::set<BattleHex> & hexes, const Mechanics * m, const Target & spellTarget) const override;
@ -41,8 +38,8 @@ public:
virtual bool eraseByImmunityFilter(const Mechanics * m, const battle::Unit * s) const; virtual bool eraseByImmunityFilter(const Mechanics * m, const battle::Unit * s) const;
protected: protected:
int32_t chainLength; int32_t chainLength = 0;
double chainFactor; double chainFactor = 0.0;
virtual bool isReceptive(const Mechanics * m, const battle::Unit * unit) const; virtual bool isReceptive(const Mechanics * m, const battle::Unit * unit) const;
virtual bool isSmartTarget(const Mechanics * m, const battle::Unit * unit, bool alwaysSmart) const; virtual bool isSmartTarget(const Mechanics * m, const battle::Unit * unit, bool alwaysSmart) const;
@ -52,7 +49,7 @@ protected:
virtual void serializeJsonUnitEffect(JsonSerializeFormat & handler) = 0; virtual void serializeJsonUnitEffect(JsonSerializeFormat & handler) = 0;
private: private:
bool ignoreImmunity; bool ignoreImmunity = false;
EffectTarget transformTargetByRange(const Mechanics * m, const Target & aimPoint, const Target & spellTarget) const; EffectTarget transformTargetByRange(const Mechanics * m, const Target & aimPoint, const Target & spellTarget) const;
EffectTarget transformTargetByChain(const Mechanics * m, const Target & aimPoint, const Target & spellTarget) const; EffectTarget transformTargetByChain(const Mechanics * m, const Target & aimPoint, const Target & spellTarget) const;