Skip to content

SRD: Spell Functions

Teekius edited this page Nov 14, 2024 · 2 revisions

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,

  1. Declare a pointer to spell functions within the global scope of your project. This is done as follows: SpellFunctions *spellAPI;

  2. Assign this pointer the address of Spell Functions within the main structure of the Spellforce Framework. Usually this is done as part of InitModule function after the framework was initialized. This is done in the following way: spellAPI = sfsf->spellAPI;

Functions

addSpell

Description:

This function creates a new spell of a given spell type. It accepts following arguments:

  1. The spell global object pointer.
  2. Spell type ID.
  3. 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).
  4. Spell source (a spell caster) entity index.
  5. Spell target entity index.
  6. 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);

To the top.


addToXData

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 1

To the top.


addVisualEffect

Description:

This function is used to spawn a visual effect. It requires the following arguments:

  1. The spell global object.
  2. Spell index (the unique index of a currently active spell).
  3. Effect type (predefined enumerator, e. g. kGdEffectSpellHitTarget).
  4. The argument which is currently unknown (can pass empty integer variable as it).
  5. 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.
  6. The internal game tick when the visual effect must appear.
  7. The amount of internal game ticks the spell must last.
  8. 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);

To the top.


checkCanApply

Description:

This function acts as a wrapper to call the Refresh handler associated with the given spell type. This function accepts the following arguments:

  1. Pointer to the spell global object.
  2. Spell index.

This function returns:

  1. 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
}

To the top.


figureAggro

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:

  1. Spell global object.
  2. Spell index (the unique index of a given spell).
  3. 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);

To the top.


figClrChkSplBfrChkBattle

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:

  1. Pointer to spell global object.
  2. Spell index.
  3. 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);

To the top.


figTryClrCHkSPlBfrJob2

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:

  1. Pointer to spell global object.
  2. Spell index.

Function Signature:

void figTryClrCHkSPlBfrJob2(SF_CGdSpell *_this, uint16_t spell_id);

Example Usage:

spellAPI->figTryClrCHkSPlBfrJob2(_this, spell_index);

To the top.


figTryUnfreeze

Description:

This function is used to clear spell flag UNFREEZE. It improves engine performance at the cost of disabling some spell functions.

  1. Pointer to spell global object.
  2. Spell index.
  3. 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);

To the top.


getChanceToResistSpell

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:

  1. 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.
  2. The entity index of a spell source (a spell caster).
  3. The entity index of a spell target (a figure which spell resistance we're trying to learn).
  4. 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);

To the top.


getRandom

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:

  1. Opaque class of spell global object.
  2. 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);

To the top.


getResourceSpellData

Description:

This function loads parameters of a spell from GameData.cff. This function accepts following arguments:

  1. The pointer to resource global object.
  2. The pointer to the structure of the SF_CGdResourceSpell type. The obtained spell parameters will be written in this variable.
  3. Spell effect ID.

This function returns:

  1. Optionally: Spell data stored in the structure belonging to the SF_CGdResourceSpell type.

Function Signature:

SF_CGdResourceSpell *getResourceSpellData(void *, SF_CGdResourceSpell *spellData, uint16_t index);

Example Usage:

spellAPI->getResourceSpellData(_this->SF_CGdResource, &spell_data, spell->spell_id);

To the top.


getSpellID

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:

  1. Pointer to spell global object.
  2. Spell index.

Function Signature:

uint16_t getSpellID(SF_CGdSpell *_this, uint16_t spell_index);

Example Usage:

spellAPI->getSpellID(_this->CGdSpell, spell_index);

To the top.


getSpellLine

Description:

This function is used to get spell type of a given spell. The function accepts following arguments:

  1. Pointer to spell global object.
  2. Spell index.

This function returns:

  1. 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);

To the top.


getSpellTag

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:

  1. Spell index.

Function Signature:

int getSpellTag(uint16_t spell_index);

Example Usage:

uint32_t spell_tag = getSpellTag(spell_index);

To the top.


getTargetsRectangle

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:

  1. Pointer to spell global object.
  2. Pointer to rectangle variable which stores the function output.
  3. Spell index.
  4. Spell radius.
  5. X-Y coordinates of the center.

This function returns:

  1. 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);

To the top.


getXData

Description:

This function is used to obtain a value of a specific XData key of a given spell. This function accepts following arguments:

  1. Pointer to spell global object.
  2. Spell index.
  3. Numerical XData key ID or its predefined enumerator.

This function returns:

  1. 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);

To the top.


initializeSpellData

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

To the top.


onSpellRemove

Description:

This function is triggered when a spell stops.

Function Signature:

void onSpellRemove(SF_CGdSpell *_this, uint16_t spell_id);

Example Usage:

To the top.


removeDLLNode

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:

  1. Pointer to spell global object.
  2. Spell index.

Function Signature:

void removeDLLNode(SF_CGdSpell *_this, uint16_t param_1);

Example Usage:

spellAPI->removeDLLNode(_this, spell_index);

To the top.


setEffectDone

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:

  1. Pointer to the spell global object.
  2. Spell index (the unique index of a currently active spell).
  3. 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);

To the top.


setXData

Description:

This function is used to assign specific value to an XData key of a given spell. The following arguments are required:

  1. Pointer to the spell global object.
  2. Spell index (the unique index of a currently active spell).
  3. The predefined enumerator of the XData Key.
  4. 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);

To the top.


spellClearFigureFlag

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:

  1. Pointer to spell global object.
  2. Spell index.
  3. Spell flag enumerator.
void spellClearFigureFlag(SF_CGdSpell *_this, uint16_t spell_id, SpellFlagKey key);

Example Usage:

spellAPI->spellClearFigureFlag(_this, spell_index, UNFREEZE);

To the top.

Types

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.

SF_GdSpell

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.

SF_CGdSpell

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.

SF_CGdResourceSpell

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.

SF_SpellEffectInfo

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.

Enums

kGdSpellLine

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

To the top.

SpellFlagKey

SpellFlagKey accepts the following flags:

    CHECK_SPELLS_BEFORE_CHECK_BATTLE = 0x04,
    CHECK_SPELLS_BEFORE_JOB2 = 0x02,
    UNFREEZE = 0x1

To the top.

SpellDataKey

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

To the top.

SpellDamagePhase

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.

To the top.

SpellTag

	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

Glossary

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

To the top.

Clone this wiki locally