-
Notifications
You must be signed in to change notification settings - Fork 1
SRD: Spell Functions
This page provides an overview of Spellforce Framework functions and types which you could use to manipulate all existing spells on the run, both standard and custom.
These functions are mostly stored within the sf_spell_functions.h header file. Please, note that you don't need to include that header in your project. It is automatically included as part of the sfsf.h general interface.
This page is up-to date for version of the Spellforce Framework 1.02-beta.
Below listed all functions you can find in sf_spell_functions.h. The spell functions can be accessed using spellAPI-> prefix, provided this group was previously initialized. In order to initialize the spell functions you should,
-
Declare a pointer to spell functions within the global scope of your project. This is done as follows:
SpellFunctions *spellAPI; -
Assign this pointer the address of Spell Functions within the main structure of the Spellforce Framework. Usually this is done as part of
InitModulefunction after the framework was initialized. This is done in the following way:spellAPI = sfsf->spellAPI;
Description:
This function creates a new spell of a given spell type. It accepts following arguments:
- The spell global object pointer.
- Spell type ID.
- The internal game tick when the spell should appear. The internal game tick can be determined via spell global object's opaque class (see Example Usage).
- Spell source (a spell caster) entity index.
- Spell target entity index.
- The purpose of the last argument is currently unknown, for safe use it's reasonable to pass it as 0.
Function Signature:
uint16_t addSpell(SF_CGdSpell *_this, uint16_t spell_id, uint16_t param2, SF_CGdTargetData *source, SF_CGdTargetData *target, uint16_t param5);Example Usage:
spellAPI->addSpell(_this->CGdSpell, spell_id, _this->OpaqueClass->current_step, &source, &target, 0);Description:
This function is used to add a specified value to a spell XData Key. It returns the summed value of the spell XData Key as a result. Function Signature:
uint32_t addToXData(SF_CGdSpell *_this, uint16_t spell_id, SpellDataKey key, uint32_t value);Example Usage:
uint8_t ticks_passed = spellAPI->addToXData(_this, spell_index, SPELL_TICK_COUNT_AUX, 1);
// after this function is called,
// both SPELL_TICK_COUNT_AUX and ticks_passed will become 1Description:
This function is used to spawn a visual effect. It requires the following arguments:
- The spell global object.
- Spell index (the unique index of a currently active spell).
- Effect type (predefined enumerator, e. g.
kGdEffectSpellHitTarget). - The argument which is currently unknown (can pass empty integer variable as it).
- The entity target data which the visual effect will be centered on. The X-Y coordinates passed as part of the target data will determine the visual effect offset relative to the target.
- The internal game tick when the visual effect must appear.
- The amount of internal game ticks the spell must last.
- The rectangle the visual effect must be entered into for AoE effects. Otherwise, the rectangle should be made having {0,0} diagonals.
Function Signature:
void addVisualEffect(SF_CGdSpell *_this, uint16_t spell_id, CGdEffectType effect_id, void *unused, SF_CGdTargetData *target, uint32_t tick_start, uint16_t tick_count, void *corner_coords);Example Usage:
spellAPI->addVisualEffect(_this, spell_index, kGdEffectSpellHitTarget, &unused, &relative_data, _this->OpaqueClass->current_step, 0, &aux_data);Description:
This function acts as a wrapper to call the Refresh handler associated with the given spell type. This function accepts the following arguments:
- Pointer to the spell global object.
- Spell index.
This function returns:
- The value the Refresh handler returned.
Function Signature:
int checkCanApply(SF_CGdSpell *_this, uint16_t index);Example Usage:
if (spellAPI->checkCanApply(_this, spell_index) == true)
{
// apply spell logic to a target
}Description:
This function must be used to trigger aggressive behavior for a figure which got attacked with a hostile spell. This function requires the following arguments:
- Spell global object.
- Spell index (the unique index of a given spell).
- Target entity index.
Function Signature:
void figureAggro(SF_CGdSpell *_this, uint16_t spell_id, uint16_t target_index);Example Usage:
spellAPI->figureAggro(_this, spell_index, target_index);Description:
This function is used to clear spell flag CHECK_SPELLS_BEFORE_CHECK_BATTLE. It improves engine performance at the cost of disabling some spell functions (e. g. Deal Damage and On Hit handlers can't be triggered without this flag raised). This function accepts following arguments:
- Pointer to spell global object.
- Spell index.
- The last argument is unknown. For safe use it should be passed as 0.
Function Signature:
void figClrChkSplBfrChkBattle(SF_CGdSpell *_this, uint16_t spell_id, uint16_t unk1);Example Usage:
spellAPI->figClrChkSplBfrChkBattle(_this, spell_index, 0);Description:
This function is used to clear spell flag CHECK_SPELLS_BEFORE_JOB2. It improves engine performance at the cost of disabling some spell functions (e. g. Deal Damage and On Hit handlers can't be triggered without this flag raised). This function accepts following arguments:
- Pointer to spell global object.
- Spell index.
Function Signature:
void figTryClrCHkSPlBfrJob2(SF_CGdSpell *_this, uint16_t spell_id);Example Usage:
spellAPI->figTryClrCHkSPlBfrJob2(_this, spell_index);Description:
This function is used to clear spell flag UNFREEZE. It improves engine performance at the cost of disabling some spell functions.
- Pointer to spell global object.
- Spell index.
- The last argument is unknown. For safe use it should be passed as 0.
Function Signature:
void figTryUnfreeze(SF_CGdSpell *_this, uint16_t spell_id, uint16_t unk1);Example Usage:
spellAPI->figTryUnfreeze(_this->CGdSpell, spell_index, 0);Description:
This functions returns target's resistance to a primary magic school which a specified spell belongs to. In case the spell has requirements for more than one magic school, the school with the highest requirement is regarded as primary.
The gotten number can be used either as a chance to resist the spell completely or as a number to mitigate the damage dealt with the spell. From the game engine point-of-view, those are the same number.
The function requires the following arguments:
- Spell global object parameter which is used for random calculations. Little is known about this parameter currently, so now it's accessed as
CGdSpell->unkn2. - The entity index of a spell source (a spell caster).
- The entity index of a spell target (a figure which spell resistance we're trying to learn).
- The spell effect info (spell effect ID and spell job ID grouped in a single variable of
SF_SpellEffectInfo).
Function Signature:
uint32_t getChanceToResistSpell(void *autoclass34, uint16_t source, uint16_t target, SF_SpellEffectInfo effect_info);Example Usage:
spell_resistance = spellAPI->getChanceToResistSpell(_this->CGdSpell->unkn2, source_index, target_index, effect_info);Description:
This function is used to obtain a random number in a range from 1 to X using internal random generator. This function accepts following arguments:
- Opaque class of spell global object.
- The value of X.
Function Signature:
uint16_t getRandom(void *autoclass14, uint16_t max_value);Example Usage:
uint16_t random_roll = spellAPI->getRandom(_this->OpaqueClass, 100);Description:
This function loads parameters of a spell from GameData.cff. This function accepts following arguments:
- The pointer to resource global object.
- The pointer to the structure of the
SF_CGdResourceSpelltype. The obtained spell parameters will be written in this variable. - Spell effect ID.
This function returns:
- Optionally: Spell data stored in the structure belonging to the
SF_CGdResourceSpelltype.
Function Signature:
SF_CGdResourceSpell *getResourceSpellData(void *, SF_CGdResourceSpell *spellData, uint16_t index);Example Usage:
spellAPI->getResourceSpellData(_this->SF_CGdResource, &spell_data, spell->spell_id);Description:
This function returns the spell effect ID of the given spell. The spell effect ID can be used to obtain spell parameters (such as damage, radius, duration, etc.) from GameData.cff. The function accepts following parameters:
- Pointer to spell global object.
- Spell index.
Function Signature:
uint16_t getSpellID(SF_CGdSpell *_this, uint16_t spell_index);Example Usage:
spellAPI->getSpellID(_this->CGdSpell, spell_index);Description:
This function is used to get spell type of a given spell. The function accepts following arguments:
- Pointer to spell global object.
- Spell index.
This function returns:
- Spell type ID.
Function Signature:
uint16_t getSpellLine(SF_CGdSpell *_this, uint16_t spell_id);Example Usage:
uint16_t spell_line_id = spellAPI->getSpellLine(figureToolbox->CGdSpell, spell_index);Description:
This function can be used to obtain a tag of a given spell. The spell tag determines spell additional behavior, such as spell belonging to summon category or being able to get triggered when it's source is attacked. This function accepts following arguments:
- Spell index.
Function Signature:
int getSpellTag(uint16_t spell_index);Example Usage:
uint32_t spell_tag = getSpellTag(spell_index);Description:
This function is used to calculate area of effect for a spell. Area of effect is calculated as a circle of given radius fit into a rectangle. The function accepts following arguments:
- Pointer to spell global object.
- Pointer to rectangle variable which stores the function output.
- Spell index.
- Spell radius.
- X-Y coordinates of the center.
This function returns:
- Optionally: rectangle covering all possible targets of a spell in area.
Function Signature:
SF_Rectangle *getTargetsRectangle(SF_CGdSpell *_this, SF_Rectangle *output, uint16_t spell_id, uint16_t radius, SF_Coord *center_maybe);Example Usage:
spellAPI->getTargetsRectangle(_this, &hit_area, spell_index, spell_data.params[0], &cast_center);Description:
This function is used to obtain a value of a specific XData key of a given spell. This function accepts following arguments:
- Pointer to spell global object.
- Spell index.
- Numerical XData key ID or its predefined enumerator.
This function returns:
- The value of a specified XData key of a given spell.
Function Signature:
uint32_t getXData(SF_CGdSpell *_this, uint16_t spell_id, SpellDataKey key);Example Usage:
uint32_t current_tick = spellAPI->getXData(_this, spell_index, SPELL_TICK_COUNT_AUX);Description:
This function is used to initialize the specific XData Key of a spell at start. The function sets the specified XData Key to 0.
Currently, this function seems to be redundant. The same effect can be achieved with setXData passing 0 as the value.
Function Signature:
void initializeSpellData(SF_CGdSpell *_this, uint16_t spell_id, SpellDataKey key);Example Usage:
spellAPI->initializeSpellData(_this, spell_index, SPELL_TICK_COUNT_AUX);Description:
This function is triggered when a spell stops.
Function Signature:
void onSpellRemove(SF_CGdSpell *_this, uint16_t spell_id);Example Usage:
Description:
This function is used to remove a spell from the list of active spells over the target. This function should be used together with setEffectDone in order to correctly finish the spell. The function accepts following arguments:
- Pointer to spell global object.
- Spell index.
Function Signature:
void removeDLLNode(SF_CGdSpell *_this, uint16_t param_1);Example Usage:
spellAPI->removeDLLNode(_this, spell_index);Description:
This function stops a Spell Effect handler of a given spell. Under normal conditions, it leads to the spell being automatically terminated during the next internal game tick. The function requires the following arguments:
- Pointer to the spell global object.
- Spell index (the unique index of a currently active spell).
- The purpose of the last argument is currently unknown. For safe use it should always be 0.
Function Signature:
void setEffectDone(SF_CGdSpell *_this, uint16_t spell_id, uint16_t param_2);Example Usage:
spellAPI->setEffectDone(_this, spell_index, 0);Description:
This function is used to assign specific value to an XData key of a given spell. The following arguments are required:
- Pointer to the spell global object.
- Spell index (the unique index of a currently active spell).
- The predefined enumerator of the XData Key.
- The value you wish to assign expressed as integer.
Function Signature:
void setXData(SF_CGdSpell *_this, uint16_t spell_id, uint8_t xdatakey, uint32_t value);Example Usage:
spellAPI->setXData(_this, spell_index, SPELL_TICK_COUNT_AUX, 0);Description:
Function Signature:
This function is used to clear a given spell flag of a spell. It works as a wrapper of more specific flag clearing functions, e. g. figClrChkSplBfrChkBattle, figTryClrCHkSPlBfrJob2. The function accepts following arguments:
- Pointer to spell global object.
- Spell index.
- Spell flag enumerator.
void spellClearFigureFlag(SF_CGdSpell *_this, uint16_t spell_id, SpellFlagKey key);Example Usage:
spellAPI->spellClearFigureFlag(_this, spell_index, UNFREEZE);Disclaimer:
We managed to reverse engineer the most important parameters for the framework functionality, but many fields still require additional researching. Even though some structures operate tens of fields, it will be unhandy to list every of them. For the sake of clarity, we list here only the fields which purpose is clear, or at least is somewhat understandable for us.
This structure is used to store a single specific instance of a spell. It uses the such parameters as
| Type | Member | Description |
|---|---|---|
| uint16_t | DLLNode | The spell starting node within engine classes. This value can be used to terminate a spell, when conventional stopping is impossible. |
| uint8_t | flags | The variable used to store spell flags. The flags are used to alternate the spell behavior, usually adding new functions at the cost of game performance. |
| uint16_t | spell_job | The spell job ID. The spell job determines the spell logic. This number is used to link Spell Type and Spell Effect handlers to each other. |
| uint16_t | spell_id | The spell effect ID. The spell effect determines spell's variable parameters such as damage, spell duration, range, etc. |
| uint16_t | spell_line | The spell type ID. The spell type determines the general behavior of the spell (e. g. Fireburst, Healing, Shelter and so on). |
| uint16_t | to_do_count | This value determines the remaining amount of internal game ticks for which the Spell Effect handler of a given spell won't be triggered. This value is used to optimize the behavior of spells designed to last for a specific duration. |
| SF_CGdTargetData | source | The spell source (commonly it's a spell caster) entity data. It stores the entity type (figure, building or object), the entity index and the entity's X-Y coordinates in game world. |
| SF_CGdTargetData | target | The spell target entity data. It stores entity type (figure, building or object), entity index and entity X-Y coordinates in game world. |
| uint16_t | xdata_key | The current usage is unknown. |
This type is used to store the global object which a specific instance of a spell belongs to. The variable of this type is usually received with majority of Spell handlers at the moment when they're triggered. The global object passes pointers to various game objects, including list of active spells, player controls, figure affected with a spell and figure jobs, but not limited by them. The spell global object possesses the following parameters:
| Type | Member | Description |
|---|---|---|
| OpaqueClass | AutoClass14 | Used by game engine to make random rolls. |
| Array[800] of SF_GdSpell | active_spell_list | The roster of every active spell in the game world. |
| *SF_CGdBuilding | CGdBuilding | The pointer to the buildings global object. |
| *SF_CGDEffect | SF_CGdEffect | The pointer to the effects global object. |
| *SF_CGdFigure | SF_CGdFigure | The pointer to the figure global object. |
| *SF_CGdFigureToolbox | SF_CGdFigureToolBox | The pointer to the figure toolbox global object. |
| *SF_CGdWorld | SF_CGdWorld | The pointer to the world global object. |
| *SF_CGdWorldToolBox | SF_CGdWorldToolBox | The pointer to the world toolbox global object. |
| void | unkn2 | Not much is known about this, but this parameter seems to be somehow used as the first parameter for getChanceToResistSpell. |
The variables of this type are used to store the spell data (spell parameters) loaded from the GameData.cff file. This structure possesses the following elements:
| Type | Member | Description |
|---|---|---|
| uint16_t | spell_id | The spell effect ID. The spell effect determines spell's variable parameters such as damage, spell duration, range, etc. |
| uint16_t | spell_line_id | The spell type ID. The spell type determines the general behavior of the spell (e. g. Fireburst, Healing, Shelter and so on). |
| Array[12] of uint8_t | skill_requirements | Skill requirements of the spell for every of 12 skills. |
| uint16_t | mana_cost | The spell mana cost. |
| uint32_t | cast_time | The spell casting time in milliseconds. |
| uint32_t | recast_time | The amount of time that must pass before the spell can be cast again. |
| uint16_t | min_range | The minimum range of the spell in game units. |
| uint16_t | max_range | The maximum range of the spell in game units. |
| uint8_t | cast_type1 | Target faction of the spell (allies, enemies, others). |
| uint8_t | cast_type2 | Target type of the spell (figure, building, object, area of effect, entire world). |
| uint32_t | params[10] | Spell parameters specific for the spell type such as damage, spell radius, amount of ticks, time between ticks, etc. |
| uint16_t | effect_power | <> |
| uint16_t | effect_range | The range of the spell's subeffect. |
This type is used to group spell parameters (spell effect ID) and spell logic (spell job ID) in a single variable. This presentation of data is required by some functions, e. g. getChanceToResistSpell. This structure possesses two parameters:
| Type | Member | Description |
|---|---|---|
| uint16_t | spell_job | The spell job ID. The spell job determines the spell logic. This number is used to link Spell Type and Spell Effect handlers to each other. |
| uint16_t | spell_id | The spell effect ID. The spell effect determines spell's variable parameters such as damage, spell duration, range, etc. |
kGdSpellLine is designed to provide an easy way to access spell types of all vanilla spells. It's much simpler to address the spell type by its name than to manually check it in GameData.cff.
kGdSpellLineFireBurst = 1,
kGdSpellLineHealing = 2,
kGdSpellLineDeath = 3,
kGdSpellLineSlowness = 4,
kGdSpellLinePoison = 5,
kGdSpellLineInvulnerability = 6,
kGdSpellLineCurePoison = 7,
kGdSpellLineFreeze = 9,
kGdSpellLineFog = 10,
// ...
/// 241 enums in total
SpellFlagKey accepts the following flags:
CHECK_SPELLS_BEFORE_CHECK_BATTLE = 0x04,
CHECK_SPELLS_BEFORE_JOB2 = 0x02,
UNFREEZE = 0x1
The every spell instance possesses own XData Keys which are used to control the spell logic and behavior. The list of all keys used by the game is provided below:
EFFECT_EFFECT_INDEX = 0x06,
EFFECT_SPELL_INDEX = 0x11,
EFFECT_SPELL_ID = 0x09,
EFFECT_ENTITY_INDEX2 = 0x1A,
EFFECT_SUBSPELL_ID = 0x1C,
EFFECT_PHYSICAL_DAMAGE = 0x1E,
EFFECT_ENTITY_INDEX = 0x2F,
EFFECT_ENTITY_INDEX3 = 0x2D,
EFFECT_ENTITY_TYPE = 0x30,
EFFECT_ENTITY_TYPE2 = 0x13,
EFFECT_DO_NOT_ADD_SUBSPELL = 0x33,
SPELL_TICK_COUNT_AUX = 0x05,
SPELL_TICK_COUNT = 0x12,
SPELL_DOUBLE_DAMAGE = 0x26,
SPELL_TARGET = 0x33,
SPELL_PESTILENCE_DAMAGE = 0x0E,
SPELL_STAT_MUL_MODIFIER = 0x0A,
SPELL_STAT_MUL_MODIFIER2 = 0x27,
SPELL_STAT_MUL_MODIFIER3 = 0x2B,
SPELL_STAT_MUL_MODIFIER4 = 0x2C,
SPELL_CONSERVATION_SHIELD = 0x0B
The Deal Damage Spell handler is triggered in one of three possible phases: PRE, DEFAULT or POST, which means
- before damage was modified by anything;
- after it was modified by spells;
- after it was modified by every factor possible (spells, resistances, armor).
PRE,
DEFAULT,
POST
This enum might also take the value of COUNT, but this phase is merely technical prop used to track the current phase of damage calculations.
NONE = 0,
SUMMON_SPELL,
DOMINATION_SPELL,
CHAIN_SPELL,
WHITE_AURA_SPELL, // In Future versions, we may be able to refactor AURA tags to be more dynamic
BLACK_AURA_SPELL,
TARGET_ONHIT_SPELL,
SPELL_TAG_COUNT
Here will come the glossary of most commonly used objects, parameters and values (WIP).
Spell ID
Spell Index
Spell Line
Spell Job
Spell Info
To Do Count