1
0
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:
nordsoft 2023-04-10 17:08:24 +04:00
parent f550457d23
commit b9cabef179
7 changed files with 44 additions and 22 deletions

View File

@ -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() )
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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