2026-05-04 13:33:11 +03:00
|
|
|
/*
|
|
|
|
|
* SpellEffectHandler.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 "SpellEffectHandler.h"
|
|
|
|
|
|
2026-06-05 15:00:29 +03:00
|
|
|
#include "../../GameLibrary.h"
|
2026-05-27 00:38:55 +03:00
|
|
|
#include "../../json/JsonUtils.h"
|
2026-06-05 15:00:29 +03:00
|
|
|
#include "../../texts/CGeneralTextHandler.h"
|
|
|
|
|
#include "../../texts/TextIdentifier.h"
|
2026-05-27 00:38:55 +03:00
|
|
|
|
2026-05-04 13:33:11 +03:00
|
|
|
#include "Effect.h"
|
|
|
|
|
|
|
|
|
|
VCMI_LIB_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
|
|
namespace spells::effects
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
SpellEffectHandler::SpellEffectHandler()
|
|
|
|
|
{
|
2026-06-03 19:40:14 +03:00
|
|
|
|
2026-05-04 13:33:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<Effect> SpellEffectHandler::create(SpellEffectID effectID) const
|
|
|
|
|
{
|
|
|
|
|
const auto & effect = effectTypes.at(effectID.getNum());
|
|
|
|
|
const auto & factory = effectTypeFactories.at(effect.type);
|
|
|
|
|
|
2026-06-05 11:15:23 +03:00
|
|
|
return factory->create(effect.effectId);
|
2026-05-04 13:33:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpellEffectHandler::registerFactory(const std::string & typeName, std::shared_ptr<ISpellEffectFactory> factory)
|
|
|
|
|
{
|
|
|
|
|
effectTypeFactories[typeName] = factory;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<JsonNode> SpellEffectHandler::loadLegacyData()
|
|
|
|
|
{
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// loads single object into game. Scope is namespace of this object, same as name of source mod
|
|
|
|
|
void SpellEffectHandler::loadObject(std::string scope, std::string name, const JsonNode & data)
|
|
|
|
|
{
|
|
|
|
|
SpellEffectType newEffect;
|
|
|
|
|
newEffect.identifier = name;
|
|
|
|
|
newEffect.modScope = scope;
|
|
|
|
|
newEffect.type = data["type"].String();
|
|
|
|
|
newEffect.scriptName = data["script"].String();
|
|
|
|
|
newEffect.validationSchema = data["schema"];
|
|
|
|
|
|
2026-06-05 15:00:29 +03:00
|
|
|
for(const auto & item : data["stringRegistrations"].Vector())
|
|
|
|
|
newEffect.stringRegistrations.push_back(item.String());
|
|
|
|
|
|
2026-06-05 11:15:23 +03:00
|
|
|
const JsonNode & patchesNode = data["patches"];
|
|
|
|
|
if (patchesNode.isVector())
|
|
|
|
|
{
|
|
|
|
|
for (const auto & patchEntry : patchesNode.Vector())
|
|
|
|
|
newEffect.patches.emplace_back(patchEntry.getModScope(), patchEntry.String());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
newEffect.effectId = scope + ':' + name;
|
2026-05-04 13:33:11 +03:00
|
|
|
registerObject(scope, "spellEffect", name, data, effectTypes.size());
|
2026-06-05 11:15:23 +03:00
|
|
|
effectTypes.push_back(std::move(newEffect));
|
2026-05-04 13:33:11 +03:00
|
|
|
|
2026-06-05 11:15:23 +03:00
|
|
|
const auto & back = effectTypes.back();
|
|
|
|
|
const auto & factory = effectTypeFactories.at(back.type);
|
|
|
|
|
factory->initialize(back.effectId, back.modScope, back.scriptName, back.patches);
|
2026-05-04 13:33:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpellEffectHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index)
|
|
|
|
|
{
|
|
|
|
|
throw std::runtime_error("Not supported");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SpellEffectHandler::afterLoadFinalization()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-05 15:00:29 +03:00
|
|
|
void SpellEffectHandler::prepareEffect(SpellEffectID effectID, JsonNode & data, const std::string & spellScope, const std::string & spellIdentifier, const std::string & effectName) const
|
2026-05-27 00:38:55 +03:00
|
|
|
{
|
2026-06-05 15:00:29 +03:00
|
|
|
const auto & effectType = effectTypes.at(effectID.getNum());
|
|
|
|
|
const std::string validationName = spellScope + ":" + spellIdentifier + " effect " + effectName;
|
|
|
|
|
|
|
|
|
|
if(!effectType.validationSchema.isNull())
|
|
|
|
|
JsonUtils::validate(data, effectType.validationSchema, validationName);
|
|
|
|
|
|
|
|
|
|
for(const auto & field : effectType.stringRegistrations)
|
|
|
|
|
{
|
|
|
|
|
const JsonNode & fieldNode = static_cast<const JsonNode &>(data)[field];
|
|
|
|
|
if(fieldNode.isNull())
|
|
|
|
|
continue;
|
|
|
|
|
const std::string & value = fieldNode.String();
|
|
|
|
|
if(value.empty())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if(value.at(0) == '@')
|
|
|
|
|
{
|
|
|
|
|
data[field].String() = value.substr(1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TextIdentifier textID("spell", spellScope, spellIdentifier, effectName, field);
|
|
|
|
|
LIBRARY->generaltexth->registerString(spellScope, textID, fieldNode);
|
|
|
|
|
data[field].String() = textID.get();
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-05-27 00:38:55 +03:00
|
|
|
}
|
|
|
|
|
|
2026-05-04 13:33:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VCMI_LIB_NAMESPACE_END
|