<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://datoolset.net/mw/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Craig+Graff</id>
		<title>Dragon Age Toolset Wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://datoolset.net/mw/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Craig+Graff"/>
		<link rel="alternate" type="text/html" href="https://datoolset.net/wiki/Special:Contributions/Craig_Graff"/>
		<updated>2026-08-19T14:23:28Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.25.6</generator>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=DEBUG_PrintToScreen&amp;diff=15574</id>
		<title>DEBUG PrintToScreen</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=DEBUG_PrintToScreen&amp;diff=15574"/>
				<updated>2011-01-24T11:50:45Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{dafunction&lt;br /&gt;
|name=DEBUG_PrintToScreen&lt;br /&gt;
|brief=Prints a string to all the client screens.&lt;br /&gt;
|param1type=string&lt;br /&gt;
|param1name=sString&lt;br /&gt;
|param1desc=The string value to print out to the screen&lt;br /&gt;
|param1default=&lt;br /&gt;
|param2type=int&lt;br /&gt;
|param2name=nPosFromTop&lt;br /&gt;
|param2desc=Where to output the string on the client's screen&lt;br /&gt;
|param2default=10&lt;br /&gt;
|param3type=float&lt;br /&gt;
|param3name=fLife&lt;br /&gt;
|param3desc=life for the string in seconds&lt;br /&gt;
|param3default=10.0&lt;br /&gt;
|returntype=void&lt;br /&gt;
|returndesc=&lt;br /&gt;
|sourcefile=script.ldf&lt;br /&gt;
|sourcemodule=&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&amp;lt;!-- This section contains the full description from the functions comments. Do not change unless you are confident these are incomplete or incorrect. --&amp;gt;&lt;br /&gt;
Prints the string sString to the screen in all the available clients.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- == Remarks == --&amp;gt;&lt;br /&gt;
&amp;lt;!-- This section contains additional comments, observations and known issues. --&amp;gt;&lt;br /&gt;
This function doesn't work in the retail version of the game. Use [[DisplayFloatyMessage]] or [[PrintToLog]] instead.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- == Examples == --&amp;gt;&lt;br /&gt;
&amp;lt;!-- This section contains examples transcluded from the snippet library. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- == See also == --&amp;gt;&lt;br /&gt;
&amp;lt;!-- This section contains links to articles, functions or constant groups. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category: Print &amp;amp; log functions]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=Useful_Scripts&amp;diff=12533</id>
		<title>Useful Scripts</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=Useful_Scripts&amp;diff=12533"/>
				<updated>2010-03-15T14:14:31Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: /* Insert content into an existing area */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox script}}&lt;br /&gt;
