mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
Fixes issues related to spell mechanics
This commit is contained in:
parent
f550457d23
commit
b9cabef179
@ -132,7 +132,11 @@ void CRandomRewardObjectInfo::configureReward(CRewardableObject * object, CRando
|
||||
reward.artifacts = JsonRandom::loadArtifacts(source["artifacts"], rng);
|
||||
reward.spells = JsonRandom::loadSpells(source["spells"], rng, spells);
|
||||
reward.creatures = JsonRandom::loadCreatures(source["creatures"], rng);
|
||||
reward.casts = JsonRandom::loadSpells(source["casts"], rng, spells);
|
||||
if(!source["spellCast"].isNull() && source["spellCast"].isStruct())
|
||||
{
|
||||
reward.spellCast.first = JsonRandom::loadSpell(source["spellCast"]["spell"], rng);
|
||||
reward.spellCast.second = source["spellCast"]["schoolLevel"].Integer();
|
||||
}
|
||||
|
||||
for ( auto node : source["changeCreatures"].Struct() )
|
||||
{
|
||||
|
@ -363,13 +363,14 @@ void CRewardableObject::grantRewardAfterLevelup(const CRewardVisitInfo & info, c
|
||||
cb->giveCreatures(this, hero, creatures, false);
|
||||
}
|
||||
|
||||
if(!info.reward.casts.empty())
|
||||
if(info.reward.spellCast.first != SpellID::NONE)
|
||||
{
|
||||
caster = std::make_unique<spells::OuterCaster>(hero, SecSkillLevel::EXPERT);
|
||||
for(const auto & c : info.reward.casts)
|
||||
{
|
||||
cb->castSpell(caster.get(), c, int3{-1, -1, -1});
|
||||
}
|
||||
caster.setActualCaster(hero);
|
||||
caster.setSpellSchoolLevel(info.reward.spellCast.second);
|
||||
cb->castSpell(&caster, info.reward.spellCast.first, int3{-1, -1, -1});
|
||||
|
||||
if(info.reward.removeObject)
|
||||
logMod->warn("Removal of object with spell casts is not supported!");
|
||||
}
|
||||
else if(info.reward.removeObject) //FIXME: object can't track spell cancel or finish, so removeObject leads to crash
|
||||
cb->removeObject(this);
|
||||
|
@ -171,8 +171,8 @@ public:
|
||||
std::vector<SpellID> spells;
|
||||
std::vector<CStackBasicDescriptor> creatures;
|
||||
|
||||
/// actions that hero may execute and object caster
|
||||
std::vector<SpellID> casts;
|
||||
/// actions that hero may execute and object caster. Pair of spellID and school level
|
||||
std::pair<SpellID, int> spellCast;
|
||||
|
||||
/// list of components that will be added to reward description. First entry in list will override displayed component
|
||||
std::vector<Component> extraComponents;
|
||||
@ -195,7 +195,8 @@ public:
|
||||
movePoints(0),
|
||||
movePercentage(-1),
|
||||
primary(4, 0),
|
||||
removeObject(false)
|
||||
removeObject(false),
|
||||
spellCast(SpellID::NONE, SecSkillLevel::NONE)
|
||||
{}
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
@ -217,7 +218,8 @@ public:
|
||||
h & spells;
|
||||
h & creatures;
|
||||
h & creaturesChange;
|
||||
h & casts;
|
||||
if(version >= 821)
|
||||
h & spellCast;
|
||||
}
|
||||
};
|
||||
|
||||
@ -324,7 +326,7 @@ protected:
|
||||
bool onceVisitableObjectCleared;
|
||||
|
||||
/// caster to cast adveture spells
|
||||
mutable std::unique_ptr<spells::OuterCaster> caster;
|
||||
mutable spells::OuterCaster caster;
|
||||
|
||||
public:
|
||||
EVisitMode getVisitMode() const;
|
||||
|
@ -32,7 +32,7 @@ namespace JsonRandom
|
||||
};
|
||||
|
||||
DLL_LINKAGE si32 loadValue(const JsonNode & value, CRandomGenerator & rng, si32 defaultValue = 0);
|
||||
DLL_LINKAGE std::string loadKey(const JsonNode & value, CRandomGenerator & rng, const std::set<std::string> & valuesSet);
|
||||
DLL_LINKAGE std::string loadKey(const JsonNode & value, CRandomGenerator & rng, const std::set<std::string> & valuesSet = {});
|
||||
DLL_LINKAGE TResources loadResources(const JsonNode & value, CRandomGenerator & rng);
|
||||
DLL_LINKAGE TResources loadResource(const JsonNode & value, CRandomGenerator & rng);
|
||||
DLL_LINKAGE std::vector<si32> loadPrimary(const JsonNode & value, CRandomGenerator & rng);
|
||||
@ -41,8 +41,8 @@ namespace JsonRandom
|
||||
DLL_LINKAGE ArtifactID loadArtifact(const JsonNode & value, CRandomGenerator & rng);
|
||||
DLL_LINKAGE std::vector<ArtifactID> loadArtifacts(const JsonNode & value, CRandomGenerator & rng);
|
||||
|
||||
DLL_LINKAGE SpellID loadSpell(const JsonNode & value, CRandomGenerator & rng, std::vector<SpellID> spells);
|
||||
DLL_LINKAGE std::vector<SpellID> loadSpells(const JsonNode & value, CRandomGenerator & rng, const std::vector<SpellID> & spells);
|
||||
DLL_LINKAGE SpellID loadSpell(const JsonNode & value, CRandomGenerator & rng, std::vector<SpellID> spells = {});
|
||||
DLL_LINKAGE std::vector<SpellID> loadSpells(const JsonNode & value, CRandomGenerator & rng, const std::vector<SpellID> & spells = {});
|
||||
|
||||
DLL_LINKAGE CStackBasicDescriptor loadCreature(const JsonNode & value, CRandomGenerator & rng);
|
||||
DLL_LINKAGE std::vector<CStackBasicDescriptor> loadCreatures(const JsonNode & value, CRandomGenerator & rng);
|
||||
|
@ -122,13 +122,7 @@ void AdventureSpellMechanics::endCast(SpellCastEnvironment * env, const Adventur
|
||||
switch(result)
|
||||
{
|
||||
case ESpellCastResult::OK:
|
||||
{
|
||||
SetMana sm;
|
||||
sm.hid = ObjectInstanceID(parameters.caster->getCasterUnitId());
|
||||
sm.absolute = false;
|
||||
sm.val = -cost;
|
||||
env->apply(&sm);
|
||||
}
|
||||
parameters.caster->spendMana(env, cost);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -584,6 +578,9 @@ std::vector <const CGTownInstance*> TownPortalMechanics::getPossibleTowns(SpellC
|
||||
|
||||
int32_t TownPortalMechanics::movementCost(const AdventureSpellCastParameters & parameters) const
|
||||
{
|
||||
if(parameters.caster != parameters.caster->getHeroCaster()) //if caster is not hero
|
||||
return 0;
|
||||
|
||||
return GameConstants::BASE_MOVEMENT_COST * ((parameters.caster->getSpellSchoolLevel(owner) >= 3) ? 2 : 3);
|
||||
}
|
||||
|
||||
|
@ -17,10 +17,24 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
namespace spells
|
||||
{
|
||||
|
||||
OuterCaster::OuterCaster()
|
||||
: ProxyCaster(nullptr), schoolLevel(0)
|
||||
{
|
||||
}
|
||||
|
||||
OuterCaster::OuterCaster(const Caster * actualCaster_, int schoolLevel_)
|
||||
: ProxyCaster(actualCaster_), schoolLevel(schoolLevel_)
|
||||
{
|
||||
}
|
||||
|
||||
void OuterCaster::setActualCaster(const Caster * actualCaster_)
|
||||
{
|
||||
actualCaster = actualCaster_;
|
||||
}
|
||||
|
||||
void OuterCaster::setSpellSchoolLevel(int level)
|
||||
{
|
||||
schoolLevel = level;
|
||||
}
|
||||
|
||||
void OuterCaster::spendMana(ServerCallback * server, const int32_t spellCost) const
|
||||
|
@ -21,7 +21,11 @@ class DLL_LINKAGE OuterCaster : public ProxyCaster
|
||||
{
|
||||
int schoolLevel;
|
||||
public:
|
||||
OuterCaster();
|
||||
OuterCaster(const Caster * actualCaster_, int schoolLevel_);
|
||||
|
||||
void setActualCaster(const Caster * actualCaster);
|
||||
void setSpellSchoolLevel(int level);
|
||||
|
||||
int32_t getSpellSchoolLevel(const Spell * spell, int32_t * outSelectedSchool = nullptr) const override;
|
||||
void spendMana(ServerCallback * server, const int32_t spellCost) const override;
|
||||
|
Loading…
Reference in New Issue
Block a user