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:
parent
cb3723b54c
commit
e82cc56ddb
@ -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);
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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())
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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>();
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user