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