Adding a new spell tutorial
This tutorial steps you through making a new spell called Full Heal. This will be a simple copy of the heal spell with a modification to the amount healed. The focus here is on creating a new spell, but the basic steps are the same for talents and other abilities.
Contents
Overview
The process of adding a spell to the game is as follows:
- Create a new module that extends the single player game
- Create a new guitype that your spell exists under
- Create a new ability entry for your spell
- Create a custom script to handle your spell
- Create strings to describe your spell in the talent page and tool tips
- Testing it in the game
Before beginning ensure you read the article on editing 2DA files and how to convert them to GDA files for use in the game.
Creating your module
These are just some basic settings required so that your module extends the Single Player campaign.
- Load the toolset and select File > Manage Modules
- Click on New and fill in the following fields:
- Name: Full Heal
- Script: (none) (Click on the ... button and select (none))
- UID: full_heal
- Extended Module: Single Player
- Click Open to load your new module (it should be selected by default)
- Select Tools > Export > Generate Module XML
You now have a new module that will be loaded whenever you play the Single Player campaign.
Creating a new Spell Type
This step is not strictly necessary to get a new spell into the game, but is recommended. By doing this, your new spell will have its own category on the talents page. This is also how you can restrict which classes have access to the spell.
For more information on the columns we are modifying refer to the article on Guitypes.xls.
- Open up your 2DA folder, it should be at \Dragon Age\tools\Source\2DA
- Copy the file guitypes.xls to a new folder, for example C:\2DA
- Open the file and delete all the rows except the headings
- Create a new row with the following details:
- ID: 777
- Label: Divine Healer
- StringID: **** (we will replace this later with the proper string ID)
- TintColor: 0x888888 (I think this only matters if you are using the progress bar)
- BlendTree: ****
- Any remaining columns in between set to 0
- Save and close the file.
- Convert it to a GDA file
- To convert from XLS to GDA, there is an application called ExcelProcessor, which can be found in your installed Dragon Age directory - Dragon Age\tools\ResourceBuild\Processors. Just drag the XLS file onto the ExcelProcessor and it automatically converts it. See Compiling 2DAs for more detail.
- Copy the GDA to your module override folder (My Documents\Bioware\Dragon Age\AddIns\full_heal\module\override)
- Rename the file guitypes_fh.GDA
Creating a new ability entry
This is where you can specify the properties of your new spell. However for this example I'm just keeping it simple. I recommend reading this page to see what can be done: ABI_base.xls
- Open up the rules folder in your 2DA folder, it should be at \Dragon Age\tools\Source\2DA\rules
- Copy ABI_Base.xls to your 2DA folder
- Open the file and find the entry for HEAL
- Copy the whole row to the bottom of the file
- Delete the rest of the rows except for the headings
- Cut your row and paste it as the first row
- Make the following changes to your HEAL row
- ID: 777777
- label: FULL HEAL
- guitype: 777
- Save and close the file
- Convert it to a GDA file (For instructions see Compiling 2DAs)
- Copy the ABI_Base.GDA file to your module override folder (My Documents\Bioware\Dragon Age\AddIns\full_heal\module\override)
- Rename the file ABI_Base_fh.GDA
Preliminary Testing
At this stage we want to ensure that the above steps worked, and that the new spell appears in-game. Simply run the game and check the talents page for a mage character. Your spell should appear in its own category down the bottom. If it doesn't try the following:
- Check that the guitype for your ability in the ABI_base 2DA is the same as the id you set for your guitype in the guitypes 2DA
- Check that your GDA files are copied to the correct override folder
- Generate your module XML file again
Creating a custom spell script
The easiest way to do this is generally open the script that the spell you are copying references, copy it to a new file and modify the contents to suit your purposes. Spell scripting is a little beyond the scope of this tutorial so I've prepared a simple script already. What it does is calculate the maximum health of the target of the spell and then heal them for that amount.
- Select File > New > Script
- Set the following properties
- Resource Name: full_heal
- Folder: \
- Click OK to create the script
- Copy the contents of the script below into the script and click Save
The script should compile correctly if you check the log.
// ----------------------------------------------------------------------------- // full_heal.nss // ----------------------------------------------------------------------------- #include "log_h" #include "abi_templates" #include "sys_traps_h" #include "spell_constants_h" const int FULL_HEAL = 777777; void _HandleImpact(struct EventSpellScriptImpactStruct stEvent) { effect eEffect; //int bHostile = FALSE; // make sure there is a location, just in case if (IsObjectValid(stEvent.oTarget) == TRUE) { stEvent.lTarget = GetLocation(stEvent.oTarget); } // ------------------------------------------------------------------------- // Handle Spells // ------------------------------------------------------------------------- switch (stEvent.nAbility) { case FULL_HEAL: { float fHeal = GetCreatureProperty(stEvent.oTarget,7,PROPERTY_VALUE_TOTAL); eEffect = EffectHeal(fHeal); eEffect = SetEffectEngineInteger(eEffect, EFFECT_INTEGER_VFX, Ability_GetImpactObjectVfxId(stEvent.nAbility)); ApplyEffectOnObject(EFFECT_DURATION_TYPE_INSTANT, eEffect, stEvent.oTarget, 0.0f, stEvent.oCaster, stEvent.nAbility); break; } } // if(bHostile) // sending only for hostile spells //SendEventOnCastAt(stEvent.oTarget, stEvent.oCaster, stEvent.nAbility, bHostile); } void main() { event ev = GetCurrentEvent(); int nEventType = GetEventType(ev); switch(nEventType) { case EVENT_TYPE_SPELLSCRIPT_PENDING: { Ability_SetSpellscriptPendingEventResult(COMMAND_RESULT_SUCCESS); break; } case EVENT_TYPE_SPELLSCRIPT_CAST: { // Get a structure with the event parameters struct EventSpellScriptCastStruct stEvent = Events_GetEventSpellScriptCastParameters(ev); // Hand this through to cast_impact SetAbilityResult(stEvent.oCaster, stEvent.nResistanceCheckResult); break; } case EVENT_TYPE_SPELLSCRIPT_IMPACT: { // Get a structure with the event parameters struct EventSpellScriptImpactStruct stEvent = Events_GetEventSpellScriptImpactParameters(ev); Log_Trace(LOG_CHANNEL_COMBAT_ABILITY, GetCurrentScriptName() + ".EVENT_TYPE_SPELLSCRIPT_IMPACT",Log_GetAbilityNameById(stEvent.nAbility)); // Handle impact if (CheckSpellResistance(stEvent.oTarget, stEvent.oCaster, stEvent.nAbility) == FALSE) { _HandleImpact(stEvent); } else { UI_DisplayMessage(stEvent.oTarget, UI_MESSAGE_RESISTED); } break; } } }
Creating new Strings
This step allows you to set your own description for the spell and have it appear correctly in tool tips.
- Ensure your module is loaded in the toolset
- Select Tools > String Editor
- Right click in the empty space and select Insert > Insert String
- Set the Type to Spells
- Set the text to Divine Healer
- Click OK to save the string
- Make a note of the string ID generated and what it is for (in this case the Spell Type)
- Repeat the above steps for the following text (without the information in brackets):
- Full Heal (note it down as the spell name)
- The mage channels divine energy to completely heal the target from all battle damage. (note it down as the description)
The last string is for the tool tip, copy and paste the text below.
<name/> (<guitypename/>) <usetype/> Range: <range/> Activation: <cost/> Cooldown: <cooldown/>s <requirements/> <conditions/> <description/>
Once these strings are all created select Tools > Export > Export Talk Table. This will compile your strings into a talk table which can be used with the game.
Updating your ability
This step involves tweaking our new spell to use the strings we created as well as the custom script. We will also adjust the cost and cooldown to make it a bit more balanced.
For the following steps I recommend using GDApp to modify your GDA files rather than editing the excel files and recreating them. It can be found on the 3rd_party_extensions page.
- Open your ABI_base_fh.GDA file with GDApp
- Set the namestrref field to the string ID for your spell name
- Set the descstrref field to the string ID for your spell description
- Set the tooltipstrref field to the string ID for your spell tooltip
- Set the cost to 50
- Set the spellscript to full_heal.ncs
- Set the cooldown to 20
- Save the file
Next we modify the guitype:
- Open your guitypes_fh.GDA file with GDApp
- Set the stringid field to the string ID for your Spell Type
- Save the file
Now we have updated GDA files which reference our spell script and new strings. It should now function correctly in the game and look like any other spell.
Testing your new spell
Your new spell should be working and properly labeled in the game. You can select it when leveling up, or you can use a debug script to add your spell manually.
With the developer console enabled, have your mage character selected and type the following:
` runscript addtalent 777777
Advanced Topics
I will try and expand this section a bit later, but for now once you are confident with these steps, try the following:
- Change the icon for the spell to make it stand out more. You can use one from another spell or make your own
- Change the different values in ABI_base to alter the spell further
- Create a new talent using the same procedure but copy and modify a talent instead of a spell
- Set the ability field of the guitypes.xls to ensure your new ability type is only available to certain classes. This is how the specialization classes limit their abilities.