&lt;br /&gt;
This page lists how to accomplish tasks that are relatively simple and commonly needed, but that otherwise require deep scripting knowledge to figure out intuitively how to do.&lt;br /&gt;
&lt;br /&gt;
Feel free to add new sections describing any tricks or techniques you think is worth documenting. If the page becomes too large it can be split up into specific topics.&lt;br /&gt;
&lt;br /&gt;
See also: [[PRCSCR Script Templates]]&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
== Run a cutscene from a trigger ==&lt;br /&gt;
&lt;br /&gt;
Create a script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;events_h&amp;quot;&lt;br /&gt;
#include &amp;quot;global_objects_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
void main ()&lt;br /&gt;
{&lt;br /&gt;
    event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    int bEventHandled = FALSE;&lt;br /&gt;
    switch (nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_ENTER:&lt;br /&gt;
        {&lt;br /&gt;
            object oCreature = GetEventCreator(ev);&lt;br /&gt;
            if(GetObjectActive(OBJECT_SELF)&lt;br /&gt;
               &amp;amp;&amp;amp; IsPartyMember(oCreature)) &lt;br /&gt;
            { &lt;br /&gt;
                resource rCutscene = R&amp;quot;my_cutscene.cut&amp;quot;;&lt;br /&gt;
                CS_LoadCutscene(rCutscene);&lt;br /&gt;
                SetObjectActive(OBJECT_SELF, FALSE);&lt;br /&gt;
            }         &lt;br /&gt;
         }&lt;br /&gt;
         break;&lt;br /&gt;
    }&lt;br /&gt;
    if (!bEventHandled) //If this event wasn't handled by this script, let the core script try&lt;br /&gt;
    {&lt;br /&gt;
        HandleEvent(ev, RESOURCE_SCRIPT_TRIGGER_CORE);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And set it as the event script for the trigger that you want to have run the cutscene.&lt;br /&gt;
&lt;br /&gt;
== Add a follower to the player's party ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
if(IsPlayer(oCreature)) {&lt;br /&gt;
  object oFollower = GetObjectByTag(&amp;quot;myfollower&amp;quot;);&lt;br /&gt;
  UT_HireFollower(oCreature, oFollower);&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that with Toolset v1.0.982.0, calling UT_HireFollower() will result in a follower who's unable to gain xp. This happens due to the call of&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
  WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, '''TRUE''');&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
to the function&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
  void WR_SetFollowerState(object oCreature, int nState, int nSendEvent = TRUE, int nMinLevel = 0, '''int bPreventLevelup''' = FALSE)&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
To enable the xp gain, the flag CREATURE_REWARD_FLAGS needs to be cleared from the follower after the hired event was processed (there the flag is set). For now the best/easiest approach to take might be to make a copy of UT_HireFollower in an include file and rename it something like UT_HireFollower_Fixed, then make the following change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, TRUE);&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
to&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, bPreventLevelup);&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Have an enemy play possum and then get up to fight ==&lt;br /&gt;
&lt;br /&gt;
Set the creature's CREATURE_SPAWN_DEAD variable to 2.&lt;br /&gt;
&lt;br /&gt;
When it's time for the creature to rise and attack, execute the following script commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
WR_SetObjectActive(oCreature, TRUE);&lt;br /&gt;
SetCommandable(oCreature, TRUE);&lt;br /&gt;
// Make sure to set this flag back to 0 to avoid problems with savegames.&lt;br /&gt;
SetLocalInt(oCreature, CREATURE_SPAWN_DEAD, 0);&lt;br /&gt;
UT_CombatStart(oCreature, oPC);&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Insert content into an existing area ==&lt;br /&gt;
&lt;br /&gt;
If you want to add new content on to an existing area (for example, putting a new character or area transition door into an area that exists in the single-player campaign) there are two different ways to do it. One is to override the existing area with a new area of your own design that duplicates the original with the exception of your additions. This is straightforward to do but can interact poorly with other add-ons - you can only have one version of an area active at a time. '''[To Editor: Edit in a Custom Module or the existing Single Player Campaign Module?]'''&lt;br /&gt;
&lt;br /&gt;
A more elegant and extensible approach is to use a [[PRCSCR]]_-prefixed M2DA. The PRCSCR M2DA has a very simple structure and a simple but profound effect:&lt;br /&gt;
&lt;br /&gt;
*ID - a unique integer identifier for each row&lt;br /&gt;
*AreaListName - a string that identifies a specific area list, or the special keyword &amp;quot;any&amp;quot;.&lt;br /&gt;
*Script - the name of a script file.&lt;br /&gt;
&lt;br /&gt;
Whenever a player enters an area in an area list in this M2DA the associated script will be run. A modder can therefore include a script with his mod that will be run when the player enters an existing area that he didn't create. This script can freely add or remove placeables and creatures and perform whatever other modifications to the area that a script is capable of doing.&lt;br /&gt;
&lt;br /&gt;
Note that the script will be run every time the player enters the area, so you'll want to have an associated plot flag to ensure that the changes are only made once.&lt;br /&gt;
&lt;br /&gt;
The following example is a script that adds a new character from an add-on module to an existing area in the main game:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
// this is the name of a precreated plot file &amp;quot;joblos_quest&amp;quot; prefixed with the special &amp;quot;plt_&amp;quot;&lt;br /&gt;
// &amp;quot;plt_&amp;quot; + quest name allows you to reference the flag names as constants.&lt;br /&gt;
#include &amp;quot;plt_joblos_quest&amp;quot; &lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    //Check whether we've added Joblo already.&lt;br /&gt;
    if (WR_GetPlotFlag(PLT_JOBLOS_QUEST, JOBLO_ADDED_TO_TOWN) == FALSE)&lt;br /&gt;
    {&lt;br /&gt;
        object oTown = GetObjectByTag(&amp;quot;lot100ar_lothering&amp;quot;); //An area's tag is the same as its resource name&lt;br /&gt;
        vector vJobloLocation = Vector(126.745f, 120.724f, 0.460568f); // See below for how to get these coordinates&lt;br /&gt;
&lt;br /&gt;
        CreateObject(&lt;br /&gt;
            OBJECT_TYPE_CREATURE,&lt;br /&gt;
            R&amp;quot;joblo.utc&amp;quot;,&lt;br /&gt;
            Location(oTown, vJobloLocation, 180.0f); //See below for how to get the value for orientation&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
        WR_SetPlotFlag(&amp;quot;joblos_quest&amp;quot;, JOBLO_ADDED_TO_TOWN, TRUE);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since you can't add [[waypoint]]s to an existing area you'll need to enter the position and orientation values for the target location manually. You can find them by creating a local copy of the area in question and temporarily adding a waypoint to copy down the coordinates and orientation you'll need.&lt;br /&gt;
&lt;br /&gt;
== Create a lootable placeable that vanishes when looted ==&lt;br /&gt;
&lt;br /&gt;
For a player-usable placeable, use the following event script to make it give its contents to the player and then vanish when clicked on.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
event ev = GetCurrentEvent();&lt;br /&gt;
int nEventType = GetEventType(ev);&lt;br /&gt;
    switch (nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_USE:&lt;br /&gt;
        {&lt;br /&gt;
        //MoveAllItems(OBJECT_SELF, GetHero());&lt;br /&gt;
        AddCreatureMoney (1000000, GetHero(), TRUE);&lt;br /&gt;
        Safe_Destroy_Object(OBJECT_SELF);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you wanted to use standard resources you could achieve the same thing (though not destroying the placeable) simply by adding &amp;quot;_autoloot&amp;quot; to the end of the placeable's tag.&lt;br /&gt;
&lt;br /&gt;
== Move the player to a new area after a cutscene plays ==&lt;br /&gt;
&lt;br /&gt;
Stand-alone cutscenes have an &amp;quot;end script&amp;quot; parameter that sets a script to run once the cutscene ends. Use a script such as the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
   DoAreaTransition(&amp;quot;destination_area_tag&amp;quot;, &amp;quot;destination_waypoint_tag&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Override Events (e.g. those in player_core) ==&lt;br /&gt;
&lt;br /&gt;
Look here: [[Event override]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[category:tutorials]]&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=2DA&amp;diff=12394</id>
		<title>2DA</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=2DA&amp;diff=12394"/>
				<updated>2010-03-03T03:43:46Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: /* Users of Open Office */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Many of the properties of objects in the toolset make reference to 2DAs (two-dimensional arrays). These are read-only arrays containing various data used by scripting and the game engine. Each 2DA is simply an organized collection of strings and numbers. The specific function of each 2DA depends on how it is used by other systems in the game.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
== Overview - what is a 2DA? ==&lt;br /&gt;
&lt;br /&gt;
A 2DA contains a set of columns, with each column having a fixed label and a fixed data type. For example, the ABI_Base 2DA has a column that is labeled &amp;quot;namestrref&amp;quot; and has the data type &amp;quot;int&amp;quot;. This means that the data stored in this column must be an integer and that the data stored in this column can be retrieved by referring to the label &amp;quot;namestrref&amp;quot;. The number and types of columns in a 2DA does not usually ever change. The columns provide the structure of the 2DA that allows it to be referred to and used in a consistent manner. The first column of every 2DA is always labeled &amp;quot;ID&amp;quot; and is always of type &amp;quot;integer&amp;quot;. This column is used to uniquely identify the rows in the 2DA.&lt;br /&gt;
&lt;br /&gt;
A 2DA's rows are what contain the data being stored in it. Each row's columns have the same set of labels and data types (as defined at the top of the 2DA) but the data contained within them can be different. Adding new rows to a 2DA is common and easy; you just need to give it a new ID number in the &amp;quot;ID&amp;quot; column and then fill in the rest of the cells with whatever information you need. Once you've given a row an ID number it generally never changes. The game also has a mechanism called &amp;quot;M2DAs&amp;quot; that allow rows to be added to existing 2DAs without having to edit the original file, see below for more detail.&lt;br /&gt;
&lt;br /&gt;
Some 2DAs reference rows in other 2DAs. For example the ABI_Base 2DA has an integer column named &amp;quot;projectile&amp;quot;, and each row can have an integer in that column that identifies a row in the PRJ_Base 2DA. These relationships are generally only defined in the scripts that use the 2DAs and are not inherent to the 2DAs themselves so you'll have to keep track of these things yourself.&lt;br /&gt;
&lt;br /&gt;
== Excel file formatting ==&lt;br /&gt;
&lt;br /&gt;
The source files for 2DAs are Microsoft Excel worksheets. This allows a wide variety of sophisticated techniques to be used to generate the values of the 2DA fields, such as macros and formulas. It also makes editing much easier since the columns can be annotated and formatted in helpful ways, and multiple related worksheets can be grouped into one file. Before they can be used by the toolset or the game, 2DAs must be converted from Excel files into a more efficient form. Processed 2DAs are stored in files with the .[[GDA]] extension.&lt;br /&gt;
&lt;br /&gt;
''See: [[compiling 2DAs]]'' - for several methods of how to perform this conversion, and where to put 2DAs.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;2&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;700pt&amp;quot; align&amp;quot;left&amp;quot;&lt;br /&gt;
|+ '''Example Worksheet &amp;quot;Monsters&amp;quot;'''&lt;br /&gt;
| width=&amp;quot;30pt&amp;quot; style=&amp;quot;background-color:#808080&amp;quot; |'''ID'''&lt;br /&gt;
| width=&amp;quot;30pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Label'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Strenght'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Name'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''ResourceExample'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Scale'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''disabled'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Commentexample'''&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''int'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''string'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''int'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''string'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''resource'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''float'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''bool'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''comment'''''&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |0&lt;br /&gt;
|INVALID&lt;br /&gt;
|****&lt;br /&gt;
|sometimes&lt;br /&gt;
|bioware said&lt;br /&gt;
|****&lt;br /&gt;
|****&lt;br /&gt;
|i stay unused&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |1&lt;br /&gt;
|Evilmonster1&lt;br /&gt;
|23&lt;br /&gt;
|Abomination&lt;br /&gt;
|prp_barrel01&lt;br /&gt;
|1,0&lt;br /&gt;
|0&lt;br /&gt;
|totally evil&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |2&lt;br /&gt;
|Evilmonster2&lt;br /&gt;
|34&lt;br /&gt;
|Shriek&lt;br /&gt;
|prp_bucket_01&lt;br /&gt;
|1,0&lt;br /&gt;
|1&lt;br /&gt;
|very bad&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Data in a 2DA is identified by a row number, with the first row (using ID zero) usually being reserved for internal use (undefined value, etc.) by convention. Each row has an arbitrary number of columns identified by strings. The grey fields in this example table are very specific to the 2DA, the white fields are arbitrary data which the Gameengine identifies for that 2DA.&lt;br /&gt;
&lt;br /&gt;
The ID of a Row is the reference for the Game to access and link to them. As such they are unique across the 2DA, and any M2DA that extends it. The contents of each column is specific to the 2DA given, and arbitrary. When extending a 2DA, new ID's have to be given, and Columns have to be exactly the same.&lt;br /&gt;
&lt;br /&gt;
=== Guidelines ===&lt;br /&gt;
*Cell A1 will contain &amp;quot;ID&amp;quot;. This is checked by the processor and the worksheet will fail if this is not the case.&lt;br /&gt;
*Column A starting at line 3 will contain an integer row ID number that is unique to that row across all files (unless creating an M2DA override). Row IDs will be listed from smallest to highest within the same file and do not need to be consecutive.&lt;br /&gt;
*A blank row or column will determine the dimension of the spreadsheet in that direction. Everything past that point is ignored by the binarizer.&lt;br /&gt;
*Column names are case sensitive. This is because of the CRC32 algorithm used to generate the hash key. Changing the case of a column name after it is in use will break the game. White space before and after a column name will be removed before hashing.&lt;br /&gt;
*Row 2 will be a &amp;quot;types&amp;quot; row. Each is a single word: [[int]], [[string]] (single chars as well), [[resource]], [[float]] or [[bool]]. A special type &amp;quot;[[comment]]&amp;quot; can be used to exclude a column from export.&lt;br /&gt;
*Any column with string data that refers to files should have a type of &amp;quot;resource&amp;quot; and not &amp;quot;string&amp;quot;. This is because the &amp;quot;resource&amp;quot; type is used to determine dependencies for the 2DA file.&lt;br /&gt;
*'bool' type may be one of: a zero or non-zero number, Yes or No (case insensitive), or words beginning with T or F (such as True! and False!). NOTE: You cannot use TRUE and FALSE because Excel converts those to a special keyword the binarizer can't parse properly at this time. '''Note:''' the scripting language doesn't have a function for retrieving boolean values from a 2DA, and the behavior of Get2DAInt when retrieving a boolean is untested. It is probably safer to just use an integer for scripting purposes.&lt;br /&gt;
*If you wish to leave a cell unfilled, the string &amp;quot;****&amp;quot; (four asterisks) can be inserted instead of a value.&lt;br /&gt;
*Any worksheets that are not exportable 2DA data will have an underscore prepended to their name - the resource builder will subsequently ignore them.&lt;br /&gt;
*Worksheets need to have unique names among all excel files, duplicates will overwrite each other as each worksheet is exported as a file&lt;br /&gt;
*You cannot have the workbook open in Excel at the same time as running the binarizer on it.&lt;br /&gt;
*Strings have a maximum length of 768 characters. Anything longer will be truncated.&lt;br /&gt;
*ExcelProcessor.exe constrains the name length of a worksheet to 27 characters.&lt;br /&gt;
&lt;br /&gt;
== Extending the game via M2DAs ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;2&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;700pt&amp;quot; align&amp;quot;left&amp;quot;&lt;br /&gt;
|+ '''Example Worksheet &amp;quot;MonstersCustom&amp;quot;'''&lt;br /&gt;
| width=&amp;quot;30pt&amp;quot; style=&amp;quot;background-color:#808080&amp;quot; |'''ID'''&lt;br /&gt;
| width=&amp;quot;30pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Label'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Strenght'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Name'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''ResourceExample'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Scale'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''disabled'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Commentexample'''&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''int'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''string'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''int'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''string'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''resource'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''float'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''bool'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''comment'''''&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |2300000&lt;br /&gt;
|Evilmonster3&lt;br /&gt;
|32&lt;br /&gt;
|Wolf&lt;br /&gt;
|c_wolfa&lt;br /&gt;
|1,0&lt;br /&gt;
|0&lt;br /&gt;
|New Monster&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An &amp;quot;M2DA&amp;quot; is a &amp;quot;Multiple 2DA&amp;quot; that stacks a number of 2DAs into one larger table. They work much like single 2DA files except they can be patched or expanded later by adding another 2DA. These are useful for any table that lists other resources, such as appearance tables, so that new resources can be added later without having to modify a monolithic table. 2DAs are merged row by row, keyed on the ID column.&lt;br /&gt;
&lt;br /&gt;
This is especially important for third-party modders, since BioWare might release an update to a core table at a later date that would overwrite any changes third parties had made to it. By using an M2DA with a unique name, and by using a range of ID numbers significantly separated from those already in use, you can ensure that your additions won't conflict with other portions of the M2DA.&lt;br /&gt;
&lt;br /&gt;
Every M2DA used by the game is listed in M2DA_base ([[2DA_base.xls]]) and is treated as a M2DA, except for those with an ID between 10000 and 10999, which are handled as regular 2DAs. Each M2DA has a label that describes the subject covered by the M2DA and a worksheet prefix that all components of that M2DA must start with, as the name is actually a prefix to the file. The system reads this prefix and then searches through all the 2DAs for the ones starting with this prefix and merges them together as one 2DA. For example: M2DA ID 0 is &amp;quot;ANIM_&amp;quot;. The system looks through its list of 2DAs and finds &amp;quot;ANIM_base&amp;quot;, &amp;quot;ANIM_combat&amp;quot; and &amp;quot;ANIM_walk&amp;quot;. It will read and merge all 3 2DAs into an M2DA called &amp;quot;ANIM_&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Note that M2DA_base is itself an M2DA file and can be extended in the same manner.&lt;br /&gt;
&lt;br /&gt;
*''This example 2DA &amp;quot;MonstersCustom&amp;quot; would be merged into the original 2DA &amp;quot;Monsters&amp;quot;, if &amp;quot;Monsters&amp;quot; were one of the worksheets listed in the M2DA_base. ''&lt;br /&gt;
&lt;br /&gt;
=== Reserved ID Ranges and overriding existing rows ===&lt;br /&gt;
&lt;br /&gt;
While M2DA files avoid some of the problems associated with ordinary 2DA files, the IDs in each row of the final M2DA must still be unique across all 2DAs associated with it. If you use an existing row ID in your M2DA you can override the existing row with new data. Note that this can be a useful mechanism in some situations, for example allowing you to override existing content without having to edit the original 2DAs directly. &lt;br /&gt;
&lt;br /&gt;
To help ensure compatibility between authors' custom content, you should make sure that the ranges you choose don't conflict with ones already in use: [[2DA_ranges_in_use]].&lt;br /&gt;
&lt;br /&gt;
''See: [[compiling 2DAs#Afterwards|compiling 2DAs]]'' - for Information on where to place M2DA files to achieve the desired effect.&lt;br /&gt;
&lt;br /&gt;
=== Bug with M2DA ===&lt;br /&gt;
&lt;br /&gt;
It should be noted, that currently there is a bug with certain M2DA's, which prevents new ID's above 255 to work in the game. It is unclear which are affected, but most certainly it is [[ItemVariations.xls]] related. See [[Bug: High M2DA ID ranges might work in the toolset, but not in game|Bug report]].&lt;br /&gt;
&lt;br /&gt;
== 2DA XLS files used in Dragon Age ==&lt;br /&gt;
&lt;br /&gt;
[[List of 2DA XLS files]]&lt;br /&gt;
&lt;br /&gt;
The source files for the 2DAs that came with the installed game can be found under the toolsets directory &lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;Installdir&amp;gt;\Dragon Age\tools\Source\2DA\&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Users of Open Office ==&lt;br /&gt;
* Users of Open Office may find that no .gda file is created when they use ExcelProcessor.exe - one workaround is to copy a worksheet from an existing .xls file (such as placeable_types from placeables.xls), process the file, then remove the extraneous .gda file (e.g. placeable_types.gda). Alternately, upload your .xls file to Google Docs and then download the file as Excel format, then process the file with ExcelProcessor.exe.&lt;br /&gt;
* When editing existing xls files, it also works to leave the format as standard while saving the file. Open Office asks to change the file to its own spreatsheet format when saving a format other then its own, don't change the format and it should work. [Edit- And yet it doesn't seem to.]&lt;br /&gt;
* It is seemingly better at this time to simply use [http://docs.google.com Google Docs] instead as a free alternative, as Open Office will truncate floating point values in certain XLS files when compiled into a [[GDA]], while seemingly not in others. This can lead to unpredictable behavior, such as the game crashing when extending [[APR_base.xls]] while all appears normal in the toolset. (Possibly this was just a result of adding an extraneous space to a cell.)&lt;br /&gt;
&lt;br /&gt;
== Adding Strings ==&lt;br /&gt;
&lt;br /&gt;
{{needs review}}&lt;br /&gt;
&lt;br /&gt;
When adding strings to a 2DA, you have two options.  The simplest is to enter **** for the StringID column.  In that case, the name column will be used in the game.&lt;br /&gt;
&lt;br /&gt;
The other approach is to use the toolset's string editor to create a new string.  When that happens, you'll get a new StringID. Next enter that number into the StringID column in the 2DA.&lt;br /&gt;
&lt;br /&gt;
The second approach works better when translating your module, at the cost of portability.  If someone else wanted to reuse your 2DA, they'd have to generate their own strings, then update the StringID number based on these IDs.&lt;br /&gt;
&lt;br /&gt;
'''Attention:'''&lt;br /&gt;
&lt;br /&gt;
* The current version of the &amp;quot;ExelProcessor&amp;quot;-App is buggy as it can't hanlde INT values above 8388607! Many thanks to elys for figuring that out.&lt;br /&gt;
* Also note that the original toolset (v1.0) core-talktable contains wrong ids as well - don't forget to delete it from the &amp;quot;packages\core\override\toolsetexport&amp;quot; directory if you are still using that version.&lt;br /&gt;
&lt;br /&gt;
'''Workaround:'''&lt;br /&gt;
&lt;br /&gt;
* Create and export your talktable, delete the core-talktable override.&lt;br /&gt;
* Create your M2DA File that you want to refer to your talk-table strings. Never Mind using the real IDs at this stage.&lt;br /&gt;
* Use the &amp;quot;Exelprocessor&amp;quot; to create the GDA file.&lt;br /&gt;
* Open the GDA-File with the toolset or elys's GDA-Editor App (http://social.bioware.com/project/755/)&lt;br /&gt;
[[File:Edit-GDA-Values.jpg]]&lt;br /&gt;
* Change the StringIDs to the StringIDs in your talktable.&lt;br /&gt;
&lt;br /&gt;
'''Remark:''' &lt;br /&gt;
&lt;br /&gt;
The previous Version stated: ''Take that StringID and add 16777216 to the number.'' this appears to be wrong and is likely a holdover from NWN.&lt;br /&gt;
&lt;br /&gt;
[[Category:2DAs]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=Community_support_ideas&amp;diff=11064</id>
		<title>Community support ideas</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=Community_support_ideas&amp;diff=11064"/>
				<updated>2010-02-07T18:55:13Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Unfortunately the team at BioWare that prepared the toolset for public use doesn't have enough resources to address every request or suggestion for improvement. The following is a collection of ideas for improvements that BioWare couldn't get to but that could quite possibly be done by community contributions instead.&lt;br /&gt;
&lt;br /&gt;
;Better, more consistent camera control settings: At BioWare the various different editors of the toolset are used by various different specialists, each focused on their own area of expertise. This has led to different camera controls schemes being used in the area and level editors, for example. The [[camera control]] schemes are set in the [[DefaultSettings.xml]] file. Community-contributed versions of DefaultSettings with more consistent control schemes would be most welcome, or perhaps even a third-party application to make it easier to edit camera controls without XML expertise.&lt;br /&gt;
&lt;br /&gt;
; Voice over management tools : BioWare was unable to release their [[voice over]] and [[localization]] software. The information needed for managing voice over work can be extracted from module [[talk table]]s; it would likely be very useful if there were some sort of application available to make recording VO for dialogue lines easier.&lt;br /&gt;
&lt;br /&gt;
; String ID migration tools : One of the knottier problems that the toolset has with [[builder to builder]] export and import is keeping [[string ID]] numbers from colliding. It frequently has to renumber string IDs as a result. The toolset is able to find and correct all of the string ID references used internally when it does this, but it is unable to automatically find and correct the filenames of voice over wav files and [[FaceFX]] files (these files include the string ID number in their filenames as a way of associating them with their respective lines). A log file is generated during the builder to builder process that records what string ID changes were done, an application that uses this log to rename files could be quite useful.&lt;br /&gt;
&lt;br /&gt;
; Other text tools : the ability to search and replace text in a module's talk table or in its scripts could be useful, especially if there are scripts that refer to specific string IDs (see string ID migration, above).&lt;br /&gt;
&lt;br /&gt;
; Model import tools : Due to legal constraints BioWare was unable to release the export scripts they used to turn 3DSMax models into the format the game uses. Third-party converters and plugins for 3DSMax or for other 3D modeling programs will be essential for full-blown content creation. See [[MMH]] and [[MSH]] for model file specifications.&lt;br /&gt;
&lt;br /&gt;
; Conflict detector : It should be relatively straightforward to extract a list of all the string IDs and [[resref]]s used by any given module. Given that, it should be possible to create an application to automatically compare a set of modules and determine if there are any conflicts between them.&lt;br /&gt;
&lt;br /&gt;
; Variable 2DA management : One of the major differences in how scripting functions between NWN and DA is that you need to pre-define [[local variable]]s in a variable [[2DA]] before they can be used. Changing this would require a major overhaul of how the engine works and so isn't really an option, but perhaps applications could be written to ease local variable management if it proves to be a long-term hassle. In theory one could perhaps scan through all the scripts in a module looking for local variable assignment functions and then try to automatically add the local variables used to local variable 2DAs.(One alternative to local variables can be found in the unlimited variable storage project[http://social.bioware.com/project/1787/]. With a single include file and a simple function call in your module script, you can have unlimited variable and array storage with no need to declare anything in a 2da.)&lt;br /&gt;
&lt;br /&gt;
[[Category:Feature requests]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=Local_variable&amp;diff=11010</id>
		<title>Local variable</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=Local_variable&amp;diff=11010"/>
				<updated>2010-02-04T04:33:55Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Local variables are persistent variables that are associated with in-game objects. They are not the same as the temporary variables you can create in a script; local variables retain their values even when no scripts are using them, and are shared across any scripts that choose to access them.&lt;br /&gt;
&lt;br /&gt;
==Functions that work ==&lt;br /&gt;
Local variables are set using the SetLocal* functions and read using the GetLocal* functions. There are a number of SetLocal* functions in the game engine.  The five that are of use to you (that Programming fully supports) are:&lt;br /&gt;
&lt;br /&gt;
*[[SetLocalInt]]&lt;br /&gt;
*[[SetLocalFloat]]&lt;br /&gt;
*[[SetLocalObject]]&lt;br /&gt;
*[[SetLocalString]]&lt;br /&gt;
*[[SetLocalResource]]&lt;br /&gt;
&lt;br /&gt;
These functions work and have been through the fire of QA for many months.  They are solid and work well.&lt;br /&gt;
&lt;br /&gt;
==Functions that don't work ==&lt;br /&gt;
There are a number of other functions that happen to exist such as:&lt;br /&gt;
*[[SetLocalPlayer]]&lt;br /&gt;
*[[SetLocalEffect]]&lt;br /&gt;
*[[SetLocalEvent]]&lt;br /&gt;
*[[SetLocalCommand]]&lt;br /&gt;
*[[SetLocalItemProperty]]&lt;br /&gt;
*[[SetLocalLocation]]&lt;br /&gt;
&lt;br /&gt;
These functions do *NOT* work the way that the first five do.  The major issue with this second set of functions is that they are not saved/loaded via the save system.  So, if a community member or designer wants to save information like this for use later, and someone saves/loads the game, that information is lost forever.  Thus, using them outside of situations where you can guarantee no save/load occurs (i.e. during combat) is pretty much guaranteed to fail for some enduser.  Furthermore, if you use these variable types in the var_ 2DAs, it will fail gloriously.&lt;br /&gt;
&lt;br /&gt;
Don’t use these functions.  They will in all likelihood be removed in a future patch.&lt;br /&gt;
&lt;br /&gt;
== Variable 2DAs ==&lt;br /&gt;
&lt;br /&gt;
Local variables must be pre-defined in a variable 2DA before they can be read or set using these functions. The structure of a variable 2DA is as follows:&lt;br /&gt;
&lt;br /&gt;
{{2da start|var_*}}&lt;br /&gt;
{{2da column|Label|string|The name of the variable.}}&lt;br /&gt;
{{2da column|Type|string|The type of the variable.}}&lt;br /&gt;
{{2da column|Default|string|The default value of the variable. Resources can have the string &amp;quot;NONE&amp;quot; to indicate an empty default.}}&lt;br /&gt;
{{2da column|IsPlot|int|Set this to 1 to indicate that a string variable is meant to contain the name of a plot resource. 0 otherwise.}}&lt;br /&gt;
{{2da end}}&lt;br /&gt;
&lt;br /&gt;
Each different type of resource has a standard default variable 2DA, whose entries are described in the variable tables associated with their respective articles. You can create your own variable tables or extend existing ones with M2DAs if you need additional local variables for specific objects.&lt;br /&gt;
&lt;br /&gt;
Dragon Age doesn't support the dynamic in-game allocation of new local variables.&lt;br /&gt;
&lt;br /&gt;
==Alternatives ==&lt;br /&gt;
An alternative to local variables can be found in the unlimited variable storage project[http://social.bioware.com/project/1787/]. With a single include file and a simple function call in your module script, you can have unlimited variable and array storage with no need to declare anything in a 2da.&lt;br /&gt;
&lt;br /&gt;
[[Category:Variable functions|*]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=Local_variable&amp;diff=11009</id>
		<title>Local variable</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=Local_variable&amp;diff=11009"/>
				<updated>2010-02-04T04:26:33Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Local variables are persistent variables that are associated with in-game objects. They are not the same as the temporary variables you can create in a script; local variables retain their values even when no scripts are using them, and are shared across any scripts that choose to access them.&lt;br /&gt;
&lt;br /&gt;
Local variables are set using the SetLocal* functions and read using the GetLocal* functions. There are a number of SetLocal* functions in the game engine.  The five that are of use to you (that Programming fully supports) are:&lt;br /&gt;
&lt;br /&gt;
*[[SetLocalInt]]&lt;br /&gt;
*[[SetLocalFloat]]&lt;br /&gt;
*[[SetLocalObject]]&lt;br /&gt;
*[[SetLocalString]]&lt;br /&gt;
*[[SetLocalResource]]&lt;br /&gt;
&lt;br /&gt;
These functions work and have been through the fire of QA for many months.  They are solid and work well.&lt;br /&gt;
&lt;br /&gt;
There are a number of other functions that happen to exist such as:&lt;br /&gt;
*[[SetLocalPlayer]]&lt;br /&gt;
*[[SetLocalEffect]]&lt;br /&gt;
*[[SetLocalEvent]]&lt;br /&gt;
*[[SetLocalCommand]]&lt;br /&gt;
*[[SetLocalItemProperty]]&lt;br /&gt;
*[[SetLocalLocation]]&lt;br /&gt;
&lt;br /&gt;
These functions do *NOT* work the way that the first five do.  The major issue with this second set of functions is that they are not saved/loaded via the save system.  So, if a community member or designer wants to save information like this for use later, and someone saves/loads the game, that information is lost forever.  Thus, using them outside of situations where you can guarantee no save/load occurs (i.e. during combat) is pretty much guaranteed to fail for some enduser.  Furthermore, if you use these variable types in the var_ 2DAs, it will fail gloriously.&lt;br /&gt;
&lt;br /&gt;
Don’t use these functions.  They will in all likelihood be removed in a future patch.&lt;br /&gt;
&lt;br /&gt;
== Variable 2DAs ==&lt;br /&gt;
&lt;br /&gt;
Local variables must be pre-defined in a variable 2DA before they can be read or set using these functions. The structure of a variable 2DA is as follows:&lt;br /&gt;
&lt;br /&gt;
{{2da start|var_*}}&lt;br /&gt;
{{2da column|Label|string|The name of the variable.}}&lt;br /&gt;
{{2da column|Type|string|The type of the variable.}}&lt;br /&gt;
{{2da column|Default|string|The default value of the variable. Resources can have the string &amp;quot;NONE&amp;quot; to indicate an empty default.}}&lt;br /&gt;
{{2da column|IsPlot|int|Set this to 1 to indicate that a string variable is meant to contain the name of a plot resource. 0 otherwise.}}&lt;br /&gt;
{{2da end}}&lt;br /&gt;
&lt;br /&gt;
Each different type of resource has a standard default variable 2DA, whose entries are described in the variable tables associated with their respective articles. You can create your own variable tables or extend existing ones with M2DAs if you need additional local variables for specific objects.&lt;br /&gt;
&lt;br /&gt;
Dragon Age doesn't support the dynamic in-game allocation of new local variables.&lt;br /&gt;
&lt;br /&gt;
An alternative to local variables can be found in the unlimited variable storage project[http://social.bioware.com/project/1787/]. With a single include file and a simple function call in your module script, you can have unlimited variable and array storage with no need to declare anything in a 2da.&lt;br /&gt;
&lt;br /&gt;
[[Category:Variable functions|*]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=Script&amp;diff=11008</id>
		<title>Script</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=Script&amp;diff=11008"/>
				<updated>2010-02-04T04:23:55Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: /* Local variables - data repositories for individual objects */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| style=&amp;quot;float:right;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| {{Resource palette}}&lt;br /&gt;
|-&lt;br /&gt;
| {{Infobox script}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Scripts in Dragon Age are used to control all manner of game activity. Much of the functionality that would normally be handled by the game engine is actually managed by core scripts, allowing deep customizability.&lt;br /&gt;
&lt;br /&gt;
== [[Scripting overview]] - basic syntax ==&lt;br /&gt;
&lt;br /&gt;
The DA scripting language is very similar to C in terms of syntax. Files can be included into other files, with files containing libraries of functions designated by a &amp;quot;_h&amp;quot; suffix. (eg. wrappers_h)&lt;br /&gt;
&lt;br /&gt;
:''See [[Scripting overview]].''&lt;br /&gt;
&lt;br /&gt;
== [[Event (dascript type)|Event]]s - driving practically everything ==&lt;br /&gt;
&lt;br /&gt;
Dragon Age has an [[Event (dascript type)|Event]]-driven scripting model, with event objects being passed to scripts containing different parameters depending on the event's type. A large portion of script-writing for a standard adventure is going to involve dealing with events. Common examples include:&lt;br /&gt;
&lt;br /&gt;
* An event is fired to a plot's script whenever one of its flags is set or cleared&lt;br /&gt;
* An event is fired to an area's script when a team of creatures dies in it or when a creature (such as the player) enters&lt;br /&gt;
* Events are fired to the module's script during character generation&lt;br /&gt;
* Events are fired to creatures when certain things happen to them (such as being hit)&lt;br /&gt;
&lt;br /&gt;
[[Custom AI]] for creatures is handled by creating custom AI event handlers.&lt;br /&gt;
&lt;br /&gt;
:''See [[Event (dascript type)|Event]] for more details.''&lt;br /&gt;
&lt;br /&gt;
== [[Effect (dascript type)|Effect]]s and [[Ability|Abilities]] - how to make things affect other things ==&lt;br /&gt;
&lt;br /&gt;
[[Effect (dascript type)|Effect]]s are a bundle of modifiers that are applied to an object or creature. Every effect has a type set on it that determines how it affects the object it is applied to. They also have a number of parameters on them, which vary based on the type, that change the specific behaviour. When the effect is removed (usually because the duration on the effect expires) the modifier is removed. These modifiers can be rule or stat based or more complicated visual and game effects.&lt;br /&gt;
&lt;br /&gt;
They can be assigned different duration types which affect how they're applied and removed:&lt;br /&gt;
&lt;br /&gt;
# Temporary: Applied for a short duration (measured in seconds)&lt;br /&gt;
# Permanent: Applied until manually removed through scripting&lt;br /&gt;
# Instant: These are one-shot modifiers that are not stored on the object (the death effect is an instant modifier for example)&lt;br /&gt;
# Equipped: Associated with an equipped item. The effect is removed when the item is unequipped. &lt;br /&gt;
&lt;br /&gt;
Effects are commonly applied by [[Ability|Abilities]], which are possessed by both creatures and player characters.&lt;br /&gt;
&lt;br /&gt;
== 2DA files - All-purpose game-wide data repositories ==&lt;br /&gt;
&lt;br /&gt;
2-Dimensional Arrays contain much of the raw data used by the game. They are generated from Microsoft Excel files. If you want to add new basic creature types, new treasure types, and so forth, you'll need to create new [[2DA]] files.&lt;br /&gt;
&lt;br /&gt;
:''See Main Article: [[2DA]]''&lt;br /&gt;
&lt;br /&gt;
== [[Treasure system]] ==&lt;br /&gt;
&lt;br /&gt;
The treasure possessed by most creatures and containers is randomly generated by the game's core scripts using a system that selects from appropriate treasure types (for example, wild animals should rarely possess steel armor in their inventories, and Darkspawn are unlikely to be carrying fine porcelain vases) and auto-scales it to be reasonably useful or valuable at the character's level. Manipulating the treasure system can involve both [[local variable]]s and [[event (type)|event]]s.&lt;br /&gt;
&lt;br /&gt;
To put a specific treasure item in a specific creature's [[inventory]], you'll have to create a new creature template for that creature. Inventory cannot be directly defined for particular objects already placed in an [[area]].&lt;br /&gt;
&lt;br /&gt;
:''See main article: [[Treasure system]]''&lt;br /&gt;
&lt;br /&gt;
== [[Local variable]]s - data repositories for individual objects ==&lt;br /&gt;
&lt;br /&gt;
[[Local variable]]s are persistent variables that are associated with in-game objects. They are not the same as the temporary variables you can create in a script; local variables retain their values even when no scripts are using them, and are shared across any scripts that choose to access them.&lt;br /&gt;
&lt;br /&gt;
Local variables are set using the SetLocal* functions and read using the GetLocal* functions. There are a number of SetLocal* functions in the game engine.&lt;br /&gt;
&lt;br /&gt;
Local variables must be pre-defined in a variable [[2DA]] before they can be read or set using these functions. Dragon Age doesn't support the dynamic in-game allocation of new local variables. &lt;br /&gt;
&lt;br /&gt;
An alternative to local variables can be found in the unlimited variable storage project[http://social.bioware.com/project/1787/]. With a single include file and a simple function call in your module script, you can have unlimited variable and array storage with no need to declare anything in a 2da.&lt;br /&gt;
&lt;br /&gt;
:''See main article: [[Local variable]]s''&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripts]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=Getting_Started&amp;diff=10779</id>
		<title>Getting Started</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=Getting_Started&amp;diff=10779"/>
				<updated>2010-02-01T23:13:05Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: /* Starting the Toolset */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installing the toolset ==&lt;br /&gt;
* First, make sure you have the game installed. The toolset relies on the game's resources and engine and cannot function without them.&lt;br /&gt;
* [http://social.bioware.com/toolset.php Download the toolset from here].&lt;br /&gt;
*[[Creating an account]] - how to create an account for this wiki and social.bioware.com&lt;br /&gt;
* [[Installing the toolset]]&lt;br /&gt;
*'''[[Installation troubleshooting]]''' - information on how to fix things in the event that toolset installation goes awry.&lt;br /&gt;
*[[Known issues]] with the current version of the toolset&lt;br /&gt;
&lt;br /&gt;
== Overview of the Toolset ==&lt;br /&gt;
&lt;br /&gt;
*[[Overview of the toolset]] - How the Toolset manages Resources you create, and giving a quiet good overview.&lt;br /&gt;
&lt;br /&gt;
*[[Comparisons with other toolkits]] - for users who are familiar with other similar toolkits (eg, the Neverwinter Nights tookit) and would like a brief overview of how the Dragon Age toolkit compares.&lt;br /&gt;
&lt;br /&gt;
== Starting the Toolset ==&lt;br /&gt;
&lt;br /&gt;
{| align=right&lt;br /&gt;
|[[File:Titlebar components.png|thumb|300px|right|How to determine which module is currently open]]&lt;br /&gt;
|-&lt;br /&gt;
|{{Warnbox|Do not edit Single Player or Core Resources with custom content!|300px}}&lt;br /&gt;
|}&lt;br /&gt;
Before using the Toolset it is important to take note of the [[Module|module]] the toolset has open. A module is a &amp;quot;container&amp;quot; that game resources are stored in; you will only be able to see the resources for the currently-open module (and any modules that it is marked as depending on). The default module when first starting the Toolset is the &amp;quot;Demo&amp;quot; module, which is a very small and simple module intended to show several common resource types in a basic pre-built adventure you can experiment with safely.&lt;br /&gt;
&lt;br /&gt;
The main Dragon Age: Origins campaign resources are stored in a module named &amp;quot;Single Player&amp;quot;. If you're just starting out with the toolset it can be dangerous to edit these, as you could inadvertantly corrupt your main campaign. Take care when exploring not to edit any of those resources without knowing what you're doing.&lt;br /&gt;
&lt;br /&gt;
The first basic steps in the Toolset shall be to create your own [[Module]]. The only possible type of Module is &amp;quot;Addin&amp;quot;, but note that this name is somewhat misleading; it is possible to have &amp;quot;standalone addins&amp;quot; that are completely separate from any other module (such as the main campaign).&lt;br /&gt;
&lt;br /&gt;
*See: [[Module]] - For a general overview of how a Module works, and what awaits you.&lt;br /&gt;
&lt;br /&gt;
== Using the Toolset ==&lt;br /&gt;
&lt;br /&gt;
As described in the overview linked to above, the game uses a wide variety of resource types. A &amp;quot;resource&amp;quot; is something that you can create, such as a script or a creature, and you will often need to combine many different resources together to accomplish a particular design goal. The toolset consists of many independent tools for working with these different types of resources. These tools can be well discussed separately.&lt;br /&gt;
&lt;br /&gt;
The next best step for learning the toolset would be to look into the categories on the [[Main Page]], which link deeper into each topic and the tools involved with them. If you are having questions at a specific part of the toolset give this Wiki a search for it. This can be very specific, and always worth a try. You may also find the [http://social.bioware.com/forum/1/subindex/70 toolset forums] to be useful in solving specific problems the documentation here may not cover.&lt;br /&gt;
&lt;br /&gt;
A list of certain Interest, and the 3 Resource types:&lt;br /&gt;
*[[Design]] - Talks mainly about Designer Resources, in question is Items, Monsters, NPC's, Vendors, etcetc&lt;br /&gt;
*[[Art]] - Talks mainly about Art Resources, in question Models, Textures, Facemorphs, etcetc&lt;br /&gt;
*[[2DA]] - Talks about the 2DA Resourcetype, which is sets of Gamewide usable variables and references.&lt;br /&gt;
*etc&lt;br /&gt;
&lt;br /&gt;
=== Tips and tricks ===&lt;br /&gt;
*[[Shortcuts]] - Assorted toolset shortcuts.&lt;br /&gt;
*[[Common Problems]] - Little things that most people will need to know but that are not necessarily obvious.&lt;br /&gt;
&lt;br /&gt;
== Specials ==&lt;br /&gt;
&lt;br /&gt;
[[Deleting a module]] - This is currently not possible by normal means. &lt;br /&gt;
&lt;br /&gt;
If you run into a problem that the documentation doesn't cover and that you can't fix, contact toolsetsupport@bioware.com&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=2DA&amp;diff=10609</id>
		<title>2DA</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=2DA&amp;diff=10609"/>
				<updated>2010-01-31T08:32:19Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: /* Users of Open Office */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Many of the properties of objects in the toolset make reference to 2DAs (two-dimensional arrays). These are read-only arrays containing various data used by scripting and the game engine. Each 2DA is simply an organized collection of strings and numbers. The specific function of each 2DA depends on how it is used by other systems in the game.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
== Overview - what is a 2DA? ==&lt;br /&gt;
&lt;br /&gt;
A 2DA contains a set of columns, with each column having a fixed label and a fixed data type. For example, the ABI_Base 2DA has a column that is labeled &amp;quot;namestrref&amp;quot; and has the data type &amp;quot;int&amp;quot;. This means that the data stored in this column must be an integer and that the data stored in this column can be retrieved by referring to the label &amp;quot;namestrref&amp;quot;. The number and types of columns in a 2DA does not usually ever change. The columns provide the structure of the 2DA that allows it to be referred to and used in a consistent manner. The first column of every 2DA is always labeled &amp;quot;ID&amp;quot; and is always of type &amp;quot;integer&amp;quot;. This column is used to uniquely identify the rows in the 2DA.&lt;br /&gt;
&lt;br /&gt;
A 2DA's rows are what contain the data being stored in it. Each row's columns have the same set of labels and data types (as defined at the top of the 2DA) but the data contained within them can be different. Adding new rows to a 2DA is common and easy; you just need to give it a new ID number in the &amp;quot;ID&amp;quot; column and then fill in the rest of the cells with whatever information you need. Once you've given a row an ID number it generally never changes. The game also has a mechanism called &amp;quot;M2DAs&amp;quot; that allow rows to be added to existing 2DAs without having to edit the original file, see below for more detail.&lt;br /&gt;
&lt;br /&gt;
Some 2DAs reference rows in other 2DAs. For example the ABI_Base 2DA has an integer column named &amp;quot;projectile&amp;quot;, and each row can have an integer in that column that identifies a row in the PRJ_Base 2DA. These relationships are generally only defined in the scripts that use the 2DAs and are not inherent to the 2DAs themselves so you'll have to keep track of these things yourself.&lt;br /&gt;
&lt;br /&gt;
== Excel file formatting ==&lt;br /&gt;
&lt;br /&gt;
The source files for 2DAs are Microsoft Excel worksheets. This allows a wide variety of sophisticated techniques to be used to generate the values of the 2DA fields, such as macros and formulas. It also makes editing much easier since the columns can be annotated and formatted in helpful ways, and multiple related worksheets can be grouped into one file. Before they can be used by the toolset or the game, 2DAs must be converted from Excel files into a more efficient form. Processed 2DAs are stored in files with the .[[GDA]] extension.&lt;br /&gt;
&lt;br /&gt;
''See: [[compiling 2DAs]]'' - for several methods of how to perform this conversion, and where to put 2DAs.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;2&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;700pt&amp;quot; align&amp;quot;left&amp;quot;&lt;br /&gt;
|+ '''Example Worksheet &amp;quot;Monsters&amp;quot;'''&lt;br /&gt;
| width=&amp;quot;30pt&amp;quot; style=&amp;quot;background-color:#808080&amp;quot; |'''ID'''&lt;br /&gt;
| width=&amp;quot;30pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Label'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Strenght'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Name'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''ResourceExample'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Scale'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''disabled'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Commentexample'''&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''int'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''string'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''int'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''string'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''resource'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''float'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''bool'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''comment'''''&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |0&lt;br /&gt;
|INVALID&lt;br /&gt;
|****&lt;br /&gt;
|sometimes&lt;br /&gt;
|bioware said&lt;br /&gt;
|****&lt;br /&gt;
|****&lt;br /&gt;
|i stay unused&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |1&lt;br /&gt;
|Evilmonster1&lt;br /&gt;
|23&lt;br /&gt;
|Abomination&lt;br /&gt;
|prp_barrel01&lt;br /&gt;
|1,0&lt;br /&gt;
|0&lt;br /&gt;
|totally evil&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |2&lt;br /&gt;
|Evilmonster2&lt;br /&gt;
|34&lt;br /&gt;
|Shriek&lt;br /&gt;
|prp_bucket_01&lt;br /&gt;
|1,0&lt;br /&gt;
|1&lt;br /&gt;
|very bad&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Data in a 2DA is identified by a row number, with the first row (using ID zero) usually being reserved for internal use (undefined value, etc.) by convention. Each row has an arbitrary number of columns identified by strings. The grey fields in this example table are very specific to the 2DA, the white fields are arbitrary data which the Gameengine identifies for that 2DA.&lt;br /&gt;
&lt;br /&gt;
The ID of a Row is the reference for the Game to access and link to them. As such they are unique across the 2DA, and any M2DA that extends it. The contents of each column is specific to the 2DA given, and arbitrary. When extending a 2DA, new ID's have to be given, and Columns have to be exactly the same.&lt;br /&gt;
&lt;br /&gt;
=== Guidelines ===&lt;br /&gt;
*Cell A1 will contain &amp;quot;ID&amp;quot;. This is checked by the processor and the worksheet will fail if this is not the case.&lt;br /&gt;
*Column A starting at line 3 will contain an integer row ID number that is unique to that row across all files (unless creating an M2DA override). Row IDs will be listed from smallest to highest within the same file and do not need to be consecutive.&lt;br /&gt;
*A blank row or column will determine the dimension of the spreadsheet in that direction. Everything past that point is ignored by the binarizer.&lt;br /&gt;
*Column names are case sensitive. This is because of the CRC32 algorithm used to generate the hash key. Changing the case of a column name after it is in use will break the game. White space before and after a column name will be removed before hashing.&lt;br /&gt;
*Row 2 will be a &amp;quot;types&amp;quot; row. Each is a single word: [[int]], [[string]] (single chars as well), [[resource]], [[float]] or [[bool]]. A special type &amp;quot;[[comment]]&amp;quot; can be used to exclude a column from export.&lt;br /&gt;
*Any column with string data that refers to files should have a type of &amp;quot;resource&amp;quot; and not &amp;quot;string&amp;quot;. This is because the &amp;quot;resource&amp;quot; type is used to determine dependencies for the 2DA file.&lt;br /&gt;
*'bool' type may be one of: a zero or non-zero number, Yes or No (case insensitive), or words beginning with T or F (such as True! and False!). NOTE: You cannot use TRUE and FALSE because Excel converts those to a special keyword the binarizer can't parse properly at this time. '''Note:''' the scripting language doesn't have a function for retrieving boolean values from a 2DA, and the behavior of Get2DAInt when retrieving a boolean is untested. It is probably safer to just use an integer for scripting purposes.&lt;br /&gt;
*If you wish to leave a cell unfilled, the string &amp;quot;****&amp;quot; (four asterisks) can be inserted instead of a value.&lt;br /&gt;
*Any worksheets that are not exportable 2DA data will have an underscore prepended to their name - the resource builder will subsequently ignore them.&lt;br /&gt;
*Worksheets need to have unique names among all excel files, duplicates will overwrite each other as each worksheet is exported as a file&lt;br /&gt;
*You cannot have the workbook open in Excel at the same time as running the binarizer on it.&lt;br /&gt;
*Strings have a maximum length of 768 characters. Anything longer will be truncated.&lt;br /&gt;
*ExcelProcessor.exe constrains the name length of a worksheet to 27 characters.&lt;br /&gt;
&lt;br /&gt;
== Extending the game via M2DAs ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;2&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;700pt&amp;quot; align&amp;quot;left&amp;quot;&lt;br /&gt;
|+ '''Example Worksheet &amp;quot;MonstersCustom&amp;quot;'''&lt;br /&gt;
| width=&amp;quot;30pt&amp;quot; style=&amp;quot;background-color:#808080&amp;quot; |'''ID'''&lt;br /&gt;
| width=&amp;quot;30pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Label'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Strenght'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Name'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''ResourceExample'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Scale'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''disabled'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Commentexample'''&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''int'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''string'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''int'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''string'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''resource'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''float'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''bool'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''comment'''''&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |2300000&lt;br /&gt;
|Evilmonster3&lt;br /&gt;
|32&lt;br /&gt;
|Wolf&lt;br /&gt;
|c_wolfa&lt;br /&gt;
|1,0&lt;br /&gt;
|0&lt;br /&gt;
|New Monster&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An &amp;quot;M2DA&amp;quot; is a &amp;quot;Multiple 2DA&amp;quot; that stacks a number of 2DAs into one larger table. They work much like single 2DA files except they can be patched or expanded later by adding another 2DA. These are useful for any table that lists other resources, such as appearance tables, so that new resources can be added later without having to modify a monolithic table. 2DAs are merged row by row, keyed on the ID column.&lt;br /&gt;
&lt;br /&gt;
This is especially important for third-party modders, since BioWare might release an update to a core table at a later date that would overwrite any changes third parties had made to it. By using an M2DA with a unique name, and by using a range of ID numbers significantly separated from those already in use, you can ensure that your additions won't conflict with other portions of the M2DA.&lt;br /&gt;
&lt;br /&gt;
Every M2DA used by the game is listed in M2DA_base ([[2DA_base.xls]]) and is treated as a M2DA, except for those with an ID between 10000 and 10999, which are handled as regular 2DAs. Each M2DA has a label that describes the subject covered by the M2DA and a worksheet prefix that all components of that M2DA must start with, as the name is actually a prefix to the file. The system reads this prefix and then searches through all the 2DAs for the ones starting with this prefix and merges them together as one 2DA. For example: M2DA ID 0 is &amp;quot;ANIM_&amp;quot;. The system looks through its list of 2DAs and finds &amp;quot;ANIM_base&amp;quot;, &amp;quot;ANIM_combat&amp;quot; and &amp;quot;ANIM_walk&amp;quot;. It will read and merge all 3 2DAs into an M2DA called &amp;quot;ANIM_&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Note that M2DA_base is itself an M2DA file and can be extended in the same manner.&lt;br /&gt;
&lt;br /&gt;
*''This example 2DA &amp;quot;MonstersCustom&amp;quot; would be merged into the original 2DA &amp;quot;Monsters&amp;quot;, if &amp;quot;Monsters&amp;quot; were one of the worksheets listed in the M2DA_base. ''&lt;br /&gt;
&lt;br /&gt;
=== Reserved ID Ranges and overriding existing rows ===&lt;br /&gt;
&lt;br /&gt;
While M2DA files avoid some of the problems associated with ordinary 2DA files, the IDs in each row of the final M2DA must still be unique across all 2DAs associated with it. If you use an existing row ID in your M2DA you can override the existing row with new data. Note that this can be a useful mechanism in some situations, for example allowing you to override existing content without having to edit the original 2DAs directly. &lt;br /&gt;
&lt;br /&gt;
To help ensure compatibility between authors' custom content, you should make sure that the ranges you choose don't conflict with ones already in use: [[2DA_ranges_in_use]].&lt;br /&gt;
&lt;br /&gt;
''See: [[compiling 2DAs#Afterwards|compiling 2DAs]]'' - for Information on where to place M2DA files to achieve the desired effect.&lt;br /&gt;
&lt;br /&gt;
=== Bug with M2DA ===&lt;br /&gt;
&lt;br /&gt;
It should be noted, that currently there is a bug with certain M2DA's, which prevents new ID's above 255 to work in the game. It is unclear which are affected, but most certainly it is [[ItemVariations.xls]] related. See [[Bug: High M2DA ID ranges might work in the toolset, but not in game|Bug report]].&lt;br /&gt;
&lt;br /&gt;
== 2DA XLS files used in Dragon Age ==&lt;br /&gt;
&lt;br /&gt;
[[List of 2DA XLS files]]&lt;br /&gt;
&lt;br /&gt;
The source files for the 2DAs that came with the installed game can be found under the toolsets directory &lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;Installdir&amp;gt;\Dragon Age\tools\Source\2DA\&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Users of Open Office ==&lt;br /&gt;
* Users of Open Office may find that no .gda file is created when they use ExcelProcessor.exe - one workaround is to copy a worksheet from an existing .xls file (such as placeable_types from placeables.xls), process the file, then remove the extraneous .gda file (e.g. placeable_types.gda). Alternately, upload your .xls file to Google Docs and then download the file as Excel format, then process the file with ExcelProcessor.exe.&lt;br /&gt;
* When editing existing xls files, it also works to leave the format as standard while saving the file. Open Office asks to change the file to its own spreatsheet format when saving a format other then its own, don't change the format and it should work. [Edit- And yet it doesn't seem to.]&lt;br /&gt;
&lt;br /&gt;
== Adding Strings ==&lt;br /&gt;
&lt;br /&gt;
{{needs review}}&lt;br /&gt;
&lt;br /&gt;
When adding strings to a 2DA, you have two options.  The simplest is to enter **** for the StringID column.  In that case, the name column will be used in the game.&lt;br /&gt;
&lt;br /&gt;
The other approach is to use the toolset's string editor to create a new string.  When that happens, you'll get a new StringID. Next enter that number into the StringID column in the 2DA.&lt;br /&gt;
&lt;br /&gt;
The second approach works better when translating your module, at the cost of portability.  If someone else wanted to reuse your 2DA, they'd have to generate their own strings, then update the StringID number based on these IDs.&lt;br /&gt;
&lt;br /&gt;
'''Attention:'''&lt;br /&gt;
&lt;br /&gt;
* The current version of the &amp;quot;ExelProcessor&amp;quot;-App is buggy as it can't hanlde INT values above 8388607! Many thanks to elys for figuring that out.&lt;br /&gt;
* Also note that the original toolset (v1.0) core-talktable contains wrong ids as well - don't forget to delete it from the &amp;quot;packages\core\override\toolsetexport&amp;quot; directory if you are still using that version.&lt;br /&gt;
&lt;br /&gt;
'''Workaround:'''&lt;br /&gt;
&lt;br /&gt;
* Create and export your talktable, delete the core-talktable override.&lt;br /&gt;
* Create your M2DA File that you want to refer to your talk-table strings. Never Mind using the real IDs at this stage.&lt;br /&gt;
* Use the &amp;quot;Exelprocessor&amp;quot; to create the GDA file.&lt;br /&gt;
* Open the GDA-File with the toolset or elys's GDA-Editor App (http://social.bioware.com/project/755/)&lt;br /&gt;
[[File:Edit-GDA-Values.jpg]]&lt;br /&gt;
* Change the StringIDs to the StringIDs in your talktable.&lt;br /&gt;
&lt;br /&gt;
'''Remark:''' &lt;br /&gt;
&lt;br /&gt;
The previous Version stated: ''Take that StringID and add 16777216 to the number.'' this appears to be wrong and is likely a holdover from NWN.&lt;br /&gt;
&lt;br /&gt;
[[Category:2DAs]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=2DA&amp;diff=10608</id>
		<title>2DA</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=2DA&amp;diff=10608"/>
				<updated>2010-01-31T08:31:52Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: /* Users of Open Office */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Many of the properties of objects in the toolset make reference to 2DAs (two-dimensional arrays). These are read-only arrays containing various data used by scripting and the game engine. Each 2DA is simply an organized collection of strings and numbers. The specific function of each 2DA depends on how it is used by other systems in the game.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
== Overview - what is a 2DA? ==&lt;br /&gt;
&lt;br /&gt;
A 2DA contains a set of columns, with each column having a fixed label and a fixed data type. For example, the ABI_Base 2DA has a column that is labeled &amp;quot;namestrref&amp;quot; and has the data type &amp;quot;int&amp;quot;. This means that the data stored in this column must be an integer and that the data stored in this column can be retrieved by referring to the label &amp;quot;namestrref&amp;quot;. The number and types of columns in a 2DA does not usually ever change. The columns provide the structure of the 2DA that allows it to be referred to and used in a consistent manner. The first column of every 2DA is always labeled &amp;quot;ID&amp;quot; and is always of type &amp;quot;integer&amp;quot;. This column is used to uniquely identify the rows in the 2DA.&lt;br /&gt;
&lt;br /&gt;
A 2DA's rows are what contain the data being stored in it. Each row's columns have the same set of labels and data types (as defined at the top of the 2DA) but the data contained within them can be different. Adding new rows to a 2DA is common and easy; you just need to give it a new ID number in the &amp;quot;ID&amp;quot; column and then fill in the rest of the cells with whatever information you need. Once you've given a row an ID number it generally never changes. The game also has a mechanism called &amp;quot;M2DAs&amp;quot; that allow rows to be added to existing 2DAs without having to edit the original file, see below for more detail.&lt;br /&gt;
&lt;br /&gt;
Some 2DAs reference rows in other 2DAs. For example the ABI_Base 2DA has an integer column named &amp;quot;projectile&amp;quot;, and each row can have an integer in that column that identifies a row in the PRJ_Base 2DA. These relationships are generally only defined in the scripts that use the 2DAs and are not inherent to the 2DAs themselves so you'll have to keep track of these things yourself.&lt;br /&gt;
&lt;br /&gt;
== Excel file formatting ==&lt;br /&gt;
&lt;br /&gt;
The source files for 2DAs are Microsoft Excel worksheets. This allows a wide variety of sophisticated techniques to be used to generate the values of the 2DA fields, such as macros and formulas. It also makes editing much easier since the columns can be annotated and formatted in helpful ways, and multiple related worksheets can be grouped into one file. Before they can be used by the toolset or the game, 2DAs must be converted from Excel files into a more efficient form. Processed 2DAs are stored in files with the .[[GDA]] extension.&lt;br /&gt;
&lt;br /&gt;
''See: [[compiling 2DAs]]'' - for several methods of how to perform this conversion, and where to put 2DAs.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;2&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;700pt&amp;quot; align&amp;quot;left&amp;quot;&lt;br /&gt;
|+ '''Example Worksheet &amp;quot;Monsters&amp;quot;'''&lt;br /&gt;
| width=&amp;quot;30pt&amp;quot; style=&amp;quot;background-color:#808080&amp;quot; |'''ID'''&lt;br /&gt;
| width=&amp;quot;30pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Label'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Strenght'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Name'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''ResourceExample'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Scale'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''disabled'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Commentexample'''&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''int'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''string'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''int'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''string'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''resource'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''float'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''bool'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''comment'''''&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |0&lt;br /&gt;
|INVALID&lt;br /&gt;
|****&lt;br /&gt;
|sometimes&lt;br /&gt;
|bioware said&lt;br /&gt;
|****&lt;br /&gt;
|****&lt;br /&gt;
|i stay unused&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |1&lt;br /&gt;
|Evilmonster1&lt;br /&gt;
|23&lt;br /&gt;
|Abomination&lt;br /&gt;
|prp_barrel01&lt;br /&gt;
|1,0&lt;br /&gt;
|0&lt;br /&gt;
|totally evil&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |2&lt;br /&gt;
|Evilmonster2&lt;br /&gt;
|34&lt;br /&gt;
|Shriek&lt;br /&gt;
|prp_bucket_01&lt;br /&gt;
|1,0&lt;br /&gt;
|1&lt;br /&gt;
|very bad&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Data in a 2DA is identified by a row number, with the first row (using ID zero) usually being reserved for internal use (undefined value, etc.) by convention. Each row has an arbitrary number of columns identified by strings. The grey fields in this example table are very specific to the 2DA, the white fields are arbitrary data which the Gameengine identifies for that 2DA.&lt;br /&gt;
&lt;br /&gt;
The ID of a Row is the reference for the Game to access and link to them. As such they are unique across the 2DA, and any M2DA that extends it. The contents of each column is specific to the 2DA given, and arbitrary. When extending a 2DA, new ID's have to be given, and Columns have to be exactly the same.&lt;br /&gt;
&lt;br /&gt;
=== Guidelines ===&lt;br /&gt;
*Cell A1 will contain &amp;quot;ID&amp;quot;. This is checked by the processor and the worksheet will fail if this is not the case.&lt;br /&gt;
*Column A starting at line 3 will contain an integer row ID number that is unique to that row across all files (unless creating an M2DA override). Row IDs will be listed from smallest to highest within the same file and do not need to be consecutive.&lt;br /&gt;
*A blank row or column will determine the dimension of the spreadsheet in that direction. Everything past that point is ignored by the binarizer.&lt;br /&gt;
*Column names are case sensitive. This is because of the CRC32 algorithm used to generate the hash key. Changing the case of a column name after it is in use will break the game. White space before and after a column name will be removed before hashing.&lt;br /&gt;
*Row 2 will be a &amp;quot;types&amp;quot; row. Each is a single word: [[int]], [[string]] (single chars as well), [[resource]], [[float]] or [[bool]]. A special type &amp;quot;[[comment]]&amp;quot; can be used to exclude a column from export.&lt;br /&gt;
*Any column with string data that refers to files should have a type of &amp;quot;resource&amp;quot; and not &amp;quot;string&amp;quot;. This is because the &amp;quot;resource&amp;quot; type is used to determine dependencies for the 2DA file.&lt;br /&gt;
*'bool' type may be one of: a zero or non-zero number, Yes or No (case insensitive), or words beginning with T or F (such as True! and False!). NOTE: You cannot use TRUE and FALSE because Excel converts those to a special keyword the binarizer can't parse properly at this time. '''Note:''' the scripting language doesn't have a function for retrieving boolean values from a 2DA, and the behavior of Get2DAInt when retrieving a boolean is untested. It is probably safer to just use an integer for scripting purposes.&lt;br /&gt;
*If you wish to leave a cell unfilled, the string &amp;quot;****&amp;quot; (four asterisks) can be inserted instead of a value.&lt;br /&gt;
*Any worksheets that are not exportable 2DA data will have an underscore prepended to their name - the resource builder will subsequently ignore them.&lt;br /&gt;
*Worksheets need to have unique names among all excel files, duplicates will overwrite each other as each worksheet is exported as a file&lt;br /&gt;
*You cannot have the workbook open in Excel at the same time as running the binarizer on it.&lt;br /&gt;
*Strings have a maximum length of 768 characters. Anything longer will be truncated.&lt;br /&gt;
*ExcelProcessor.exe constrains the name length of a worksheet to 27 characters.&lt;br /&gt;
&lt;br /&gt;
== Extending the game via M2DAs ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;2&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;700pt&amp;quot; align&amp;quot;left&amp;quot;&lt;br /&gt;
|+ '''Example Worksheet &amp;quot;MonstersCustom&amp;quot;'''&lt;br /&gt;
| width=&amp;quot;30pt&amp;quot; style=&amp;quot;background-color:#808080&amp;quot; |'''ID'''&lt;br /&gt;
| width=&amp;quot;30pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Label'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Strenght'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Name'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''ResourceExample'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Scale'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''disabled'''&lt;br /&gt;
| width=&amp;quot;50pt&amp;quot; style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''Commentexample'''&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''int'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''string'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''int'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''string'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''resource'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''float'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''bool'''''&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |'''''comment'''''&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;background-color:#AFAFAF&amp;quot; |2300000&lt;br /&gt;
|Evilmonster3&lt;br /&gt;
|32&lt;br /&gt;
|Wolf&lt;br /&gt;
|c_wolfa&lt;br /&gt;
|1,0&lt;br /&gt;
|0&lt;br /&gt;
|New Monster&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An &amp;quot;M2DA&amp;quot; is a &amp;quot;Multiple 2DA&amp;quot; that stacks a number of 2DAs into one larger table. They work much like single 2DA files except they can be patched or expanded later by adding another 2DA. These are useful for any table that lists other resources, such as appearance tables, so that new resources can be added later without having to modify a monolithic table. 2DAs are merged row by row, keyed on the ID column.&lt;br /&gt;
&lt;br /&gt;
This is especially important for third-party modders, since BioWare might release an update to a core table at a later date that would overwrite any changes third parties had made to it. By using an M2DA with a unique name, and by using a range of ID numbers significantly separated from those already in use, you can ensure that your additions won't conflict with other portions of the M2DA.&lt;br /&gt;
&lt;br /&gt;
Every M2DA used by the game is listed in M2DA_base ([[2DA_base.xls]]) and is treated as a M2DA, except for those with an ID between 10000 and 10999, which are handled as regular 2DAs. Each M2DA has a label that describes the subject covered by the M2DA and a worksheet prefix that all components of that M2DA must start with, as the name is actually a prefix to the file. The system reads this prefix and then searches through all the 2DAs for the ones starting with this prefix and merges them together as one 2DA. For example: M2DA ID 0 is &amp;quot;ANIM_&amp;quot;. The system looks through its list of 2DAs and finds &amp;quot;ANIM_base&amp;quot;, &amp;quot;ANIM_combat&amp;quot; and &amp;quot;ANIM_walk&amp;quot;. It will read and merge all 3 2DAs into an M2DA called &amp;quot;ANIM_&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Note that M2DA_base is itself an M2DA file and can be extended in the same manner.&lt;br /&gt;
&lt;br /&gt;
*''This example 2DA &amp;quot;MonstersCustom&amp;quot; would be merged into the original 2DA &amp;quot;Monsters&amp;quot;, if &amp;quot;Monsters&amp;quot; were one of the worksheets listed in the M2DA_base. ''&lt;br /&gt;
&lt;br /&gt;
=== Reserved ID Ranges and overriding existing rows ===&lt;br /&gt;
&lt;br /&gt;
While M2DA files avoid some of the problems associated with ordinary 2DA files, the IDs in each row of the final M2DA must still be unique across all 2DAs associated with it. If you use an existing row ID in your M2DA you can override the existing row with new data. Note that this can be a useful mechanism in some situations, for example allowing you to override existing content without having to edit the original 2DAs directly. &lt;br /&gt;
&lt;br /&gt;
To help ensure compatibility between authors' custom content, you should make sure that the ranges you choose don't conflict with ones already in use: [[2DA_ranges_in_use]].&lt;br /&gt;
&lt;br /&gt;
''See: [[compiling 2DAs#Afterwards|compiling 2DAs]]'' - for Information on where to place M2DA files to achieve the desired effect.&lt;br /&gt;
&lt;br /&gt;
=== Bug with M2DA ===&lt;br /&gt;
&lt;br /&gt;
It should be noted, that currently there is a bug with certain M2DA's, which prevents new ID's above 255 to work in the game. It is unclear which are affected, but most certainly it is [[ItemVariations.xls]] related. See [[Bug: High M2DA ID ranges might work in the toolset, but not in game|Bug report]].&lt;br /&gt;
&lt;br /&gt;
== 2DA XLS files used in Dragon Age ==&lt;br /&gt;
&lt;br /&gt;
[[List of 2DA XLS files]]&lt;br /&gt;
&lt;br /&gt;
The source files for the 2DAs that came with the installed game can be found under the toolsets directory &lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;Installdir&amp;gt;\Dragon Age\tools\Source\2DA\&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Users of Open Office ==&lt;br /&gt;
* Users of Open Office may find that no .gda file is created when they use ExcelProcessor.exe - one workaround is to copy a worksheet from an existing .xls file (such as placeable_types from placeables.xls), process the file, then remove the extraneous .gda file (e.g. placeable_types.gda). Alternately, upload your .xls file to Google Docs and then download the file as Excel format, then process the file with ExcelProcessor.exe.&lt;br /&gt;
* When editing existing xls files, it also works to leave the format as standard while saving the file. Open Office asks to change the file to its own spreatsheet format when saving a format other then its own, don't change the format and it should work. [Ed- And yet it doesn't seem to.]&lt;br /&gt;
&lt;br /&gt;
== Adding Strings ==&lt;br /&gt;
&lt;br /&gt;
{{needs review}}&lt;br /&gt;
&lt;br /&gt;
When adding strings to a 2DA, you have two options.  The simplest is to enter **** for the StringID column.  In that case, the name column will be used in the game.&lt;br /&gt;
&lt;br /&gt;
The other approach is to use the toolset's string editor to create a new string.  When that happens, you'll get a new StringID. Next enter that number into the StringID column in the 2DA.&lt;br /&gt;
&lt;br /&gt;
The second approach works better when translating your module, at the cost of portability.  If someone else wanted to reuse your 2DA, they'd have to generate their own strings, then update the StringID number based on these IDs.&lt;br /&gt;
&lt;br /&gt;
'''Attention:'''&lt;br /&gt;
&lt;br /&gt;
* The current version of the &amp;quot;ExelProcessor&amp;quot;-App is buggy as it can't hanlde INT values above 8388607! Many thanks to elys for figuring that out.&lt;br /&gt;
* Also note that the original toolset (v1.0) core-talktable contains wrong ids as well - don't forget to delete it from the &amp;quot;packages\core\override\toolsetexport&amp;quot; directory if you are still using that version.&lt;br /&gt;
&lt;br /&gt;
'''Workaround:'''&lt;br /&gt;
&lt;br /&gt;
* Create and export your talktable, delete the core-talktable override.&lt;br /&gt;
* Create your M2DA File that you want to refer to your talk-table strings. Never Mind using the real IDs at this stage.&lt;br /&gt;
* Use the &amp;quot;Exelprocessor&amp;quot; to create the GDA file.&lt;br /&gt;
* Open the GDA-File with the toolset or elys's GDA-Editor App (http://social.bioware.com/project/755/)&lt;br /&gt;
[[File:Edit-GDA-Values.jpg]]&lt;br /&gt;
* Change the StringIDs to the StringIDs in your talktable.&lt;br /&gt;
&lt;br /&gt;
'''Remark:''' &lt;br /&gt;
&lt;br /&gt;
The previous Version stated: ''Take that StringID and add 16777216 to the number.'' this appears to be wrong and is likely a holdover from NWN.&lt;br /&gt;
&lt;br /&gt;
[[Category:2DAs]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=2DA&amp;diff=10099</id>
		<title>2DA</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=2DA&amp;diff=10099"/>
				<updated>2010-01-24T22:04:54Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: /* Users of Open Office */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Many of the properties of objects in the toolset make reference to 2DAs (two-dimensional arrays). These are read-only arrays containing various data used by scripting and the game engine. For example, the set of local variables that an object supports is defined in a 2DA.&lt;br /&gt;
&lt;br /&gt;
The source files for 2DAs are Microsoft Excel worksheets. This allows a wide variety of sophisticated techniques to be used to generate the values of the 2DA fields, such as macros and formulas. It also makes editing much easier since the columns can be annotated and formatted in helpful ways, and multiple related worksheets can be grouped into one file.&lt;br /&gt;
&lt;br /&gt;
Data in a 2DA is identified by a row number, with the first row (row zero) usually being reserved for internal use (undefined value, etc.) by convention. Each row has an arbitrary number of columns identified by strings. &lt;br /&gt;
&lt;br /&gt;
Before they can be used by the toolset or the game, 2DAs must be converted from Excel files into a more efficient form. Processed 2DAs are stored in files with the .[[GDA]] extension.&lt;br /&gt;
&lt;br /&gt;
== Excel file formatting ==&lt;br /&gt;
&lt;br /&gt;
Cell A1 will contain &amp;quot;ID&amp;quot;. This is checked by the processor and the worksheet will fail if this is not the case.&lt;br /&gt;
&lt;br /&gt;
Column A starting at line 3 will contain an integer row ID number that is unique to that row across all files (unless creating an M2DA override). Row IDs will be listed from smallest to highest within the same file and do not need to be consecutive.&lt;br /&gt;
&lt;br /&gt;
A blank row or column will determine the dimension of the spreadsheet in that direction. Everything past that point is ignored by the binarizer.&lt;br /&gt;
&lt;br /&gt;
Column names are case sensitive. This is because of the CRC32 algorithm used to generate the hash key. Changing the case of a column name after it is in use will break the game. White space before and after a column name will be removed before hashing.&lt;br /&gt;
&lt;br /&gt;
Row 2 will be a &amp;quot;types&amp;quot; row. Each is a single word: [[int]], [[string]] (single chars as well), [[resource]], [[float]] or [[bool]]. A special type &amp;quot;[[comment]]&amp;quot; can be used to exclude a column from export.&lt;br /&gt;
&lt;br /&gt;
Any column with string data that refers to files should have a type of &amp;quot;resource&amp;quot; and not &amp;quot;string&amp;quot;. This is because the &amp;quot;resource&amp;quot; type is used to determine dependencies for the 2DA file.&lt;br /&gt;
&lt;br /&gt;
'bool' type may be one of: a zero or non-zero number, Yes or No (case insensitive), or words beginning with T or F (such as True! and False!). NOTE: You cannot use TRUE and FALSE because Excel converts those to a special keyword the binarizer can't parse properly at this time. '''Note:''' the scripting language doesn't have a function for retrieving boolean values from a 2DA, and the behavior of Get2DAInt when retrieving a boolean is untested. It is probably safer to just use an integer for scripting purposes.&lt;br /&gt;
&lt;br /&gt;
If you wish to leave a cell unfilled, the string &amp;quot;****&amp;quot; (four asterisks) can be inserted instead of a value.&lt;br /&gt;
&lt;br /&gt;
Any worksheets that are not exportable 2DA data will have an underscore prepended to their name - the resource builder will subsequently ignore them.&lt;br /&gt;
&lt;br /&gt;
Worksheets need to have unique names among all excel files, duplicates will overwrite each other as each worksheet is exported as a file&lt;br /&gt;
&lt;br /&gt;
You cannot have the workbook open in Excel at the same time as running the binarizer on it.&lt;br /&gt;
&lt;br /&gt;
Strings have a maximum length of 768 characters. Anything longer will be truncated.&lt;br /&gt;
&lt;br /&gt;
ExcelProcessor.exe constrains the name length of a worksheet to 27 characters. &lt;br /&gt;
&lt;br /&gt;
== Extending the game via M2DAs ==&lt;br /&gt;
&lt;br /&gt;
An &amp;quot;M2DA&amp;quot; is a &amp;quot;Multiple 2DA&amp;quot; that stacks a number of 2DA files into one larger table. They work much like single 2DA files except they can be patched or expanded later by adding more resources. These are useful for any table that lists other resources, such as appearance tables, so that new resources can be added later without having to modify a monolithic table.&lt;br /&gt;
&lt;br /&gt;
This is especially important for third-party modders, since BioWare might release an update to a core table at a later date that would overwrite any changes third parties had made to it. By using an M2DA with a unique name, and by using a range of ID numbers significantly separated from those already in use, you can ensure that your additions won't conflict with other portions of the M2DA.&lt;br /&gt;
&lt;br /&gt;
A list of all M2DAs used by the game can be found in [[2DA_base.xls]]. Every 2da listed in M2DA_base is treated as a M2DA, except for those with an ID between 10000 and 10999 which are handled as regular 2DAs. Each M2DA has a label that describes the subject covered by the M2DA and a worksheet prefix that all components of that M2DA must use.&lt;br /&gt;
&lt;br /&gt;
Every worksheet listed in the [[2DA_base.xls]] file is actually a prefix. The system reads this prefix and then searches through all the 2DAs for the ones starting with this prefix and merges them together as one 2DA. For example: M2DA Id 0 is &amp;quot;ANIM_&amp;quot;. The system looks through its list of 2das and finds &amp;quot;ANIM_base&amp;quot;, &amp;quot;ANIM_combat&amp;quot; and &amp;quot;ANIM_walk&amp;quot;. It will read and merge all 3 2DAs into an M2DA called &amp;quot;ANIM_&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Not all of the prefixes end in an underscore. For example, longsword variations are in worksheets prefixed with &amp;quot;longsword_variation&amp;quot;, so both &amp;quot;longsword_variation_candy&amp;quot; and &amp;quot;longsword_variationcandy&amp;quot; would work as M2DA worksheet names.&lt;br /&gt;
&lt;br /&gt;
2DAs are merged row by row, keyed on the ID column. If two rows in two different 2DAs to be merged have the same ID, the row in the 2da with the highest priority wins.&lt;br /&gt;
&lt;br /&gt;
== Converting XLS files into 2DA files ==&lt;br /&gt;
&lt;br /&gt;
In the &amp;quot;Dragon Age\tools\ResourceBuild\Processors&amp;quot; folder there is an executable named &amp;quot;ExcelProcessor.exe&amp;quot;. This is the file that handles conversions from XLS to 2DA format. Below are described 3 ways in which this file may be used.&lt;br /&gt;
&lt;br /&gt;
=== Drag &amp;amp; Drop Method ===&lt;br /&gt;
&lt;br /&gt;
# Copy ExcelProcessor.exe and source .XLS files to a new directory (not explicitly neccessary, but advised)&lt;br /&gt;
# Select source .XLS files and drag them onto ExcelProcessor.exe&lt;br /&gt;
# Cut &amp;amp; Paste resulting .2DA files, which will be located in the same directory as the source .XLS files, to your desired location (usually to &amp;quot;My Documents\BioWare\Dragon Age\AddIns\yourmodulename\module\overrides\&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Adding 2DA export to the Windows XP file explorer ===&lt;br /&gt;
&lt;br /&gt;
Here's an easy way to add a context (ie, right-click) menu item that quickly converts new or updated Dragon Age Excel files into GDA format: &lt;br /&gt;
&lt;br /&gt;
Setup: &lt;br /&gt;
&lt;br /&gt;
# Open Windows Explorer and click Tools | Folder Options.&lt;br /&gt;
# In the File Types tab, select the XLS extension from the list and click the Advanced button.&lt;br /&gt;
# Click the New button and put 'Binarize 2DA' in the Action field.&lt;br /&gt;
# Paste the following in the Application field and click OK (update the drive and folder names to match your client): &amp;lt;tt&amp;gt;&amp;quot;C:\Program Files\Dragon Age\tools\ResourceBuild\Processors\ExcelProcessor.exe&amp;quot;  &amp;quot;%1&amp;quot;  -outdir=&amp;quot;C:\Documents and Settings\YOURNAME\My Documents\BioWare\Dragon Age\packages\core\override&amp;quot;&amp;lt;/tt&amp;gt;&lt;br /&gt;
## For the Steam version, use the following: &amp;lt;tt&amp;gt;&amp;quot;C:\Program Files\Steam\steamapps\common\dragon age origins\tools\ResourceBuild\Processors\ExcelProcessor.exe&amp;quot;  &amp;quot;%1&amp;quot; -outdir=&amp;quot;C:\Documents and Settings\YOURNAME\My Documents\BioWare\Dragon Age\packages\core\override&amp;quot;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that paths with spaces in them can cause Windows trouble, if your paths have spaces in them remember to wrap them in quotation marks.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&lt;br /&gt;
# Using Windows Explorer, navigate to your 2DA folder (in my case C:\DA\tag\main\data\Source\2DA) and select the Excel file(s) to process. Right click and select 'Binarize 2DA' from the context menu. &lt;br /&gt;
# Confirm a corresponding GDA file is created in your override folder (in my case C:\DA\tag\main\build\packages\core\override) for each Excel file processed.&lt;br /&gt;
&lt;br /&gt;
[[File:Adding binarize 2da to Windows XP explorer.png|center|thumb|300px|An example of how setting this up in Windows XP looks]]&lt;br /&gt;
&lt;br /&gt;
=== Using a .BAT file ===&lt;br /&gt;
&lt;br /&gt;
The following method may work better for you instead:&lt;br /&gt;
&lt;br /&gt;
*Create two folders called C:\2DA\ and C:\2DA\Override\&lt;br /&gt;
*Copy ExcelProcessor.exe to C:\2DA\&lt;br /&gt;
*Copy the Excel spreadsheets containing the 2DA you want to use in the game to C:\2DA\&lt;br /&gt;
*Create a batch file with the following line in it (change &amp;quot;placeables.xls&amp;quot; to whatever Excel file you're working with):&lt;br /&gt;
C:\2DA\ExcelProcessor.exe placeables.xls -outdir=C:\2DA\override\&lt;br /&gt;
*Run your batch file&lt;br /&gt;
*Find the GDA file from the C:\2DA\Override\ directory and copy it to the game's override directory. Remember to take into account the naming conventions of M2DAs; you may need to rename your 2DA files with a new suffix unique to your module to allow it to add to the core 2DAs without conflict.&lt;br /&gt;
*'''If you copied your new 2DA file in your Override directory while Dragon Age Game was running, you will need to exit to windows and re-run the game to let your changes to work.'''&lt;br /&gt;
&lt;br /&gt;
== 2DA XLS files used in Dragon Age ==&lt;br /&gt;
&lt;br /&gt;
''Note: This list is very incomplete right now''&lt;br /&gt;
&lt;br /&gt;
Bear in mind that 2DAs names are actually based on the names of the worksheets inside these Excel files, not the names of the files themselves. Some of these files contain a large number of individual 2DAs within them. They are bundled together into Excel files based on the nature of the 2DAs for convenience.&lt;br /&gt;
&lt;br /&gt;
=== Creatures ===&lt;br /&gt;
&lt;br /&gt;
*[[APR_base.xls]] - appearance types for creatures&lt;br /&gt;
*[[ABI_base.xls]] - integrates all talents and spells into the game&lt;br /&gt;
*[[ANIM_base.xls]]&lt;br /&gt;
*[[ANIM_combat.xls]]&lt;br /&gt;
*[[ANIM placeables.xls]]&lt;br /&gt;
*[[SyncAnimations.xls]]&lt;br /&gt;
*[[CLA_base.xls]] - Defines the character classes used throughout the game&lt;br /&gt;
*[[background.xls]] - defines the various origin stories available to each race and class.&lt;br /&gt;
&lt;br /&gt;
=== Objects ===&lt;br /&gt;
*[[placeables.xls]] - interactive object types&lt;br /&gt;
*[[BITM base.xls]] - item types&lt;br /&gt;
*[[ItemVariations.xls]] - item appearance variations (eg, all the different ways a longsword can look)&lt;br /&gt;
*[[PRJ_base.xls]] - how various projectiles look and behave&lt;br /&gt;
*[[VFX_base.xls]] - Visual effects&lt;br /&gt;
&lt;br /&gt;
=== Areas and plots ===&lt;br /&gt;
&lt;br /&gt;
*[[worldmaps.xls]] - world maps for open-ended travel between areas&lt;br /&gt;
*[[plottypes.xls]] - how plots are grouped at the highest level in the game GUI (codex entry types, story, etc.)&lt;br /&gt;
*[[areadata.xls]] - sets various properties for specific areas&lt;br /&gt;
*[[rewards.xls]] - rewards for plot completion&lt;br /&gt;
&lt;br /&gt;
=== Adding to the official campaign ===&lt;br /&gt;
*[[PRCSCR]] - specifies scripts to run when an area or area list is loaded or entered.&lt;br /&gt;
&lt;br /&gt;
== Adding Strings ==&lt;br /&gt;
&lt;br /&gt;
When adding strings to a 2DA, you have two options.  The simplest is to enter **** for the StringID column.  In that case, the name column will be used in the game.&lt;br /&gt;
&lt;br /&gt;
The other approach is to use the toolset's string editor to create a new string.  When that happens, you'll get a new StringID. Next enter that number into the StringID column in the 2DA.&lt;br /&gt;
&lt;br /&gt;
The second approach works better when translating your module, at the cost of portability.  If someone else wanted to reuse your 2DA, they'd have to generate their own strings, then update the StringID number based on these IDs.&lt;br /&gt;
&lt;br /&gt;
'''Attention:'''&lt;br /&gt;
&lt;br /&gt;
* The current version of the &amp;quot;ExelProcessor&amp;quot;-App is buggy as it can't hanlde INT values above 8388607! Many thanks to elys for figuring that out.&lt;br /&gt;
* Also note that the original toolset (v1.0) core-talktable contains wrong ids as well - don't forget to delete it from the &amp;quot;packages\core\override\toolsetexport&amp;quot; directory if you are still using that version.&lt;br /&gt;
&lt;br /&gt;
'''Workaround:'''&lt;br /&gt;
&lt;br /&gt;
* Create and export your talktable, delete the core-talktable override.&lt;br /&gt;
* Create your M2DA File that you want to refer to your talk-table strings. Never Mind using the real IDs at this stage.&lt;br /&gt;
* Use the &amp;quot;Exelprocessor&amp;quot; to create the GDA file.&lt;br /&gt;
* Open the GDA-File with the toolset or elys's GDA-Editor App (http://social.bioware.com/project/755/)&lt;br /&gt;
[[File:Edit-GDA-Values.jpg]]&lt;br /&gt;
* Change the StringIDs to the StringIDs in your talktable.&lt;br /&gt;
&lt;br /&gt;
'''Remark:''' &lt;br /&gt;
&lt;br /&gt;
The previous Version stated: ''Take that StringID and add 16777216 to the number.'' this appears to be wrong and is likely a holdover from NWN.&lt;br /&gt;
&lt;br /&gt;
== Reserved ID Ranges ==&lt;br /&gt;
&lt;br /&gt;
While M2DA files avoid some of the problems associated with ordinary 2DA files, the IDs in each row of the final M2DA must still be unique across all 2DAs associated with it.&lt;br /&gt;
&lt;br /&gt;
To help ensure compatibility between authors' custom content, you should make sure that the ranges you choose don't conflict with ones already in use: [[2DA_ranges_in_use]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Users of Open Office ==&lt;br /&gt;
* Users of Open Office may find that no .gda file is created when they use ExcelProcessor.exe - one workaround is to copy a worksheet from an existing .xls file (such as placeable_types from placeables.xls), process the file, then remove the extraneous .gda file (e.g. placeable_types.gda). Alternately, upload your .xls file to Google Docs and then download the file as Excel format, then process the file with ExcelProcessor.exe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:2DAs]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=2DA&amp;diff=9373</id>
		<title>2DA</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=2DA&amp;diff=9373"/>
				<updated>2010-01-07T21:54:47Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: /* Adding Strings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Many of the properties of objects in the toolset make reference to 2DAs (two-dimensional arrays). These are read-only arrays containing various data used by scripting and the game engine. For example, the set of local variables that an object supports is defined in a 2DA.&lt;br /&gt;
&lt;br /&gt;
The source files for 2DAs are Microsoft Excel worksheets. This allows a wide variety of sophisticated techniques to be used to generate the values of the 2DA fields, such as macros and formulas. It also makes editing much easier since the columns can be annotated and formatted in helpful ways, and multiple related worksheets can be grouped into one file.&lt;br /&gt;
&lt;br /&gt;
Data in a 2DA is identified by a row number, with the first row (row zero) usually being reserved for internal use (undefined value, etc.) by convention. Each row has an arbitrary number of columns identified by strings. &lt;br /&gt;
&lt;br /&gt;
Before they can be used by the toolset or the game, 2DAs must be converted from Excel files into a more efficient form. Processed 2DAs are stored in files with the .[[GDA]] extension.&lt;br /&gt;
&lt;br /&gt;
== Excel file formatting ==&lt;br /&gt;
&lt;br /&gt;
Cell A1 will contain &amp;quot;ID&amp;quot;. This is checked by the processor and the worksheet will fail if this is not the case.&lt;br /&gt;
&lt;br /&gt;
Column A starting at line 3 will contain an integer row ID number that is unique to that row across all files (unless creating an M2DA override). Row IDs will be listed from smallest to highest within the same file and do not need to be consecutive.&lt;br /&gt;
&lt;br /&gt;
A blank row or column will determine the dimension of the spreadsheet in that direction. Everything past that point is ignored by the binarizer.&lt;br /&gt;
&lt;br /&gt;
Column names are case sensitive. This is because of the CRC32 algorithm used to generate the hash key. Changing the case of a column name after it is in use will break the game. White space before and after a column name will be removed before hashing.&lt;br /&gt;
&lt;br /&gt;
Row 2 will be a &amp;quot;types&amp;quot; row. Each is a single word: [[int]], [[string]] (single chars as well), [[resource]], [[float]] or [[bool]]. A special type &amp;quot;[[comment]]&amp;quot; can be used to exclude a column from export.&lt;br /&gt;
&lt;br /&gt;
Any column with string data that refers to files should have a type of &amp;quot;resource&amp;quot; and not &amp;quot;string&amp;quot;. This is because the &amp;quot;resource&amp;quot; type is used to determine dependencies for the 2DA file.&lt;br /&gt;
&lt;br /&gt;
'bool' type may be one of: a zero or non-zero number, Yes or No (case insensitive), or words beginning with T or F (such as True! and False!). NOTE: You cannot use TRUE and FALSE because Excel converts those to a special keyword the binarizer can't parse properly at this time. '''Note:''' the scripting language doesn't have a function for retrieving boolean values from a 2DA, and the behavior of Get2DAInt when retrieving a boolean is untested. It is probably safer to just use an integer for scripting purposes.&lt;br /&gt;
&lt;br /&gt;
If you wish to leave a cell unfilled, the string &amp;quot;****&amp;quot; (four asterisks) can be inserted instead of a value.&lt;br /&gt;
&lt;br /&gt;
Any worksheets that are not exportable 2DA data will have an underscore prepended to their name - the resource builder will subsequently ignore them.&lt;br /&gt;
&lt;br /&gt;
Worksheets need to have unique names among all excel files, duplicates will overwrite each other as each worksheet is exported as a file&lt;br /&gt;
&lt;br /&gt;
You cannot have the workbook open in Excel at the same time as running the binarizer on it.&lt;br /&gt;
&lt;br /&gt;
Strings have a maximum length of 768 characters. Anything longer will be truncated.&lt;br /&gt;
&lt;br /&gt;
ExcelProcessor.exe constrains the name length of a worksheet to 27 characters. &lt;br /&gt;
&lt;br /&gt;
== Extending the game via M2DAs ==&lt;br /&gt;
&lt;br /&gt;
An &amp;quot;M2DA&amp;quot; is a &amp;quot;Multiple 2DA&amp;quot; that stacks a number of 2DA files into one larger table. They work much like single 2DA files except they can be patched or expanded later by adding more resources. These are useful for any table that lists other resources, such as appearance tables, so that new resources can be added later without having to modify a monolithic table.&lt;br /&gt;
&lt;br /&gt;
This is especially important for third-party modders, since BioWare might release an update to a core table at a later date that would overwrite any changes third parties had made to it. By using an M2DA with a unique name, and by using a range of ID numbers significantly separated from those already in use, you can ensure that your additions won't conflict with other portions of the M2DA.&lt;br /&gt;
&lt;br /&gt;
A list of all M2DAs used by the game can be found in [[2DA_base.xls]]. Every 2da listed in M2DA_base is treated as a M2DA, except for those with an ID between 10000 and 10999 which are handled as regular 2DAs. Each M2DA has a label that describes the subject covered by the M2DA and a worksheet prefix that all components of that M2DA must use.&lt;br /&gt;
&lt;br /&gt;
Every worksheet listed in the [[2DA_base.xls]] file is actually a prefix. The system reads this prefix and then searches through all the 2DAs for the ones starting with this prefix and merges them together as one 2DA. For example: M2DA Id 0 is &amp;quot;ANIM_&amp;quot;. The system looks through its list of 2das and finds &amp;quot;ANIM_base&amp;quot;, &amp;quot;ANIM_combat&amp;quot; and &amp;quot;ANIM_walk&amp;quot;. It will read and merge all 3 2DAs into an M2DA called &amp;quot;ANIM_&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Not all of the prefixes end in an underscore. For example, longsword variations are in worksheets prefixed with &amp;quot;longsword_variation&amp;quot;, so both &amp;quot;longsword_variation_candyland&amp;quot; and &amp;quot;longsword_variationcandyland&amp;quot; would work as M2DA worksheet names.&lt;br /&gt;
&lt;br /&gt;
2DAs are merged row by row, keyed on the ID column. If two rows in two different 2DAs to be merged have the same ID, the row in the 2da with the highest priority wins.&lt;br /&gt;
&lt;br /&gt;
== Converting XLS files into 2DA files ==&lt;br /&gt;
&lt;br /&gt;
In the &amp;quot;Dragon Age\tools\ResourceBuild\Processors&amp;quot; folder there is an executable named &amp;quot;ExcelProcessor.exe&amp;quot;. This is the file that handles conversions from XLS to 2DA format. Below are described 3 ways in which this file may be used.&lt;br /&gt;
&lt;br /&gt;
=== Drag &amp;amp; Drop Method ===&lt;br /&gt;
&lt;br /&gt;
# Copy ExcelProcessor.exe and source .XLS files to a new directory (not explicitly neccessary, but advised)&lt;br /&gt;
# Select source .XLS files and drag them onto ExcelProcessor.exe&lt;br /&gt;
# Cut &amp;amp; Paste resulting .2DA files, which will be located in the same directory as the source .XLS files, to your desired location (usually to &amp;quot;My Documents\BioWare\Dragon Age\AddIns\yourmodulename\module\overrides\&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Adding 2DA export to the Windows XP file explorer ===&lt;br /&gt;
&lt;br /&gt;
Here's an easy way to add a context (ie, right-click) menu item that quickly converts new or updated Dragon Age Excel files into GDA format: &lt;br /&gt;
&lt;br /&gt;
Setup: &lt;br /&gt;
&lt;br /&gt;
# Open Windows Explorer and click Tools | Folder Options.&lt;br /&gt;
# In the File Types tab, select the XLS extension from the list and click the Advanced button.&lt;br /&gt;
# Click the New button and put 'Binarize 2DA' in the Action field.&lt;br /&gt;
# Paste the following in the Application field and click OK (update the drive and folder names to match your client): &amp;lt;tt&amp;gt;&amp;quot;C:\Program Files\Dragon Age\tools\ResourceBuild\Processors\ExcelProcessor.exe&amp;quot;  &amp;quot;%1&amp;quot;  -outdir=&amp;quot;C:\Documents and Settings\YOURNAME\My Documents\BioWare\Dragon Age\packages\core\override&amp;quot;&amp;lt;/tt&amp;gt;&lt;br /&gt;
## For the Steam version, use the following: &amp;lt;tt&amp;gt;&amp;quot;C:\Program Files\Steam\steamapps\common\dragon age origins\tools\ResourceBuild\Processors\ExcelProcessor.exe&amp;quot;  &amp;quot;%1&amp;quot; -outdir=&amp;quot;C:\Documents and Settings\YOURNAME\My Documents\BioWare\Dragon Age\packages\core\override&amp;quot;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that paths with spaces in them can cause Windows trouble, if your paths have spaces in them remember to wrap them in quotation marks.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&lt;br /&gt;
# Using Windows Explorer, navigate to your 2DA folder (in my case C:\DA\tag\main\data\Source\2DA) and select the Excel file(s) to process. Right click and select 'Binarize 2DA' from the context menu. &lt;br /&gt;
# Confirm a corresponding GDA file is created in your override folder (in my case C:\DA\tag\main\build\packages\core\override) for each Excel file processed.&lt;br /&gt;
&lt;br /&gt;
[[File:Adding binarize 2da to Windows XP explorer.png|center|thumb|300px|An example of how setting this up in Windows XP looks]]&lt;br /&gt;
&lt;br /&gt;
=== Using a .BAT file ===&lt;br /&gt;
&lt;br /&gt;
The following method may work better for you instead:&lt;br /&gt;
&lt;br /&gt;
*Create two folders called C:\2DA\ and C:\2DA\Override\&lt;br /&gt;
*Copy ExcelProcessor.exe to C:\2DA\&lt;br /&gt;
*Copy the Excel spreadsheets containing the 2DA you want to use in the game to C:\2DA\&lt;br /&gt;
*Create a batch file with the following line in it (change &amp;quot;placeables.xls&amp;quot; to whatever Excel file you're working with):&lt;br /&gt;
C:\2DA\ExcelProcessor.exe placeables.xls -outdir=C:\2DA\override\&lt;br /&gt;
*Run your batch file&lt;br /&gt;
*Find the GDA file from the C:\2DA\Override\ directory and copy it to the game's override directory. Remember to take into account the naming conventions of M2DAs; you may need to rename your 2DA files with a new suffix unique to your module to allow it to add to the core 2DAs without conflict.&lt;br /&gt;
&lt;br /&gt;
== 2DA XLS files used in Dragon Age ==&lt;br /&gt;
&lt;br /&gt;
''Note: This list is very incomplete right now''&lt;br /&gt;
&lt;br /&gt;
Bear in mind that 2DAs names are actually based on the names of the worksheets inside these Excel files, not the names of the files themselves. Some of these files contain a large number of individual 2DAs within them. They are bundled together into Excel files based on the nature of the 2DAs for convenience.&lt;br /&gt;
&lt;br /&gt;
=== Creatures ===&lt;br /&gt;
&lt;br /&gt;
*[[APR_base.xls]] - appearance types for creatures&lt;br /&gt;
*[[ABI_base.xls]] - integrates all talents and spells into the game&lt;br /&gt;
*[[ANIM_base.xls]]&lt;br /&gt;
*[[ANIM_combat.xls]]&lt;br /&gt;
*[[ANIM placeables.xls]]&lt;br /&gt;
*[[SyncAnimations.xls]]&lt;br /&gt;
*[[CLA_base.xls]] - Defines the character classes used throughout the game&lt;br /&gt;
*[[background.xls]] - defines the various origin stories available to each race and class.&lt;br /&gt;
&lt;br /&gt;
=== Objects ===&lt;br /&gt;
*[[placeables.xls]] - interactive object types&lt;br /&gt;
*[[BITM base.xls]] - item types&lt;br /&gt;
*[[ItemVariations.xls]] - item appearance variations (eg, all the different ways a longsword can look)&lt;br /&gt;
*[[PRJ_base.xls]] - how various projectiles look and behave&lt;br /&gt;
*[[VFX_base.xls]] - Visual effects&lt;br /&gt;
&lt;br /&gt;
=== Areas and plots ===&lt;br /&gt;
&lt;br /&gt;
*[[worldmaps.xls]] - world maps for open-ended travel between areas&lt;br /&gt;
*[[plottypes.xls]] - how plots are grouped at the highest level in the game GUI (codex entry types, story, etc.)&lt;br /&gt;
*[[areadata.xls]] - sets various properties for specific areas&lt;br /&gt;
*[[rewards.xls]] - rewards for plot completion&lt;br /&gt;
&lt;br /&gt;
=== Adding to the official campaign ===&lt;br /&gt;
*[[PRCSCR]] - specifies scripts to run when an area or area list is loaded or entered.&lt;br /&gt;
&lt;br /&gt;
== Adding Strings ==&lt;br /&gt;
&lt;br /&gt;
When adding strings to a 2DA, you have two options.  The simplest is to enter **** for the StringID column.  In that case, the name column will be used in the game.&lt;br /&gt;
&lt;br /&gt;
The other approach is to use the toolset's string editor to create a new string.  When that happens, you'll get a new StringID. Next enter that number into the StringID column in the 2DA.&lt;br /&gt;
&lt;br /&gt;
The second approach works better when translating your module, at the cost of portability.  If someone else wanted to reuse your 2DA, they'd have to generate their own strings, then update the StringID number based on these IDs.&lt;br /&gt;
&lt;br /&gt;
'''Attention:'''&lt;br /&gt;
&lt;br /&gt;
* The current version of the &amp;quot;ExelProcessor&amp;quot;-App is buggy as it can't hanlde INT values above 8388607! Many thanks to elys for figuring that out.&lt;br /&gt;
* Also note that the original toolset (v1.0) core-talktable contains wrong ids as well - don't forget to delete it from the &amp;quot;packages\core\override\toolsetexport&amp;quot; directory if you are still using that version.&lt;br /&gt;
&lt;br /&gt;
'''Workaround:'''&lt;br /&gt;
&lt;br /&gt;
* Create and export your talktable, delete the core-talktable override.&lt;br /&gt;
* Create your M2DA File that you want to refer to your talk-table strings. Never Mind using the real IDs at this stage.&lt;br /&gt;
* Use the &amp;quot;Exelprocessor&amp;quot; to create the GDA file.&lt;br /&gt;
* Open the GDA-File with the toolset or elys's GDA-Editor App (http://social.bioware.com/project/755/)&lt;br /&gt;
[[File:Edit-GDA-Values.jpg]]&lt;br /&gt;
* Change the StringIDs to the StringIDs in your talktable.&lt;br /&gt;
&lt;br /&gt;
'''Remark:''' &lt;br /&gt;
&lt;br /&gt;
The previous Version stated: ''Take that StringID and add 16777216 to the number.'' this appears to be wrong and is likely a holdover from NWN.&lt;br /&gt;
&lt;br /&gt;
== Reserved ID Ranges ==&lt;br /&gt;
&lt;br /&gt;
While M2DA files avoid some of the problems associated with ordinary 2DA files, the IDs in each row of the final M2DA must still be unique across all 2DAs associated with it.&lt;br /&gt;
&lt;br /&gt;
To help ensure compatibility between authors' custom content, you should make sure that the ranges you choose don't conflict with ones already in use: [[2DA_ranges_in_use]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Users of Open Office ==&lt;br /&gt;
* Users of Open Office may find that no .gda file is created when they use ExcelProcessor.exe - one workaround is to copy a worksheet from an existing .xls file (such as placeable_types from placeables.xls), process the file, then remove the extraneous .gda file (e.g. placeable_types.gda).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:2DAs]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9355</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9355"/>
				<updated>2010-01-06T17:29:02Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: /* Why don't my followers gain XP? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Simple Follower Creation ==&lt;br /&gt;
&lt;br /&gt;
Follow these steps to create a follower that&lt;br /&gt;
&lt;br /&gt;
- Levels up with a default package&lt;br /&gt;
&lt;br /&gt;
- Can be chosen from the party picker&lt;br /&gt;
&lt;br /&gt;
- Can gain XP&lt;br /&gt;
&lt;br /&gt;
This guide assumes you know how to create a creature and are comfortable with basic scripting.&lt;br /&gt;
&lt;br /&gt;
You should only use this simple method if you are sure there will be empty space in the active party when your follower is recruited.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create the creature ===&lt;br /&gt;
&lt;br /&gt;
Create a creature to act as your follower.  Set its name, appearance, gender, head morph, conversation, inventory etc as you want them to behave in-game.&lt;br /&gt;
&lt;br /&gt;
Set an appropriate '''Tag''' (you'll be using it a lot).  I suggest &amp;quot;party_charname&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Make sure you choose a '''Class'''.  For most followers this should be Rogue, Warrior or Wizard.&lt;br /&gt;
&lt;br /&gt;
[[File:class.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under Package/Scaling set:&lt;br /&gt;
&lt;br /&gt;
'''General Package Type''' to be '''Party Members'''&lt;br /&gt;
&lt;br /&gt;
'''Package''' to be an appropriate value (probably &amp;quot;Generic - Wizard&amp;quot; or similar)&lt;br /&gt;
&lt;br /&gt;
'''Package AI''' (there should only be one choice)&lt;br /&gt;
&lt;br /&gt;
'''Rank''' to be '''Player'''&lt;br /&gt;
&lt;br /&gt;
[[File:package.jpg]]&lt;br /&gt;
&lt;br /&gt;
Save and export your character as normal.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Override char_stage ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In your resource palette, open char_stage under the Global folder:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:area_palette.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create a new waypoint for your follower to appear on the party picker.  This waypoint '''must''' have a tag in the form of &amp;quot;char_&amp;quot; followed by the exact tag of your follower.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:char_stage.jpg]]&lt;br /&gt;
&lt;br /&gt;
In this example the tag of my follower is '''bc_party_miera''' so her waypoint tag must be '''char_bc_party_miera'''&lt;br /&gt;
&lt;br /&gt;
For a standalone module (such as in this example), put your waypoint wherever you please.  The illustrated one is directly on top of Morrigan's.  For an add-in to the main campaign, you should position your wp appropriately relative to the core party members.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Save and export the area.&lt;br /&gt;
&lt;br /&gt;
Move the '''char_stage.are''' and '''char_stage.lst''' files from your core export folder to your module's export folder (probably from \Documents\Bioware\Dragon Age\packages\core\override\toolsetexport to \Documents\Bioware\Dragon Age\AddIns\yourModule\module\override\toolsetoverride).  This ensures that the modification to the character stage only takes effect if your module is installed and enabled, which will help manage compatibility problems.  Make sure those files are included when you package your module for distribution.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create m2DAs for the Party Picker ===&lt;br /&gt;
&lt;br /&gt;
You will need to create two Excel spreadsheets.&lt;br /&gt;
&lt;br /&gt;
The first should be named (both worksheet and file) '''partypicker_''' with a unique suffix.  In this example, my first spreadsheet is named partypicker_fofbc.xls with a worksheet name of partypicker_fofbc - the suffix being the acronym of my module.&lt;br /&gt;
&lt;br /&gt;
Set up your columns as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:partypickerm2da.jpg]]&lt;br /&gt;
&lt;br /&gt;
The '''ID''' for your follower must be '''12 or higher'''.  11 is the highest value used in the base 2DA.  12 is fine for standalone modules, add-ins will probably want to use an arbitrarily high number to avoid potential conflicts.&lt;br /&gt;
&lt;br /&gt;
The '''Label''' should be the follower's name as you wish it to appear on the party picker.&lt;br /&gt;
&lt;br /&gt;
The '''Tag''' must be your follower's tag.&lt;br /&gt;
&lt;br /&gt;
All other values are non-functioning defaults and should be specified as in the image above unless you know explicitly what you're doing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second spreadsheet should be named '''party_picker_''' (note middle underscore).  Once again append your unique suffix (in this example party_picker_fofbc.xls with party_picker_fofbc as its worksheet).&lt;br /&gt;
&lt;br /&gt;
Set up your columns and data like so:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:party_pickerm2da.jpg]]&lt;br /&gt;
&lt;br /&gt;
'''ID''' and '''Tag''' should match what you did in the first spreadsheet.  Specify INVALID COLUMN for the third column.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you're familiar with m2DAs, generate them from these files, copy them to your module's override directory, and skip to the next step.  Otherwise, read on:&lt;br /&gt;
&lt;br /&gt;
- Go to '''\Program Files\Dragon Age\tools\ResourceBuild\Processors''' (or wherever you installed Dragon Age)&lt;br /&gt;
&lt;br /&gt;
- Copy '''ExcelProcessor.exe''' from that folder to whichever folder has the excel sheets you just created.&lt;br /&gt;
&lt;br /&gt;
- Drag and drop your xls files onto ExcelProcessor.  This will create .gda files.&lt;br /&gt;
&lt;br /&gt;
- Copy these .gda files to your module's export directory (probably \Documents\Bioware\Dragon Age\AddIns\yourModule\module\override\toolsetoverride).  Make sure they are included in your .dazip when the time comes to build your module.&lt;br /&gt;
&lt;br /&gt;
If you are an OpenOffice user and have trouble with ExcelProcessor, you can use [http://social.bioware.com/project/755/ GDApp] to directly create the 2DAs.  It rocks!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Capture the EVENT_TYPE_PARTYMEMBER_ADDED Event ===&lt;br /&gt;
&lt;br /&gt;
Amusingly enough, the Party Picker does not actually add followers to the party.  However it raises an event that allows you to do so.  Your module script needs to capture this event and execute some code.&lt;br /&gt;
&lt;br /&gt;
The following example shows what to do with the event.  The full script would work as a module script for an add-in (assuming it didn't need to do anything else), but otherwise you'll have to incorporate the event into your own script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    switch(nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_ADDED:&lt;br /&gt;
        {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);  //Allows the follower to gain XP&lt;br /&gt;
            SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);  //Adds follower to the active party&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE)''' is the key statement to add the follower to the active party.  You must have this.&lt;br /&gt;
&lt;br /&gt;
'''SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0)''' is a bug-fix, as followers hired with UT_HireFollower() do not receive XP by default.  This statement fixes that, and I consider it best practice to keep it in this event to ensure it is always set.  You will not wish to do this if you want a follower that should not gain XP to be on the party picker.&lt;br /&gt;
&lt;br /&gt;
Note that you do not need to intercept the corresponding event for a party member being removed - the party picker handles spawning/despawning, and thus will successfully remove members.&lt;br /&gt;
&lt;br /&gt;
Remember to save and export your module script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create Your Hiring Script ===&lt;br /&gt;
&lt;br /&gt;
Now all that remains is to actually hire the follower :)&lt;br /&gt;
&lt;br /&gt;
Create a script to handle the hiring (which will most likely be fired from a conversation).  The script is quite simple:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
&lt;br /&gt;
        object oFollower = GetObjectByTag(&amp;quot;bc_party_miera&amp;quot;); //Use CreateObject() if the creature isn't present in the module yet&lt;br /&gt;
&lt;br /&gt;
        UT_HireFollower(oFollower);   //Hires the follower&lt;br /&gt;
&lt;br /&gt;
        SetPartyPickerGUIStatus(2);&lt;br /&gt;
&lt;br /&gt;
        ShowPartyPickerGUI();  //Shows the Party Picker; necessary for the follower to gain XP&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make sure you use your own follower's tag and not the example one :)&lt;br /&gt;
&lt;br /&gt;
This script fires the party picker after hiring the follower.  That is absolutely necessary via this method, as we have put the XP fix onto an event fired by the party picker.  You cannot put the XP fix into this script, it must be called from a later one (the bug is caused by an errant call to an event in player_core, which will be executed AFTER this script).&lt;br /&gt;
&lt;br /&gt;
If everything worked, you should see something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:picker_success.jpg|thumb|200px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Advanced Follower Creation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow these steps to have full control over the creation of your follower, with options such as:&lt;br /&gt;
&lt;br /&gt;
- Unique level-up template&lt;br /&gt;
&lt;br /&gt;
- Class and specialisation chosen via script&lt;br /&gt;
&lt;br /&gt;
- Any starting state&lt;br /&gt;
&lt;br /&gt;
- Level higher than the PC&lt;br /&gt;
&lt;br /&gt;
- Starts with a specialisation point rather than a specific specialisation&lt;br /&gt;
&lt;br /&gt;
- Set plot flags in the call to the hire script&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Prepare Creature, char_stage and Party Picker m2DAs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the same steps to create your create your follower creature, override char_stage and create your Party Picker m2DAs as above.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create Party Plot ===&lt;br /&gt;
&lt;br /&gt;
While not necessary, it's very helpful to have plot flags set when a follower is hired or joins/leaves the active party.  This makes conversation interjections and the like very easy.&lt;br /&gt;
&lt;br /&gt;
Create a plot with appropriate flags.  There's no real need to associate journal text with them:&lt;br /&gt;
&lt;br /&gt;
[[File:follower_plot.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Add Plot Flags to Party Picker Event Intercept ===&lt;br /&gt;
&lt;br /&gt;
We then update our module script to make use of that plot, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
#include &amp;quot;plt_bc_create_party&amp;quot;   //make sure you include your own plot, not mine&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    switch(nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_ADDED:&lt;br /&gt;
        {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);&lt;br /&gt;
            SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);&lt;br /&gt;
            &lt;br /&gt;
            if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               //You must explicitly test for your follower's tag.&lt;br /&gt;
                WR_SetPlotFlag(PLT_BC_CREATE_PARTY, PARTY_MIERA_IN_PARTY, TRUE);     //Make sure you use your own flags!&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            break;&lt;br /&gt;
        }  &lt;br /&gt;
        &lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_DROPPED:                    &lt;br /&gt;
        {&lt;br /&gt;
              object oFollower = GetEventObject(ev, 0); &lt;br /&gt;
              &lt;br /&gt;
              if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) { &lt;br /&gt;
                WR_SetPlotFlag(PLT_BC_CREATE_PARTY, PARTY_MIERA_IN_PARTY, FALSE);     //As above, but set false.&lt;br /&gt;
              }&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a Level Up Template ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can skip this step if you're content to use one of the generic Rogue, Wizard or Warrior templates, but I don't recommend it.  Making a template that suits your character is easy and will almost always be better for the player than a generic one that spends points poorly.&lt;br /&gt;
&lt;br /&gt;
Go to \Program Files\Dragon Age\tools\Source\2DA (or wherever you installed Dragon Age).&lt;br /&gt;
&lt;br /&gt;
You should see a number of excel sheets of the form '''ALCharacter.xls''' (such as ALAlistair.xls, ALLeliana.xls, ALRogue_Default.xls etc).  Open the one closest to your character (ie Morrigan or Wynne for a wizard, Leliana or Zevran for a rogue).  Save a copy as '''ALYourcharacter.xls''' in whatever directory you're using to create your 2DAs, remembering to rename the worksheet '''ALYourcharacter''' (in this example, ALMiera.xls with ALMiera as its worksheet).&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
[[File:ALtable.jpg|thumb|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Columns B''' and '''C''' are the talents/spells available to this character.  Do not change them.&lt;br /&gt;
&lt;br /&gt;
'''Columns F''' and '''G''' are the skills available to this character.  Do not change them.&lt;br /&gt;
&lt;br /&gt;
We will edit the remaining columns like so:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting Stat Weights ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The stat weights in '''column J''' determine how the follower will spend their attribute points, in a rough ratio.  So if Dexterity is set to 1.5 and Intelligence to 1, you should expect to see 3 points of Dex for every 2 points of Cunning in-game (note Intelligence is the label used in the toolset for Cunning).&lt;br /&gt;
&lt;br /&gt;
Simply change the values in J to reflect how you'd like the character to spend their points.  In this example we're creating a wizard, so we're not going to mess around:&lt;br /&gt;
&lt;br /&gt;
[[File:miera_stat_weights.jpg]]&lt;br /&gt;
&lt;br /&gt;
This character will only raise magic.  I set the value to 5 rather than something like 1 to provide room underneath for the other stats while still overwhelmingly favouring magic, but in practice I only really ever want that one stat.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting Talent and Skill Priorities ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Columns D''' and '''E''' are the talents/spells that the character will buy, in preference order from top to bottom.&lt;br /&gt;
&lt;br /&gt;
'''Columns H''' and '''I''' are the skills available to this character, in preference order from top to bottom.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To change these, just copy the appropriate two cells from columns B&amp;amp;C or F&amp;amp;G over the ones you want to replace.&lt;br /&gt;
&lt;br /&gt;
For example, here we're copying Morrigan's template.  Morrigan has Spider Shape high in her preferences, which we do not want.&lt;br /&gt;
&lt;br /&gt;
[[File:AlMori_talent_pref.jpg]]&lt;br /&gt;
&lt;br /&gt;
We decide we'd prefer Flame Blast, so we find it in columns B&amp;amp;C and copy both cells:&lt;br /&gt;
&lt;br /&gt;
[[File:ALMori_copy.jpg]]&lt;br /&gt;
&lt;br /&gt;
Then we select the cells we want to replace in columns D&amp;amp;E and paste over them:&lt;br /&gt;
&lt;br /&gt;
[[File:ALMori_paste.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Continue this process until your priorities list for both skills and talents/spells is exactly as you want it.  Make sure you have at least as many priorities as the core follower you're copying - points that cannot be spent according to these priorities have a habit of vanishing.&lt;br /&gt;
&lt;br /&gt;
If you used any abilities from a specialisation, make sure you remember to set that specialisation with the function we'll introduce later.  The autolevel scripts will add specialisation abilities to a character regardless of whether they have that spec or not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Create a M2DA_base_ m2DA ====&lt;br /&gt;
&lt;br /&gt;
Dragon Age will need to know where to find your autolevel template.  We tell it by extending M2DA_base.gda&lt;br /&gt;
&lt;br /&gt;
Create a spreadsheet with the name and worksheet name in the form '''M2DA_base_''' with your unique suffix (in this example, M2DA_base_fofbc.xls with M2DA_base_fofbc as a worksheet).&lt;br /&gt;
&lt;br /&gt;
Set up its columns and data like so (note I used GDApp because Open Office wasn't cooperating for this one!):&lt;br /&gt;
&lt;br /&gt;
[[File:m2da_base_fofbc.jpg]]&lt;br /&gt;
&lt;br /&gt;
The '''ID''' should be very high to avoid conflicts.  I've arbitrarily chosen 50,000+ here.  Carefully note the ID you've chosen for your character, you will need it later.&lt;br /&gt;
&lt;br /&gt;
Set the '''Label''' and '''Worksheet''' to be the name of your autolevel template worksheet (ALCharactername if you've been following this).&lt;br /&gt;
&lt;br /&gt;
Set the '''PackageIDForAI''' to be 0, it shouldn't be needed for followers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you're done, use ExcelProcessor to make GDAs of both spreadsheets and copy them to your module's export folder.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a New Hire Function Include ===&lt;br /&gt;
&lt;br /&gt;
Many vital steps of follower addition happen inside an event in player_core.  Followers tend to be extremely buggy (no skill tree, for example) if this event does not fire.&lt;br /&gt;
&lt;br /&gt;
However, that event is not very flexible.  In order to control it to our requirements, we need to replicate its functionality inside our own script.  This is probably much safer than messing with player_core directly!&lt;br /&gt;
&lt;br /&gt;
Create a new script file, naming it something like '''hireCustomFollower_h'''.  We will be including this wherever we want to hire a follower.&lt;br /&gt;
&lt;br /&gt;
Paste in the following script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;sys_chargen_h&amp;quot;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;sys_rewards_h&amp;quot;&lt;br /&gt;
#include &amp;quot;approval_h&amp;quot;&lt;br /&gt;
#include &amp;quot;sys_autolevelup_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*  Jye Nicolson 5-Jan-2010&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This function set duplicates the full functionality chain of UT_HireFollower, with the following exceptions:&lt;br /&gt;
&lt;br /&gt;
-  Followers can gain XP&lt;br /&gt;
-  Autolevel status can be set (default off)&lt;br /&gt;
-  Followers can be set to any starting state (default Available) and will still be properly initalised and added to the party pool&lt;br /&gt;
-  Autolevel tables for non-core followers can be explicitly set.&lt;br /&gt;
-  Class and Specialisation can be chosen via script&lt;br /&gt;
-  Followers without specialisations are granted a spec point by default.&lt;br /&gt;
&lt;br /&gt;
It should only ever be called once each for characters you intend to be full followers.&lt;br /&gt;
Much of the protective code handling summoned creatures etc. in player_core is not present here.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Calling the function:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
&lt;br /&gt;
hireCustomFollower(oFollower, CLASS_WARRIOR);&lt;br /&gt;
&lt;br /&gt;
Change the class to CLASS_WIZARD or CLASS_ROGUE as appropriate.  &lt;br /&gt;
This will hire your follower and make them available.  &lt;br /&gt;
They will auto level up with a default package, and receive a free spec point.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Best Practice:&lt;br /&gt;
&lt;br /&gt;
hireCustomFollower(oFollower, CLASS_WARRIOR, PLT_YOUR_PARTY_PLOT, YOUR_FOLLOWER_JOINED_FLAG, ABILITY_TALENT_HIDDEN_CHAMPION);&lt;br /&gt;
&lt;br /&gt;
Where the plot and flag are those for your module (remember to create the plot and include it on the calling script), and ABILITY_TALENT_HIDDEN etc is the desired spec.&lt;br /&gt;
&lt;br /&gt;
You should also have a custom ALTable set up.  &lt;br /&gt;
See wiki for details, and remember to edit it in to GetCustomFollowerALTable below or pass it directly as an argument to hireCustomFollower.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Full argument list:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void hireCustomFollower (&lt;br /&gt;
        object oFollower,   //Pass your follower object, mandatory&lt;br /&gt;
        &lt;br /&gt;
        int nForceClass,    //Pass a Class constant here, usually CLASS_ROGUE, CLASS_WARRIOR, CLASS_WIZARD.  Mandatory due to a bug.&lt;br /&gt;
        &lt;br /&gt;
        string sPlot = &amp;quot;&amp;quot;,   //It's recommended you have a plot flag to be set when the follower joins.  Pass the plot constant here.  Remember to #include in calling script&lt;br /&gt;
        &lt;br /&gt;
        int nPlotFlag = &amp;quot;&amp;quot;,  //And then pass the flag constant.  Will be set to TRUE if available.&lt;br /&gt;
        &lt;br /&gt;
        int nForceSpec = 0,  //This is the ID of the Specialisation you want.  Note they are NOT classes, but abilities.  The full list is:&lt;br /&gt;
                             //ABILITY_SPELL_HIDDEN_ARCANE_WARRIOR, ABILITY_SPELL_HIDDEN_BLOODMAGE, ABILITY_SPELL_HIDDEN_SHAPESHIFTER, ABILITY_SPELL_HIDDEN_SPIRIT_HEALER&lt;br /&gt;
                             //ABILITY_SPELL_HIDDEN_BARD, ABILITY_TALENT_HIDDEN_ASSASSIN, ABILITY_TALENT_HIDDEN_DUELIST, ABILITY_TALENT_HIDDEN_RANGER&lt;br /&gt;
                             //ABILITY_TALENT_HIDDEN_BERSERKER, ABILITY_TALENT_HIDDEN_CHAMPION, ABILITY_TALENT_HIDDEN_REAVER, ABILITY_TALENT_HIDDEN_TEMPLAR&lt;br /&gt;
                             //I recommended forcing a spec, particularly if your ALTable includes abilities from one.&lt;br /&gt;
        &lt;br /&gt;
        int nALTable = 0,    //This is the ID of an ALTable from 2DA_base.GDA or your module's m2DA_base_*.GDA  I recommended the latter, but you can edit that into GetCustomFollowerALTable below rather than passing it.&lt;br /&gt;
        &lt;br /&gt;
        int bInvokePicker = FALSE,  //Sets whether the party picker should be opened on hiring.  I think it's cleaner to call the picker outside this script, particularly if you have multiple hires at once.&lt;br /&gt;
        &lt;br /&gt;
        int nInitialState = FOLLOWER_STATE_AVAILABLE,  //This sets whether the follower joins the active party or not.  Options are:&lt;br /&gt;
                                                       //FOLLOWER_STATE_ACTIVE (put them in the active party)&lt;br /&gt;
                                                       //FOLLOWER_STATE_LOCKEDACTIVE (force them into the active party and keep them there, remember to change this later.&lt;br /&gt;
                                                       //FOLLOWER_STATE_AVAILABLE (make them available on the party picker (if you've set it up for them), but not in the active party)&lt;br /&gt;
                                                       //Plus some others you're unlikely to need at this time.  Defaults to AVAILABLE because having 4+ active followers is screwy.&lt;br /&gt;
                                                       &lt;br /&gt;
        string sCurrPlot = &amp;quot;&amp;quot;,  //If you set FOLLOWER_STATE_ACTIVE or FOLLOWER_STATE_LOCKEDACTIVE, the script will check to see if you passed this.&lt;br /&gt;
                                //It is recommended that you have a plot flag set for a given follower being in the active party, this makes conversation interjection etc. much easier.&lt;br /&gt;
&lt;br /&gt;
        int nCurrPlotFlag = 0,  //This flag will be set if FOLLOWER_STATE_ACTIVE or FOLLOWER_STATE_LOCKEDACTIVE are true&lt;br /&gt;
                                //AND sCurrPlot has a value AND nCurrPlotFlag is &amp;gt; 0.  &lt;br /&gt;
                                //ie if you added someone to the active party and have a plot flag to cope with it.&lt;br /&gt;
&lt;br /&gt;
        int nAutolevel = 0,     //Sets the Autolevel flag on the character sheet.  0 is off, 1 is on, 2 forces it on and removes it so the player can't turn it off.&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        bFreeSpecPoint = TRUE,  //This grants a specialisation point to the follower if they do not have a specialisation.  &lt;br /&gt;
                                //It's important to set this false for classes that do not have specs, such as CLASS_DOG.&lt;br /&gt;
                                &lt;br /&gt;
        int nTargetLevel = 0,   //If you want a specific level, set this.  Generally not worthwhile unless you set it higher than the player, since they'll just get XP from the party picker anyway.&lt;br /&gt;
        &lt;br /&gt;
        int nMinLevel = 0       //Set this if there's a specific level you don't want the follower to go below.  Probably only useful if the PC might be very low level but not necessarily so. &lt;br /&gt;
        &lt;br /&gt;
        )&lt;br /&gt;
                        &lt;br /&gt;
&lt;br /&gt;
*/       &lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
/* GetCustomFollowerALTable()  &lt;br /&gt;
&lt;br /&gt;
This function is where you put your custom table assignments.&lt;br /&gt;
&lt;br /&gt;
You should explicitly test for the tag of your follower (not mine!) and assign a value to nTable from your m2DA extension to M2DA_base &lt;br /&gt;
&lt;br /&gt;
See wiki for details on how to do this, or ignore it to get the default Warrior/Rogue/Wizard AL tables.&lt;br /&gt;
&lt;br /&gt;
NOTE: you MUST explicitly set a table for non-Warrior/Rogue/Wizards, eg dogs.  Use TABLE_AL_DOG for a default Mabari.&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
int GetCustomFollowerALTable(object oFollower) {&lt;br /&gt;
    int nTable = _GetTableToUseForAL(oFollower);&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               &lt;br /&gt;
        nTable = 50143;   &lt;br /&gt;
    }   &lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_jysavin&amp;quot;) {&lt;br /&gt;
        nTable = 50144;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_geldual&amp;quot;) {&lt;br /&gt;
        nTable = 50145;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_braghon&amp;quot;) {&lt;br /&gt;
        nTable = 50146;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return nTable;    &lt;br /&gt;
    &lt;br /&gt;
}   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// This just cleans up the main function a little&lt;br /&gt;
&lt;br /&gt;
int GetCustomFollowerTargetLevel(object oFollower, object oHero, int nPackage, int nMinLevel = 0) {&lt;br /&gt;
            int nPlayerLevel = GetLevel(oHero);&lt;br /&gt;
            int nTargetLevel = 0;&lt;br /&gt;
&lt;br /&gt;
            if((nPlayerLevel &amp;gt;= 13) || (nPlayerLevel == 1) || (!_UT_GetIsPlotFollower(oFollower))) {&lt;br /&gt;
               nTargetLevel = nPlayerLevel;&lt;br /&gt;
            } else {&lt;br /&gt;
               nTargetLevel = nPlayerLevel + 1;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            if (nMinLevel == 0) {  //If nMinLevel is not specified, checks package 2DA for a value&lt;br /&gt;
              nMinLevel = GetM2DAInt(TABLE_PACKAGES, &amp;quot;MinLevel&amp;quot;, nPackage);&lt;br /&gt;
             }&lt;br /&gt;
            if(nMinLevel &amp;gt; 0 &amp;amp;&amp;amp; nMinLevel &amp;gt; nTargetLevel) {&lt;br /&gt;
               nTargetLevel = nMinLevel;&lt;br /&gt;
            }          &lt;br /&gt;
            &lt;br /&gt;
            return nTargetLevel;&lt;br /&gt;
    &lt;br /&gt;
}   &lt;br /&gt;
&lt;br /&gt;
// Moving this black box out :)  I don't really understand it, but it should function if you have tactics set up in a package.&lt;br /&gt;
&lt;br /&gt;
void InitCustomFollowerTactics(object oFollower, int nPackage) {&lt;br /&gt;
         int nTableID = GetM2DAInt(TABLE_PACKAGES, &amp;quot;FollowerTacticsTable&amp;quot;, nPackage);&lt;br /&gt;
         if (nTableID != -1)&lt;br /&gt;
            {&lt;br /&gt;
             int nRows = GetM2DARows(nTableID);&lt;br /&gt;
             int nMaxTactics = GetNumTactics(oFollower);&lt;br /&gt;
&lt;br /&gt;
             int nTacticsEntry = 1;&lt;br /&gt;
             int i;&lt;br /&gt;
             for (i = 1; i &amp;lt;= nRows &amp;amp;&amp;amp; nTacticsEntry &amp;lt;= nMaxTactics; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                        int bAddEntry = FALSE;&lt;br /&gt;
                        int nTargetType = GetM2DAInt(nTableID, &amp;quot;TargetType&amp;quot;, i);&lt;br /&gt;
                        int nCondition = GetM2DAInt(nTableID, &amp;quot;Condition&amp;quot;, i);&lt;br /&gt;
                        int nCommandType = GetM2DAInt(nTableID, &amp;quot;Command&amp;quot;, i);&lt;br /&gt;
                        int nCommandParam = GetM2DAInt(nTableID, &amp;quot;SubCommand&amp;quot;, i);&lt;br /&gt;
&lt;br /&gt;
                        int nUseType = GetM2DAInt(TABLE_COMMAND_TYPES, &amp;quot;UseType&amp;quot;, nCommandType);&lt;br /&gt;
                        if (nUseType == 0)&lt;br /&gt;
                        {&lt;br /&gt;
                            bAddEntry = TRUE;&lt;br /&gt;
                        }&lt;br /&gt;
                        else&lt;br /&gt;
                        {&lt;br /&gt;
                            bAddEntry = HasAbility(oFollower, nCommandParam);&lt;br /&gt;
                        }&lt;br /&gt;
&lt;br /&gt;
                        if (bAddEntry)&lt;br /&gt;
                        {&lt;br /&gt;
                            SetTacticEntry(oFollower, nTacticsEntry, TRUE, nTargetType, nCondition, nCommandType, nCommandParam);&lt;br /&gt;
                            ++nTacticsEntry;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
}  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* InitCustomFollowerSpec:&lt;br /&gt;
&lt;br /&gt;
This function tries to set the forced Specialisation.  If there is none, it checks the package for one.  &lt;br /&gt;
&lt;br /&gt;
If there isn't either of those, it grants a free spec point if bFreeSpecPoint is true.&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void InitCustomFollowerSpec(object oFollower, int nPackage, int nForceSpec, int bFreeSpecPoint) {&lt;br /&gt;
    // Find specialization, and optionally add a spec point if none is found.&lt;br /&gt;
&lt;br /&gt;
        if (nForceSpec == 0) {&lt;br /&gt;
    &lt;br /&gt;
        int nSpecAbility = GetM2DAInt(TABLE_PACKAGES, &amp;quot;switch1_class&amp;quot;, nPackage); // followers can have only 1 advanced class&lt;br /&gt;
         if(nSpecAbility &amp;gt; 0)&lt;br /&gt;
         {&lt;br /&gt;
          AddAbility(oFollower, nSpecAbility);&lt;br /&gt;
         } else {&lt;br /&gt;
             if (bFreeSpecPoint) {&lt;br /&gt;
                 SetCreatureProperty(oFollower, 38, 1.00);&lt;br /&gt;
             }&lt;br /&gt;
         }                    &lt;br /&gt;
        &lt;br /&gt;
        } else {&lt;br /&gt;
         &lt;br /&gt;
             AddAbility(oFollower, nForceSpec);&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* hireCustomFollower()  (See doco at top of page)&lt;br /&gt;
&lt;br /&gt;
I strongly suggest you reorder the parameters if you're adding many followers with advanced options.&lt;br /&gt;
&lt;br /&gt;
Feel free to leave them alone if you only want to set class, plot, spec or don't mind long declarations.&lt;br /&gt;
&lt;br /&gt;
Note nForceClass is currently compulsory due to flakiness with GetCreatureCoreClass()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void hireCustomFollower(object oFollower, int nForceClass, string sPlot = &amp;quot;&amp;quot;, int nPlotFlag = 0, int nForceSpec = 0, int nALTable = 0, int bInvokePicker = FALSE, int nInitialState = FOLLOWER_STATE_AVAILABLE, string sCurrPlot = &amp;quot;&amp;quot;, int nCurrPlotFlag = 0, int nAutolevel = 0, int bFreeSpecPoint = TRUE, int nTargetLevel = 0, int nMinLevel = 0) {&lt;br /&gt;
&lt;br /&gt;
        object oHero = GetHero();&lt;br /&gt;
&lt;br /&gt;
        /* #################  BEGIN BASIC FOLLOWER JOIN BLOCK   ###################&lt;br /&gt;
&lt;br /&gt;
        This loosely replicates WR_SetFollowerState.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        */    &lt;br /&gt;
        &lt;br /&gt;
        if (nForceClass == 0) {&lt;br /&gt;
            nForceClass = GetCreatureCoreClass(oFollower);           //This is not working.  Hence nForceClass mandatory.&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
        SetGroupId(oFollower, GetGroupId(oHero));      //Puts the follower in the pc's Group.&lt;br /&gt;
        SetEventScript(oFollower, RESOURCE_SCRIPT_PLAYER_CORE);  //This makes them act like a player.&lt;br /&gt;
        SetFollowerState(oFollower, nInitialState);  //This sets whether they are available, in the active party etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /* #################  END BASIC FOLLOWER JOIN BLOCK ##################### */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /* #################  BEGIN PLAYER_CORE EVENT_TYPE_PARTY_MEMBER_HIRED EMULATION #################&lt;br /&gt;
&lt;br /&gt;
         This replicates the EVENT_TYPE_PARTY_MEMBER_HIRED handler from player_core, stripped down for simplicity and allowing our custom options.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        */&lt;br /&gt;
&lt;br /&gt;
        Chargen_EnableTacticsPresets(oFollower);    //I assume this is important.&lt;br /&gt;
        &lt;br /&gt;
        SetLocalInt(oFollower, FOLLOWER_SCALED, 1);  //This should prevent the follower being rescaled by player_core or what have you&lt;br /&gt;
        &lt;br /&gt;
        int nPackage = GetPackage(oFollower);  //Gets the package, which will be used to find a number of 2DA IDs.&lt;br /&gt;
        int nPackageClass = GetM2DAInt(TABLE_PACKAGES, &amp;quot;StartingClass&amp;quot;, nPackage);  //I don't think this is used, even by player_core&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        // set behavior according to package&lt;br /&gt;
        int nBehavior = GetM2DAInt(TABLE_PACKAGES, &amp;quot;FollowerBehavior&amp;quot;, nPackage);&lt;br /&gt;
&lt;br /&gt;
        if(nBehavior &amp;gt;= 0) {&lt;br /&gt;
            SetAIBehavior(oFollower, nBehavior);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        Chargen_InitializeCharacter(oFollower);      //We initialise the follower and choose race/class.&lt;br /&gt;
        &lt;br /&gt;
        Chargen_SelectRace(oFollower,GetCreatureRacialType(oFollower));&lt;br /&gt;
        Chargen_SelectCoreClass(oFollower,nForceClass);        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         if (nTargetLevel == 0) {   //This block picks a target level if not specified&lt;br /&gt;
            &lt;br /&gt;
              nTargetLevel = GetCustomFollowerTargetLevel(oFollower, oHero, nPackage, nMinLevel);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         int nXp = RW_GetXPNeededForLevel(Max(nTargetLevel, 1));      //Here is where the XP is calculated and rewarded&lt;br /&gt;
         RewardXP(oFollower, nXp, FALSE, FALSE);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         // add hidden approval talents - (JN: I don't know how to set these yet, but when I figure it out this should make it work)&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         int nIndex = Approval_GetFollowerIndex(oFollower);&lt;br /&gt;
         Approval_AddFollowerBonusAbility(nIndex, 0);&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
          //Handle Specialisation&lt;br /&gt;
          InitCustomFollowerSpec(oFollower, nPackage, nForceSpec, bFreeSpecPoint);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         // This spends all available attribute and stat points on the&lt;br /&gt;
         // creature according to the levelup table.  (JN:  this replicates AL_DoAutoLevelUp but with our choice of table)&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
         if (nALTable == 0) {&lt;br /&gt;
            nALTable = GetCustomFollowerALTable(oFollower);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         AL_SpendAttributePoints(oFollower, nALTable, FALSE);&lt;br /&gt;
         AL_SpendSkillPoints(oFollower, nALTable, TRUE);&lt;br /&gt;
         AL_SpendSpecializationPoints(oFollower, nALTable);&lt;br /&gt;
         AL_SpendTalentSpellPoints(oFollower, nALTable, TRUE);&lt;br /&gt;
&lt;br /&gt;
        // -------------------------------------------------------------------------&lt;br /&gt;
        // Update various UIs&lt;br /&gt;
        // -------------------------------------------------------------------------&lt;br /&gt;
        Chargen_SetNumTactics(oFollower);&lt;br /&gt;
        SetCanLevelUp(oFollower,Chargen_HasPointsToSpend(oFollower));&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        // load tactics&lt;br /&gt;
         InitCustomFollowerTactics(oFollower, nPackage);&lt;br /&gt;
&lt;br /&gt;
         /* #################  END PLAYER_CORE EVENT_TYPE_PARTY_MEMBER_HIRED EMULATION ################# */     &lt;br /&gt;
             &lt;br /&gt;
         &lt;br /&gt;
         SetAutoLevelUp(oFollower, nAutolevel);         //This is the autolevel flag on the character sheet.&lt;br /&gt;
         &lt;br /&gt;
         //Set plot flags&lt;br /&gt;
         &lt;br /&gt;
         if (!((sPlot == &amp;quot;&amp;quot;) || (nPlotFlag == 0))) {           //Joined Party&lt;br /&gt;
            WR_SetPlotFlag(sPlot, nPlotFlag, TRUE);   &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         if ((nInitialState == FOLLOWER_STATE_ACTIVE) || (nInitialState == FOLLOWER_STATE_LOCKEDACTIVE)) {&lt;br /&gt;
            if (!((sCurrPlot == &amp;quot;&amp;quot;) || (nCurrPlotFlag == 0))) {&lt;br /&gt;
                WR_SetPlotFlag(sCurrPlot, nCurrPlotFlag, TRUE);   //Currently in Party&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
            &lt;br /&gt;
        // Invoke picker if requested.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (bInvokePicker) {&lt;br /&gt;
             SetPartyPickerGUIStatus(2);&lt;br /&gt;
             ShowPartyPickerGUI();&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Yeah, I know.  It can't really be any smaller.  Feel free to modify it if you're confident with scripting.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Add Your Custom Autolevel Template to GetCustomFollowerALTable() ====&lt;br /&gt;
&lt;br /&gt;
While you can pass the ID you made for your autolevel template to that monster function as an argument, it's better to have them all in one place if you have multiple followers.&lt;br /&gt;
&lt;br /&gt;
GetCustomFollowerALTable() is the first function in our include, and you can add an explicit if test for your follower there to assign the correct table id (the one from your M2DA_base_ m2DA).  There is a function very much like it in sys_autolevel_h.nss for the core followers, so we'll copy Bioware's practice.&lt;br /&gt;
&lt;br /&gt;
Let's take a look at the function by itself:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int GetCustomFollowerALTable(object oFollower) {&lt;br /&gt;
    int nTable = _GetTableToUseForAL(oFollower);&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               &lt;br /&gt;
        nTable = 50143;   &lt;br /&gt;
    }   &lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_jysavin&amp;quot;) {&lt;br /&gt;
        nTable = 50144;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_geldual&amp;quot;) {&lt;br /&gt;
        nTable = 50145;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_braghon&amp;quot;) {&lt;br /&gt;
        nTable = 50146;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return nTable;    &lt;br /&gt;
    &lt;br /&gt;
}  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So we have a test for each follower tag from my module, matching up to an ID which is assigned to nTable.  All you need to do is change a tag from my follower to yours, and my ID to the correct one from your M2DA_base_* m2DA.  Then you should delete the rest of the example if statements :)&lt;br /&gt;
&lt;br /&gt;
Save and export the script.  Ignore the compiler error about lack of main();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Include Function In Your Hire Script and Call It ===&lt;br /&gt;
&lt;br /&gt;
So instead of a hire script that calls UT_HireFollower(), we want one that includes our shiny new function and calls it.&lt;br /&gt;
&lt;br /&gt;
Take a look at the following example:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;plt_bc_create_party&amp;quot;   //Make sure you include your party handling plot&lt;br /&gt;
#include &amp;quot;hireCustomFollower_h&amp;quot;  // And include the function script - which will in turn include a bunch of stuff&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
&lt;br /&gt;
                    //Initialising my objects, not super-relevant to the example &lt;br /&gt;
                     &lt;br /&gt;
                    object oHero = GetHero();&lt;br /&gt;
                    object oMiera = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_miera.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oJysavin = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_jysavin.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oBraghon = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_braghon.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oSpider = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_geldual.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    //Simplest hire call - adds to the party as a wizard.  Class is currently compulsory due to a bug.&lt;br /&gt;
&lt;br /&gt;
                    hireCustomFollower(oMiera, CLASS_WIZARD);&lt;br /&gt;
                   &lt;br /&gt;
&lt;br /&gt;
                    //Add to the party and set joining plot flags&lt;br /&gt;
                                      &lt;br /&gt;
                   &lt;br /&gt;
                    hireCustomFollower(oJysavin, CLASS_WARRIOR, PLT_BC_CREATE_PARTY, PARTY_JYSAVIN_JOINED);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    //Add to the party, set plot flags, force a specialisation&lt;br /&gt;
                    &lt;br /&gt;
                    hireCustomFollower(oBraghon, CLASS_ROGUE, PLT_BC_CREATE_PARTY, PARTY_BRAGHON_JOINED, ABILITY_TALENT_HIDDEN_ASSASSIN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    //More complex example - Follower added as a unique class (Dog), not granted a specialisation or spec point.  &lt;br /&gt;
                    //Note unique classes must have an ALTable passed here or specified in GetCustomFollowerALTable() or they won't work&lt;br /&gt;
                    &lt;br /&gt;
                    hireCustomFollower(oSpider, CLASS_DOG, PLT_BC_CREATE_PARTY, PARTY_GELDUAL_JOINED, 0, 0, FALSE, FOLLOWER_STATE_AVAILABLE, &amp;quot;&amp;quot;, 0, 0, FALSE);&lt;br /&gt;
                      &lt;br /&gt;
                   &lt;br /&gt;
                    //Show the party picker to let the player choose from their new companions!&lt;br /&gt;
&lt;br /&gt;
                    SetPartyPickerGUIStatus(2);&lt;br /&gt;
&lt;br /&gt;
                    ShowPartyPickerGUI();                                                                                                                      &lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The example shows several of the more simple ways of invoking the function.  Check the comments at the start of the function for a full list of arguments.&lt;br /&gt;
&lt;br /&gt;
I would suggest best practice for most followers would be to call as follows:&lt;br /&gt;
&lt;br /&gt;
'''hireCustomFollower(oFollower, CLASS, PLOT, PLOT_FLAG, SPECIALISATION)'''&lt;br /&gt;
&lt;br /&gt;
This will safely set the follower up as the desired class and specialisation (doubly important if there are spec abilities in their ALTable) while setting your plot flag for them being in the party.  hireCustomFollower(oFollower, CLASS, PLOT, PLOT_FLAG, SPECIALISATION, 0, TRUE) will do the same while invoking the Party Picker automatically.&lt;br /&gt;
&lt;br /&gt;
Note that the specialisations are abilities and not classes - you'll find them as ABILITY_HIDDEN_ constants.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If it's all worked, you should find you can now add followers with a lot more flexibility!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:picker_advanced.jpg|thumb|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Common Follower Problems &amp;amp; FAQ ==&lt;br /&gt;
&lt;br /&gt;
====Why don't my followers gain XP?====&lt;br /&gt;
There is a bug in UT_HireFollower. For now the best/easiest approach to take might be to make a copy of UT_HireFollower in an include file and rename it something like UT_HireFollower_Fixed, then make the following change:&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, TRUE);&lt;br /&gt;
to&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, bPreventLevelup);&lt;br /&gt;
(Note: Be aware if you use the name UT_HireFollower_Fixed you may end up finding your include file conflicting with someone else who has named it the same in their include.)&lt;br /&gt;
&lt;br /&gt;
Alternately you need to clear a flag in a separate script to the one in which they're hired.&lt;br /&gt;
&lt;br /&gt;
You must use the '''SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);''' statement in a script you can be sure will run soon after your hiring script.&lt;br /&gt;
&lt;br /&gt;
====When I choose followers from the Party Picker, they spawn into the area but do not join.====&lt;br /&gt;
&lt;br /&gt;
You need to intercept the EVENT_TYPE_PARTYMEMBER_ADDED event and set the follower to FOLLOWER_STATE_ACTIVE.  See Simple Follower Creation earlier in this document.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====My followers don't have skill trees!====&lt;br /&gt;
&lt;br /&gt;
If a follower hasn't been through an initial chargen/autolevel event (via player_core/sys_autolevel_h) then the skill tree doesn't show.  You're probably trying to be clever and get around UT_HireFollower without going all the way (see monster function above ^_^).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====My followers don't have a class====&lt;br /&gt;
&lt;br /&gt;
GetCreatureCoreClass() seems flaky under some conditions.  It's best to explicitly set the class yourself; this is why class is currently a mandatory argument to hireCustomFollower()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Isn't there an easier way to do this?====&lt;br /&gt;
&lt;br /&gt;
Possibly.  There is a way of recruiting a follower by setting a plot flag.  However I don't understand it, and I expect it still doesn't allow custom autolevel templates, full control over specialisations etc.  There's still a fair bit of stuff hardcoded for the core followers, I'm not sure putting a custom follower through the same process as Al, Leli et al will have good results.&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9354</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9354"/>
				<updated>2010-01-06T17:19:15Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: /* Why don't my followers gain XP? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Simple Follower Creation ==&lt;br /&gt;
&lt;br /&gt;
Follow these steps to create a follower that&lt;br /&gt;
&lt;br /&gt;
- Levels up with a default package&lt;br /&gt;
&lt;br /&gt;
- Can be chosen from the party picker&lt;br /&gt;
&lt;br /&gt;
- Can gain XP&lt;br /&gt;
&lt;br /&gt;
This guide assumes you know how to create a creature and are comfortable with basic scripting.&lt;br /&gt;
&lt;br /&gt;
You should only use this simple method if you are sure there will be empty space in the active party when your follower is recruited.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create the creature ===&lt;br /&gt;
&lt;br /&gt;
Create a creature to act as your follower.  Set its name, appearance, gender, head morph, conversation, inventory etc as you want them to behave in-game.&lt;br /&gt;
&lt;br /&gt;
Set an appropriate '''Tag''' (you'll be using it a lot).  I suggest &amp;quot;party_charname&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Make sure you choose a '''Class'''.  For most followers this should be Rogue, Warrior or Wizard.&lt;br /&gt;
&lt;br /&gt;
[[File:class.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under Package/Scaling set:&lt;br /&gt;
&lt;br /&gt;
'''General Package Type''' to be '''Party Members'''&lt;br /&gt;
&lt;br /&gt;
'''Package''' to be an appropriate value (probably &amp;quot;Generic - Wizard&amp;quot; or similar)&lt;br /&gt;
&lt;br /&gt;
'''Package AI''' (there should only be one choice)&lt;br /&gt;
&lt;br /&gt;
'''Rank''' to be '''Player'''&lt;br /&gt;
&lt;br /&gt;
[[File:package.jpg]]&lt;br /&gt;
&lt;br /&gt;
Save and export your character as normal.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Override char_stage ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In your resource palette, open char_stage under the Global folder:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:area_palette.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create a new waypoint for your follower to appear on the party picker.  This waypoint '''must''' have a tag in the form of &amp;quot;char_&amp;quot; followed by the exact tag of your follower.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:char_stage.jpg]]&lt;br /&gt;
&lt;br /&gt;
In this example the tag of my follower is '''bc_party_miera''' so her waypoint tag must be '''char_bc_party_miera'''&lt;br /&gt;
&lt;br /&gt;
For a standalone module (such as in this example), put your waypoint wherever you please.  The illustrated one is directly on top of Morrigan's.  For an add-in to the main campaign, you should position your wp appropriately relative to the core party members.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Save and export the area.&lt;br /&gt;
&lt;br /&gt;
Move the '''char_stage.are''' and '''char_stage.lst''' files from your core export folder to your module's export folder (probably from \Documents\Bioware\Dragon Age\packages\core\override\toolsetexport to \Documents\Bioware\Dragon Age\AddIns\yourModule\module\override\toolsetoverride).  This ensures that the modification to the character stage only takes effect if your module is installed and enabled, which will help manage compatibility problems.  Make sure those files are included when you package your module for distribution.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create m2DAs for the Party Picker ===&lt;br /&gt;
&lt;br /&gt;
You will need to create two Excel spreadsheets.&lt;br /&gt;
&lt;br /&gt;
The first should be named (both worksheet and file) '''partypicker_''' with a unique suffix.  In this example, my first spreadsheet is named partypicker_fofbc.xls with a worksheet name of partypicker_fofbc - the suffix being the acronym of my module.&lt;br /&gt;
&lt;br /&gt;
Set up your columns as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:partypickerm2da.jpg]]&lt;br /&gt;
&lt;br /&gt;
The '''ID''' for your follower must be '''12 or higher'''.  11 is the highest value used in the base 2DA.  12 is fine for standalone modules, add-ins will probably want to use an arbitrarily high number to avoid potential conflicts.&lt;br /&gt;
&lt;br /&gt;
The '''Label''' should be the follower's name as you wish it to appear on the party picker.&lt;br /&gt;
&lt;br /&gt;
The '''Tag''' must be your follower's tag.&lt;br /&gt;
&lt;br /&gt;
All other values are non-functioning defaults and should be specified as in the image above unless you know explicitly what you're doing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second spreadsheet should be named '''party_picker_''' (note middle underscore).  Once again append your unique suffix (in this example party_picker_fofbc.xls with party_picker_fofbc as its worksheet).&lt;br /&gt;
&lt;br /&gt;
Set up your columns and data like so:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:party_pickerm2da.jpg]]&lt;br /&gt;
&lt;br /&gt;
'''ID''' and '''Tag''' should match what you did in the first spreadsheet.  Specify INVALID COLUMN for the third column.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you're familiar with m2DAs, generate them from these files, copy them to your module's override directory, and skip to the next step.  Otherwise, read on:&lt;br /&gt;
&lt;br /&gt;
- Go to '''\Program Files\Dragon Age\tools\ResourceBuild\Processors''' (or wherever you installed Dragon Age)&lt;br /&gt;
&lt;br /&gt;
- Copy '''ExcelProcessor.exe''' from that folder to whichever folder has the excel sheets you just created.&lt;br /&gt;
&lt;br /&gt;
- Drag and drop your xls files onto ExcelProcessor.  This will create .gda files.&lt;br /&gt;
&lt;br /&gt;
- Copy these .gda files to your module's export directory (probably \Documents\Bioware\Dragon Age\AddIns\yourModule\module\override\toolsetoverride).  Make sure they are included in your .dazip when the time comes to build your module.&lt;br /&gt;
&lt;br /&gt;
If you are an OpenOffice user and have trouble with ExcelProcessor, you can use [http://social.bioware.com/project/755/ GDApp] to directly create the 2DAs.  It rocks!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Capture the EVENT_TYPE_PARTYMEMBER_ADDED Event ===&lt;br /&gt;
&lt;br /&gt;
Amusingly enough, the Party Picker does not actually add followers to the party.  However it raises an event that allows you to do so.  Your module script needs to capture this event and execute some code.&lt;br /&gt;
&lt;br /&gt;
The following example shows what to do with the event.  The full script would work as a module script for an add-in (assuming it didn't need to do anything else), but otherwise you'll have to incorporate the event into your own script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    switch(nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_ADDED:&lt;br /&gt;
        {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);  //Allows the follower to gain XP&lt;br /&gt;
            SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);  //Adds follower to the active party&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE)''' is the key statement to add the follower to the active party.  You must have this.&lt;br /&gt;
&lt;br /&gt;
'''SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0)''' is a bug-fix, as followers hired with UT_HireFollower() do not receive XP by default.  This statement fixes that, and I consider it best practice to keep it in this event to ensure it is always set.  You will not wish to do this if you want a follower that should not gain XP to be on the party picker.&lt;br /&gt;
&lt;br /&gt;
Note that you do not need to intercept the corresponding event for a party member being removed - the party picker handles spawning/despawning, and thus will successfully remove members.&lt;br /&gt;
&lt;br /&gt;
Remember to save and export your module script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create Your Hiring Script ===&lt;br /&gt;
&lt;br /&gt;
Now all that remains is to actually hire the follower :)&lt;br /&gt;
&lt;br /&gt;
Create a script to handle the hiring (which will most likely be fired from a conversation).  The script is quite simple:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
&lt;br /&gt;
        object oFollower = GetObjectByTag(&amp;quot;bc_party_miera&amp;quot;); //Use CreateObject() if the creature isn't present in the module yet&lt;br /&gt;
&lt;br /&gt;
        UT_HireFollower(oFollower);   //Hires the follower&lt;br /&gt;
&lt;br /&gt;
        SetPartyPickerGUIStatus(2);&lt;br /&gt;
&lt;br /&gt;
        ShowPartyPickerGUI();  //Shows the Party Picker; necessary for the follower to gain XP&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make sure you use your own follower's tag and not the example one :)&lt;br /&gt;
&lt;br /&gt;
This script fires the party picker after hiring the follower.  That is absolutely necessary via this method, as we have put the XP fix onto an event fired by the party picker.  You cannot put the XP fix into this script, it must be called from a later one (the bug is caused by an errant call to an event in player_core, which will be executed AFTER this script).&lt;br /&gt;
&lt;br /&gt;
If everything worked, you should see something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:picker_success.jpg|thumb|200px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Advanced Follower Creation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow these steps to have full control over the creation of your follower, with options such as:&lt;br /&gt;
&lt;br /&gt;
- Unique level-up template&lt;br /&gt;
&lt;br /&gt;
- Class and specialisation chosen via script&lt;br /&gt;
&lt;br /&gt;
- Any starting state&lt;br /&gt;
&lt;br /&gt;
- Level higher than the PC&lt;br /&gt;
&lt;br /&gt;
- Starts with a specialisation point rather than a specific specialisation&lt;br /&gt;
&lt;br /&gt;
- Set plot flags in the call to the hire script&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Prepare Creature, char_stage and Party Picker m2DAs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the same steps to create your create your follower creature, override char_stage and create your Party Picker m2DAs as above.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create Party Plot ===&lt;br /&gt;
&lt;br /&gt;
While not necessary, it's very helpful to have plot flags set when a follower is hired or joins/leaves the active party.  This makes conversation interjections and the like very easy.&lt;br /&gt;
&lt;br /&gt;
Create a plot with appropriate flags.  There's no real need to associate journal text with them:&lt;br /&gt;
&lt;br /&gt;
[[File:follower_plot.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Add Plot Flags to Party Picker Event Intercept ===&lt;br /&gt;
&lt;br /&gt;
We then update our module script to make use of that plot, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
#include &amp;quot;plt_bc_create_party&amp;quot;   //make sure you include your own plot, not mine&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    switch(nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_ADDED:&lt;br /&gt;
        {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);&lt;br /&gt;
            SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);&lt;br /&gt;
            &lt;br /&gt;
            if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               //You must explicitly test for your follower's tag.&lt;br /&gt;
                WR_SetPlotFlag(PLT_BC_CREATE_PARTY, PARTY_MIERA_IN_PARTY, TRUE);     //Make sure you use your own flags!&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            break;&lt;br /&gt;
        }  &lt;br /&gt;
        &lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_DROPPED:                    &lt;br /&gt;
        {&lt;br /&gt;
              object oFollower = GetEventObject(ev, 0); &lt;br /&gt;
              &lt;br /&gt;
              if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) { &lt;br /&gt;
                WR_SetPlotFlag(PLT_BC_CREATE_PARTY, PARTY_MIERA_IN_PARTY, FALSE);     //As above, but set false.&lt;br /&gt;
              }&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a Level Up Template ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can skip this step if you're content to use one of the generic Rogue, Wizard or Warrior templates, but I don't recommend it.  Making a template that suits your character is easy and will almost always be better for the player than a generic one that spends points poorly.&lt;br /&gt;
&lt;br /&gt;
Go to \Program Files\Dragon Age\tools\Source\2DA (or wherever you installed Dragon Age).&lt;br /&gt;
&lt;br /&gt;
You should see a number of excel sheets of the form '''ALCharacter.xls''' (such as ALAlistair.xls, ALLeliana.xls, ALRogue_Default.xls etc).  Open the one closest to your character (ie Morrigan or Wynne for a wizard, Leliana or Zevran for a rogue).  Save a copy as '''ALYourcharacter.xls''' in whatever directory you're using to create your 2DAs, remembering to rename the worksheet '''ALYourcharacter''' (in this example, ALMiera.xls with ALMiera as its worksheet).&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
[[File:ALtable.jpg|thumb|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Columns B''' and '''C''' are the talents/spells available to this character.  Do not change them.&lt;br /&gt;
&lt;br /&gt;
'''Columns F''' and '''G''' are the skills available to this character.  Do not change them.&lt;br /&gt;
&lt;br /&gt;
We will edit the remaining columns like so:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting Stat Weights ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The stat weights in '''column J''' determine how the follower will spend their attribute points, in a rough ratio.  So if Dexterity is set to 1.5 and Intelligence to 1, you should expect to see 3 points of Dex for every 2 points of Cunning in-game (note Intelligence is the label used in the toolset for Cunning).&lt;br /&gt;
&lt;br /&gt;
Simply change the values in J to reflect how you'd like the character to spend their points.  In this example we're creating a wizard, so we're not going to mess around:&lt;br /&gt;
&lt;br /&gt;
[[File:miera_stat_weights.jpg]]&lt;br /&gt;
&lt;br /&gt;
This character will only raise magic.  I set the value to 5 rather than something like 1 to provide room underneath for the other stats while still overwhelmingly favouring magic, but in practice I only really ever want that one stat.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting Talent and Skill Priorities ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Columns D''' and '''E''' are the talents/spells that the character will buy, in preference order from top to bottom.&lt;br /&gt;
&lt;br /&gt;
'''Columns H''' and '''I''' are the skills available to this character, in preference order from top to bottom.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To change these, just copy the appropriate two cells from columns B&amp;amp;C or F&amp;amp;G over the ones you want to replace.&lt;br /&gt;
&lt;br /&gt;
For example, here we're copying Morrigan's template.  Morrigan has Spider Shape high in her preferences, which we do not want.&lt;br /&gt;
&lt;br /&gt;
[[File:AlMori_talent_pref.jpg]]&lt;br /&gt;
&lt;br /&gt;
We decide we'd prefer Flame Blast, so we find it in columns B&amp;amp;C and copy both cells:&lt;br /&gt;
&lt;br /&gt;
[[File:ALMori_copy.jpg]]&lt;br /&gt;
&lt;br /&gt;
Then we select the cells we want to replace in columns D&amp;amp;E and paste over them:&lt;br /&gt;
&lt;br /&gt;
[[File:ALMori_paste.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Continue this process until your priorities list for both skills and talents/spells is exactly as you want it.  Make sure you have at least as many priorities as the core follower you're copying - points that cannot be spent according to these priorities have a habit of vanishing.&lt;br /&gt;
&lt;br /&gt;
If you used any abilities from a specialisation, make sure you remember to set that specialisation with the function we'll introduce later.  The autolevel scripts will add specialisation abilities to a character regardless of whether they have that spec or not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Create a M2DA_base_ m2DA ====&lt;br /&gt;
&lt;br /&gt;
Dragon Age will need to know where to find your autolevel template.  We tell it by extending M2DA_base.gda&lt;br /&gt;
&lt;br /&gt;
Create a spreadsheet with the name and worksheet name in the form '''M2DA_base_''' with your unique suffix (in this example, M2DA_base_fofbc.xls with M2DA_base_fofbc as a worksheet).&lt;br /&gt;
&lt;br /&gt;
Set up its columns and data like so (note I used GDApp because Open Office wasn't cooperating for this one!):&lt;br /&gt;
&lt;br /&gt;
[[File:m2da_base_fofbc.jpg]]&lt;br /&gt;
&lt;br /&gt;
The '''ID''' should be very high to avoid conflicts.  I've arbitrarily chosen 50,000+ here.  Carefully note the ID you've chosen for your character, you will need it later.&lt;br /&gt;
&lt;br /&gt;
Set the '''Label''' and '''Worksheet''' to be the name of your autolevel template worksheet (ALCharactername if you've been following this).&lt;br /&gt;
&lt;br /&gt;
Set the '''PackageIDForAI''' to be 0, it shouldn't be needed for followers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you're done, use ExcelProcessor to make GDAs of both spreadsheets and copy them to your module's export folder.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create a New Hire Function Include ===&lt;br /&gt;
&lt;br /&gt;
Many vital steps of follower addition happen inside an event in player_core.  Followers tend to be extremely buggy (no skill tree, for example) if this event does not fire.&lt;br /&gt;
&lt;br /&gt;
However, that event is not very flexible.  In order to control it to our requirements, we need to replicate its functionality inside our own script.  This is probably much safer than messing with player_core directly!&lt;br /&gt;
&lt;br /&gt;
Create a new script file, naming it something like '''hireCustomFollower_h'''.  We will be including this wherever we want to hire a follower.&lt;br /&gt;
&lt;br /&gt;
Paste in the following script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;sys_chargen_h&amp;quot;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;sys_rewards_h&amp;quot;&lt;br /&gt;
#include &amp;quot;approval_h&amp;quot;&lt;br /&gt;
#include &amp;quot;sys_autolevelup_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*  Jye Nicolson 5-Jan-2010&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This function set duplicates the full functionality chain of UT_HireFollower, with the following exceptions:&lt;br /&gt;
&lt;br /&gt;
-  Followers can gain XP&lt;br /&gt;
-  Autolevel status can be set (default off)&lt;br /&gt;
-  Followers can be set to any starting state (default Available) and will still be properly initalised and added to the party pool&lt;br /&gt;
-  Autolevel tables for non-core followers can be explicitly set.&lt;br /&gt;
-  Class and Specialisation can be chosen via script&lt;br /&gt;
-  Followers without specialisations are granted a spec point by default.&lt;br /&gt;
&lt;br /&gt;
It should only ever be called once each for characters you intend to be full followers.&lt;br /&gt;
Much of the protective code handling summoned creatures etc. in player_core is not present here.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Calling the function:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
&lt;br /&gt;
hireCustomFollower(oFollower, CLASS_WARRIOR);&lt;br /&gt;
&lt;br /&gt;
Change the class to CLASS_WIZARD or CLASS_ROGUE as appropriate.  &lt;br /&gt;
This will hire your follower and make them available.  &lt;br /&gt;
They will auto level up with a default package, and receive a free spec point.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Best Practice:&lt;br /&gt;
&lt;br /&gt;
hireCustomFollower(oFollower, CLASS_WARRIOR, PLT_YOUR_PARTY_PLOT, YOUR_FOLLOWER_JOINED_FLAG, ABILITY_TALENT_HIDDEN_CHAMPION);&lt;br /&gt;
&lt;br /&gt;
Where the plot and flag are those for your module (remember to create the plot and include it on the calling script), and ABILITY_TALENT_HIDDEN etc is the desired spec.&lt;br /&gt;
&lt;br /&gt;
You should also have a custom ALTable set up.  &lt;br /&gt;
See wiki for details, and remember to edit it in to GetCustomFollowerALTable below or pass it directly as an argument to hireCustomFollower.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Full argument list:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void hireCustomFollower (&lt;br /&gt;
        object oFollower,   //Pass your follower object, mandatory&lt;br /&gt;
        &lt;br /&gt;
        int nForceClass,    //Pass a Class constant here, usually CLASS_ROGUE, CLASS_WARRIOR, CLASS_WIZARD.  Mandatory due to a bug.&lt;br /&gt;
        &lt;br /&gt;
        string sPlot = &amp;quot;&amp;quot;,   //It's recommended you have a plot flag to be set when the follower joins.  Pass the plot constant here.  Remember to #include in calling script&lt;br /&gt;
        &lt;br /&gt;
        int nPlotFlag = &amp;quot;&amp;quot;,  //And then pass the flag constant.  Will be set to TRUE if available.&lt;br /&gt;
        &lt;br /&gt;
        int nForceSpec = 0,  //This is the ID of the Specialisation you want.  Note they are NOT classes, but abilities.  The full list is:&lt;br /&gt;
                             //ABILITY_SPELL_HIDDEN_ARCANE_WARRIOR, ABILITY_SPELL_HIDDEN_BLOODMAGE, ABILITY_SPELL_HIDDEN_SHAPESHIFTER, ABILITY_SPELL_HIDDEN_SPIRIT_HEALER&lt;br /&gt;
                             //ABILITY_SPELL_HIDDEN_BARD, ABILITY_TALENT_HIDDEN_ASSASSIN, ABILITY_TALENT_HIDDEN_DUELIST, ABILITY_TALENT_HIDDEN_RANGER&lt;br /&gt;
                             //ABILITY_TALENT_HIDDEN_BERSERKER, ABILITY_TALENT_HIDDEN_CHAMPION, ABILITY_TALENT_HIDDEN_REAVER, ABILITY_TALENT_HIDDEN_TEMPLAR&lt;br /&gt;
                             //I recommended forcing a spec, particularly if your ALTable includes abilities from one.&lt;br /&gt;
        &lt;br /&gt;
        int nALTable = 0,    //This is the ID of an ALTable from 2DA_base.GDA or your module's m2DA_base_*.GDA  I recommended the latter, but you can edit that into GetCustomFollowerALTable below rather than passing it.&lt;br /&gt;
        &lt;br /&gt;
        int bInvokePicker = FALSE,  //Sets whether the party picker should be opened on hiring.  I think it's cleaner to call the picker outside this script, particularly if you have multiple hires at once.&lt;br /&gt;
        &lt;br /&gt;
        int nInitialState = FOLLOWER_STATE_AVAILABLE,  //This sets whether the follower joins the active party or not.  Options are:&lt;br /&gt;
                                                       //FOLLOWER_STATE_ACTIVE (put them in the active party)&lt;br /&gt;
                                                       //FOLLOWER_STATE_LOCKEDACTIVE (force them into the active party and keep them there, remember to change this later.&lt;br /&gt;
                                                       //FOLLOWER_STATE_AVAILABLE (make them available on the party picker (if you've set it up for them), but not in the active party)&lt;br /&gt;
                                                       //Plus some others you're unlikely to need at this time.  Defaults to AVAILABLE because having 4+ active followers is screwy.&lt;br /&gt;
                                                       &lt;br /&gt;
        string sCurrPlot = &amp;quot;&amp;quot;,  //If you set FOLLOWER_STATE_ACTIVE or FOLLOWER_STATE_LOCKEDACTIVE, the script will check to see if you passed this.&lt;br /&gt;
                                //It is recommended that you have a plot flag set for a given follower being in the active party, this makes conversation interjection etc. much easier.&lt;br /&gt;
&lt;br /&gt;
        int nCurrPlotFlag = 0,  //This flag will be set if FOLLOWER_STATE_ACTIVE or FOLLOWER_STATE_LOCKEDACTIVE are true&lt;br /&gt;
                                //AND sCurrPlot has a value AND nCurrPlotFlag is &amp;gt; 0.  &lt;br /&gt;
                                //ie if you added someone to the active party and have a plot flag to cope with it.&lt;br /&gt;
&lt;br /&gt;
        int nAutolevel = 0,     //Sets the Autolevel flag on the character sheet.  0 is off, 1 is on, 2 forces it on and removes it so the player can't turn it off.&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        bFreeSpecPoint = TRUE,  //This grants a specialisation point to the follower if they do not have a specialisation.  &lt;br /&gt;
                                //It's important to set this false for classes that do not have specs, such as CLASS_DOG.&lt;br /&gt;
                                &lt;br /&gt;
        int nTargetLevel = 0,   //If you want a specific level, set this.  Generally not worthwhile unless you set it higher than the player, since they'll just get XP from the party picker anyway.&lt;br /&gt;
        &lt;br /&gt;
        int nMinLevel = 0       //Set this if there's a specific level you don't want the follower to go below.  Probably only useful if the PC might be very low level but not necessarily so. &lt;br /&gt;
        &lt;br /&gt;
        )&lt;br /&gt;
                        &lt;br /&gt;
&lt;br /&gt;
*/       &lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
/* GetCustomFollowerALTable()  &lt;br /&gt;
&lt;br /&gt;
This function is where you put your custom table assignments.&lt;br /&gt;
&lt;br /&gt;
You should explicitly test for the tag of your follower (not mine!) and assign a value to nTable from your m2DA extension to M2DA_base &lt;br /&gt;
&lt;br /&gt;
See wiki for details on how to do this, or ignore it to get the default Warrior/Rogue/Wizard AL tables.&lt;br /&gt;
&lt;br /&gt;
NOTE: you MUST explicitly set a table for non-Warrior/Rogue/Wizards, eg dogs.  Use TABLE_AL_DOG for a default Mabari.&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
int GetCustomFollowerALTable(object oFollower) {&lt;br /&gt;
    int nTable = _GetTableToUseForAL(oFollower);&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               &lt;br /&gt;
        nTable = 50143;   &lt;br /&gt;
    }   &lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_jysavin&amp;quot;) {&lt;br /&gt;
        nTable = 50144;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_geldual&amp;quot;) {&lt;br /&gt;
        nTable = 50145;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_braghon&amp;quot;) {&lt;br /&gt;
        nTable = 50146;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return nTable;    &lt;br /&gt;
    &lt;br /&gt;
}   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// This just cleans up the main function a little&lt;br /&gt;
&lt;br /&gt;
int GetCustomFollowerTargetLevel(object oFollower, object oHero, int nPackage, int nMinLevel = 0) {&lt;br /&gt;
            int nPlayerLevel = GetLevel(oHero);&lt;br /&gt;
            int nTargetLevel = 0;&lt;br /&gt;
&lt;br /&gt;
            if((nPlayerLevel &amp;gt;= 13) || (nPlayerLevel == 1) || (!_UT_GetIsPlotFollower(oFollower))) {&lt;br /&gt;
               nTargetLevel = nPlayerLevel;&lt;br /&gt;
            } else {&lt;br /&gt;
               nTargetLevel = nPlayerLevel + 1;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            if (nMinLevel == 0) {  //If nMinLevel is not specified, checks package 2DA for a value&lt;br /&gt;
              nMinLevel = GetM2DAInt(TABLE_PACKAGES, &amp;quot;MinLevel&amp;quot;, nPackage);&lt;br /&gt;
             }&lt;br /&gt;
            if(nMinLevel &amp;gt; 0 &amp;amp;&amp;amp; nMinLevel &amp;gt; nTargetLevel) {&lt;br /&gt;
               nTargetLevel = nMinLevel;&lt;br /&gt;
            }          &lt;br /&gt;
            &lt;br /&gt;
            return nTargetLevel;&lt;br /&gt;
    &lt;br /&gt;
}   &lt;br /&gt;
&lt;br /&gt;
// Moving this black box out :)  I don't really understand it, but it should function if you have tactics set up in a package.&lt;br /&gt;
&lt;br /&gt;
void InitCustomFollowerTactics(object oFollower, int nPackage) {&lt;br /&gt;
         int nTableID = GetM2DAInt(TABLE_PACKAGES, &amp;quot;FollowerTacticsTable&amp;quot;, nPackage);&lt;br /&gt;
         if (nTableID != -1)&lt;br /&gt;
            {&lt;br /&gt;
             int nRows = GetM2DARows(nTableID);&lt;br /&gt;
             int nMaxTactics = GetNumTactics(oFollower);&lt;br /&gt;
&lt;br /&gt;
             int nTacticsEntry = 1;&lt;br /&gt;
             int i;&lt;br /&gt;
             for (i = 1; i &amp;lt;= nRows &amp;amp;&amp;amp; nTacticsEntry &amp;lt;= nMaxTactics; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                        int bAddEntry = FALSE;&lt;br /&gt;
                        int nTargetType = GetM2DAInt(nTableID, &amp;quot;TargetType&amp;quot;, i);&lt;br /&gt;
                        int nCondition = GetM2DAInt(nTableID, &amp;quot;Condition&amp;quot;, i);&lt;br /&gt;
                        int nCommandType = GetM2DAInt(nTableID, &amp;quot;Command&amp;quot;, i);&lt;br /&gt;
                        int nCommandParam = GetM2DAInt(nTableID, &amp;quot;SubCommand&amp;quot;, i);&lt;br /&gt;
&lt;br /&gt;
                        int nUseType = GetM2DAInt(TABLE_COMMAND_TYPES, &amp;quot;UseType&amp;quot;, nCommandType);&lt;br /&gt;
                        if (nUseType == 0)&lt;br /&gt;
                        {&lt;br /&gt;
                            bAddEntry = TRUE;&lt;br /&gt;
                        }&lt;br /&gt;
                        else&lt;br /&gt;
                        {&lt;br /&gt;
                            bAddEntry = HasAbility(oFollower, nCommandParam);&lt;br /&gt;
                        }&lt;br /&gt;
&lt;br /&gt;
                        if (bAddEntry)&lt;br /&gt;
                        {&lt;br /&gt;
                            SetTacticEntry(oFollower, nTacticsEntry, TRUE, nTargetType, nCondition, nCommandType, nCommandParam);&lt;br /&gt;
                            ++nTacticsEntry;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
}  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* InitCustomFollowerSpec:&lt;br /&gt;
&lt;br /&gt;
This function tries to set the forced Specialisation.  If there is none, it checks the package for one.  &lt;br /&gt;
&lt;br /&gt;
If there isn't either of those, it grants a free spec point if bFreeSpecPoint is true.&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void InitCustomFollowerSpec(object oFollower, int nPackage, int nForceSpec, int bFreeSpecPoint) {&lt;br /&gt;
    // Find specialization, and optionally add a spec point if none is found.&lt;br /&gt;
&lt;br /&gt;
        if (nForceSpec == 0) {&lt;br /&gt;
    &lt;br /&gt;
        int nSpecAbility = GetM2DAInt(TABLE_PACKAGES, &amp;quot;switch1_class&amp;quot;, nPackage); // followers can have only 1 advanced class&lt;br /&gt;
         if(nSpecAbility &amp;gt; 0)&lt;br /&gt;
         {&lt;br /&gt;
          AddAbility(oFollower, nSpecAbility);&lt;br /&gt;
         } else {&lt;br /&gt;
             if (bFreeSpecPoint) {&lt;br /&gt;
                 SetCreatureProperty(oFollower, 38, 1.00);&lt;br /&gt;
             }&lt;br /&gt;
         }                    &lt;br /&gt;
        &lt;br /&gt;
        } else {&lt;br /&gt;
         &lt;br /&gt;
             AddAbility(oFollower, nForceSpec);&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* hireCustomFollower()  (See doco at top of page)&lt;br /&gt;
&lt;br /&gt;
I strongly suggest you reorder the parameters if you're adding many followers with advanced options.&lt;br /&gt;
&lt;br /&gt;
Feel free to leave them alone if you only want to set class, plot, spec or don't mind long declarations.&lt;br /&gt;
&lt;br /&gt;
Note nForceClass is currently compulsory due to flakiness with GetCreatureCoreClass()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void hireCustomFollower(object oFollower, int nForceClass, string sPlot = &amp;quot;&amp;quot;, int nPlotFlag = 0, int nForceSpec = 0, int nALTable = 0, int bInvokePicker = FALSE, int nInitialState = FOLLOWER_STATE_AVAILABLE, string sCurrPlot = &amp;quot;&amp;quot;, int nCurrPlotFlag = 0, int nAutolevel = 0, int bFreeSpecPoint = TRUE, int nTargetLevel = 0, int nMinLevel = 0) {&lt;br /&gt;
&lt;br /&gt;
        object oHero = GetHero();&lt;br /&gt;
&lt;br /&gt;
        /* #################  BEGIN BASIC FOLLOWER JOIN BLOCK   ###################&lt;br /&gt;
&lt;br /&gt;
        This loosely replicates WR_SetFollowerState.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        */    &lt;br /&gt;
        &lt;br /&gt;
        if (nForceClass == 0) {&lt;br /&gt;
            nForceClass = GetCreatureCoreClass(oFollower);           //This is not working.  Hence nForceClass mandatory.&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
        SetGroupId(oFollower, GetGroupId(oHero));      //Puts the follower in the pc's Group.&lt;br /&gt;
        SetEventScript(oFollower, RESOURCE_SCRIPT_PLAYER_CORE);  //This makes them act like a player.&lt;br /&gt;
        SetFollowerState(oFollower, nInitialState);  //This sets whether they are available, in the active party etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /* #################  END BASIC FOLLOWER JOIN BLOCK ##################### */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /* #################  BEGIN PLAYER_CORE EVENT_TYPE_PARTY_MEMBER_HIRED EMULATION #################&lt;br /&gt;
&lt;br /&gt;
         This replicates the EVENT_TYPE_PARTY_MEMBER_HIRED handler from player_core, stripped down for simplicity and allowing our custom options.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        */&lt;br /&gt;
&lt;br /&gt;
        Chargen_EnableTacticsPresets(oFollower);    //I assume this is important.&lt;br /&gt;
        &lt;br /&gt;
        SetLocalInt(oFollower, FOLLOWER_SCALED, 1);  //This should prevent the follower being rescaled by player_core or what have you&lt;br /&gt;
        &lt;br /&gt;
        int nPackage = GetPackage(oFollower);  //Gets the package, which will be used to find a number of 2DA IDs.&lt;br /&gt;
        int nPackageClass = GetM2DAInt(TABLE_PACKAGES, &amp;quot;StartingClass&amp;quot;, nPackage);  //I don't think this is used, even by player_core&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        // set behavior according to package&lt;br /&gt;
        int nBehavior = GetM2DAInt(TABLE_PACKAGES, &amp;quot;FollowerBehavior&amp;quot;, nPackage);&lt;br /&gt;
&lt;br /&gt;
        if(nBehavior &amp;gt;= 0) {&lt;br /&gt;
            SetAIBehavior(oFollower, nBehavior);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        Chargen_InitializeCharacter(oFollower);      //We initialise the follower and choose race/class.&lt;br /&gt;
        &lt;br /&gt;
        Chargen_SelectRace(oFollower,GetCreatureRacialType(oFollower));&lt;br /&gt;
        Chargen_SelectCoreClass(oFollower,nForceClass);        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         if (nTargetLevel == 0) {   //This block picks a target level if not specified&lt;br /&gt;
            &lt;br /&gt;
              nTargetLevel = GetCustomFollowerTargetLevel(oFollower, oHero, nPackage, nMinLevel);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         int nXp = RW_GetXPNeededForLevel(Max(nTargetLevel, 1));      //Here is where the XP is calculated and rewarded&lt;br /&gt;
         RewardXP(oFollower, nXp, FALSE, FALSE);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         // add hidden approval talents - (JN: I don't know how to set these yet, but when I figure it out this should make it work)&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         int nIndex = Approval_GetFollowerIndex(oFollower);&lt;br /&gt;
         Approval_AddFollowerBonusAbility(nIndex, 0);&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
          //Handle Specialisation&lt;br /&gt;
          InitCustomFollowerSpec(oFollower, nPackage, nForceSpec, bFreeSpecPoint);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         // This spends all available attribute and stat points on the&lt;br /&gt;
         // creature according to the levelup table.  (JN:  this replicates AL_DoAutoLevelUp but with our choice of table)&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
         if (nALTable == 0) {&lt;br /&gt;
            nALTable = GetCustomFollowerALTable(oFollower);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         AL_SpendAttributePoints(oFollower, nALTable, FALSE);&lt;br /&gt;
         AL_SpendSkillPoints(oFollower, nALTable, TRUE);&lt;br /&gt;
         AL_SpendSpecializationPoints(oFollower, nALTable);&lt;br /&gt;
         AL_SpendTalentSpellPoints(oFollower, nALTable, TRUE);&lt;br /&gt;
&lt;br /&gt;
        // -------------------------------------------------------------------------&lt;br /&gt;
        // Update various UIs&lt;br /&gt;
        // -------------------------------------------------------------------------&lt;br /&gt;
        Chargen_SetNumTactics(oFollower);&lt;br /&gt;
        SetCanLevelUp(oFollower,Chargen_HasPointsToSpend(oFollower));&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        // load tactics&lt;br /&gt;
         InitCustomFollowerTactics(oFollower, nPackage);&lt;br /&gt;
&lt;br /&gt;
         /* #################  END PLAYER_CORE EVENT_TYPE_PARTY_MEMBER_HIRED EMULATION ################# */     &lt;br /&gt;
             &lt;br /&gt;
         &lt;br /&gt;
         SetAutoLevelUp(oFollower, nAutolevel);         //This is the autolevel flag on the character sheet.&lt;br /&gt;
         &lt;br /&gt;
         //Set plot flags&lt;br /&gt;
         &lt;br /&gt;
         if (!((sPlot == &amp;quot;&amp;quot;) || (nPlotFlag == 0))) {           //Joined Party&lt;br /&gt;
            WR_SetPlotFlag(sPlot, nPlotFlag, TRUE);   &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         if ((nInitialState == FOLLOWER_STATE_ACTIVE) || (nInitialState == FOLLOWER_STATE_LOCKEDACTIVE)) {&lt;br /&gt;
            if (!((sCurrPlot == &amp;quot;&amp;quot;) || (nCurrPlotFlag == 0))) {&lt;br /&gt;
                WR_SetPlotFlag(sCurrPlot, nCurrPlotFlag, TRUE);   //Currently in Party&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
            &lt;br /&gt;
        // Invoke picker if requested.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (bInvokePicker) {&lt;br /&gt;
             SetPartyPickerGUIStatus(2);&lt;br /&gt;
             ShowPartyPickerGUI();&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Yeah, I know.  It can't really be any smaller.  Feel free to modify it if you're confident with scripting.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Add Your Custom Autolevel Template to GetCustomFollowerALTable() ====&lt;br /&gt;
&lt;br /&gt;
While you can pass the ID you made for your autolevel template to that monster function as an argument, it's better to have them all in one place if you have multiple followers.&lt;br /&gt;
&lt;br /&gt;
GetCustomFollowerALTable() is the first function in our include, and you can add an explicit if test for your follower there to assign the correct table id (the one from your M2DA_base_ m2DA).  There is a function very much like it in sys_autolevel_h.nss for the core followers, so we'll copy Bioware's practice.&lt;br /&gt;
&lt;br /&gt;
Let's take a look at the function by itself:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int GetCustomFollowerALTable(object oFollower) {&lt;br /&gt;
    int nTable = _GetTableToUseForAL(oFollower);&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               &lt;br /&gt;
        nTable = 50143;   &lt;br /&gt;
    }   &lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_jysavin&amp;quot;) {&lt;br /&gt;
        nTable = 50144;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_geldual&amp;quot;) {&lt;br /&gt;
        nTable = 50145;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_braghon&amp;quot;) {&lt;br /&gt;
        nTable = 50146;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return nTable;    &lt;br /&gt;
    &lt;br /&gt;
}  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So we have a test for each follower tag from my module, matching up to an ID which is assigned to nTable.  All you need to do is change a tag from my follower to yours, and my ID to the correct one from your M2DA_base_* m2DA.  Then you should delete the rest of the example if statements :)&lt;br /&gt;
&lt;br /&gt;
Save and export the script.  Ignore the compiler error about lack of main();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Include Function In Your Hire Script and Call It ===&lt;br /&gt;
&lt;br /&gt;
So instead of a hire script that calls UT_HireFollower(), we want one that includes our shiny new function and calls it.&lt;br /&gt;
&lt;br /&gt;
Take a look at the following example:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;plt_bc_create_party&amp;quot;   //Make sure you include your party handling plot&lt;br /&gt;
#include &amp;quot;hireCustomFollower_h&amp;quot;  // And include the function script - which will in turn include a bunch of stuff&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
&lt;br /&gt;
                    //Initialising my objects, not super-relevant to the example &lt;br /&gt;
                     &lt;br /&gt;
                    object oHero = GetHero();&lt;br /&gt;
                    object oMiera = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_miera.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oJysavin = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_jysavin.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oBraghon = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_braghon.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oSpider = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_geldual.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    //Simplest hire call - adds to the party as a wizard.  Class is currently compulsory due to a bug.&lt;br /&gt;
&lt;br /&gt;
                    hireCustomFollower(oMiera, CLASS_WIZARD);&lt;br /&gt;
                   &lt;br /&gt;
&lt;br /&gt;
                    //Add to the party and set joining plot flags&lt;br /&gt;
                                      &lt;br /&gt;
                   &lt;br /&gt;
                    hireCustomFollower(oJysavin, CLASS_WARRIOR, PLT_BC_CREATE_PARTY, PARTY_JYSAVIN_JOINED);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    //Add to the party, set plot flags, force a specialisation&lt;br /&gt;
                    &lt;br /&gt;
                    hireCustomFollower(oBraghon, CLASS_ROGUE, PLT_BC_CREATE_PARTY, PARTY_BRAGHON_JOINED, ABILITY_TALENT_HIDDEN_ASSASSIN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    //More complex example - Follower added as a unique class (Dog), not granted a specialisation or spec point.  &lt;br /&gt;
                    //Note unique classes must have an ALTable passed here or specified in GetCustomFollowerALTable() or they won't work&lt;br /&gt;
                    &lt;br /&gt;
                    hireCustomFollower(oSpider, CLASS_DOG, PLT_BC_CREATE_PARTY, PARTY_GELDUAL_JOINED, 0, 0, FALSE, FOLLOWER_STATE_AVAILABLE, &amp;quot;&amp;quot;, 0, 0, FALSE);&lt;br /&gt;
                      &lt;br /&gt;
                   &lt;br /&gt;
                    //Show the party picker to let the player choose from their new companions!&lt;br /&gt;
&lt;br /&gt;
                    SetPartyPickerGUIStatus(2);&lt;br /&gt;
&lt;br /&gt;
                    ShowPartyPickerGUI();                                                                                                                      &lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The example shows several of the more simple ways of invoking the function.  Check the comments at the start of the function for a full list of arguments.&lt;br /&gt;
&lt;br /&gt;
I would suggest best practice for most followers would be to call as follows:&lt;br /&gt;
&lt;br /&gt;
'''hireCustomFollower(oFollower, CLASS, PLOT, PLOT_FLAG, SPECIALISATION)'''&lt;br /&gt;
&lt;br /&gt;
This will safely set the follower up as the desired class and specialisation (doubly important if there are spec abilities in their ALTable) while setting your plot flag for them being in the party.  hireCustomFollower(oFollower, CLASS, PLOT, PLOT_FLAG, SPECIALISATION, 0, TRUE) will do the same while invoking the Party Picker automatically.&lt;br /&gt;
&lt;br /&gt;
Note that the specialisations are abilities and not classes - you'll find them as ABILITY_HIDDEN_ constants.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If it's all worked, you should find you can now add followers with a lot more flexibility!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:picker_advanced.jpg|thumb|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Common Follower Problems &amp;amp; FAQ ==&lt;br /&gt;
&lt;br /&gt;
====Why don't my followers gain XP?====&lt;br /&gt;
There is a bug in UT_HireFollower. For now the best/easiest approach to take might be to make a copy of UT_HireFollower in an include file and rename it something like UT_HireFollower_Fixed, then make the following change:&lt;br /&gt;
&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, TRUE);&lt;br /&gt;
to&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, bPreventLevelup);&lt;br /&gt;
&lt;br /&gt;
Alternately you need to clear a flag in a seperate script to the one in which they're hired.&lt;br /&gt;
&lt;br /&gt;
You must use the '''SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);''' statement in a script you can be sure will run soon after your hiring script.&lt;br /&gt;
&lt;br /&gt;
====When I choose followers from the Party Picker, they spawn into the area but do not join.====&lt;br /&gt;
&lt;br /&gt;
You need to intercept the EVENT_TYPE_PARTYMEMBER_ADDED event and set the follower to FOLLOWER_STATE_ACTIVE.  See Simple Follower Creation earlier in this document.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====My followers don't have skill trees!====&lt;br /&gt;
&lt;br /&gt;
If a follower hasn't been through an initial chargen/autolevel event (via player_core/sys_autolevel_h) then the skill tree doesn't show.  You're probably trying to be clever and get around UT_HireFollower without going all the way (see monster function above ^_^).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====My followers don't have a class====&lt;br /&gt;
&lt;br /&gt;
GetCreatureCoreClass() seems flaky under some conditions.  It's best to explicitly set the class yourself; this is why class is currently a mandatory argument to hireCustomFollower()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Isn't there an easier way to do this?====&lt;br /&gt;
&lt;br /&gt;
Possibly.  There is a way of recruiting a follower by setting a plot flag.  However I don't understand it, and I expect it still doesn't allow custom autolevel templates, full control over specialisations etc.  There's still a fair bit of stuff hardcoded for the core followers, I'm not sure putting a custom follower through the same process as Al, Leli et al will have good results.&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=How-tos&amp;diff=9251</id>
		<title>How-tos</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=How-tos&amp;diff=9251"/>
				<updated>2010-01-03T20:37:34Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: /* Add a follower to the player's party */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists how to accomplish tasks that are relatively simple and commonly needed, but that touch on multiple areas of the toolset or are difficult to figure out intuitively how to do.&lt;br /&gt;
&lt;br /&gt;
Just collecting ideas at the moment, add headers if you think a how-to is needed on a particular subject.&lt;br /&gt;
&lt;br /&gt;
*[[3D control]]&lt;br /&gt;
&lt;br /&gt;
== Run a cutscene from a trigger ==&lt;br /&gt;
&lt;br /&gt;
Create a script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;events_h&amp;quot;&lt;br /&gt;
#include &amp;quot;global_objects_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
void main ()&lt;br /&gt;
{&lt;br /&gt;
    event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    int bEventHandled = FALSE;&lt;br /&gt;
    switch (nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_ENTER:&lt;br /&gt;
        {&lt;br /&gt;
            object oCreature = GetEventCreator(ev);&lt;br /&gt;
            if(GetObjectActive(OBJECT_SELF)&lt;br /&gt;
               &amp;amp;&amp;amp; IsPartyMember(oCreature)) &lt;br /&gt;
            { &lt;br /&gt;
                resource rCutscene = R&amp;quot;my_cutscene.cut&amp;quot;;&lt;br /&gt;
                CS_LoadCutscene(rCutscene);&lt;br /&gt;
                SetObjectActive(OBJECT_SELF, FALSE);&lt;br /&gt;
            }         &lt;br /&gt;
         }&lt;br /&gt;
         break;&lt;br /&gt;
    }&lt;br /&gt;
    if (!bEventHandled) //If this event wasn't handled by this script, let the core script try&lt;br /&gt;
    {&lt;br /&gt;
        HandleEvent(ev, RESOURCE_SCRIPT_TRIGGER_CORE);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And set it as the event script for the trigger that you want to have run the cutscene.&lt;br /&gt;
&lt;br /&gt;
== Add a follower to the player's party ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
if(IsPlayer(oCreature)) {&lt;br /&gt;
  object oFollower = GetObjectByTag(&amp;quot;myfollower&amp;quot;);&lt;br /&gt;
  UT_HireFollower(oCreature, oFollower);&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that with Toolset v1.0.982.0, calling UT_HireFollower() will result in a follower who's unable to gain xp. This happens due to the call of&lt;br /&gt;
  WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, '''TRUE''');&lt;br /&gt;
to the function&lt;br /&gt;
  void WR_SetFollowerState(object oCreature, int nState, int nSendEvent = TRUE, int nMinLevel = 0, '''int bPreventLevelup''' = FALSE)&lt;br /&gt;
To enable the xp gain, the flag CREATURE_REWARD_FLAGS needs to be cleared from the follower after the hired event was processed (there the flag is set). For now the best/easiest approach to take might be to make a copy of UT_HireFollower in an include file and rename it something like UT_HireFollower_Fixed, then make the following change:&lt;br /&gt;
&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, TRUE);&lt;br /&gt;
to&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, bPreventLevelup);&lt;br /&gt;
&lt;br /&gt;
== Have an enemy play possum and then get up to fight ==&lt;br /&gt;
&lt;br /&gt;
Set the creature's CREATURE_SPAWN_DEAD variable to 2.&lt;br /&gt;
&lt;br /&gt;
When it's time for the creature to rise and attack, execute the following script commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
WR_SetObjectActive(oCreature, TRUE);&lt;br /&gt;
SetCommandable(oCreature, TRUE);&lt;br /&gt;
// Make sure to set this flag back to 0 to avoid problems with savegames.&lt;br /&gt;
SetLocalInt(oCreature, CREATURE_SPAWN_DEAD, 0);&lt;br /&gt;
UT_CombatStart(oCreature, oPC);&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Insert content into an existing area ==&lt;br /&gt;
&lt;br /&gt;
If you want to add new content on to an existing area (for example, putting a new character or area transition door into an area that exists in the single-player campaign) there are two different ways to do it. One is to override the existing area with a new area of your own design that duplicates the original with the exception of your additions. This is straightforward to do but can interact poorly with other add-ons - you can only have one version of an area active at a time.&lt;br /&gt;
&lt;br /&gt;
A more elegant and extensible approach is to use a [[PRCSCR]]_-prefixed M2DA. The PRCSCR M2DA has a very simple structure and a simple but profound effect:&lt;br /&gt;
&lt;br /&gt;
*ID - a unique integer identifier for each row&lt;br /&gt;
*AreaListName - a string that identifies a specific area list, or the special keyword &amp;quot;any&amp;quot;.&lt;br /&gt;
*Script - the name of a script file.&lt;br /&gt;
&lt;br /&gt;
Whenever a player enters an area in an area list in this M2DA the associated script will be run. A modder can therefore include a script with his mod that will be run when the player enters an existing area that he didn't create. This script can freely add or remove placeables and creatures and perform whatever other modifications to the area that a script is capable of doing.&lt;br /&gt;
&lt;br /&gt;
Note that the script will be run every time the player enters the area, so you'll want to have an associated plot flag to ensure that the changes are only made once.&lt;br /&gt;
&lt;br /&gt;
The following example is a script that adds a new character from an add-on module to an existing area in the main game:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
// this is the name of a precreated plot file &amp;quot;joblos_quest&amp;quot; prefixed with the special &amp;quot;plt_&amp;quot;&lt;br /&gt;
// &amp;quot;plt_&amp;quot; + quest name allows you to reference the flag names as constants.&lt;br /&gt;
#include &amp;quot;plt_joblos_quest&amp;quot; &lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    //Check whether we've added Joblo already.&lt;br /&gt;
    if (WR_GetPlotFlag(PLT_JOBLOS_QUEST, JOBLO_ADDED_TO_TOWN) == FALSE)&lt;br /&gt;
    {&lt;br /&gt;
        object oTown = GetObjectByTag(&amp;quot;lot100ar_lothering&amp;quot;); //An area's tag is the same as its resource name&lt;br /&gt;
        vector vJobloLocation = Vector(126.745f, 120.724f, 0.460568f); // See below for how to get these coordinates&lt;br /&gt;
&lt;br /&gt;
        CreateObject(&lt;br /&gt;
            OBJECT_TYPE_CREATURE,&lt;br /&gt;
            R&amp;quot;joblo.utc&amp;quot;,&lt;br /&gt;
            Location(oTown, vJobloLocation, 180.0f) //See below for how to get the value for orientation&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
        WR_SetPlotFlag(&amp;quot;joblos_quest&amp;quot;, JOBLO_ADDED_TO_TOWN, TRUE);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since you can't add [[waypoint]]s to an existing area you'll need to enter the position and orientation values for the target location manually. You can find them by creating a local copy of the area in question and temporarily adding a waypoint to copy down the coordinates and orientation you'll need.&lt;br /&gt;
&lt;br /&gt;
== Add new music ==&lt;br /&gt;
&lt;br /&gt;
Open up [[FMOD]]&lt;br /&gt;
&lt;br /&gt;
It creates a project - set the build directory to your DA override directory - with project highlighted, it is over on the top right about half way down the project settings. You can set a default resource directory but that will just set where the file browser defaults to so it is optional. I'd also define a name in those parameters while you are there.&lt;br /&gt;
&lt;br /&gt;
From there, you need a new event !!(not sure whether a blank default is generated or whether you have to right click and make a default blank event)!!. After you have an event, highlight it and change to the event tab (2nd tab). Here you need to import your file to link to that event.&lt;br /&gt;
&lt;br /&gt;
On that tab I think it creates a empty row for your new event - right click and add wavetable or something like that - I think I use the top option. (Again, might be wrong but the basic goal is getting a audio file in that screen that plays when you hit the play button at the top)&lt;br /&gt;
&lt;br /&gt;
Browse to your wav file or whatever you have.&lt;br /&gt;
&lt;br /&gt;
From there you should be able to play the sound both in the pop-up box and (once that is closed) back in the event tab. You'll see the name of the wave in that once empty row (IIRC).&lt;br /&gt;
&lt;br /&gt;
If you want, you can add layers of sounds to this event using the same process over and over, but keeping it simple; we'll just move along.&lt;br /&gt;
&lt;br /&gt;
Now you have a project and an event. You can set various parameters on the first tab that alter pitch etc on the first tab. (When you import the sound, you set whether it is a one shot or looping).&lt;br /&gt;
&lt;br /&gt;
Once you have that done, go to the top drop down and find build. Build the files and you should see extra files in your override directory.&lt;br /&gt;
&lt;br /&gt;
From there, just open up the toolset (or hit refresh from within the toolset) and your project and event sounds should show up in the listing of sounds.&lt;br /&gt;
&lt;br /&gt;
You can then drag and drop them into the game or cutscene and they will play.&lt;br /&gt;
&lt;br /&gt;
== Adding music to cutscenes ==&lt;br /&gt;
&lt;br /&gt;
The way we have been doing the music changes is via placed sound objects.  These sound objects are generally created in [[FMOD]], and in FMOD you can say if the music will persist after the cutscene or end when the cutscene ends.&lt;br /&gt;
&lt;br /&gt;
We are just using other sounds to switch music tracks. Designers can add music switch parameter to any sound in Fmod Designer, usually this is just VO line to change music track, for example:&lt;br /&gt;
&lt;br /&gt;
[[Image:FMOD music switch.jpg]]&lt;br /&gt;
&lt;br /&gt;
If there are no other sounds, designers can create empty sound event and add #music parameter there and place this sound on cutscene timeline.&lt;br /&gt;
Music track has to be defined in the same group as music in current area in “music.fdp” to work.&lt;br /&gt;
&lt;br /&gt;
[[Image:FMOD music switch 2.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #music:name,1 – non looping, for stingers&lt;br /&gt;
 #music:name – for looping music&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
Another way&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
1. Open up '''FMOD''' (fmod comes with dragon age, do a search for fmod in dragon age directory)&lt;br /&gt;
&lt;br /&gt;
2. '''File''' ---&amp;gt; '''New Project''' --&amp;gt; and call the project whatever you want and place it in whatever folder you want.&lt;br /&gt;
&lt;br /&gt;
3. '''Double click''' the '''folder''' under '''Hierarchy''' (purple icon folder) and an event will appear beneath it. Name this event whatever you want.  (If there is no event for some reason right click and add one).&lt;br /&gt;
&lt;br /&gt;
4. Now click '''&amp;quot;Event Editor&amp;quot;''' Tab. (Make sure your event was selected before you do this).&lt;br /&gt;
&lt;br /&gt;
5. '''Right click''' one of the open sound fields (find it) and click '''&amp;quot;Add Sound&amp;quot;'''. (just right click all over until you see the option).&lt;br /&gt;
&lt;br /&gt;
6. In this window you will see '''&amp;quot;LOOPING&amp;quot;''' and '''&amp;quot;ONE SHOT&amp;quot;''' on the right hand side. Looping will be selected by default.  If you want your music to loop over &amp;amp; over again even after a cutscene is over leave it there. If you want your music to play ONE TIME then select &amp;quot;One Shot&amp;quot;.  &lt;br /&gt;
&lt;br /&gt;
7. Now it's time to '''pick your music file''' by clicking '''&amp;quot;new wavetable&amp;quot;'''. '''Browse''' to your music file (wav), select it and '''press ok'''.&lt;br /&gt;
&lt;br /&gt;
8. '''VERY VERY IMPORTANT'''.. '''YOU MUST DO THIS STEP'''....... Right click slightly above the timeline and click '''&amp;quot;ADD PARAMETER&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
9. Now '''right click''' your new blank parameter, look at the bottom and click '''&amp;quot;PARAMETER PROPERTIES&amp;quot;'''.  Another new window will pop up.&lt;br /&gt;
&lt;br /&gt;
10. '''VERY IMPORTANT'''..... Name this parameter: &lt;br /&gt;
&lt;br /&gt;
   #duck:music,1000,0,5000,-30      &lt;br /&gt;
&lt;br /&gt;
Now click ok.&lt;br /&gt;
   &lt;br /&gt;
11. Your new parameter should read: '''#duck:music,1000,0,5000,-30 (Primary)'''&lt;br /&gt;
&lt;br /&gt;
12. Now click '''&amp;quot;Build&amp;quot;'''  and do '''&amp;quot;build project&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
13. Note the new files in the directory where you saved the project.&lt;br /&gt;
&lt;br /&gt;
14. Copy the '''FEV &amp;amp; FSB''' files from your FMOD project folder '''INTO YOUR OVERRIDE folder'''.  I made a folder called music to be organized.&lt;br /&gt;
&lt;br /&gt;
    FMODProjectFolder/whatever.fev&lt;br /&gt;
    FMODProjectFolder/whatever.fsb&lt;br /&gt;
&lt;br /&gt;
COPY TO&lt;br /&gt;
&lt;br /&gt;
    Dragon Age\modules\Single Player\override\toolsetexport\music&lt;br /&gt;
&lt;br /&gt;
15. Now open up '''toolset''' and navigate to '''sound palette''' and you should see your new sound file.   Type the name of your sound file in the filter to find it faster.  (Do not type the folder name in the filter. The filter works by filenames and not folders).&lt;br /&gt;
&lt;br /&gt;
16. Open a '''cutscene''', then left click your new sound file in the right hand sound palette window to select and highlight it.  (just a simple left click on it).&lt;br /&gt;
&lt;br /&gt;
17. Now '''left click anywhere in your cutscene''' and a sound icon will be added which is your sound file.&lt;br /&gt;
&lt;br /&gt;
'''Congrats''', 17 steps and now you've added a simple music file to your project and ready for your cutscene. *Sweats*&lt;br /&gt;
&lt;br /&gt;
== Delete resources ==&lt;br /&gt;
&lt;br /&gt;
Resource deletion can sometimes be a bit complicated. Check the following:&lt;br /&gt;
&lt;br /&gt;
*Resources must be checked in when deleted. This is so that the toolset can be sure that all dependencies have been properly resolved.&lt;br /&gt;
*If other resources reference the resource it can't be deleted. This means that sometimes you'll need to delete resources in a specific order. For example, you can't delete a creature that's being used in an area, but you could delete the area and then delete the creature. Occasionally there may be circular references that you'll need to break by editing the resources before deleting them. For example:&lt;br /&gt;
**A stage can reference an area, which can then reference the stage.&lt;br /&gt;
**A plot file can have an associated event script, which will almost certainly include the plot file.&lt;br /&gt;
**A stage can reference a creature, which references a dialogue, which references the original stage.&lt;br /&gt;
&lt;br /&gt;
== Removing Modules ==&lt;br /&gt;
&lt;br /&gt;
Deleting a Module from the Toolset&lt;br /&gt;
Setup:&lt;br /&gt;
I created a module called Meep with a unique id of rcfMeep, added in one area with a waypoint, configured the starting area/waypoint info, and exported it with dependencies.  And now I want to strip it out.&lt;br /&gt;
&lt;br /&gt;
Step 1: Removing it from the game&lt;br /&gt;
&lt;br /&gt;
* Navigate to My Documents\Bioware\AddIns&lt;br /&gt;
* Delete the folder called rcfMeep&lt;br /&gt;
* Done&lt;br /&gt;
&lt;br /&gt;
Removing from the game is fairly easy.  The toolset?  Not so much.  The reason for this is that the information is stored in the SQL Database.  Now if you just want to remove the module from the Manage Modules list, that is easy.&lt;br /&gt;
&lt;br /&gt;
* Open Sql Server Management Studio Express.  I'm not sure if the default installation installs this or not.  If not, it can be downloaded from Microsoft.&lt;br /&gt;
* Connect to the BWDATOOLSET server, assuming that you kept the default options.&lt;br /&gt;
* Expand Databases&lt;br /&gt;
* Expand bw_dragonage_content&lt;br /&gt;
* Expand Tables&lt;br /&gt;
* Right click and select open on the dbo.Modules table&lt;br /&gt;
* This will bring up an excell-like window.  Find your module, right-click on the row, and select delete.  Say ok to the confirmation.&lt;br /&gt;
* Module is now PERMANENTLY removed.  Absolutely no way of recovering it.&lt;br /&gt;
&lt;br /&gt;
Now depending on the size of the Module, you just orphaned a bunch of resources.  Areas, placables, conversations, they all get placed into the database.  And once you remove the module ID, you just lost your ability to remove these resources.  Now do keep in mind that 95% of this junk is just text, so it hardly takes up any room.  It's not really a major issue.  However if you [[How-tos#Delete resources|delete out the resources]] within the toolset before you remove the module reference you should avoid this.&lt;br /&gt;
&lt;br /&gt;
== Override Events (e.g. those in player_core) ==&lt;br /&gt;
Look here: [[Event override]]&lt;br /&gt;
&lt;br /&gt;
== Create a lootable placeable that vanishes when looted ==&lt;br /&gt;
&lt;br /&gt;
For a player-usable placeable, use the following event script to make it give its contents to the player and then vanish when clicked on.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
event ev = GetCurrentEvent();&lt;br /&gt;
int nEventType = GetEventType(ev);&lt;br /&gt;
    switch (nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_USE:&lt;br /&gt;
        {&lt;br /&gt;
        //MoveAllItems(OBJECT_SELF, GetHero());&lt;br /&gt;
        AddCreatureMoney (1000000, GetHero(), TRUE);&lt;br /&gt;
        Safe_Destroy_Object(OBJECT_SELF);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you wanted to use standard resources you could achieve the same thing (though not destroying the placeable) simply by adding &amp;quot;_autoloot&amp;quot; to the end of the placeable's tag.&lt;br /&gt;
&lt;br /&gt;
== Move the player to a new area after a cutscene plays ==&lt;br /&gt;
&lt;br /&gt;
Stand-alone cutscenes have an &amp;quot;end script&amp;quot; parameter that sets a script to run once the cutscene ends. Use a script such as the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
   DoAreaTransition(&amp;quot;destination_area_tag&amp;quot;, &amp;quot;destination_waypoint_tag&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
[[category:tutorials]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=How-tos&amp;diff=9129</id>
		<title>How-tos</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=How-tos&amp;diff=9129"/>
				<updated>2010-01-01T05:14:27Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: /* Insert content into an existing area */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists how to accomplish tasks that are relatively simple and commonly needed, but that touch on multiple areas of the toolset or are difficult to figure out intuitively how to do.&lt;br /&gt;
&lt;br /&gt;
Just collecting ideas at the moment, add headers if you think a how-to is needed on a particular subject.&lt;br /&gt;
&lt;br /&gt;
*[[3D control]]&lt;br /&gt;
&lt;br /&gt;
== Run a cutscene from a trigger ==&lt;br /&gt;
&lt;br /&gt;
Create a script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;events_h&amp;quot;&lt;br /&gt;
#include &amp;quot;global_objects_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
void main ()&lt;br /&gt;
{&lt;br /&gt;
    event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    int bEventHandled = FALSE;&lt;br /&gt;
    switch (nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_ENTER:&lt;br /&gt;
        {&lt;br /&gt;
            object oCreature = GetEventCreator(ev);&lt;br /&gt;
            if(GetObjectActive(OBJECT_SELF)&lt;br /&gt;
               &amp;amp;&amp;amp; IsPartyMember(oCreature)) &lt;br /&gt;
            { &lt;br /&gt;
                resource rCutscene = R&amp;quot;my_cutscene.cut&amp;quot;;&lt;br /&gt;
                CS_LoadCutscene(rCutscene);&lt;br /&gt;
                SetObjectActive(OBJECT_SELF, FALSE);&lt;br /&gt;
            }         &lt;br /&gt;
         }&lt;br /&gt;
         break;&lt;br /&gt;
    }&lt;br /&gt;
    if (!bEventHandled) //If this event wasn't handled by this script, let the core script try&lt;br /&gt;
    {&lt;br /&gt;
        HandleEvent(ev, RESOURCE_SCRIPT_TRIGGER_CORE);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And set it as the event script for the trigger that you want to have run the cutscene.&lt;br /&gt;
&lt;br /&gt;
== Add a follower to the player's party ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
if(IsPlayer(oCreature)) {&lt;br /&gt;
  object oFollower = GetObjectByTag(&amp;quot;myfollower&amp;quot;);&lt;br /&gt;
  UT_HireFollower(oCreature, oFollower);&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that with Toolset v1.0.982.0, calling UT_HireFollower() will result in a follower who's unable to gain xp. This happens due to the call of&lt;br /&gt;
  WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, '''TRUE''');&lt;br /&gt;
to the function&lt;br /&gt;
  void WR_SetFollowerState(object oCreature, int nState, int nSendEvent = TRUE, int nMinLevel = 0, '''int bPreventLevelup''' = FALSE)&lt;br /&gt;
To enable the xp gain, the flag CREATURE_REWARD_FLAGS needs to be cleared from the follower after the hired event was processed (there the flag is set). Alternatively, the relevant contents of UT_HireFollower() are to be called directly using bPreventLevelup = FALSE.&lt;br /&gt;
&lt;br /&gt;
== Have an enemy play possum and then get up to fight ==&lt;br /&gt;
&lt;br /&gt;
Set the creature's CREATURE_SPAWN_DEAD variable to 2.&lt;br /&gt;
&lt;br /&gt;
When it's time for the creature to rise and attack, execute the following script commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
WR_SetObjectActive(oCreature, TRUE);&lt;br /&gt;
SetCommandable(oCreature, TRUE);&lt;br /&gt;
// Make sure to set this flag back to 0 to avoid problems with savegames.&lt;br /&gt;
SetLocalInt(oCreature, CREATURE_SPAWN_DEAD, 0);&lt;br /&gt;
UT_CombatStart(oCreature, oPC);&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Insert content into an existing area ==&lt;br /&gt;
&lt;br /&gt;
If you want to add new content on to an existing area (for example, putting a new character or area transition door into an area that exists in the single-player campaign) there are two different ways to do it. One is to override the existing area with a new area of your own design that duplicates the original with the exception of your additions. This is straightforward to do but can interact poorly with other add-ons - you can only have one version of an area active at a time.&lt;br /&gt;
&lt;br /&gt;
A more elegant and extensible approach is to use a [[PRCSCR]]_-prefixed M2DA. The PRCSCR M2DA has a very simple structure and a simple but profound effect:&lt;br /&gt;
&lt;br /&gt;
*ID - a unique integer identifier for each row&lt;br /&gt;
*AreaListName - a string that identifies a specific area list, or the special keyword &amp;quot;any&amp;quot;.&lt;br /&gt;
*Script - the name of a script file.&lt;br /&gt;
&lt;br /&gt;
Whenever a player enters an area in an area list in this M2DA the associated script will be run. A modder can therefore include a script with his mod that will be run when the player enters an existing area that he didn't create. This script can freely add or remove placeables and creatures and perform whatever other modifications to the area that a script is capable of doing.&lt;br /&gt;
&lt;br /&gt;
Note that the script will be run every time the player enters the area, so you'll want to have an associated plot flag to ensure that the changes are only made once.&lt;br /&gt;
&lt;br /&gt;
The following example is a script that adds a new character from an add-on module to an existing area in the main game:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
// this is the name of a precreated plot file &amp;quot;joblos_quest&amp;quot; prefixed with the special &amp;quot;plt_&amp;quot;&lt;br /&gt;
// &amp;quot;plt_&amp;quot; + quest name allows you to reference the flag names as constants.&lt;br /&gt;
#include &amp;quot;plt_joblos_quest&amp;quot; &lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    //Check whether we've added Joblo already.&lt;br /&gt;
    if (WR_GetPlotFlag(PLT_JOBLOS_QUEST, JOBLO_ADDED_TO_TOWN) == FALSE)&lt;br /&gt;
    {&lt;br /&gt;
        object oTown = GetObjectByTag(&amp;quot;lot100ar_lothering&amp;quot;); //An area's tag is the same as its resource name&lt;br /&gt;
        vector vJobloLocation = Vector(126.745f, 120.724f, 0.460568f); // See below for how to get these coordinates&lt;br /&gt;
&lt;br /&gt;
        CreateObject(&lt;br /&gt;
            OBJECT_TYPE_CREATURE,&lt;br /&gt;
            R&amp;quot;joblo.utc&amp;quot;,&lt;br /&gt;
            Location(oTown, vJobloLocation, 180.0f) //See below for how to get the value for orientation&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
        WR_SetPlotFlag(&amp;quot;joblos_quest&amp;quot;, JOBLO_ADDED_TO_TOWN, TRUE);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since you can't add [[waypoint]]s to an existing area you'll need to enter the position and orientation values for the target location manually. You can find them by creating a local copy of the area in question and temporarily adding a waypoint to copy down the coordinates and orientation you'll need.&lt;br /&gt;
&lt;br /&gt;
== Add new music ==&lt;br /&gt;
&lt;br /&gt;
Open up [[FMOD]]&lt;br /&gt;
&lt;br /&gt;
It creates a project - set the build directory to your DA override directory - with project highlighted, it is over on the top right about half way down the project settings. You can set a default resource directory but that will just set where the file browser defaults to so it is optional. I'd also define a name in those parameters while you are there.&lt;br /&gt;
&lt;br /&gt;
From there, you need a new event !!(not sure whether a blank default is generated or whether you have to right click and make a default blank event)!!. After you have an event, highlight it and change to the event tab (2nd tab). Here you need to import your file to link to that event.&lt;br /&gt;
&lt;br /&gt;
On that tab I think it creates a empty row for your new event - right click and add wavetable or something like that - I think I use the top option. (Again, might be wrong but the basic goal is getting a audio file in that screen that plays when you hit the play button at the top)&lt;br /&gt;
&lt;br /&gt;
Browse to your wav file or whatever you have.&lt;br /&gt;
&lt;br /&gt;
From there you should be able to play the sound both in the pop-up box and (once that is closed) back in the event tab. You'll see the name of the wave in that once empty row (IIRC).&lt;br /&gt;
&lt;br /&gt;
If you want, you can add layers of sounds to this event using the same process over and over, but keeping it simple; we'll just move along.&lt;br /&gt;
&lt;br /&gt;
Now you have a project and an event. You can set various parameters on the first tab that alter pitch etc on the first tab. (When you import the sound, you set whether it is a one shot or looping).&lt;br /&gt;
&lt;br /&gt;
Once you have that done, go to the top drop down and find build. Build the files and you should see extra files in your override directory.&lt;br /&gt;
&lt;br /&gt;
From there, just open up the toolset (or hit refresh from within the toolset) and your project and event sounds should show up in the listing of sounds.&lt;br /&gt;
&lt;br /&gt;
You can then drag and drop them into the game or cutscene and they will play.&lt;br /&gt;
&lt;br /&gt;
== Adding music to cutscenes ==&lt;br /&gt;
&lt;br /&gt;
The way we have been doing the music changes is via placed sound objects.  These sound objects are generally created in [[FMOD]], and in FMOD you can say if the music will persist after the cutscene or end when the cutscene ends.&lt;br /&gt;
&lt;br /&gt;
We are just using other sounds to switch music tracks. Designers can add music switch parameter to any sound in Fmod Designer, usually this is just VO line to change music track, for example:&lt;br /&gt;
&lt;br /&gt;
[[Image:FMOD music switch.jpg]]&lt;br /&gt;
&lt;br /&gt;
If there are no other sounds, designers can create empty sound event and add #music parameter there and place this sound on cutscene timeline.&lt;br /&gt;
Music track has to be defined in the same group as music in current area in “music.fdp” to work.&lt;br /&gt;
&lt;br /&gt;
[[Image:FMOD music switch 2.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #music:name,1 – non looping, for stingers&lt;br /&gt;
 #music:name – for looping music&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
Another way&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
1. Open up '''FMOD''' (fmod comes with dragon age, do a search for fmod in dragon age directory)&lt;br /&gt;
&lt;br /&gt;
2. '''File''' ---&amp;gt; '''New Project''' --&amp;gt; and call the project whatever you want and place it in whatever folder you want.&lt;br /&gt;
&lt;br /&gt;
3. '''Double click''' the '''folder''' under '''Hierarchy''' (purple icon folder) and an event will appear beneath it. Name this event whatever you want.  (If there is no event for some reason right click and add one).&lt;br /&gt;
&lt;br /&gt;
4. Now click '''&amp;quot;Event Editor&amp;quot;''' Tab. (Make sure your event was selected before you do this).&lt;br /&gt;
&lt;br /&gt;
5. '''Right click''' one of the open sound fields (find it) and click '''&amp;quot;Add Sound&amp;quot;'''. (just right click all over until you see the option).&lt;br /&gt;
&lt;br /&gt;
6. In this window you will see '''&amp;quot;LOOPING&amp;quot;''' and '''&amp;quot;ONE SHOT&amp;quot;''' on the right hand side. Looping will be selected by default.  If you want your music to loop over &amp;amp; over again even after a cutscene is over leave it there. If you want your music to play ONE TIME then select &amp;quot;One Shot&amp;quot;.  &lt;br /&gt;
&lt;br /&gt;
7. Now it's time to '''pick your music file''' by clicking '''&amp;quot;new wavetable&amp;quot;'''. '''Browse''' to your music file (wav), select it and '''press ok'''.&lt;br /&gt;
&lt;br /&gt;
8. '''VERY VERY IMPORTANT'''.. '''YOU MUST DO THIS STEP'''....... Right click slightly above the timeline and click '''&amp;quot;ADD PARAMETER&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
9. Now '''right click''' your new blank parameter, look at the bottom and click '''&amp;quot;PARAMETER PROPERTIES&amp;quot;'''.  Another new window will pop up.&lt;br /&gt;
&lt;br /&gt;
10. '''VERY IMPORTANT'''..... Name this parameter: &lt;br /&gt;
&lt;br /&gt;
   #duck:music,1000,0,5000,-30      &lt;br /&gt;
&lt;br /&gt;
Now click ok.&lt;br /&gt;
   &lt;br /&gt;
11. Your new parameter should read: '''#duck:music,1000,0,5000,-30 (Primary)'''&lt;br /&gt;
&lt;br /&gt;
12. Now click '''&amp;quot;Build&amp;quot;'''  and do '''&amp;quot;build project&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
13. Note the new files in the directory where you saved the project.&lt;br /&gt;
&lt;br /&gt;
14. Copy the '''FEV &amp;amp; FSB''' files from your FMOD project folder '''INTO YOUR OVERRIDE folder'''.  I made a folder called music to be organized.&lt;br /&gt;
&lt;br /&gt;
    FMODProjectFolder/whatever.fev&lt;br /&gt;
    FMODProjectFolder/whatever.fsb&lt;br /&gt;
&lt;br /&gt;
COPY TO&lt;br /&gt;
&lt;br /&gt;
    Dragon Age\modules\Single Player\override\toolsetexport\music&lt;br /&gt;
&lt;br /&gt;
15. Now open up '''toolset''' and navigate to '''sound palette''' and you should see your new sound file.   Type the name of your sound file in the filter to find it faster.  (Do not type the folder name in the filter. The filter works by filenames and not folders).&lt;br /&gt;
&lt;br /&gt;
16. Open a '''cutscene''', then left click your new sound file in the right hand sound palette window to select and highlight it.  (just a simple left click on it).&lt;br /&gt;
&lt;br /&gt;
17. Now '''left click anywhere in your cutscene''' and a sound icon will be added which is your sound file.&lt;br /&gt;
&lt;br /&gt;
'''Congrats''', 17 steps and now you've added a simple music file to your project and ready for your cutscene. *Sweats*&lt;br /&gt;
&lt;br /&gt;
== Delete resources ==&lt;br /&gt;
&lt;br /&gt;
Resource deletion can sometimes be a bit complicated. Check the following:&lt;br /&gt;
&lt;br /&gt;
*Resources must be checked in when deleted. This is so that the toolset can be sure that all dependencies have been properly resolved.&lt;br /&gt;
*If other resources reference the resource it can't be deleted. This means that sometimes you'll need to delete resources in a specific order. For example, you can't delete a creature that's being used in an area, but you could delete the area and then delete the creature. Occasionally there may be circular references that you'll need to break by editing the resources before deleting them. For example:&lt;br /&gt;
**A stage can reference an area, which can then reference the stage.&lt;br /&gt;
**A plot file can have an associated event script, which will almost certainly include the plot file.&lt;br /&gt;
**A stage can reference a creature, which references a dialogue, which references the original stage.&lt;br /&gt;
&lt;br /&gt;
== Removing Modules ==&lt;br /&gt;
&lt;br /&gt;
Deleting a Module from the Toolset&lt;br /&gt;
Setup:&lt;br /&gt;
I created a module called Meep with a unique id of rcfMeep, added in one area with a waypoint, configured the starting area/waypoint info, and exported it with dependencies.  And now I want to strip it out.&lt;br /&gt;
&lt;br /&gt;
Step 1: Removing it from the game&lt;br /&gt;
&lt;br /&gt;
* Navigate to My Documents\Bioware\AddIns&lt;br /&gt;
* Delete the folder called rcfMeep&lt;br /&gt;
* Done&lt;br /&gt;
&lt;br /&gt;
Removing from the game is fairly easy.  The toolset?  Not so much.  The reason for this is that the information is stored in the SQL Database.  Now if you just want to remove the module from the Manage Modules list, that is easy.&lt;br /&gt;
&lt;br /&gt;
* Open Sql Server Management Studio Express.  I'm not sure if the default installation installs this or not.  If not, it can be downloaded from Microsoft.&lt;br /&gt;
* Connect to the BWDATOOLSET server, assuming that you kept the default options.&lt;br /&gt;
* Expand Databases&lt;br /&gt;
* Expand bw_dragonage_content&lt;br /&gt;
* Expand Tables&lt;br /&gt;
* Right click and select open on the dbo.Modules table&lt;br /&gt;
* This will bring up an excell-like window.  Find your module, right-click on the row, and select delete.  Say ok to the confirmation.&lt;br /&gt;
* Module is now PERMANENTLY removed.  Absolutely no way of recovering it.&lt;br /&gt;
&lt;br /&gt;
Now depending on the size of the Module, you just orphaned a bunch of resources.  Areas, placables, conversations, they all get placed into the database.  And once you remove the module ID, you just lost your ability to remove these resources.  Now do keep in mind that 95% of this junk is just text, so it hardly takes up any room.  It's not really a major issue.  However if you [[How-tos#Delete resources|delete out the resources]] within the toolset before you remove the module reference you should avoid this.&lt;br /&gt;
&lt;br /&gt;
== Override Events (e.g. those in player_core) ==&lt;br /&gt;
Look here: [[Event override]]&lt;br /&gt;
&lt;br /&gt;
== Create a lootable placeable that vanishes when looted ==&lt;br /&gt;
&lt;br /&gt;
For a player-usable placeable, use the following event script to make it give its contents to the player and then vanish when clicked on.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
event ev = GetCurrentEvent();&lt;br /&gt;
int nEventType = GetEventType(ev);&lt;br /&gt;
    switch (nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_USE:&lt;br /&gt;
        {&lt;br /&gt;
        //MoveAllItems(OBJECT_SELF, GetHero());&lt;br /&gt;
        AddCreatureMoney (1000000, GetHero(), TRUE);&lt;br /&gt;
        Safe_Destroy_Object(OBJECT_SELF);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you wanted to use standard resources you could achieve the same thing (though not destroying the placeable) simply by adding &amp;quot;_autoloot&amp;quot; to the end of the placeable's tag.&lt;br /&gt;
&lt;br /&gt;
== Move the player to a new area after a cutscene plays ==&lt;br /&gt;
&lt;br /&gt;
Stand-alone cutscenes have an &amp;quot;end script&amp;quot; parameter that sets a script to run once the cutscene ends. Use a script such as the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
   DoAreaTransition(&amp;quot;destination_area_tag&amp;quot;, &amp;quot;destination_waypoint_tag&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
[[category:tutorials]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=How-tos&amp;diff=9121</id>
		<title>How-tos</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=How-tos&amp;diff=9121"/>
				<updated>2009-12-30T21:00:19Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: /* Run a cutscene from a trigger */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page lists how to accomplish tasks that are relatively simple and commonly needed, but that touch on multiple areas of the toolset or are difficult to figure out intuitively how to do.&lt;br /&gt;
&lt;br /&gt;
Just collecting ideas at the moment, add headers if you think a how-to is needed on a particular subject.&lt;br /&gt;
&lt;br /&gt;
*[[3D control]]&lt;br /&gt;
&lt;br /&gt;
== Run a cutscene from a trigger ==&lt;br /&gt;
&lt;br /&gt;
Create a script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;events_h&amp;quot;&lt;br /&gt;
#include &amp;quot;global_objects_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
void main ()&lt;br /&gt;
{&lt;br /&gt;
    event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    int bEventHandled = FALSE;&lt;br /&gt;
    switch (nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_ENTER:&lt;br /&gt;
        {&lt;br /&gt;
            object oCreature = GetEventCreator(ev);&lt;br /&gt;
            if(GetObjectActive(OBJECT_SELF)&lt;br /&gt;
               &amp;amp;&amp;amp; IsPartyMember(oCreature)) &lt;br /&gt;
            { &lt;br /&gt;
                resource rCutscene = R&amp;quot;my_cutscene.cut&amp;quot;;&lt;br /&gt;
                CS_LoadCutscene(rCutscene);&lt;br /&gt;
                SetObjectActive(OBJECT_SELF, FALSE);&lt;br /&gt;
            }         &lt;br /&gt;
         }&lt;br /&gt;
         break;&lt;br /&gt;
    }&lt;br /&gt;
    if (!bEventHandled) //If this event wasn't handled by this script, let the core script try&lt;br /&gt;
    {&lt;br /&gt;
        HandleEvent(ev, RESOURCE_SCRIPT_TRIGGER_CORE);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And set it as the event script for the trigger that you want to have run the cutscene.&lt;br /&gt;
&lt;br /&gt;
== Add a follower to the player's party ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
if(IsPlayer(oCreature)) {&lt;br /&gt;
  object oFollower = GetObjectByTag(&amp;quot;myfollower&amp;quot;);&lt;br /&gt;
  UT_HireFollower(oCreature, oFollower);&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that with Toolset v1.0.982.0, calling UT_HireFollower() will result in a follower who's unable to gain xp. This happens due to the call of&lt;br /&gt;
  WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, '''TRUE''');&lt;br /&gt;
to the function&lt;br /&gt;
  void WR_SetFollowerState(object oCreature, int nState, int nSendEvent = TRUE, int nMinLevel = 0, '''int bPreventLevelup''' = FALSE)&lt;br /&gt;
To enable the xp gain, the flag CREATURE_REWARD_FLAGS needs to be cleared from the follower after the hired event was processed (there the flag is set). Alternatively, the relevant contents of UT_HireFollower() are to be called directly using bPreventLevelup = FALSE.&lt;br /&gt;
&lt;br /&gt;
== Have an enemy play possum and then get up to fight ==&lt;br /&gt;
&lt;br /&gt;
Set the creature's CREATURE_SPAWN_DEAD variable to 2.&lt;br /&gt;
&lt;br /&gt;
When it's time for the creature to rise and attack, execute the following script commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
WR_SetObjectActive(oCreature, TRUE);&lt;br /&gt;
SetCommandable(oCreature, TRUE);&lt;br /&gt;
// Make sure to set this flag back to 0 to avoid problems with savegames.&lt;br /&gt;
SetLocalInt(oCreature, CREATURE_SPAWN_DEAD, 0);&lt;br /&gt;
UT_CombatStart(oCreature, oPC);&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Insert content into an existing area ==&lt;br /&gt;
&lt;br /&gt;
If you want to add new content on to an existing area (for example, putting a new character or area transition door into an area that exists in the single-player campaign) there are two different ways to do it. One is to override the existing area with a new area of your own design that duplicates the original with the exception of your additions. This is straightforward to do but can interact poorly with other add-ons - you can only have one version of an area active at a time.&lt;br /&gt;
&lt;br /&gt;
A more elegant and extensible approach is to use a [[PRCSCR]]_-prefixed M2DA. The PRCSCR M2DA has a very simple structure and a simple but profound effect:&lt;br /&gt;
&lt;br /&gt;
*ID - a unique integer identifier for each row&lt;br /&gt;
*AreaListName - a string that identifies a specific area list, or the special keyword &amp;quot;any&amp;quot;.&lt;br /&gt;
*Script - the name of a script file.&lt;br /&gt;
&lt;br /&gt;
Whenever a player enters an area in an area list in this M2DA the associated script will be run. A modder can therefore include a script with his mod that will be run when the player enters an existing area that he didn't create. This script can freely add or remove placeables and creatures and perform whatever other modifications to the area that a script is capable of doing.&lt;br /&gt;
&lt;br /&gt;
Note that the script will be run every time the player enters the area, so you'll want to have an associated plot flag to ensure that the changes are only made once.&lt;br /&gt;
&lt;br /&gt;
The following example is a script that adds a new character from an add-on module to an existing area in the main game:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    //Check whether we've added Joblo already.&lt;br /&gt;
    if (WR_GetPlotFlag(&amp;quot;joblos_quest&amp;quot;, JOBLO_ADDED_TO_TOWN) == FALSE)&lt;br /&gt;
    {&lt;br /&gt;
        object oTown = GetObjectByTag(&amp;quot;lot100ar_lothering&amp;quot;); //An area's tag is the same as its resource name&lt;br /&gt;
        vector vJobloLocation = Vector(126.745f,120.724f,0.460568f); // See below for how to get these coordinates&lt;br /&gt;
&lt;br /&gt;
        CreateObject(&lt;br /&gt;
            OBJECT_TYPE_CREATURE,&lt;br /&gt;
            R&amp;quot;joblo.utc&amp;quot;,&lt;br /&gt;
            Location(oTown, vJobloLocation, 180.0f) //See below for how to get the value for orientation&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
        WR_SetPlotFlag(&amp;quot;joblos_quest&amp;quot;, JOBLO_ADDED_TO_TOWN, TRUE);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since you can't add [[waypoint]]s to an existing area you'll need to enter the position and orientation values for the target location manually. You can find them by creating a local copy of the area in question and temporarily adding a waypoint to copy down the coordinates and orientation you'll need.&lt;br /&gt;
&lt;br /&gt;
== Add new music ==&lt;br /&gt;
&lt;br /&gt;
Open up [[FMOD]]&lt;br /&gt;
&lt;br /&gt;
It creates a project - set the build directory to your DA override directory - with project highlighted, it is over on the top right about half way down the project settings. You can set a default resource directory but that will just set where the file browser defaults to so it is optional. I'd also define a name in those parameters while you are there.&lt;br /&gt;
&lt;br /&gt;
From there, you need a new event !!(not sure whether a blank default is generated or whether you have to right click and make a default blank event)!!. After you have an event, highlight it and change to the event tab (2nd tab). Here you need to import your file to link to that event.&lt;br /&gt;
&lt;br /&gt;
On that tab I think it creates a empty row for your new event - right click and add wavetable or something like that - I think I use the top option. (Again, might be wrong but the basic goal is getting a audio file in that screen that plays when you hit the play button at the top)&lt;br /&gt;
&lt;br /&gt;
Browse to your wav file or whatever you have.&lt;br /&gt;
&lt;br /&gt;
From there you should be able to play the sound both in the pop-up box and (once that is closed) back in the event tab. You'll see the name of the wave in that once empty row (IIRC).&lt;br /&gt;
&lt;br /&gt;
If you want, you can add layers of sounds to this event using the same process over and over, but keeping it simple; we'll just move along.&lt;br /&gt;
&lt;br /&gt;
Now you have a project and an event. You can set various parameters on the first tab that alter pitch etc on the first tab. (When you import the sound, you set whether it is a one shot or looping).&lt;br /&gt;
&lt;br /&gt;
Once you have that done, go to the top drop down and find build. Build the files and you should see extra files in your override directory.&lt;br /&gt;
&lt;br /&gt;
From there, just open up the toolset (or hit refresh from within the toolset) and your project and event sounds should show up in the listing of sounds.&lt;br /&gt;
&lt;br /&gt;
You can then drag and drop them into the game or cutscene and they will play.&lt;br /&gt;
&lt;br /&gt;
== Adding music to cutscenes ==&lt;br /&gt;
&lt;br /&gt;
The way we have been doing the music changes is via placed sound objects.  These sound objects are generally created in [[FMOD]], and in FMOD you can say if the music will persist after the cutscene or end when the cutscene ends.&lt;br /&gt;
&lt;br /&gt;
We are just using other sounds to switch music tracks. Designers can add music switch parameter to any sound in Fmod Designer, usually this is just VO line to change music track, for example:&lt;br /&gt;
&lt;br /&gt;
[[Image:FMOD music switch.jpg]]&lt;br /&gt;
&lt;br /&gt;
If there are no other sounds, designers can create empty sound event and add #music parameter there and place this sound on cutscene timeline.&lt;br /&gt;
Music track has to be defined in the same group as music in current area in “music.fdp” to work.&lt;br /&gt;
&lt;br /&gt;
[[Image:FMOD music switch 2.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #music:name,1 – non looping, for stingers&lt;br /&gt;
 #music:name – for looping music&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
Another way&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
1. Open up '''FMOD''' (fmod comes with dragon age, do a search for fmod in dragon age directory)&lt;br /&gt;
&lt;br /&gt;
2. '''File''' ---&amp;gt; '''New Project''' --&amp;gt; and call the project whatever you want and place it in whatever folder you want.&lt;br /&gt;
&lt;br /&gt;
3. '''Double click''' the '''folder''' under '''Hierarchy''' (purple icon folder) and an event will appear beneath it. Name this event whatever you want.  (If there is no event for some reason right click and add one).&lt;br /&gt;
&lt;br /&gt;
4. Now click '''&amp;quot;Event Editor&amp;quot;''' Tab. (Make sure your event was selected before you do this).&lt;br /&gt;
&lt;br /&gt;
5. '''Right click''' one of the open sound fields (find it) and click '''&amp;quot;Add Sound&amp;quot;'''. (just right click all over until you see the option).&lt;br /&gt;
&lt;br /&gt;
6. In this window you will see '''&amp;quot;LOOPING&amp;quot;''' and '''&amp;quot;ONE SHOT&amp;quot;''' on the right hand side. Looping will be selected by default.  If you want your music to loop over &amp;amp; over again even after a cutscene is over leave it there. If you want your music to play ONE TIME then select &amp;quot;One Shot&amp;quot;.  &lt;br /&gt;
&lt;br /&gt;
7. Now it's time to '''pick your music file''' by clicking '''&amp;quot;new wavetable&amp;quot;'''. '''Browse''' to your music file (wav), select it and '''press ok'''.&lt;br /&gt;
&lt;br /&gt;
8. '''VERY VERY IMPORTANT'''.. '''YOU MUST DO THIS STEP'''....... Right click slightly above the timeline and click '''&amp;quot;ADD PARAMETER&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
9. Now '''right click''' your new blank parameter, look at the bottom and click '''&amp;quot;PARAMETER PROPERTIES&amp;quot;'''.  Another new window will pop up.&lt;br /&gt;
&lt;br /&gt;
10. '''VERY IMPORTANT'''..... Name this parameter: &lt;br /&gt;
&lt;br /&gt;
   #duck:music,1000,0,5000,-30      &lt;br /&gt;
&lt;br /&gt;
Now click ok.&lt;br /&gt;
   &lt;br /&gt;
11. Your new parameter should read: '''#duck:music,1000,0,5000,-30 (Primary)'''&lt;br /&gt;
&lt;br /&gt;
12. Now click '''&amp;quot;Build&amp;quot;'''  and do '''&amp;quot;build project&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
13. Note the new files in the directory where you saved the project.&lt;br /&gt;
&lt;br /&gt;
14. Copy the '''FEV &amp;amp; FSB''' files from your FMOD project folder '''INTO YOUR OVERRIDE folder'''.  I made a folder called music to be organized.&lt;br /&gt;
&lt;br /&gt;
    FMODProjectFolder/whatever.fev&lt;br /&gt;
    FMODProjectFolder/whatever.fsb&lt;br /&gt;
&lt;br /&gt;
COPY TO&lt;br /&gt;
&lt;br /&gt;
    Dragon Age\modules\Single Player\override\toolsetexport\music&lt;br /&gt;
&lt;br /&gt;
15. Now open up '''toolset''' and navigate to '''sound palette''' and you should see your new sound file.   Type the name of your sound file in the filter to find it faster.  (Do not type the folder name in the filter. The filter works by filenames and not folders).&lt;br /&gt;
&lt;br /&gt;
16. Open a '''cutscene''', then left click your new sound file in the right hand sound palette window to select and highlight it.  (just a simple left click on it).&lt;br /&gt;
&lt;br /&gt;
17. Now '''left click anywhere in your cutscene''' and a sound icon will be added which is your sound file.&lt;br /&gt;
&lt;br /&gt;
'''Congrats''', 17 steps and now you've added a simple music file to your project and ready for your cutscene. *Sweats*&lt;br /&gt;
&lt;br /&gt;
== Delete resources ==&lt;br /&gt;
&lt;br /&gt;
Resource deletion can sometimes be a bit complicated. Check the following:&lt;br /&gt;
&lt;br /&gt;
*Resources must be checked in when deleted. This is so that the toolset can be sure that all dependencies have been properly resolved.&lt;br /&gt;
*If other resources reference the resource it can't be deleted. This means that sometimes you'll need to delete resources in a specific order. For example, you can't delete a creature that's being used in an area, but you could delete the area and then delete the creature. Occasionally there may be circular references that you'll need to break by editing the resources before deleting them. For example:&lt;br /&gt;
**A stage can reference an area, which can then reference the stage.&lt;br /&gt;
**A plot file can have an associated event script, which will almost certainly include the plot file.&lt;br /&gt;
**A stage can reference a creature, which references a dialogue, which references the original stage.&lt;br /&gt;
&lt;br /&gt;
== Removing Modules ==&lt;br /&gt;
&lt;br /&gt;
Deleting a Module from the Toolset&lt;br /&gt;
Setup:&lt;br /&gt;
I created a module called Meep with a unique id of rcfMeep, added in one area with a waypoint, configured the starting area/waypoint info, and exported it with dependencies.  And now I want to strip it out.&lt;br /&gt;
&lt;br /&gt;
Step 1: Removing it from the game&lt;br /&gt;
&lt;br /&gt;
* Navigate to My Documents\Bioware\AddIns&lt;br /&gt;
* Delete the folder called rcfMeep&lt;br /&gt;
* Done&lt;br /&gt;
&lt;br /&gt;
Removing from the game is fairly easy.  The toolset?  Not so much.  The reason for this is that the information is stored in the SQL Database.  Now if you just want to remove the module from the Manage Modules list, that is easy.&lt;br /&gt;
&lt;br /&gt;
* Open Sql Server Management Studio Express.  I'm not sure if the default installation installs this or not.  If not, it can be downloaded from Microsoft.&lt;br /&gt;
* Connect to the BWDATOOLSET server, assuming that you kept the default options.&lt;br /&gt;
* Expand Databases&lt;br /&gt;
* Expand bw_dragonage_content&lt;br /&gt;
* Expand Tables&lt;br /&gt;
* Right click and select open on the dbo.Modules table&lt;br /&gt;
* This will bring up an excell-like window.  Find your module, right-click on the row, and select delete.  Say ok to the confirmation.&lt;br /&gt;
* Module is now PERMANENTLY removed.  Absolutely no way of recovering it.&lt;br /&gt;
&lt;br /&gt;
Now depending on the size of the Module, you just orphaned a bunch of resources.  Areas, placables, conversations, they all get placed into the database.  And once you remove the module ID, you just lost your ability to remove these resources.  Now do keep in mind that 95% of this junk is just text, so it hardly takes up any room.  It's not really a major issue.  However if you [[How-tos#Delete resources|delete out the resources]] within the toolset before you remove the module reference you should avoid this.&lt;br /&gt;
&lt;br /&gt;
== Override Events (e.g. those in player_core) ==&lt;br /&gt;
Look here: [[Event override]]&lt;br /&gt;
&lt;br /&gt;
== Create a lootable placeable that vanishes when looted ==&lt;br /&gt;
&lt;br /&gt;
For a player-usable placeable, use the following event script to make it give its contents to the player and then vanish when clicked on.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
event ev = GetCurrentEvent();&lt;br /&gt;
int nEventType = GetEventType(ev);&lt;br /&gt;
    switch (nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_USE:&lt;br /&gt;
        {&lt;br /&gt;
        //MoveAllItems(OBJECT_SELF, GetHero());&lt;br /&gt;
        AddCreatureMoney (1000000, GetHero(), TRUE);&lt;br /&gt;
        Safe_Destroy_Object(OBJECT_SELF);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you wanted to use standard resources you could achieve the same thing (though not destroying the placeable) simply by adding &amp;quot;_autoloot&amp;quot; to the end of the placeable's tag.&lt;br /&gt;
&lt;br /&gt;
== Move the player to a new area after a cutscene plays ==&lt;br /&gt;
&lt;br /&gt;
Stand-alone cutscenes have an &amp;quot;end script&amp;quot; parameter that sets a script to run once the cutscene ends. Use a script such as the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
   DoAreaTransition(&amp;quot;destination_area_tag&amp;quot;, &amp;quot;destination_waypoint_tag&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
[[category:tutorials]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=2DA_ranges_in_use&amp;diff=8636</id>
		<title>2DA ranges in use</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=2DA_ranges_in_use&amp;diff=8636"/>
				<updated>2009-12-08T22:16:51Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is meant to enumerate row ID ranges that are used by the main game and by various popular addins, to avoid accidental overlap. Note that there's no need for 2DA row IDs to be sequential, so you can use very large row ID numbers to reduce the chances of collision.&lt;br /&gt;
&lt;br /&gt;
Version 1.0 of the toolset has a bug in ExcelProcessor.exe that causes row IDs to become inaccurate when larger than 8 million. This bug will be fixed in the next release of the toolset.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== ABI_base ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range&lt;br /&gt;
! Used by&lt;br /&gt;
|-&lt;br /&gt;
| '''0-200262'''&lt;br /&gt;
| '''Bioware - Main campaign'''&lt;br /&gt;
|-&lt;br /&gt;
| '''0-1000000'''&lt;br /&gt;
| '''Bioware - reserved'''&lt;br /&gt;
|-&lt;br /&gt;
| 568000-568020&lt;br /&gt;
| Phaenan's [http://social.bioware.com/project/672/ The Winter Forge] (Currently 6 used rows)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== APR_base ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range&lt;br /&gt;
! Used by&lt;br /&gt;
|-&lt;br /&gt;
| '''0-90'''&lt;br /&gt;
| '''Bioware - Main campaign'''&lt;br /&gt;
|-&lt;br /&gt;
| '''0-1000000'''&lt;br /&gt;
| '''Bioware - reserved'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== crafting_recipe_types ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range&lt;br /&gt;
! Used by&lt;br /&gt;
|-&lt;br /&gt;
| '''0-7'''&lt;br /&gt;
| '''Bioware - Main campaign'''&lt;br /&gt;
|-&lt;br /&gt;
| '''0-1000000'''&lt;br /&gt;
| '''Bioware - reserved'''&lt;br /&gt;
|-&lt;br /&gt;
| 568000-568010&lt;br /&gt;
| Phaenan's [http://social.bioware.com/project/672/ The Winter Forge] (Currently 2 used rows)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== crafting_recipes ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range&lt;br /&gt;
! Used by&lt;br /&gt;
|-&lt;br /&gt;
| '''0-91'''&lt;br /&gt;
| '''Bioware - Main campaign'''&lt;br /&gt;
|-&lt;br /&gt;
| '''0-1000000'''&lt;br /&gt;
| '''Bioware - reserved'''&lt;br /&gt;
|-&lt;br /&gt;
| 568000-568999&lt;br /&gt;
| Phaenan's [http://social.bioware.com/project/672/ The Winter Forge] (Currently 326 used rows)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== M2DA_base ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range&lt;br /&gt;
! Used by&lt;br /&gt;
|-&lt;br /&gt;
| '''0-1016, 2000-2010, 10011-10142, ...? '''&lt;br /&gt;
| '''Bioware - Main campaign'''&lt;br /&gt;
|-&lt;br /&gt;
| '''0-1000000'''&lt;br /&gt;
| '''Bioware - reserved'''&lt;br /&gt;
|-&lt;br /&gt;
| 7000000 - 7000050&lt;br /&gt;
| FtG - [http://social.bioware.com/project/567/ Ongoing UI Mod Project] &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== PRCSCR ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range&lt;br /&gt;
! Used by&lt;br /&gt;
|-&lt;br /&gt;
| '''0-1000000'''&lt;br /&gt;
| '''Bioware - reserved'''&lt;br /&gt;
|-&lt;br /&gt;
| 86568000-86568010&lt;br /&gt;
| Phaenan's [http://social.bioware.com/project/672/ The Winter Forge] (Currently 3 used rows)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== placeable_types ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range&lt;br /&gt;
! Used by&lt;br /&gt;
|-&lt;br /&gt;
| '''0-1000000'''&lt;br /&gt;
| '''Bioware - reserved'''&lt;br /&gt;
|-&lt;br /&gt;
| 6549-6700&lt;br /&gt;
| PavelNovotny - [http://social.bioware.com/project/517/ Gay Bars of Ferelden]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:2DAs]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=2DA_ranges_in_use&amp;diff=8635</id>
		<title>2DA ranges in use</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=2DA_ranges_in_use&amp;diff=8635"/>
				<updated>2009-12-08T22:16:14Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is meant to enumerate row ID ranges that are used by the main game and by various popular addins, to avoid accidental overlap. Note that there's no need for 2DA row IDs to be sequential, so you can use very large row ID numbers to reduce the chances of collision.&lt;br /&gt;
&lt;br /&gt;
Version 1.0 of the toolset has a bug in ExcelProcessor.exe that causes row IDs to become inaccurate when larger than 8 million. This bug will be fixed in the next release of the toolset.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== ABI_base ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range&lt;br /&gt;
! Used by&lt;br /&gt;
|-&lt;br /&gt;
| '''0-200262'''&lt;br /&gt;
| '''Bioware - Main campaign'''&lt;br /&gt;
|-&lt;br /&gt;
| '''0-1000000'''&lt;br /&gt;
| '''Bioware - reserved'''&lt;br /&gt;
|-&lt;br /&gt;
| 568000-568020&lt;br /&gt;
| Phaenan's [http://social.bioware.com/project/672/ The Winter Forge] (Currently 6 used rows)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== APR_base ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range&lt;br /&gt;
! Used by&lt;br /&gt;
|-&lt;br /&gt;
| '''0-90'''&lt;br /&gt;
| '''Bioware - Main campaign'''&lt;br /&gt;
|-&lt;br /&gt;
| '''0-1000000'''&lt;br /&gt;
| '''Bioware - reserved'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== crafting_recipe_types ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range&lt;br /&gt;
! Used by&lt;br /&gt;
|-&lt;br /&gt;
| '''0-7'''&lt;br /&gt;
| '''Bioware - Main campaign'''&lt;br /&gt;
|-&lt;br /&gt;
| '''0-1000000'''&lt;br /&gt;
| '''Bioware - reserved'''&lt;br /&gt;
|-&lt;br /&gt;
| 568000-568010&lt;br /&gt;
| Phaenan's [http://social.bioware.com/project/672/ The Winter Forge] (Currently 2 used rows)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== crafting_recipes ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range&lt;br /&gt;
! Used by&lt;br /&gt;
|-&lt;br /&gt;
| '''0-91'''&lt;br /&gt;
| '''Bioware - Main campaign'''&lt;br /&gt;
|-&lt;br /&gt;
| '''0-1000000'''&lt;br /&gt;
| '''Bioware - reserved'''&lt;br /&gt;
|-&lt;br /&gt;
| 568000-568999&lt;br /&gt;
| Phaenan's [http://social.bioware.com/project/672/ The Winter Forge] (Currently 326 used rows)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== M2DA_base ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range&lt;br /&gt;
! Used by&lt;br /&gt;
|-&lt;br /&gt;
| '''0-1016, 2000-2010, 10011-10142, ...? '''&lt;br /&gt;
| '''Bioware - Main campaign'''&lt;br /&gt;
|-&lt;br /&gt;
| '''0-1000000'''&lt;br /&gt;
| '''Bioware - reserved'''&lt;br /&gt;
|-&lt;br /&gt;
| 7000000 - 7000050&lt;br /&gt;
| FtG - [http://social.bioware.com/project/567/ Ongoing UI Mod Project] &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== PRCSCR ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range&lt;br /&gt;
! Used by&lt;br /&gt;
|-&lt;br /&gt;
| '''0-1000000'''&lt;br /&gt;
| '''Bioware - reserved'''&lt;br /&gt;
|-&lt;br /&gt;
| 86568000-86568010&lt;br /&gt;
| Phaenan's [http://social.bioware.com/project/672/ The Winter Forge] (Currently 3 used rows)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== placeable_types ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range&lt;br /&gt;
! Used by&lt;br /&gt;
|-&lt;br /&gt;
| '''0-1000000'''&lt;br /&gt;
| '''Bioware - reserved'''&lt;br /&gt;
|-&lt;br /&gt;
| '''6549-6700'''&lt;br /&gt;
| '''PavelNovotny - [http://social.bioware.com/project/517/ Gay Bars of Ferelden]'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:2DAs]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=2DA&amp;diff=8607</id>
		<title>2DA</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=2DA&amp;diff=8607"/>
				<updated>2009-12-07T18:37:55Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Many of the properties of objects in the toolset make reference to 2DAs (two-dimensional arrays). These are read-only arrays containing various data used by scripting and the game engine. For example, the set of local variables that an object supports is defined in a 2DA.&lt;br /&gt;
&lt;br /&gt;
The source files for 2DAs are Microsoft Excel worksheets. This allows a wide variety of sophisticated techniques to be used to generate the values of the 2DA fields, such as macros and formulas. It also makes editing much easier since the columns can be annotated and formatted in helpful ways, and multiple related worksheets can be grouped into one file.&lt;br /&gt;
&lt;br /&gt;
Data in a 2DA is identified by a row number, with the first row (row zero) usually being reserved for internal use (undefined value, etc.) by convention. Each row has an arbitrary number of columns identified by strings. &lt;br /&gt;
&lt;br /&gt;
Before they can be used by the toolset or the game, 2DAs must be converted from Excel files into a more efficient form. Processed 2DAs are stored in files with the .[[GDA]] extension.&lt;br /&gt;
&lt;br /&gt;
== Excel file formatting ==&lt;br /&gt;
&lt;br /&gt;
Cell A1 will contain &amp;quot;ID&amp;quot;. This is checked by the processor and the worksheet will fail if this is not the case.&lt;br /&gt;
&lt;br /&gt;
Column A starting at line 3 will contain an integer row ID number that is unique to that row across all files (unless creating an M2DA override). Row IDs will be listed from smallest to highest within the same file and do not need to be consecutive.&lt;br /&gt;
&lt;br /&gt;
A blank row or column will determine the dimension of the spreadsheet in that direction. Everything past that point is ignored by the binarizer.&lt;br /&gt;
&lt;br /&gt;
Column names are case sensitive. This is because of the CRC32 algorithm used to generate the hash key. Changing the case of a column name after it is in use will break the game. White space before and after a column name will be removed before hashing.&lt;br /&gt;
&lt;br /&gt;
Row 2 will be a &amp;quot;types&amp;quot; row. Each is a single word: [[int]], [[string]] (single chars as well), [[resource]], [[float]] or [[bool]]. A special type &amp;quot;[[comment]]&amp;quot; can be used to exclude a column from export.&lt;br /&gt;
&lt;br /&gt;
Any column with string data that refers to files should have a type of &amp;quot;resource&amp;quot; and not &amp;quot;string&amp;quot;. This is because the &amp;quot;resource&amp;quot; type is used to determine dependencies for the 2DA file.&lt;br /&gt;
&lt;br /&gt;
'bool' type may be one of: a zero or non-zero number, Yes or No (case insensitive), or words beginning with T or F (such as True! and False!). NOTE: You cannot use TRUE and FALSE because Excel converts those to a special keyword the binarizer can't parse properly at this time. '''Note:''' the scripting language doesn't have a function for retrieving boolean values from a 2DA, and the behavior of Get2DAInt when retrieving a boolean is untested. It is probably safer to just use an integer for scripting purposes.&lt;br /&gt;
&lt;br /&gt;
If you wish to leave a cell unfilled, the string &amp;quot;****&amp;quot; (four asterisks) can be inserted instead of a value.&lt;br /&gt;
&lt;br /&gt;
Any worksheets that are not exportable 2DA data will have an underscore prepended to their name - the resource builder will subsequently ignore them.&lt;br /&gt;
&lt;br /&gt;
Worksheets need to have unique names among all excel files, duplicates will overwrite each other as each worksheet is exported as a file&lt;br /&gt;
&lt;br /&gt;
You cannot have the workbook open in Excel at the same time as running the binarizer on it.&lt;br /&gt;
&lt;br /&gt;
Strings have a maximum length of 768 characters. Anything longer will be truncated.&lt;br /&gt;
&lt;br /&gt;
ExcelProcessor.exe constrains the name length of a worksheet to 27 characters. &lt;br /&gt;
&lt;br /&gt;
== Extending the game via M2DAs ==&lt;br /&gt;
&lt;br /&gt;
An &amp;quot;M2DA&amp;quot; is a &amp;quot;Multiple 2DA&amp;quot; that stacks a number of 2DA files into one larger table. They work much like single 2DA files except they can be patched or expanded later by adding more resources. These are useful for any table that lists other resources, such as appearance tables, so that new resources can be added later without having to modify a monolithic table.&lt;br /&gt;
&lt;br /&gt;
This is especially important for third-party modders, since BioWare might release an update to a core table at a later date that would overwrite any changes third parties had made to it. By using an M2DA with a unique name, and by using a range of ID numbers significantly separated from those already in use, you can ensure that your additions won't conflict with other portions of the M2DA.&lt;br /&gt;
&lt;br /&gt;
A list of all M2DAs used by the game can be found in [[2DA_base.xls]]. Every 2da listed in M2DA_base is treated as a M2DA, except for those with an ID between 10000 and 10999 which are handled as regular 2DAs. Each M2DA has a label that describes the subject covered by the M2DA and a worksheet prefix that all components of that M2DA must use.&lt;br /&gt;
&lt;br /&gt;
Every worksheet listed in the [[2DA_base.xls]] file is actually a prefix. The system reads this prefix and then searches through all the 2DAs for the ones starting with this prefix and merges them together as one 2DA. For example: M2DA Id 0 is &amp;quot;ANIM_&amp;quot;. The system looks through its list of 2das and finds &amp;quot;ANIM_base&amp;quot;, &amp;quot;ANIM_combat&amp;quot; and &amp;quot;ANIM_walk&amp;quot;. It will read and merge all 3 2DAs into an M2DA called &amp;quot;ANIM_&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Not all of the prefixes end in an underscore. For example, longsword variations are in worksheets prefixed with &amp;quot;longsword_variation&amp;quot;, so both &amp;quot;longsword_variation_candyland&amp;quot; and &amp;quot;longsword_variationcandyland&amp;quot; would work as M2DA worksheet names.&lt;br /&gt;
&lt;br /&gt;
2DAs are merged row by row, keyed on the ID column. If two rows in two different 2DAs to be merged have the same ID, the row in the 2da with the highest priority wins.&lt;br /&gt;
&lt;br /&gt;
== Converting XLS files into 2DA files ==&lt;br /&gt;
&lt;br /&gt;
In the &amp;quot;Dragon Age\tools\ResourceBuild\Processors&amp;quot; folder there is an executable named &amp;quot;ExcelProcessor.exe&amp;quot;. This is the file that handles conversions from XLS to 2DA format. Below are described 3 ways in which this file may be used.&lt;br /&gt;
&lt;br /&gt;
=== Drag &amp;amp; Drop Method ===&lt;br /&gt;
&lt;br /&gt;
# Copy ExcelProcessor.exe and source .XLS files to a new directory (not explicitly neccessary, but advised)&lt;br /&gt;
# Select source .XLS files and drag them onto ExcelProcessor.exe&lt;br /&gt;
# Cut &amp;amp; Paste resulting .2DA files, which will be located in the same directory as the source .XLS files, to your desired location (usually to &amp;quot;My Documents\BioWare\Dragon Age\AddIns\yourmodulename\module\overrides\&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Adding 2DA export to the Windows XP file explorer ===&lt;br /&gt;
&lt;br /&gt;
Here's an easy way to add a context (ie, right-click) menu item that quickly converts new or updated Dragon Age Excel files into GDA format: &lt;br /&gt;
&lt;br /&gt;
Setup: &lt;br /&gt;
&lt;br /&gt;
# Open Windows Explorer and click Tools | Folder Options.&lt;br /&gt;
# In the File Types tab, select the XLS extension from the list and click the Advanced button.&lt;br /&gt;
# Click the New button and put 'Binarize 2DA' in the Action field.&lt;br /&gt;
# Paste the following in the Application field and click OK (update the drive and folder names to match your client): &amp;lt;tt&amp;gt;C:\DA\tag\main\ResourceBuild\Processors\ExcelProcessor.exe  &amp;quot;%l&amp;quot;  -outdir=C:\DA\tag\main\build\packages\core\override&amp;lt;/tt&amp;gt;&lt;br /&gt;
## For the Steam version, use the following: &amp;lt;tt&amp;gt;&amp;quot;C:\Program Files\Steam\steamapps\common\dragon age origins\tools\ResourceBuild\Processors\ExcelProcessor.exe&amp;quot;  &amp;quot;%1&amp;quot; -outdir=&amp;quot;C:\Documents and Settings\YOURNAME\My Documents\BioWare\Dragon Age\packages\core\override&amp;quot;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that paths with spaces in them can cause Windows trouble, if your paths have spaces in them remember to wrap them in quotation marks.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&lt;br /&gt;
# Using Windows Explorer, navigate to your 2DA folder (in my case C:\DA\tag\main\data\Source\2DA) and select the Excel file(s) to process. Right click and select 'Binarize 2DA' from the context menu. &lt;br /&gt;
# Confirm a corresponding GDA file is created in your override folder (in my case C:\DA\tag\main\build\packages\core\override) for each Excel file processed.&lt;br /&gt;
&lt;br /&gt;
=== Using a .BAT file ===&lt;br /&gt;
&lt;br /&gt;
If you have problems using the 2daExporter.xls spreadsheet to generate 2DAs the following method may work instead:&lt;br /&gt;
&lt;br /&gt;
*Create two folders called C:\2DA\ and C:\2DA\Override\&lt;br /&gt;
*Copy ExcelProcessor.exe to C:\2DA\&lt;br /&gt;
*Copy the Excel spreadsheets containing the 2DA you want to use in the game to C:\2DA\&lt;br /&gt;
*Create a batch file with the following line in it (change &amp;quot;placeables.xls&amp;quot; to whatever Excel file you're working with):&lt;br /&gt;
C:\2DA\ExcelProcessor.exe placeables.xls -outdir=C:\2DA\override\&lt;br /&gt;
*Run your batch file&lt;br /&gt;
*Find the GDA file from the C:\2DA\Override\ directory and copy it to the game's override directory. Remember to take into account the naming conventions of M2DAs; you may need to rename your 2DA files with a new suffix unique to your module to allow it to add to the core 2DAs without conflict.&lt;br /&gt;
&lt;br /&gt;
== 2DA XLS files used in Dragon Age ==&lt;br /&gt;
&lt;br /&gt;
''Note: This list is very incomplete right now''&lt;br /&gt;
&lt;br /&gt;
Bear in mind that 2DAs names are actually based on the names of the worksheets inside these Excel files, not the names of the files themselves. Some of these files contain a large number of individual 2DAs within them. They are bundled together into Excel files based on the nature of the 2DAs for convenience.&lt;br /&gt;
&lt;br /&gt;
=== Creatures ===&lt;br /&gt;
&lt;br /&gt;
*[[APR_base.xls]] - appearance types for creatures&lt;br /&gt;
*[[ABI_base.xls]] - integrates all talents and spells into the game&lt;br /&gt;
*[[ANIM_base.xls]]&lt;br /&gt;
*[[ANIM_combat.xls]]&lt;br /&gt;
*[[ANIM placeables.xls]]&lt;br /&gt;
*[[SyncAnimations.xls]]&lt;br /&gt;
*[[CLA_base.xls]] - Defines the character classes used throughout the game&lt;br /&gt;
*[[background.xls]] - defines the various origin stories available to each race and class.&lt;br /&gt;
&lt;br /&gt;
=== Objects ===&lt;br /&gt;
*[[placeables.xls]] - interactive object types&lt;br /&gt;
*[[BITM base.xls]] - item types&lt;br /&gt;
*[[ItemVariations.xls]] - item appearance variations (eg, all the different ways a longsword can look)&lt;br /&gt;
*[[PRJ_base.xls]] - how various projectiles look and behave&lt;br /&gt;
*[[VFX_base.xls]] - Visual effects&lt;br /&gt;
&lt;br /&gt;
=== Areas and plots ===&lt;br /&gt;
&lt;br /&gt;
*[[worldmaps.xls]] - world maps for open-ended travel between areas&lt;br /&gt;
*[[plottypes.xls]] - how plots are grouped at the highest level in the game GUI (codex entry types, story, etc.)&lt;br /&gt;
*[[areadata.xls]] - sets various properties for specific areas&lt;br /&gt;
*[[rewards.xls]] - rewards for plot completion&lt;br /&gt;
&lt;br /&gt;
=== Adding to the official campaign ===&lt;br /&gt;
*[[PRCSCR]] - specifies scripts to run when an area or area list is loaded or entered.&lt;br /&gt;
&lt;br /&gt;
== Adding Strings ==&lt;br /&gt;
&lt;br /&gt;
When adding strings to a 2DA, you have two options.  The simplest is to enter **** for the StringID column.  In that case, the name column will be used in the game.&lt;br /&gt;
&lt;br /&gt;
The other approach is to use the toolset's string editor to create a new string.  When that happens, you'll get a new StringID. Next enter that number into the StringID column in the 2DA.&lt;br /&gt;
&lt;br /&gt;
The second approach works better when translating your module, at the cost of portability.  If someone else wanted to reuse your 2DA, they'd have to generate their own strings, then update the StringID number based on these IDs.&lt;br /&gt;
&lt;br /&gt;
'''Attention:'''&lt;br /&gt;
&lt;br /&gt;
* The current version of the &amp;quot;Exelprocessor&amp;quot;-App is buggy as it can't hanlde INT values above 8388607! Many thx to elys for figuring that out.&lt;br /&gt;
* Also note that the current toolset core-talktable contains wrong ids as well - don't forget to delete it from the &amp;quot;packages\core\override\toolsetexport&amp;quot; directory.&lt;br /&gt;
&lt;br /&gt;
'''Workaround:'''&lt;br /&gt;
&lt;br /&gt;
* Create and export your talktable, delete the core-talktable override.&lt;br /&gt;
* Create your M2DA File that you want to refer to your talk-table strings. Never Mind using the real IDs at this stage.&lt;br /&gt;
* Use the &amp;quot;Exelprocessor&amp;quot; to create the GDA file.&lt;br /&gt;
* Open the GDA-File with the toolset or elys's GDA-Editor App (http://social.bioware.com/project/755/)&lt;br /&gt;
[[File:Edit-GDA-Values.jpg]]&lt;br /&gt;
* Change the StringIDs to the StringIDs in your talktable.&lt;br /&gt;
&lt;br /&gt;
'''Remark:''' &lt;br /&gt;
&lt;br /&gt;
The previous Version stated: ''Take that StringID and add 16777216 to the number.'' this appears to be wrong and is likely a holdover from NWN.&lt;br /&gt;
&lt;br /&gt;
== Reserved ID Ranges ==&lt;br /&gt;
&lt;br /&gt;
While M2DA files avoid some of the problems associated with ordinary 2DA files, the IDs in each row of the final M2DA must still be unique across all 2DAs associated with it.&lt;br /&gt;
&lt;br /&gt;
To help ensure compatibility between authors' custom content, you should make sure that the ranges you choose don't conflict with ones already in use: [[2DA_ranges_in_use]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Users of Open Office ==&lt;br /&gt;
* Users of Open Office may find that no .gda file is created when they use ExcelProcessor.exe - one workaround is to copy a worksheet from an existing .xls file (such as placeable_types from placeables.xls), process the file, then remove the extraneous .gds file (e.g. placeable_types.gda).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:2DAs]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=PRCSCR.xls&amp;diff=8606</id>
		<title>PRCSCR.xls</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=PRCSCR.xls&amp;diff=8606"/>
				<updated>2009-12-07T17:27:54Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Whenever a player enters an area in an area list in this M2DA the associated script will be run. A modder can therefore include a script with his mod that will be run when the player enters an existing area that he didn't create. This script can freely add or remove placeables and creatures and perform whatever other modifications to the area that a script is capable of doing.&lt;br /&gt;
&lt;br /&gt;
Note that the script will be run every time the player enters the area, so you'll want to have an associated plot flag to ensure that the changes are only made once. &lt;br /&gt;
&lt;br /&gt;
{{2da start|PRCSCR_}}&lt;br /&gt;
{{2da column|AreaListName|string|a string that identifies a specific area list, or the special keyword &amp;quot;any&amp;quot;.}}&lt;br /&gt;
{{2da column|Script|string|the name of a script file to run}}&lt;br /&gt;
{{2da end}}&lt;br /&gt;
&lt;br /&gt;
Using &amp;quot;any&amp;quot; in the AreaListName column will trigger the specified script when entering or loading any area.&lt;br /&gt;
&lt;br /&gt;
[[Category:2DAs]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=2DA&amp;diff=8605</id>
		<title>2DA</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=2DA&amp;diff=8605"/>
				<updated>2009-12-07T17:24:04Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Many of the properties of objects in the toolset make reference to 2DAs (two-dimensional arrays). These are read-only arrays containing various data used by scripting and the game engine. For example, the set of local variables that an object supports is defined in a 2DA.&lt;br /&gt;
&lt;br /&gt;
The source files for 2DAs are Microsoft Excel worksheets. This allows a wide variety of sophisticated techniques to be used to generate the values of the 2DA fields, such as macros and formulas. It also makes editing much easier since the columns can be annotated and formatted in helpful ways, and multiple related worksheets can be grouped into one file.&lt;br /&gt;
&lt;br /&gt;
Data in a 2DA is identified by a row number, with the first row (row zero) usually being reserved for internal use (undefined value, etc.) by convention. Each row has an arbitrary number of columns identified by strings. &lt;br /&gt;
&lt;br /&gt;
Before they can be used by the toolset or the game, 2DAs must be converted from Excel files into a more efficient form. Processed 2DAs are stored in files with the .[[GDA]] extension.&lt;br /&gt;
&lt;br /&gt;
== Excel file formatting ==&lt;br /&gt;
&lt;br /&gt;
Cell A1 will contain &amp;quot;ID&amp;quot;. This is checked by the processor and the worksheet will fail if this is not the case.&lt;br /&gt;
&lt;br /&gt;
Column A starting at line 3 will contain an integer row ID number that is unique to that row across all files (unless creating an M2DA override). Row IDs will be listed from smallest to highest within the same file and do not need to be consecutive.&lt;br /&gt;
&lt;br /&gt;
A blank row or column will determine the dimension of the spreadsheet in that direction. Everything past that point is ignored by the binarizer.&lt;br /&gt;
&lt;br /&gt;
Column names are case sensitive. This is because of the CRC32 algorithm used to generate the hash key. Changing the case of a column name after it is in use will break the game. White space before and after a column name will be removed before hashing.&lt;br /&gt;
&lt;br /&gt;
Row 2 will be a &amp;quot;types&amp;quot; row. Each is a single word: [[int]], [[string]] (single chars as well), [[resource]], [[float]] or [[bool]]. A special type &amp;quot;[[comment]]&amp;quot; can be used to exclude a column from export.&lt;br /&gt;
&lt;br /&gt;
Any column with string data that refers to files should have a type of &amp;quot;resource&amp;quot; and not &amp;quot;string&amp;quot;. This is because the &amp;quot;resource&amp;quot; type is used to determine dependencies for the 2DA file.&lt;br /&gt;
&lt;br /&gt;
'bool' type may be one of: a zero or non-zero number, Yes or No (case insensitive), or words beginning with T or F (such as True! and False!). NOTE: You cannot use TRUE and FALSE because Excel converts those to a special keyword the binarizer can't parse properly at this time. '''Note:''' the scripting language doesn't have a function for retrieving boolean values from a 2DA, and the behavior of Get2DAInt when retrieving a boolean is untested. It is probably safer to just use an integer for scripting purposes.&lt;br /&gt;
&lt;br /&gt;
If you wish to leave a cell unfilled, the string &amp;quot;****&amp;quot; (four asterisks) can be inserted instead of a value.&lt;br /&gt;
&lt;br /&gt;
Any worksheets that are not exportable 2DA data will have an underscore prepended to their name - the resource builder will subsequently ignore them.&lt;br /&gt;
&lt;br /&gt;
Worksheets need to have unique names among all excel files, duplicates will overwrite each other as each worksheet is exported as a file&lt;br /&gt;
&lt;br /&gt;
You cannot have the workbook open in Excel at the same time as running the binarizer on it.&lt;br /&gt;
&lt;br /&gt;
Strings have a maximum length of 768 characters. Anything longer will be truncated.&lt;br /&gt;
&lt;br /&gt;
ExcelProcessor.exe constrains the name length of a worksheet to 27 characters. &lt;br /&gt;
&lt;br /&gt;
== Extending the game via M2DAs ==&lt;br /&gt;
&lt;br /&gt;
An &amp;quot;M2DA&amp;quot; is a &amp;quot;Multiple 2DA&amp;quot; that stacks a number of 2DA files into one larger table. They work much like single 2DA files except they can be patched or expanded later by adding more resources. These are useful for any table that lists other resources, such as appearance tables, so that new resources can be added later without having to modify a monolithic table.&lt;br /&gt;
&lt;br /&gt;
This is especially important for third-party modders, since BioWare might release an update to a core table at a later date that would overwrite any changes third parties had made to it. By using an M2DA with a unique name, and by using a range of ID numbers significantly separated from those already in use, you can ensure that your additions won't conflict with other portions of the M2DA.&lt;br /&gt;
&lt;br /&gt;
A list of all M2DAs used by the game can be found in [[2DA_base.xls]]. Every 2da listed in M2DA_base is treated as a M2DA, except for those with an ID between 10000 and 10999 which are handled as regular 2DAs. Each M2DA has a label that describes the subject covered by the M2DA and a worksheet prefix that all components of that M2DA must use.&lt;br /&gt;
&lt;br /&gt;
Every worksheet listed in the [[2DA_base.xls]] file is actually a prefix. The system reads this prefix and then searches through all the 2DAs for the ones starting with this prefix and merges them together as one 2DA. For example: M2DA Id 0 is &amp;quot;ANIM_&amp;quot;. The system looks through its list of 2das and finds &amp;quot;ANIM_base&amp;quot;, &amp;quot;ANIM_combat&amp;quot; and &amp;quot;ANIM_walk&amp;quot;. It will read and merge all 3 2DAs into an M2DA called &amp;quot;ANIM_&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Not all of the prefixes end in an underscore. For example, longsword variations are in worksheets prefixed with &amp;quot;longsword_variation&amp;quot;, so both &amp;quot;longsword_variation_candyland&amp;quot; and &amp;quot;longsword_variationcandyland&amp;quot; would work as M2DA worksheet names.&lt;br /&gt;
&lt;br /&gt;
2DAs are merged row by row, keyed on the ID column. If two rows in two different 2DAs to be merged have the same ID, the row in the 2da with the highest priority wins.&lt;br /&gt;
&lt;br /&gt;
== Converting XLS files into 2DA files ==&lt;br /&gt;
&lt;br /&gt;
In the &amp;quot;Dragon Age\tools\ResourceBuild\Processors&amp;quot; folder there is an executable named &amp;quot;ExcelProcessor.exe&amp;quot;. This is the file that handles conversions from XLS to 2DA format. Below are described 3 ways in which this file may be used.&lt;br /&gt;
&lt;br /&gt;
=== Drag &amp;amp; Drop Method ===&lt;br /&gt;
&lt;br /&gt;
# Copy ExcelProcessor.exe and source .XLS files to a new directory (not explicitly neccessary, but advised)&lt;br /&gt;
# Select source .XLS files and drag them onto ExcelProcessor.exe&lt;br /&gt;
# Cut &amp;amp; Paste resulting .2DA files, which will be located in the same directory as the source .XLS files, to your desired location (usually to &amp;quot;My Documents\BioWare\Dragon Age\AddIns\yourmodulename\module\overrides\&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Adding 2DA export to the Windows XP file explorer ===&lt;br /&gt;
&lt;br /&gt;
Here's an easy way to add a context (ie, right-click) menu item that quickly converts new or updated Dragon Age Excel files into GDA format: &lt;br /&gt;
&lt;br /&gt;
Setup: &lt;br /&gt;
&lt;br /&gt;
# Open Windows Explorer and click Tools | Folder Options.&lt;br /&gt;
# In the File Types tab, select the XLS extension from the list and click the Advanced button.&lt;br /&gt;
# Click the New button and put 'Binarize 2DA' in the Action field.&lt;br /&gt;
# Paste the following in the Application field and click OK (update the drive and folder names to match your client): &amp;lt;tt&amp;gt;C:\DA\tag\main\ResourceBuild\Processors\ExcelProcessor.exe  &amp;quot;%l&amp;quot;  -outdir=C:\DA\tag\main\build\packages\core\override&amp;lt;/tt&amp;gt;&lt;br /&gt;
## For the Steam version, use the following: &amp;lt;tt&amp;gt;&amp;quot;C:\Program Files\Steam\steamapps\common\dragon age origins\tools\ResourceBuild\Processors\ExcelProcessor.exe&amp;quot;  &amp;quot;%1&amp;quot; -outdir=&amp;quot;C:\Documents and Settings\YOURNAME\My Documents\BioWare\Dragon Age\packages\core\override&amp;quot;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that paths with spaces in them can cause Windows trouble, if your paths have spaces in them remember to wrap them in quotation marks.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&lt;br /&gt;
# Using Windows Explorer, navigate to your 2DA folder (in my case C:\DA\tag\main\data\Source\2DA) and select the Excel file(s) to process. Right click and select 'Binarize 2DA' from the context menu. &lt;br /&gt;
# Confirm a corresponding GDA file is created in your override folder (in my case C:\DA\tag\main\build\packages\core\override) for each Excel file processed.&lt;br /&gt;
&lt;br /&gt;
=== Using a .BAT file ===&lt;br /&gt;
&lt;br /&gt;
If you have problems using the 2daExporter.xls spreadsheet to generate 2DAs the following method may work instead:&lt;br /&gt;
&lt;br /&gt;
*Create two folders called C:\2DA\ and C:\2DA\Override\&lt;br /&gt;
*Copy ExcelProcessor.exe to C:\2DA\&lt;br /&gt;
*Copy the Excel spreadsheets containing the 2DA you want to use in the game to C:\2DA\&lt;br /&gt;
*Create a batch file with the following line in it (change &amp;quot;placeables.xls&amp;quot; to whatever Excel file you're working with):&lt;br /&gt;
C:\2DA\ExcelProcessor.exe placeables.xls -outdir=C:\2DA\override\&lt;br /&gt;
*Run your batch file&lt;br /&gt;
*Find the GDA file from the C:\2DA\Override\ directory and copy it to the game's override directory. Remember to take into account the naming conventions of M2DAs; you may need to rename your 2DA files with a new suffix unique to your module to allow it to add to the core 2DAs without conflict.&lt;br /&gt;
&lt;br /&gt;
== 2DA XLS files used in Dragon Age ==&lt;br /&gt;
&lt;br /&gt;
''Note: This list is very incomplete right now''&lt;br /&gt;
&lt;br /&gt;
Bear in mind that 2DAs names are actually based on the names of the worksheets inside these Excel files, not the names of the files themselves. Some of these files contain a large number of individual 2DAs within them. They are bundled together into Excel files based on the nature of the 2DAs for convenience.&lt;br /&gt;
&lt;br /&gt;
=== Creatures ===&lt;br /&gt;
&lt;br /&gt;
*[[APR_base.xls]] - appearance types for creatures&lt;br /&gt;
*[[ABI_base.xls]] - integrates all talents and spells into the game&lt;br /&gt;
*[[ANIM_base.xls]]&lt;br /&gt;
*[[ANIM_combat.xls]]&lt;br /&gt;
*[[ANIM placeables.xls]]&lt;br /&gt;
*[[SyncAnimations.xls]]&lt;br /&gt;
*[[CLA_base.xls]] - Defines the character classes used throughout the game&lt;br /&gt;
*[[background.xls]] - defines the various origin stories available to each race and class.&lt;br /&gt;
&lt;br /&gt;
=== Objects ===&lt;br /&gt;
*[[placeables.xls]] - interactive object types&lt;br /&gt;
*[[BITM base.xls]] - item types&lt;br /&gt;
*[[ItemVariations.xls]] - item appearance variations (eg, all the different ways a longsword can look)&lt;br /&gt;
*[[PRJ_base.xls]] - how various projectiles look and behave&lt;br /&gt;
*[[VFX_base.xls]] - Visual effects&lt;br /&gt;
&lt;br /&gt;
=== Areas and plots ===&lt;br /&gt;
&lt;br /&gt;
*[[worldmaps.xls]] - world maps for open-ended travel between areas&lt;br /&gt;
*[[plottypes.xls]] - how plots are grouped at the highest level in the game GUI (codex entry types, story, etc.)&lt;br /&gt;
*[[areadata.xls]] - sets various properties for specific areas&lt;br /&gt;
*[[rewards.xls]] - rewards for plot completion&lt;br /&gt;
&lt;br /&gt;
=== Adding to the official campaign ===&lt;br /&gt;
*[[PRCSCR]] - specifies scripts to run when an area or area list is loaded or entered.&lt;br /&gt;
&lt;br /&gt;
== Adding Strings ==&lt;br /&gt;
&lt;br /&gt;
When adding strings to a 2DA, you have two options.  The simplest is to enter **** for the StringID column.  In that case, the name column will be used in the game.&lt;br /&gt;
&lt;br /&gt;
The other approach is to use the toolset's string editor to create a new string.  When that happens, you'll get a new StringID. Next enter that number into the StringID column in the 2DA.&lt;br /&gt;
&lt;br /&gt;
The second approach works better when translating your module, at the cost of portability.  If someone else wanted to reuse your 2DA, they'd have to generate their own strings, then update the StringID number based on these IDs.&lt;br /&gt;
&lt;br /&gt;
'''Attention:'''&lt;br /&gt;
&lt;br /&gt;
* The current version of the &amp;quot;Exelprocessor&amp;quot;-App is buggy as it can't hanlde INT values above 8388607! Many thx to elys for figuring that out.&lt;br /&gt;
* Also note that the current toolset core-talktable contains wrong ids as well - don't forget to delete it from the &amp;quot;packages\core\override\toolsetexport&amp;quot; directory.&lt;br /&gt;
* Users of Open Office may find that no .gda file is created when they use ExcelProcessor.exe - one workaround is to copy a worksheet from an existing .xls file (such as placeable_types from placeables.xls), process the file, then remove the extraneous .gds file (e.g. placeable_types.gda).&lt;br /&gt;
&lt;br /&gt;
'''Workaround:'''&lt;br /&gt;
&lt;br /&gt;
* Create and export your talktable, delete the core-talktable override.&lt;br /&gt;
* Create your M2DA File that you want to refer to your talk-table strings. Never Mind using the real IDs at this stage.&lt;br /&gt;
* Use the &amp;quot;Exelprocessor&amp;quot; to create the GDA file.&lt;br /&gt;
* Open the GDA-File with the toolset or elys's GDA-Editor App (http://social.bioware.com/project/755/)&lt;br /&gt;
[[File:Edit-GDA-Values.jpg]]&lt;br /&gt;
* Change the StringIDs to the StringIDs in your talktable.&lt;br /&gt;
&lt;br /&gt;
'''Remark:''' &lt;br /&gt;
&lt;br /&gt;
The previous Version stated: ''Take that StringID and add 16777216 to the number.'' this appears to be wrong and is likely a holdover from NWN.&lt;br /&gt;
&lt;br /&gt;
== Reserved ID Ranges ==&lt;br /&gt;
&lt;br /&gt;
While M2DA files avoid some of the problems associated with ordinary 2DA files, the IDs in each row of the final M2DA must still be unique across all 2DAs associated with it.&lt;br /&gt;
&lt;br /&gt;
To help ensure compatibility between authors' custom content, you should make sure that the ranges you choose don't conflict with ones already in use: [[2DA_ranges_in_use]].&lt;br /&gt;
&lt;br /&gt;
[[Category:2DAs]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=Area_tutorial&amp;diff=5209</id>
		<title>Area tutorial</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=Area_tutorial&amp;diff=5209"/>
				<updated>2009-09-09T20:48:25Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Once you have created a new module (see [[creating a module]]), the first thing you will likely want to do is create one or more areas where your adventure is going to be set.&lt;br /&gt;
&lt;br /&gt;
== Creating the area ==&lt;br /&gt;
&lt;br /&gt;
[[Image:New resource.png|thumb|New resource menu]]&lt;br /&gt;
&lt;br /&gt;
There are several ways to reach the &amp;quot;new area&amp;quot; command; you can right-click on the resource palette window, or select &amp;quot;new&amp;quot; from the file menu.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Areas are represented with the [[Image:IconArea.png]] icon. When you select it you'll be presented with a &amp;quot;Create New Resource&amp;quot; window:&lt;br /&gt;
&lt;br /&gt;
[[Image:Create new resource.png|center|]]&lt;br /&gt;
&lt;br /&gt;
{{sidebox|&lt;br /&gt;
* Resref names should be useful to the designer&lt;br /&gt;
* Set the &amp;quot;area layout&amp;quot; property to assign terrain to an area&lt;br /&gt;
* &amp;quot;Resource Name&amp;quot; and &amp;quot;Tag&amp;quot; are only seen by developers&lt;br /&gt;
* &amp;quot;Name&amp;quot; may be seen by players&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Most of the fields are already filled in with good defaults for the module you're working with. You'll need to supply a &amp;quot;ResRef Name&amp;quot;, which is the name by which the resource will be known internally to the toolset. (This is the &amp;quot;Name&amp;quot; field on the &amp;quot;Create New Resource&amp;quot; dialog box.) You'll probably want to use a name that will remind you, the module designer, of the purpose or important features of the area. Changing a resource's name is difficult to do later. We're going to call the first area of the tutorial &amp;quot;hut_exterior&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
After creating the area you'll be presented with a completely blank area editor. There will be no environment or objects of any kind. To specify what environment you'll be placing objects into, open the object inspector and select the &amp;quot;Area Layout&amp;quot; property. There will be an ellipsis button ([[Image:ellipsis.png]]) in the property's data field that will bring up a resource selection window where you can select an environment to use for this area. The environment we wish to select is in the area layout file &amp;quot;ost101d.arl&amp;quot;. Once we select it, the area layout appears in the main area window.&lt;br /&gt;
&lt;br /&gt;
The resource's internal resource name is hut_exterior but the player will not see this when he's playing the game. To give the area a name meaningful to the player we'll set the &amp;quot;Name&amp;quot; field to &amp;quot;Deep in the Swamp&amp;quot;. All of the other defaults are fine for now, we will leave them as is.&lt;br /&gt;
&lt;br /&gt;
[[Image:Area tutorial 1.png|thumb|600px|center]]&lt;br /&gt;
&lt;br /&gt;
== Area Basics ==&lt;br /&gt;
{{sidebox|&lt;br /&gt;
* See [[3D control]] for camera and movement controls&lt;br /&gt;
* You can double-click on an object in the area's object list to zoom in to it.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Moving the view around inside the area layout can be somewhat non-intuitive and frustrating at first. The toolset has a number of different control schemes it can be set to; see [[3D control]] for a summary of the various options. By default, you can:&lt;br /&gt;
&lt;br /&gt;
* zoom in and out by using the mouse wheel&lt;br /&gt;
* rotate the camera around the target it's focused on by holding the middle button down or by holding down the Ctrl key and the right mouse button while moving the mouse&lt;br /&gt;
* translate the camera by holding down the Ctrl key and the left mouse button while moving the mouse&lt;br /&gt;
&lt;br /&gt;
To see where you are a bit better, it is helpful to deactivate real lighting or turn on full brightness.  Above the area viewer, the sun-like button should be toggled so that it isn't highlighted; see [[Area]] for a more complete summary of various options within the Area Editor.&lt;br /&gt;
&lt;br /&gt;
Before we move along to placing a starting location, it is important to touch upon Pathfinding points.  All BioWare areas include walkmesh or pathfinding information.  To view pathfinding information for your area, goto View, then Environment, and then toggle Pathfinding Points on.  The green dots represent areas where characters can walk.  Note, in this map, the area that is walkable is quite small compared to the entire area.  When placing your starting location, you should ensure it is in a walkable portion of the area.&lt;br /&gt;
&lt;br /&gt;
== Setting the start point ==&lt;br /&gt;
&lt;br /&gt;
{{sidebox|&lt;br /&gt;
* Create a waypoint to mark where the player starts the game&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This is going to be the starting area for the adventure, so we're going to want to define a spot within the area where the player will first appear. This is done by setting a [[waypoint]]. Waypoints are very simple objects that mark locations in an area that other objects in the game can refer to; they are not normally visible to the player. To create a waypoint, right-click somewhere in the area and select &amp;quot;Insert Waypoint&amp;quot; from the resulting menu. A waypoint will appear at the location of your mouse pointer and follow it around along the area's floor; move it to the approximate place you want to have the player appear and left-click to place it. By default the waypoint is named &amp;quot;Waypoint&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The waypoint will be automatically selected, indicated by a yellow wireframe box surrounding it. You'll also see the waypoint listed in the area's object list, to the left of the display window. If you lose track of the waypoint later a good way to find it again is to right-click on the waypoint in the list and select &amp;quot;Zoom to Object&amp;quot; in the resulting menu or double click on its tag to center the object in the display window. The waypoint's properties will be shown in the object inspector. We want to change the waypoint's name to something more informative, in this case to &amp;quot;start&amp;quot;. More importantly for the game itself, though, we'll also want to change the waypoint's tag to &amp;quot;start&amp;quot; (it defaults to blank). An object's tag is how scripts and other resources will refer to the waypoint. Since this particular waypoint is never going to be visible to the player it's likely that the waypoint's name will never be seen at all.&lt;br /&gt;
&lt;br /&gt;
The player will also start out facing in the same direction that the waypoint is facing (indicated by the arrow-shaped base of the waypoint object). If we don't want the player to start out facing in the default direction, we'll want to rotate the waypoint to point in a new direction. To rotate an object, use the toolbar to switch from standard selection mode ([[Image:Standard selection mode.png]]) to 3-axis rotation mode ([[Image:3 axis rotation mode.png]]). &lt;br /&gt;
When you select the waypoint in this mode you'll see a set of circles around the waypoint's base with various orientations; clicking and holding the mouse button on one of them will allow you to rotate the waypoint around its center.&lt;br /&gt;
&lt;br /&gt;
[[Image:Waypoint rotation.png|center]]&lt;br /&gt;
&lt;br /&gt;
Now that we have an area and a waypoint to start at, we can now tell the module that this is where the player is to appear. Reopen the &amp;quot;Manage Modules&amp;quot; window (available via a command under the File menu), select your module, and click the &amp;quot;Properties&amp;quot; button. This opens the module's properties. For the &amp;quot;Starting Area&amp;quot; property, click on the ellipsis button ([[Image:ellipsis.png]]) and select the starting area from the areas available in the module; since we've only put one area in so far &amp;quot;hut_exterior&amp;quot; will be the only available option. Once the area has been selected we can then select the starting waypoint from the waypoints currently placed in the area. Again, we've only put in one so this will be easy. You can also set the player to appear ath the origin of the map (coordinates 0,0,0), but this is generally a poor choice and available only as a default in case there are no waypoints defined yet.&lt;br /&gt;
&lt;br /&gt;
== Area transitions via doors ==&lt;br /&gt;
&lt;br /&gt;
Adventures almost always have more than one area in them, so we'll create a second area to demonstrate travel between the two. The area &amp;quot;hut_interior&amp;quot; will use area layout ost102d, which is a cosy little room that represents the interior of the small hut present in the hut_exterior area.&lt;br /&gt;
&lt;br /&gt;
{{sidebox|&lt;br /&gt;
* [[Door]]s are special placeables&lt;br /&gt;
* Doors can attach to &amp;quot;hooks&amp;quot; pre-built into the area layout&lt;br /&gt;
* Area transition doors use a different &amp;quot;appearance&amp;quot; than within-area doors&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Next we will need to create some doors. We'll create a default door placeable using the &amp;quot;New Placable&amp;quot; command, reached in a similar way as the &amp;quot;New Area&amp;quot; command explained earlier (placeables will be covered in another tutorial, but the core game resources will come with a variety of default doors usable in many situations like this) and place it in the area near the empty doorframe built into the hut's exterior. For an area transition, use one of the &amp;quot;Area Transition&amp;quot; appearances for the door. To place the door, click on it in the palette; the mouse cursor will turn into a crosshair; then click in the area viewer near the doorframe.&lt;br /&gt;
&lt;br /&gt;
As a side note, if you accidentally use one of the standard door appearances it won't work as an area transition: the door will simply swing open when clicked on instead. Each standard door appearance has a matching area transition door appearance in the resource database so this can be an easy mistake to make, but it's also easily correctable - just go back to the door's placeable resource and swap in the correct appearance, and all copies of that door in use throughout your game will be updated.&lt;br /&gt;
&lt;br /&gt;
You may notice that when the door you placed in the area is selected a small blue sphere will appear at one edge in addition to the yellow wireframe bounding box. This is the door's &amp;quot;hook&amp;quot;. Area layouts come with hidden &amp;quot;hooks&amp;quot; pre-installed to place doors on, and doors have matching hooks of their own. If you click on the blue sphere it will turn red, and all of the compatible door hooks built into the area's layout will appear. The following image illustrates this:&lt;br /&gt;
&lt;br /&gt;
[[Image:Door with door hook selected.png|400px|center|thumb|Drag the red sphere near to the blue sphere to automatically position the door]]&lt;br /&gt;
&lt;br /&gt;
To hook a door up with its frame, simply click and drag the door's hook to a location very close to the matching frame hook. You don't need to get the positioning exact; if the two hooks are close enough together when you release the mouse button they'll automatically snap together. The door will be positioned and reoriented to fit correctly into the frame.&lt;br /&gt;
&lt;br /&gt;
Note that door hooks are only there to make it easy to get exact matches on frames and walls that need a snug fit, to ensure that Artists and Designers don't have to spend a lot of time putting it in place. Doors will function just as well off of hooks as on them.&lt;br /&gt;
&lt;br /&gt;
{{sidebox|&lt;br /&gt;
* Area transition effect is defined in the door's &amp;quot;Variables&amp;quot; property&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Next, we'll tell the game engine that the door is an area transition door and that when the player clicks on it he will be transported to another area of the game. This is done by setting two of the door's [[variable]]s. Select the door (either in the area's object palette or directly in the main display window) and right-click on it, selecting &amp;quot;properties&amp;quot; from the resulting menu. This will open the door's properties in the Object Inspector window. Select the &amp;quot;Variables&amp;quot; property and click on the ellipsis ([[Image:ellipsis.png]]) button. This will open up the variable browser for that particular instance of the door object.&lt;br /&gt;
&lt;br /&gt;
There are two key variables in this list that we'll need to set:&lt;br /&gt;
&lt;br /&gt;
*PLC_AT_DEST_AREA_TAG - tag of the destination area&lt;br /&gt;
*PLC_AT_DEST_TAG - tag of the destination waypoint within the destination area&lt;br /&gt;
&lt;br /&gt;
Once we've set these the door will become an area transition door, and when the player interacts with it they'll be transported to the target area.&lt;br /&gt;
&lt;br /&gt;
The destination area is &amp;quot;hut_interior&amp;quot;. We'll create a waypoint just inside the hut's interior door, tagged &amp;quot;hut_door_interior&amp;quot;, to serve as the place where the player appears.&lt;br /&gt;
&lt;br /&gt;
Here is how the exterior door's variables should look:&lt;br /&gt;
&lt;br /&gt;
[[Image:Area tutorial door variables.png|frame|center|Area transition door's variables]]&lt;br /&gt;
&lt;br /&gt;
And here is the interior door, with the destination waypoint:&lt;br /&gt;
&lt;br /&gt;
[[Image:Area tutorial interior door.png|frame|center|Interior door with destination waypoint]]&lt;br /&gt;
&lt;br /&gt;
The interior door is set up in the same manner, with a destination area of &amp;quot;hut_exterior&amp;quot; and a matching destination waypoint of &amp;quot;hut_door_exterior&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
{{sidebox|&lt;br /&gt;
* Use invisible area transition &amp;quot;doors&amp;quot; when the transition is already built into the area layout art&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
If you want to create an area transition that doesn't look like a door, or is otherwise already represented by the level art, you can use an invisible 'door' instead. Appearances for these invisible placeables are named &amp;quot;Area Transition, Invisible&amp;quot;. Set its variables the same way as was done for the visible door.&lt;br /&gt;
&lt;br /&gt;
[[Image:Area Transition, Invisible.png|frame|center|Invisible area transition]]&lt;br /&gt;
&lt;br /&gt;
The player won't see this 'door' in the game, but when he moves the mouse pointer over it it will change to signify that an area transition lies there and it can be right-clicked to be activated just like a visible door.&lt;br /&gt;
&lt;br /&gt;
== Area transitions via triggers ==&lt;br /&gt;
&lt;br /&gt;
{{sidebox|&lt;br /&gt;
* Triggers use variables with a different prefix for setting their area transition effect&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Finally, you can also create an area transition that triggers automatically when the player walks into a predefined area. This is done using [[trigger]]s. ([[Image:IconTrigger.png]]) You'll first have to create a trigger resource, much like how you had to create a placeable door earlier, but trigger resources are much simpler and for area transitions you won't need to change any of the defaults. Create a default trigger with &amp;quot;New -&amp;gt; Trigger&amp;quot; (either by right-clicking the resource palette or from the File menu) and give it an informative name such as &amp;quot;trigger_area_transition&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Go back to your area map, select the trigger from the resource palette, and then click on the map to define the corner points of the area the trigger will occupy. Double-click the last vertex to complete the polygon. A trigger can have any number of vertices, and vertices can be moved, added, or deleted after the trigger is created so don't worry if you don't get it exactly right. Note that the blue plane the trigger uses to show the enclosed area will pass through the ground and may not be entirely visible in the toolset, but it extends infinitely upward so the trigger will still take effect if the player enters its boundaries.&lt;br /&gt;
&lt;br /&gt;
To set the trigger's destination, you'll find a familiar pair of variables in the trigger's default variable table:&lt;br /&gt;
&lt;br /&gt;
*TRIGGER_AT_DEST_AREA_TAG - tag of the destination area&lt;br /&gt;
*TRIGGER_AT_DEST_TAG - tag of the destination waypoint within the destination area&lt;br /&gt;
&lt;br /&gt;
(Note the prefix &amp;quot;TRIGGER&amp;quot; instead of &amp;quot;PLC&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Below is an example where we've placed both a trigger and an invisible door across a pathway. Note that this is redundant, only one or the other is really needed. For most purposes a placeable area transition is probably best. (''It is worth noting that placeable area transitions prompt a popup asking the player if they want to transition when bumped, but not when clicked upon - effectively acting as either a door or a trigger.'') The waypoint shown is the arrival spot for the player when coming in from the other side; note how it's placed outside the trigger area, allowing the player to immediately back up and retreat through the area transition if he chooses. &lt;br /&gt;
&lt;br /&gt;
[[Image:Area Transition, invisible with trigger.png|center]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Areas]]&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=GetEventResource&amp;diff=4828</id>
		<title>GetEventResource</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=GetEventResource&amp;diff=4828"/>
				<updated>2009-08-17T22:20:26Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{dafunction&lt;br /&gt;
|name=GetEventResource&lt;br /&gt;
|brief=Gets the specified resource on the event.&lt;br /&gt;
|param1type=event&lt;br /&gt;
|param1name=evEvent&lt;br /&gt;
|param1desc=The event to get the resource from&lt;br /&gt;
|param2type=int&lt;br /&gt;
|param2name=nIndex&lt;br /&gt;
|param2desc=The index of the resource to get&lt;br /&gt;
|returntype=resource&lt;br /&gt;
|returndesc=Returns the specified resource, returns an empty resource on error.&lt;br /&gt;
|sourcefile=script.ldf&lt;br /&gt;
|sourcemodule=&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&amp;lt;!-- This section contains the full description from the functions comments. Do not change unless you are confident these are incomplete or incorrect. --&amp;gt;&lt;br /&gt;
Gets the specified resource on the event.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- == Remarks == --&amp;gt;&lt;br /&gt;
&amp;lt;!-- This section contains additional comments, observations and known issues. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- == Examples == --&amp;gt;&lt;br /&gt;
&amp;lt;!-- This section contains examples transcluded from the snippet library. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&amp;lt;!-- This section contains links to articles, functions or constant groups. --&amp;gt;&lt;br /&gt;
[[SetEventResource]]&lt;br /&gt;
[[Category: Event functions]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=EVENT_TYPE_TRANSITION_TO_WORLD_MAP&amp;diff=4703</id>
		<title>EVENT TYPE TRANSITION TO WORLD MAP</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=EVENT_TYPE_TRANSITION_TO_WORLD_MAP&amp;diff=4703"/>
				<updated>2009-08-07T05:43:02Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{event&lt;br /&gt;
|when=Player uses the generic transition system to open the world map&lt;br /&gt;
|from=&lt;br /&gt;
|to= [[module]]&lt;br /&gt;
|string0name= sWorldMap&lt;br /&gt;
|string0desc{the tag of the map to activate}&lt;br /&gt;
|string1name=sTransType&lt;br /&gt;
|string1desc={{undocumented}}&lt;br /&gt;
|string2name= sWorldMapLoc1&lt;br /&gt;
|string2desc={the tag of a map location to activate}&lt;br /&gt;
|string3name= sWorldMapLoc2&lt;br /&gt;
|string3desc={the tag of a map location to activate}&lt;br /&gt;
|string4name= sWorldMapLoc3&lt;br /&gt;
|string4desc={the tag of a map location to activate}&lt;br /&gt;
|string5name=sWorldMapLoc4&lt;br /&gt;
|string5desc={the tag of a map location to activate}&lt;br /&gt;
|string6name= sWorldMapLoc5&lt;br /&gt;
|string6desc={the tag of a map location to activate}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Event types|TRANSITION_TO_WORLD_MAP]]&lt;br /&gt;
[[Category:Maps]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=EVENT_TYPE_TRANSITION_TO_WORLD_MAP&amp;diff=4702</id>
		<title>EVENT TYPE TRANSITION TO WORLD MAP</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=EVENT_TYPE_TRANSITION_TO_WORLD_MAP&amp;diff=4702"/>
				<updated>2009-08-07T05:42:05Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{event&lt;br /&gt;
|when=Player uses the generic transition system to open the world map&lt;br /&gt;
|from=&lt;br /&gt;
|to= [[module]]&lt;br /&gt;
|string0name= sWorldMap&lt;br /&gt;
|string0desc{{the tag of the map to activate}}&lt;br /&gt;
|string1name=sTransType&lt;br /&gt;
|string1desc={{undocumented}}&lt;br /&gt;
|string2name= sWorldMapLoc1&lt;br /&gt;
|string2desc={{the tag of a map location to activate}}&lt;br /&gt;
|string3name= sWorldMapLoc2&lt;br /&gt;
|string3desc={{the tag of a map location to activate}}&lt;br /&gt;
|string4name= sWorldMapLoc3&lt;br /&gt;
|string4desc={{the tag of a map location to activate}}&lt;br /&gt;
|string5name=sWorldMapLoc4&lt;br /&gt;
|string5desc={{the tag of a map location to activate}}&lt;br /&gt;
|string6name= sWorldMapLoc5&lt;br /&gt;
|string6desc={{the tag of a map location to activate}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Event types|TRANSITION_TO_WORLD_MAP]]&lt;br /&gt;
[[Category:Maps]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	<entry>
		<id>https://datoolset.net/mw/index.php?title=EVENT_TYPE_TRANSITION_TO_WORLD_MAP&amp;diff=4701</id>
		<title>EVENT TYPE TRANSITION TO WORLD MAP</title>
		<link rel="alternate" type="text/html" href="https://datoolset.net/mw/index.php?title=EVENT_TYPE_TRANSITION_TO_WORLD_MAP&amp;diff=4701"/>
				<updated>2009-08-07T05:40:13Z</updated>
		
		<summary type="html">&lt;p&gt;Craig Graff: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{event&lt;br /&gt;
|when=Player uses the generic transition system to open the world map&lt;br /&gt;
|from=&lt;br /&gt;
|to= [[module]]&lt;br /&gt;
|string0name= sWorldMap&lt;br /&gt;
|string0desc{{the tag of the map to activate}}&lt;br /&gt;
|string1name=sTransType&lt;br /&gt;
|string1desc={{undocumented}}&lt;br /&gt;
|string2name= sWorldMapLoc1&lt;br /&gt;
|string2desc={{undocumented}}&lt;br /&gt;
|string3name= sWorldMapLoc2&lt;br /&gt;
|string3desc={{undocumented}}&lt;br /&gt;
|string4name= sWorldMapLoc3&lt;br /&gt;
|string4desc={{undocumented}}&lt;br /&gt;
|string5name=sWorldMapLoc4&lt;br /&gt;
|string5desc={{undocumented}}&lt;br /&gt;
|string6name= sWorldMapLoc5&lt;br /&gt;
|string6desc={{undocumented}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Event types|TRANSITION_TO_WORLD_MAP]]&lt;br /&gt;
[[Category:Maps]]&lt;/div&gt;</summary>
		<author><name>Craig Graff</name></author>	</entry>

	</feed>