1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-23 22:37:55 +02:00

Somewhat configurable spell schools

This commit is contained in:
Ivan Savenko
2025-06-09 16:54:35 +03:00
parent e0de65d56c
commit 4e47894e7a
17 changed files with 233 additions and 107 deletions

View File

@@ -33,7 +33,6 @@
#include "../widgets/VideoWidget.h" #include "../widgets/VideoWidget.h"
#include "../adventureMap/AdventureMapInterface.h" #include "../adventureMap/AdventureMapInterface.h"
#include "../../lib/CConfigHandler.h" #include "../../lib/CConfigHandler.h"
#include "../../lib/GameConstants.h" #include "../../lib/GameConstants.h"
#include "../../lib/GameLibrary.h" #include "../../lib/GameLibrary.h"
@@ -42,11 +41,21 @@
#include "../../lib/spells/CSpellHandler.h" #include "../../lib/spells/CSpellHandler.h"
#include "../../lib/spells/ISpellMechanics.h" #include "../../lib/spells/ISpellMechanics.h"
#include "../../lib/spells/Problem.h" #include "../../lib/spells/Problem.h"
#include "../../lib/spells/SpellSchoolHandler.h"
#include "../../lib/texts/CGeneralTextHandler.h" #include "../../lib/texts/CGeneralTextHandler.h"
#include "../../lib/texts/TextOperations.h" #include "../../lib/texts/TextOperations.h"
#include "../../lib/mapObjects/CGHeroInstance.h" #include "../../lib/mapObjects/CGHeroInstance.h"
// Ordering of spell school tabs in SpelTab.def
static const std::array schoolTabOrder =
{
SpellSchool::AIR,
SpellSchool::FIRE,
SpellSchool::WATER,
SpellSchool::EARTH,
SpellSchool::ANY
};
CSpellWindow::InteractiveArea::InteractiveArea(const Rect & myRect, std::function<void()> funcL, int helpTextId, CSpellWindow * _owner) CSpellWindow::InteractiveArea::InteractiveArea(const Rect & myRect, std::function<void()> funcL, int helpTextId, CSpellWindow * _owner)
{ {
addUsedEvents(LCLICK | SHOW_POPUP | HOVER); addUsedEvents(LCLICK | SHOW_POPUP | HOVER);
@@ -85,12 +94,11 @@ public:
if(A->getLevel() > B->getLevel()) if(A->getLevel() > B->getLevel())
return false; return false;
for (const auto schoolId : LIBRARY->spellSchoolHandler->getAllObjects())
for(auto schoolId = 0; schoolId < GameConstants::DEFAULT_SCHOOLS; schoolId++)
{ {
if(A->school.at(SpellSchool(schoolId)) && !B->school.at(SpellSchool(schoolId))) if(A->schools.count(schoolId) && !B->schools.count(schoolId))
return true; return true;
if(!A->school.at(SpellSchool(schoolId)) && B->school.at(SpellSchool(schoolId))) if(!A->schools.count(schoolId) && B->schools.count(schoolId))
return false; return false;
} }
@@ -423,7 +431,7 @@ void CSpellWindow::computeSpellsPerArea()
for(const CSpell * spell : mySpells) for(const CSpell * spell : mySpells)
{ {
if(spell->isCombat() ^ !battleSpellsOnly if(spell->isCombat() ^ !battleSpellsOnly
&& ((selectedTab == 4) || spell->school.at(SpellSchool(selectedTab))) && ((selectedTab == 4) || spell->schools.count(schoolTabOrder.at(selectedTab)))
) )
{ {
spellsCurSite.push_back(spell); spellsCurSite.push_back(spell);
@@ -726,7 +734,7 @@ void CSpellWindow::SpellArea::setSpell(const CSpell * spell)
mySpell = spell; mySpell = spell;
if(mySpell) if(mySpell)
{ {
SpellSchool whichSchool; //0 - air magic, 1 - fire magic, 2 - water magic, 3 - earth magic, SpellSchool whichSchool;
schoolLevel = owner->myHero->getSpellSchoolLevel(mySpell, &whichSchool); schoolLevel = owner->myHero->getSpellSchoolLevel(mySpell, &whichSchool);
auto spellCost = owner->myInt->cb->getSpellCost(mySpell, owner->myHero); auto spellCost = owner->myInt->cb->getSpellCost(mySpell, owner->myHero);
@@ -736,21 +744,14 @@ void CSpellWindow::SpellArea::setSpell(const CSpell * spell)
{ {
OBJECT_CONSTRUCTION; OBJECT_CONSTRUCTION;
static const std::array schoolBorders = {
AnimationPath::builtin("SplevA.def"),
AnimationPath::builtin("SplevF.def"),
AnimationPath::builtin("SplevW.def"),
AnimationPath::builtin("SplevE.def")
};
schoolBorder.reset(); schoolBorder.reset();
if (owner->selectedTab >= 4) if (owner->selectedTab >= 4)
{ {
if (whichSchool.hasValue()) if (whichSchool.hasValue())
schoolBorder = std::make_shared<CAnimImage>(schoolBorders.at(whichSchool.getNum()), schoolLevel); schoolBorder = std::make_shared<CAnimImage>(LIBRARY->spellSchoolHandler->getById(whichSchool)->getSpellBordersPath(), schoolLevel);
} }
else else
schoolBorder = std::make_shared<CAnimImage>(schoolBorders.at(owner->selectedTab), schoolLevel); schoolBorder = std::make_shared<CAnimImage>(LIBRARY->spellSchoolHandler->getById(schoolTabOrder.at(owner->selectedTab))->getSpellBordersPath(), schoolLevel);
} }
ColorRGBA firstLineColor, secondLineColor; ColorRGBA firstLineColor, secondLineColor;

View File

@@ -99,6 +99,10 @@
"config/spells/vcmiAbility.json", "config/spells/vcmiAbility.json",
"config/spells/moats.json" "config/spells/moats.json"
], ],
"spellSchools" :
[
"config/spellSchools.json"
],
"skills" : "skills" :
[ [
"config/skills.json" "config/skills.json"

View File

@@ -0,0 +1,19 @@
{
"type" : "object",
"$schema" : "http://json-schema.org/draft-04/schema",
"title" : "VCMI spell school format",
"description" : "Format used to define new spell schools in VCMI",
"required" : [ "schoolBorders" ],
"additionalProperties" : false,
"properties" : {
"index" : {
"type" : "number",
"description" : "numeric id of h3 spell school, prohibited for new schools"
},
"schoolBorders" : {
"type" : "string",
"description" : "File with frame borders of mastery levels for spells of this spell school in spellbook",
"format" : "animationFile"
}
}
}

21
config/spellSchools.json Normal file
View File

@@ -0,0 +1,21 @@
{
"air" : {
"index" : 0,
"schoolBorders" : "SplevA"
},
"fire" : {
"index" : 1,
"schoolBorders" : "SplevF"
},
"earth" : {
"index" : 2,
"schoolBorders" : "SplevE"
},
"water" : {
"index" : 3,
"schoolBorders" : "SplevW"
}
}

View File

@@ -255,6 +255,7 @@ set(lib_MAIN_SRCS
spells/ObstacleCasterProxy.cpp spells/ObstacleCasterProxy.cpp
spells/Problem.cpp spells/Problem.cpp
spells/ProxyCaster.cpp spells/ProxyCaster.cpp
spells/SpellSchoolHandler.cpp
spells/TargetCondition.cpp spells/TargetCondition.cpp
spells/ViewSpellInt.cpp spells/ViewSpellInt.cpp
@@ -699,6 +700,7 @@ set(lib_MAIN_HEADERS
spells/ObstacleCasterProxy.h spells/ObstacleCasterProxy.h
spells/Problem.h spells/Problem.h
spells/ProxyCaster.h spells/ProxyCaster.h
spells/SpellSchoolHandler.h
spells/TargetCondition.h spells/TargetCondition.h
spells/ViewSpellInt.h spells/ViewSpellInt.h

View File

@@ -18,6 +18,7 @@
#include "RiverHandler.h" #include "RiverHandler.h"
#include "TerrainHandler.h" #include "TerrainHandler.h"
#include "spells/CSpellHandler.h" #include "spells/CSpellHandler.h"
#include "spells/SpellSchoolHandler.h"
#include "spells/effects/Registry.h" #include "spells/effects/Registry.h"
#include "CSkillHandler.h" #include "CSkillHandler.h"
#include "entities/artifact/CArtHandler.h" #include "entities/artifact/CArtHandler.h"
@@ -178,6 +179,7 @@ void GameLibrary::initializeLibrary()
createHandler(biomeHandler); createHandler(biomeHandler);
createHandler(objh); createHandler(objh);
createHandler(objtypeh); createHandler(objtypeh);
createHandler(spellSchoolHandler);
createHandler(spellh); createHandler(spellh);
createHandler(skillh); createHandler(skillh);
createHandler(terviewh); createHandler(terviewh);

View File

@@ -40,6 +40,7 @@ class IHandlerBase;
class IGameSettings; class IGameSettings;
class GameSettings; class GameSettings;
class CIdentifierStorage; class CIdentifierStorage;
class SpellSchoolHandler;
#if SCRIPTING_ENABLED #if SCRIPTING_ENABLED
namespace scripting namespace scripting
@@ -78,6 +79,7 @@ public:
std::unique_ptr<CHeroClassHandler> heroclassesh; std::unique_ptr<CHeroClassHandler> heroclassesh;
std::unique_ptr<CCreatureHandler> creh; std::unique_ptr<CCreatureHandler> creh;
std::unique_ptr<CSpellHandler> spellh; std::unique_ptr<CSpellHandler> spellh;
std::unique_ptr<SpellSchoolHandler> spellSchoolHandler;
std::unique_ptr<CSkillHandler> skillh; std::unique_ptr<CSkillHandler> skillh;
// TODO: Remove ObjectHandler altogether? // TODO: Remove ObjectHandler altogether?
std::unique_ptr<CObjectHandler> objh; std::unique_ptr<CObjectHandler> objh;

View File

@@ -17,6 +17,7 @@
#include "../GameLibrary.h" #include "../GameLibrary.h"
#include "../IGameSettings.h" #include "../IGameSettings.h"
#include "spells/SpellSchoolHandler.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
@@ -59,22 +60,18 @@ bool BonusValueCache::hasBonus() const
MagicSchoolMasteryCache::MagicSchoolMasteryCache(const IBonusBearer * target) MagicSchoolMasteryCache::MagicSchoolMasteryCache(const IBonusBearer * target)
:target(target) :target(target)
,schools(LIBRARY->spellSchoolHandler->getAllObjects().size() + 1)
{} {}
void MagicSchoolMasteryCache::update() const void MagicSchoolMasteryCache::update() const
{ {
static const CSelector allBonusesSelector = Selector::type()(BonusType::MAGIC_SCHOOL_SKILL); static const CSelector allBonusesSelector = Selector::type()(BonusType::MAGIC_SCHOOL_SKILL);
static const std::array schoolsSelector = {
Selector::subtype()(SpellSchool::ANY),
Selector::subtype()(SpellSchool::AIR),
Selector::subtype()(SpellSchool::FIRE),
Selector::subtype()(SpellSchool::WATER),
Selector::subtype()(SpellSchool::EARTH),
};
auto list = target->getBonuses(allBonusesSelector); auto list = target->getBonuses(allBonusesSelector);
for (int i = 0; i < schoolsSelector.size(); ++i) schools[0] = list->valOfBonuses(Selector::subtype()(SpellSchool::ANY));
schools[i] = list->valOfBonuses(schoolsSelector[i]);
for (int i = 1; i < schools.size(); ++i)
schools[i] = list->valOfBonuses(Selector::subtype()(SpellSchool(i-1)));
version = target->getTreeVersion(); version = target->getTreeVersion();
} }

View File

@@ -171,7 +171,7 @@ class MagicSchoolMasteryCache
{ {
const IBonusBearer * target; const IBonusBearer * target;
mutable std::atomic<int32_t> version = 0; mutable std::atomic<int32_t> version = 0;
mutable std::array<std::atomic<int32_t>, 4+1> schools; mutable std::vector<std::atomic<int32_t>> schools;
void update() const; void update() const;
public: public:

View File

@@ -29,9 +29,10 @@
#include "modding/IdentifierStorage.h" #include "modding/IdentifierStorage.h"
#include "modding/ModScope.h" #include "modding/ModScope.h"
#include "GameLibrary.h" #include "GameLibrary.h"
#include "CCreatureHandler.h"//todo: remove #include "CCreatureHandler.h"
#include "spells/CSpellHandler.h" //todo: remove #include "spells/CSpellHandler.h"
#include "CSkillHandler.h"//todo: remove #include "spells/SpellSchoolHandler.h"
#include "CSkillHandler.h"
#include "entities/artifact/CArtifact.h" #include "entities/artifact/CArtifact.h"
#include "entities/faction/CFaction.h" #include "entities/faction/CFaction.h"
#include "entities/hero/CHero.h" #include "entities/hero/CHero.h"
@@ -39,7 +40,7 @@
#include "mapObjectConstructors/AObjectTypeHandler.h" #include "mapObjectConstructors/AObjectTypeHandler.h"
#include "constants/StringConstants.h" #include "constants/StringConstants.h"
#include "texts/CGeneralTextHandler.h" #include "texts/CGeneralTextHandler.h"
#include "TerrainHandler.h" //TODO: remove #include "TerrainHandler.h"
#include "RiverHandler.h" #include "RiverHandler.h"
#include "RoadHandler.h" #include "RoadHandler.h"
#include "BattleFieldHandler.h" #include "BattleFieldHandler.h"
@@ -77,8 +78,8 @@ const TeamID TeamID::NO_TEAM(-1);
const SpellSchool SpellSchool::ANY(-1); const SpellSchool SpellSchool::ANY(-1);
const SpellSchool SpellSchool::AIR(0); const SpellSchool SpellSchool::AIR(0);
const SpellSchool SpellSchool::FIRE(1); const SpellSchool SpellSchool::FIRE(1);
const SpellSchool SpellSchool::WATER(2); const SpellSchool SpellSchool::EARTH(2);
const SpellSchool SpellSchool::EARTH(3); const SpellSchool SpellSchool::WATER(3);
const FactionID FactionID::NONE(-2); const FactionID FactionID::NONE(-2);
const FactionID FactionID::DEFAULT(-1); const FactionID FactionID::DEFAULT(-1);
@@ -595,7 +596,7 @@ std::string SpellSchool::encode(const si32 index)
if (index == ANY.getNum()) if (index == ANY.getNum())
return "any"; return "any";
return SpellConfig::SCHOOL[index].jsonName; return LIBRARY->spellSchoolHandler->getById(SpellSchool(index))->getJsonKey();
} }
std::string SpellSchool::entityType() std::string SpellSchool::entityType()

View File

@@ -25,7 +25,6 @@ namespace GameConstants
constexpr int CREATURES_PER_TOWN = 8; //without upgrades constexpr int CREATURES_PER_TOWN = 8; //without upgrades
constexpr int SPELL_LEVELS = 5; constexpr int SPELL_LEVELS = 5;
constexpr int SPELL_SCHOOL_LEVELS = 4; constexpr int SPELL_SCHOOL_LEVELS = 4;
constexpr int DEFAULT_SCHOOLS = 4;
constexpr int CRE_LEVELS = 10; // number of creature experience levels constexpr int CRE_LEVELS = 10; // number of creature experience levels
constexpr int HERO_GOLD_COST = 2500; constexpr int HERO_GOLD_COST = 2500;

View File

@@ -39,6 +39,7 @@
#include "../mapObjectConstructors/CObjectClassesHandler.h" #include "../mapObjectConstructors/CObjectClassesHandler.h"
#include "../rmg/CRmgTemplateStorage.h" #include "../rmg/CRmgTemplateStorage.h"
#include "../spells/CSpellHandler.h" #include "../spells/CSpellHandler.h"
#include "../spells/SpellSchoolHandler.h"
#include "../GameLibrary.h" #include "../GameLibrary.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
@@ -248,6 +249,7 @@ void CContentHandler::init()
handlers.insert(std::make_pair("objects", ContentTypeHandler(LIBRARY->objtypeh.get(), "object"))); handlers.insert(std::make_pair("objects", ContentTypeHandler(LIBRARY->objtypeh.get(), "object")));
handlers.insert(std::make_pair("heroes", ContentTypeHandler(LIBRARY->heroh.get(), "hero"))); handlers.insert(std::make_pair("heroes", ContentTypeHandler(LIBRARY->heroh.get(), "hero")));
handlers.insert(std::make_pair("spells", ContentTypeHandler(LIBRARY->spellh.get(), "spell"))); handlers.insert(std::make_pair("spells", ContentTypeHandler(LIBRARY->spellh.get(), "spell")));
handlers.insert(std::make_pair("spellSchools", ContentTypeHandler(LIBRARY->spellSchoolHandler.get(), "spellSchool")));
handlers.insert(std::make_pair("skills", ContentTypeHandler(LIBRARY->skillh.get(), "skill"))); handlers.insert(std::make_pair("skills", ContentTypeHandler(LIBRARY->skillh.get(), "skill")));
handlers.insert(std::make_pair("templates", ContentTypeHandler(LIBRARY->tplh.get(), "template"))); handlers.insert(std::make_pair("templates", ContentTypeHandler(LIBRARY->tplh.get(), "template")));
#if SCRIPTING_ENABLED #if SCRIPTING_ENABLED

View File

@@ -23,10 +23,6 @@ VCMI_LIB_NAMESPACE_BEGIN
CIdentifierStorage::CIdentifierStorage() CIdentifierStorage::CIdentifierStorage()
{ {
//TODO: moddable spell schools
for (auto i = 0; i < GameConstants::DEFAULT_SCHOOLS; ++i)
registerObject(ModScope::scopeBuiltin(), "spellSchool", SpellConfig::SCHOOL[i].jsonName, SpellConfig::SCHOOL[i].id.getNum());
registerObject(ModScope::scopeBuiltin(), "spellSchool", "any", SpellSchool::ANY.getNum()); registerObject(ModScope::scopeBuiltin(), "spellSchool", "any", SpellSchool::ANY.getNum());
for (int i = 0; i < GameConstants::RESOURCE_QUANTITY; ++i) for (int i = 0; i < GameConstants::RESOURCE_QUANTITY; ++i)

View File

@@ -12,7 +12,6 @@
#include <cctype> #include <cctype>
#include "CBonusTypeHandler.h"
#include "CSpellHandler.h" #include "CSpellHandler.h"
#include "Problem.h" #include "Problem.h"
@@ -22,56 +21,23 @@
#include "../constants/StringConstants.h" #include "../constants/StringConstants.h"
#include "../battle/BattleInfo.h" #include "../CBonusTypeHandler.h"
#include "../battle/CBattleInfoCallback.h" #include "../battle/CBattleInfoCallback.h"
#include "../battle/Unit.h" #include "../battle/Unit.h"
#include "../json/JsonBonus.h" #include "../json/JsonBonus.h"
#include "../json/JsonUtils.h" #include "../json/JsonUtils.h"
#include "../GameLibrary.h" #include "../GameLibrary.h"
#include "../mapObjects/CGHeroInstance.h" //todo: remove
#include "../modding/IdentifierStorage.h" #include "../modding/IdentifierStorage.h"
#include "../modding/ModUtility.h"
#include "../serializer/CSerializer.h"
#include "../texts/CLegacyConfigParser.h" #include "../texts/CLegacyConfigParser.h"
#include "../texts/CGeneralTextHandler.h" #include "../texts/CGeneralTextHandler.h"
#include "ISpellMechanics.h" #include "ISpellMechanics.h"
#include "bonuses/BonusSelector.h"
#include "spells/SpellSchoolHandler.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
namespace SpellConfig static constexpr std::array LEVEL_NAMES = {"none", "basic", "advanced", "expert"};
{
static const std::string LEVEL_NAMES[] = {"none", "basic", "advanced", "expert"};
const spells::SchoolInfo SCHOOL[4] =
{
{
SpellSchool::AIR,
"air"
},
{
SpellSchool::FIRE,
"fire"
},
{
SpellSchool::WATER,
"water"
},
{
SpellSchool::EARTH,
"earth"
}
};
//order as described in http://bugs.vcmi.eu/view.php?id=91
static const SpellSchool SCHOOL_ORDER[4] =
{
SpellSchool::AIR, //=0
SpellSchool::FIRE, //=1
SpellSchool::EARTH,//=3(!)
SpellSchool::WATER //=2(!)
};
} //namespace SpellConfig
///CSpell ///CSpell
CSpell::CSpell(): CSpell::CSpell():
@@ -133,7 +99,7 @@ int64_t CSpell::calculateDamage(const spells::Caster * caster) const
bool CSpell::hasSchool(SpellSchool which) const bool CSpell::hasSchool(SpellSchool which) const
{ {
return school.count(which) && school.at(which); return schools.count(which);
} }
bool CSpell::canBeCast(const CBattleInfoCallback * cb, spells::Mode mode, const spells::Caster * caster) const bool CSpell::canBeCast(const CBattleInfoCallback * cb, spells::Mode mode, const spells::Caster * caster) const
@@ -159,13 +125,11 @@ spells::AimType CSpell::getTargetType() const
void CSpell::forEachSchool(const std::function<void(const SpellSchool &, bool &)>& cb) const void CSpell::forEachSchool(const std::function<void(const SpellSchool &, bool &)>& cb) const
{ {
bool stop = false; bool stop = false;
for(auto iter : SpellConfig::SCHOOL_ORDER) for(auto schoolID : LIBRARY->spellSchoolHandler->getAllObjects())
{ {
const spells::SchoolInfo & cnf = SpellConfig::SCHOOL[iter.getNum()]; if(schools.count(schoolID))
if(school.at(cnf.id))
{ {
cb(cnf.id, stop); cb(schoolID, stop);
if(stop) if(stop)
break; break;
} }
@@ -190,7 +154,7 @@ std::string CSpell::getNameTranslated() const
std::string CSpell::getDescriptionTextID(int32_t level) const std::string CSpell::getDescriptionTextID(int32_t level) const
{ {
TextIdentifier id("spell", modScope, identifier, "description", SpellConfig::LEVEL_NAMES[level]); TextIdentifier id("spell", modScope, identifier, "description", LEVEL_NAMES[level]);
return id.get(); return id.get();
} }
@@ -581,7 +545,6 @@ bool DLL_LINKAGE isInScreenRange(const int3 & center, const int3 & pos)
///CSpellHandler ///CSpellHandler
std::vector<JsonNode> CSpellHandler::loadLegacyData() std::vector<JsonNode> CSpellHandler::loadLegacyData()
{ {
using namespace SpellConfig;
std::vector<JsonNode> legacyData; std::vector<JsonNode> legacyData;
CLegacyConfigParser parser(TextPath::builtin("DATA/SPTRAITS.TXT")); CLegacyConfigParser parser(TextPath::builtin("DATA/SPTRAITS.TXT"));
@@ -757,8 +720,6 @@ std::shared_ptr<CSpell> CSpellHandler::loadFromJson(const std::string & scope, c
assert(identifier.find(':') == std::string::npos); assert(identifier.find(':') == std::string::npos);
assert(!scope.empty()); assert(!scope.empty());
using namespace SpellConfig;
SpellID id(static_cast<si32>(index)); SpellID id(static_cast<si32>(index));
auto spell = std::make_shared<CSpell>(); auto spell = std::make_shared<CSpell>();
@@ -783,11 +744,15 @@ std::shared_ptr<CSpell> CSpellHandler::loadFromJson(const std::string & scope, c
logMod->trace("%s: loading spell %s", __FUNCTION__, spell->getNameTranslated()); logMod->trace("%s: loading spell %s", __FUNCTION__, spell->getNameTranslated());
const auto schoolNames = json["school"]; for(const auto & schoolJson : json["school"].Struct())
for(const spells::SchoolInfo & info : SpellConfig::SCHOOL)
{ {
spell->school[info.id] = schoolNames[info.jsonName].Bool(); if (schoolJson.second.Bool())
{
LIBRARY->identifiers()->requestIdentifier(schoolJson.second.getModScope(), "spellSchool", schoolJson.first, [=](si32 schoolID)
{
spell->schools.emplace(schoolID);
});
}
} }
spell->castOnSelf = json["canCastOnSelf"].Bool(); spell->castOnSelf = json["canCastOnSelf"].Bool();

View File

@@ -35,21 +35,8 @@ namespace test
namespace spells namespace spells
{ {
class ISpellMechanicsFactory;
class ISpellMechanicsFactory; class IBattleCast;
class IBattleCast;
struct SchoolInfo
{
SpellSchool id; //backlink
std::string jsonName;
};
}
namespace SpellConfig
{
extern const spells::SchoolInfo SCHOOL[4];
} }
enum class VerticalPosition : ui8{TOP, CENTER, BOTTOM}; enum class VerticalPosition : ui8{TOP, CENTER, BOTTOM};
@@ -148,7 +135,7 @@ public:
using BTVector = std::vector<BonusType>; using BTVector = std::vector<BonusType>;
std::map<SpellSchool, bool> school; std::set<SpellSchool> schools;
std::map<FactionID, si32> probabilities; //% chance to gain for castles std::map<FactionID, si32> probabilities; //% chance to gain for castles
bool onlyOnWaterMap; //Spell will be banned on maps without water bool onlyOnWaterMap; //Spell will be banned on maps without water

View File

@@ -0,0 +1,56 @@
/*
* SpellSchoolHandler.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "SpellSchoolHandler.h"
#include "../json/JsonNode.h"
std::vector<JsonNode> SpellSchoolHandler::loadLegacyData()
{
objects.resize(4);
return std::vector<JsonNode>(4, JsonNode(JsonMap()));
}
std::shared_ptr<spells::SpellSchoolType> SpellSchoolHandler::loadObjectImpl(std::string scope, std::string name, const JsonNode & data, size_t index)
{
auto ret = std::make_shared<spells::SpellSchoolType>();
ret->id = SpellSchool(index);
ret->jsonName = name;
ret->spellBordersPath = AnimationPath::fromJson(data["schoolBorders"]);
return ret;
}
/// loads single object into game. Scope is namespace of this object, same as name of source mod
void SpellSchoolHandler::loadObject(std::string scope, std::string name, const JsonNode & data)
{
objects.push_back(loadObjectImpl(scope, name, data, objects.size()));
registerObject(scope, "spellSchool", name, objects.back()->getIndex());
}
void SpellSchoolHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index)
{
assert(objects[index] == nullptr); // ensure that this id was not loaded before
objects[index] = loadObjectImpl(scope, name, data, index);
registerObject(scope, "spellSchool", name, objects[index]->getIndex());
}
std::vector<SpellSchool> SpellSchoolHandler::getAllObjects() const
{
std::vector<SpellSchool> result;
for (const auto & school : objects)
result.push_back(school->id);
return result;
}

View File

@@ -0,0 +1,72 @@
/*
* SpellSchoolHandler.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "../constants/EntityIdentifiers.h"
#include "../IHandlerBase.h"
#include "../filesystem/ResourcePath.h"
VCMI_LIB_NAMESPACE_BEGIN
class SpellSchoolHandler;
namespace spells
{
class DLL_LINKAGE SpellSchoolType
{
friend class VCMI_LIB_WRAP_NAMESPACE(SpellSchoolHandler);
SpellSchool id; //backlink
std::string jsonName;
AnimationPath spellBordersPath;
public:
std::string getJsonKey() const
{
return jsonName;
}
AnimationPath getSpellBordersPath() const
{
return spellBordersPath;
}
int getIndex()
{
return id.getNum();
}
};
}
class DLL_LINKAGE SpellSchoolHandler : public IHandlerBase
{
std::shared_ptr<spells::SpellSchoolType> loadObjectImpl(std::string scope, std::string name, const JsonNode & data, size_t index);
public:
std::vector<JsonNode> loadLegacyData() override;
/// loads single object into game. Scope is namespace of this object, same as name of source mod
void loadObject(std::string scope, std::string name, const JsonNode & data) override;
void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override;
std::vector<SpellSchool> getAllObjects() const;
const spells::SpellSchoolType * getById(SpellSchool index) const
{
return objects.at(index).get();
}
private:
std::vector<std::shared_ptr<spells::SpellSchoolType>> objects;
};
VCMI_LIB_NAMESPACE_END