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

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Community_Contest_7:_Module_Contest&amp;diff=16052</id>
		<title>Community Contest 7: Module Contest</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Community_Contest_7:_Module_Contest&amp;diff=16052"/>
				<updated>2011-04-04T05:08:28Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* Eye and Shadow by Mengtzu */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Community_Contest_back.jpg|link=Community_Contest_Main_Page]] [[File:CC_BSN_GetInvolved.jpg|link=http://social.bioware.com/group/2535/&amp;amp;v=discussions]]&lt;br /&gt;
&lt;br /&gt;
== Brief ==&lt;br /&gt;
'''Create a short playable module'''. The module must be compatible with the Contest 7 Framework and must include content from at least three contests in the [[Community_Contest_Catalogue|Community Contest Catalogue]]. See requirements for more information.&lt;br /&gt;
&lt;br /&gt;
We're adding on to a &amp;quot;jobs board&amp;quot;-esque framework, so try and think of short modules which might make sense from that starting point.&lt;br /&gt;
&lt;br /&gt;
The contest discussion thread can be found [http://social.bioware.com/group/2535/discussion/13221/1496060/#post_1496060 here].&lt;br /&gt;
&lt;br /&gt;
'''DEADLINE: Monday 4 April''' - your entry must be ready for judging before midday GMT+0. It is strongly recommended you submit well before this time (sunday!) in case you run into troubles. Modifications to your submission are welcomed - the newest version of your entry will be judged, although modifications made ''after'' the submission date will not be judged.&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
All entries must:&lt;br /&gt;
* reserve a [[Community_Contest_ID_Ranges|string range]] before starting&lt;br /&gt;
* reserve all [[Community_Contest_ID_Ranges#2da_Ranges|M2DA ranges]] they use:&lt;br /&gt;
** Entrants '''will''' need to extend the [[Community_Contest_ID_Ranges#JobBoardPlots|JobBoardPlots]] M2DA&lt;br /&gt;
** Entrants '''may''' have to extend the [[Community_Contest_ID_Ranges#prcscr|PRCSCR]] M2DA&lt;br /&gt;
** Entrants '''may''' also extend other M2DAs - please also reserve these as needed, staying within the [[Community_Contest_ID_Ranges|community contest range]].&lt;br /&gt;
* use the [http://social.bioware.com/project/4161/&amp;amp;v=files Contest 7 Framework]&lt;br /&gt;
* use at least 1 piece of content from 3 or more of the following catalogue sections:&lt;br /&gt;
** settlement level&lt;br /&gt;
** room SEL&lt;br /&gt;
** prop model&lt;br /&gt;
** Character (party/merchant/quest giver)&lt;br /&gt;
** Head morph&lt;br /&gt;
** minigame script&lt;br /&gt;
** equipment&lt;br /&gt;
* '''must be a SHORT module''' - 5-15 minutes gameplay is a good target, but there is no &amp;quot;limit&amp;quot;&lt;br /&gt;
* fulfil the following as a minimum:&lt;br /&gt;
** at least 100 words dialogue&lt;br /&gt;
** a journal entry to track the progress of the quest from being visible on the job board through acceptance to completion&lt;br /&gt;
** at least one combat encounter&lt;br /&gt;
** reward the player, but do so appropriately (do not give a massive reward or overpowered gear for a small job)&lt;br /&gt;
* scale to all levels of player (preferred) OR include a &amp;quot;recommended level&amp;quot; in the job board description&lt;br /&gt;
* complete the [[Community_Contest_6:_Equipment_Contest#Checklist|entry checklist]] below and agree to the [[Community_Contest_6:_Equipment_Contest#Consent_to_Share|Consent to Share]]&lt;br /&gt;
&lt;br /&gt;
=== Guidelines ===&lt;br /&gt;
Strong entries will:&lt;br /&gt;
* not attempt an epic module - a '''smaller scope''' will allow you time to really polish your module.&lt;br /&gt;
* provide an engaging and interesting experience, favouring quality above quantity.&lt;br /&gt;
* avoid repetition and tiresome/uninteresting dialogues and combat.&lt;br /&gt;
* include one or more cutscenes to heighten drama&lt;br /&gt;
&lt;br /&gt;
=== Suggestions ===&lt;br /&gt;
* My *friend/relative* has gone missing while in the *dangerous area*, please investigate!&lt;br /&gt;
* Bounty hunt&lt;br /&gt;
* Any other short quest, really.&lt;br /&gt;
&lt;br /&gt;
=== Allowable ===&lt;br /&gt;
While no &amp;quot;bonus points&amp;quot; will be given for the following, entrants may: &lt;br /&gt;
* enter the contest several times.&lt;br /&gt;
* include new custom content provided it can be shared (see not allowable custom content below)&lt;br /&gt;
&lt;br /&gt;
=== Not Allowable ===&lt;br /&gt;
Please:&lt;br /&gt;
* do not use custom content for which you do not have permission to share, or you do not wish to be shared in the catalogue.&lt;br /&gt;
* do not override core resources unless under exceptional circumstances (if in doubt, ask in the contest thread)&lt;br /&gt;
&lt;br /&gt;
== Groups and Prizes ==&lt;br /&gt;
&lt;br /&gt;
=== Groups ===&lt;br /&gt;
This contest has one group, with higher prizes than normal!&lt;br /&gt;
&lt;br /&gt;
* 1st place - 30 points, chooses first&lt;br /&gt;
* 2nd place - 20 points, chooses second&lt;br /&gt;
* 3rd place - 10 points, chooses third&lt;br /&gt;
* Best Newcomer - 5 points (unless 1st, 2nd or 3rd place)&lt;br /&gt;
* All other entries meeting requirements - 3 points&lt;br /&gt;
&lt;br /&gt;
=== Best Newcomer Award ===&lt;br /&gt;
If an entrant has not entered a Community Contest before, they qualify for the Best Newcomer Award. This award is given to the newcomer with the highest number of votes.&lt;br /&gt;
&lt;br /&gt;
=== Prizes ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Community_Contest_Prizes|Community Contest Prizes]]&lt;br /&gt;
&lt;br /&gt;
== Helpful Links ==&lt;br /&gt;
* [[Community_Contest_ID_Ranges|Reserve your string and GDA IDs here]]&lt;br /&gt;
* [[Community_Contest_Catalogue|Browse Catalogue content here]]&lt;br /&gt;
* [http://social.bioware.com/project/4161/ Community Contest 7 Framework] - includes a *very* useful readme (essential reading!)&lt;br /&gt;
* [[Module_tutorial|Module Tutorial]] - the CC7 framework readme supercedes much information here&lt;br /&gt;
&lt;br /&gt;
= Submitting an Entry = &lt;br /&gt;
&lt;br /&gt;
=== Entry File(s) ===&lt;br /&gt;
&lt;br /&gt;
'''Builder File Contents:'''&lt;br /&gt;
* dadbdata of your module (do not include core resources)&lt;br /&gt;
* any data/override files required. mike will be impressed if you put them in the correct folder... module/data is usually sufficient! core/override is usually over-the-top and conflict-prone)&lt;br /&gt;
&lt;br /&gt;
'''Player File:'''&lt;br /&gt;
(the player file is optional - we'll be bundling them all together)&lt;br /&gt;
&lt;br /&gt;
'''File Format:'''&lt;br /&gt;
.7z file (preferred)&lt;br /&gt;
&lt;br /&gt;
=== Checklist ===&lt;br /&gt;
&lt;br /&gt;
# Create your file (see above)&lt;br /&gt;
# Create a [http://www.dragonagenexus.com/ Dragon Age Nexus] page for your entry and upload the above file. Please include &amp;quot;Community Contest&amp;quot; in the title.&lt;br /&gt;
# Edit '''this''' page with a description and pictures of your content. &lt;br /&gt;
#* Please include pictures which are both functional as well as attractive (so your work can be seen clearly)&lt;br /&gt;
#* Link to your DA Nexus page. See the sample entry.&lt;br /&gt;
# Optionally, let us know in the [http://social.bioware.com/group/2535/#discussions Contest Discussion Thread] that you've entered&lt;br /&gt;
&lt;br /&gt;
For the general entry guidelines (as well as more detail on the above steps), please see the [[Community_Contest_Entry_FAQ|Entry FAQs]]&lt;br /&gt;
&lt;br /&gt;
For information on Judging, please see the [[Community_Contest_Judging|Judging]] page.&lt;br /&gt;
&lt;br /&gt;
== Consent to Share ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;font size=&amp;quot;5&amp;quot; color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;IMPORTANT - consent to share&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;By entering this competition you consent to share your work for other community members to benefit from.&lt;br /&gt;
 Where appropriate, source files should be shared (prop models, VFXProj files). &lt;br /&gt;
 The work *MUST* be your own (obviously you may use DA assets).&lt;br /&gt;
 Others may use and modify your work in their Dragon Age mods, though are encouraged to give credit. &lt;br /&gt;
 As the entries are judged, local copies will be saved If your work is taken down.&lt;br /&gt;
 If your work is taken down, you allow for it to be re-uploaded, crediting the work in your name. &amp;lt;/b&amp;gt; &amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Entries =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sample Entry Placeholder==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=1559 Dragon Age Nexus project page]'''&lt;br /&gt;
This slot will hopefully be replaced by a &amp;quot;proper&amp;quot; sample entry for you to examine.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CC5_mike_roomtop.jpg|303px|Room Plan]] [[File:CC5_mike_roomcorner.jpg|400px|Room Glamour Shot]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Spiders &amp;amp; Knives ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=2535 Dragon Age Nexus project page]'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
''&amp;quot;First catch your client&amp;quot;, to misquote Paragon Beeton.''&lt;br /&gt;
&lt;br /&gt;
''It seemed a simple enough job: earn a few coins by clearing a wandering band of darkspawn out of a Lothering Knight's home. Except that the client has gone missing!''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
Spiders &amp;amp; Knives takes place in and around Lothering, so it needs to be completed before Lothering is destroyed by the darkspawn. The mod is suitable for any class - the main reward item at the end of the main path is tailored to the main player character.&lt;br /&gt;
&lt;br /&gt;
As far as I can tell, the difficulty level is broadly similar to other Lothering quests, whilst the rewards are a little higher - although hopefully not to an unbalancing extent. The main quest path has around 30 minutes of gameplay; there is an alternative, shorter, path of around 15-20 minutes which also provides a nice item as a reward, but less gold.&lt;br /&gt;
&lt;br /&gt;
To begin the quest, look at either the new Job Board in Denerim or the Chanter's Board in Lothering. You might also stumble upon the starting point of the quest whilst exploring around Lothering.&lt;br /&gt;
&lt;br /&gt;
Note that this mod is silent. Instead of VO I have used timed silences, so I recommend you use subtitles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Thanks To/Resources Used:'''&lt;br /&gt;
&lt;br /&gt;
Nimee: for 'A place to call home', from CC5. With apologies for the mess the darkspawn have made of the place.&lt;br /&gt;
&lt;br /&gt;
Lord Uber Dowzen (uberdowzen): for Arbither, from CC3-mini. Also Vaylise whose character's nickname I nicked for her.&lt;br /&gt;
&lt;br /&gt;
Vaylise: The Valorous, armour from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Adonnay: Crow &amp;amp; Crane, twin swords from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Nattfodd: HjorrMikill, greatsword from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Helekanalaith: Knotwood Staff, mages staff from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Gisle Aune: Dagger of Ashyera's Cult, from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
mikemike37: Warhammer, from CC6.&lt;br /&gt;
&lt;br /&gt;
Note that whilst I have used the authors' models for these items, the actual items are mostly my handiwork - so if there's anything wrong it's likely my fault not theirs.&lt;br /&gt;
&lt;br /&gt;
Sunjammer: CC7 Framework, including the new Job Board, and his Builders' Guide.&lt;br /&gt;
&lt;br /&gt;
If I've forgotten anyone, please let me know &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CC7_Web2.jpg|400px|Spider Web]]     [[File:CC7-Knives.jpg|400px|Knives]]&lt;br /&gt;
&lt;br /&gt;
[[File:CC7_My_Home3.jpg|400px|Look what they have done to my home!]]     [[File:CC7_Storage_Chest.jpg|400px|Storage Chest]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Eye and Shadow by Mengtzu ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=2563 Dragon Age Nexus project page]'''&lt;br /&gt;
&lt;br /&gt;
'''For Players:'''&lt;br /&gt;
&lt;br /&gt;
* Challenging encounters designed to teach key skills (focus fire, target selection, burn phases and positioning) - though easier and a bit more accessible than my standalones.&lt;br /&gt;
* Tuned for geared, high level parties, but accessible early to any looking for a profitable challenge&lt;br /&gt;
* Supply-based rewards scaled with level, intended to be conveniently imported to DLC and the expansion&lt;br /&gt;
* A curious situation with some fun twists on Qunari and Elven lore.&lt;br /&gt;
* A total of four possible resolutions to the adventure.&lt;br /&gt;
&lt;br /&gt;
'''For Builders'''&lt;br /&gt;
&lt;br /&gt;
While this odd little scenario may not appeal to all players, the .dadbdata should be of interest to almost any builder.  The module features commented examples of some useful encounter design tricks and scripting practices, including:&lt;br /&gt;
&lt;br /&gt;
* Area heartbeats (timed encounter phases, periodic damage auras, boss health regen)&lt;br /&gt;
* Creature events (damage mitigation based on phase, add spawns on death)&lt;br /&gt;
* Solid basics like function and constant libraries, plot scripting etc.&lt;br /&gt;
&lt;br /&gt;
'''CC Resources used:'''&lt;br /&gt;
&lt;br /&gt;
* Community Contest #1: Lord of Fangs (&amp;quot;Hakkon's Gift&amp;quot;/Eight Knots)  &lt;br /&gt;
* Community Contest #3: Vaylise (&amp;quot;Knives&amp;quot;/Anaris), uberdowzen (&amp;quot;Saarebas&amp;quot;/Kithshok)&lt;br /&gt;
* Community Contest #6: Adonnay (&amp;quot;Crow &amp;amp; Crane&amp;quot;/Geldauran's swords)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Spiritsleli.jpg|400px|Leliana against the spirits]] [[File:Geldauran.jpg|390px|Geldauran]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Community_Contest_7:_Module_Contest&amp;diff=16051</id>
		<title>Community Contest 7: Module Contest</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Community_Contest_7:_Module_Contest&amp;diff=16051"/>
				<updated>2011-04-04T05:07:47Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* Eye and Shadow by Mengtzu */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Community_Contest_back.jpg|link=Community_Contest_Main_Page]] [[File:CC_BSN_GetInvolved.jpg|link=http://social.bioware.com/group/2535/&amp;amp;v=discussions]]&lt;br /&gt;
&lt;br /&gt;
== Brief ==&lt;br /&gt;
'''Create a short playable module'''. The module must be compatible with the Contest 7 Framework and must include content from at least three contests in the [[Community_Contest_Catalogue|Community Contest Catalogue]]. See requirements for more information.&lt;br /&gt;
&lt;br /&gt;
We're adding on to a &amp;quot;jobs board&amp;quot;-esque framework, so try and think of short modules which might make sense from that starting point.&lt;br /&gt;
&lt;br /&gt;
The contest discussion thread can be found [http://social.bioware.com/group/2535/discussion/13221/1496060/#post_1496060 here].&lt;br /&gt;
&lt;br /&gt;
'''DEADLINE: Monday 4 April''' - your entry must be ready for judging before midday GMT+0. It is strongly recommended you submit well before this time (sunday!) in case you run into troubles. Modifications to your submission are welcomed - the newest version of your entry will be judged, although modifications made ''after'' the submission date will not be judged.&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
All entries must:&lt;br /&gt;
* reserve a [[Community_Contest_ID_Ranges|string range]] before starting&lt;br /&gt;
* reserve all [[Community_Contest_ID_Ranges#2da_Ranges|M2DA ranges]] they use:&lt;br /&gt;
** Entrants '''will''' need to extend the [[Community_Contest_ID_Ranges#JobBoardPlots|JobBoardPlots]] M2DA&lt;br /&gt;
** Entrants '''may''' have to extend the [[Community_Contest_ID_Ranges#prcscr|PRCSCR]] M2DA&lt;br /&gt;
** Entrants '''may''' also extend other M2DAs - please also reserve these as needed, staying within the [[Community_Contest_ID_Ranges|community contest range]].&lt;br /&gt;
* use the [http://social.bioware.com/project/4161/&amp;amp;v=files Contest 7 Framework]&lt;br /&gt;
* use at least 1 piece of content from 3 or more of the following catalogue sections:&lt;br /&gt;
** settlement level&lt;br /&gt;
** room SEL&lt;br /&gt;
** prop model&lt;br /&gt;
** Character (party/merchant/quest giver)&lt;br /&gt;
** Head morph&lt;br /&gt;
** minigame script&lt;br /&gt;
** equipment&lt;br /&gt;
* '''must be a SHORT module''' - 5-15 minutes gameplay is a good target, but there is no &amp;quot;limit&amp;quot;&lt;br /&gt;
* fulfil the following as a minimum:&lt;br /&gt;
** at least 100 words dialogue&lt;br /&gt;
** a journal entry to track the progress of the quest from being visible on the job board through acceptance to completion&lt;br /&gt;
** at least one combat encounter&lt;br /&gt;
** reward the player, but do so appropriately (do not give a massive reward or overpowered gear for a small job)&lt;br /&gt;
* scale to all levels of player (preferred) OR include a &amp;quot;recommended level&amp;quot; in the job board description&lt;br /&gt;
* complete the [[Community_Contest_6:_Equipment_Contest#Checklist|entry checklist]] below and agree to the [[Community_Contest_6:_Equipment_Contest#Consent_to_Share|Consent to Share]]&lt;br /&gt;
&lt;br /&gt;
=== Guidelines ===&lt;br /&gt;
Strong entries will:&lt;br /&gt;
* not attempt an epic module - a '''smaller scope''' will allow you time to really polish your module.&lt;br /&gt;
* provide an engaging and interesting experience, favouring quality above quantity.&lt;br /&gt;
* avoid repetition and tiresome/uninteresting dialogues and combat.&lt;br /&gt;
* include one or more cutscenes to heighten drama&lt;br /&gt;
&lt;br /&gt;
=== Suggestions ===&lt;br /&gt;
* My *friend/relative* has gone missing while in the *dangerous area*, please investigate!&lt;br /&gt;
* Bounty hunt&lt;br /&gt;
* Any other short quest, really.&lt;br /&gt;
&lt;br /&gt;
=== Allowable ===&lt;br /&gt;
While no &amp;quot;bonus points&amp;quot; will be given for the following, entrants may: &lt;br /&gt;
* enter the contest several times.&lt;br /&gt;
* include new custom content provided it can be shared (see not allowable custom content below)&lt;br /&gt;
&lt;br /&gt;
=== Not Allowable ===&lt;br /&gt;
Please:&lt;br /&gt;
* do not use custom content for which you do not have permission to share, or you do not wish to be shared in the catalogue.&lt;br /&gt;
* do not override core resources unless under exceptional circumstances (if in doubt, ask in the contest thread)&lt;br /&gt;
&lt;br /&gt;
== Groups and Prizes ==&lt;br /&gt;
&lt;br /&gt;
=== Groups ===&lt;br /&gt;
This contest has one group, with higher prizes than normal!&lt;br /&gt;
&lt;br /&gt;
* 1st place - 30 points, chooses first&lt;br /&gt;
* 2nd place - 20 points, chooses second&lt;br /&gt;
* 3rd place - 10 points, chooses third&lt;br /&gt;
* Best Newcomer - 5 points (unless 1st, 2nd or 3rd place)&lt;br /&gt;
* All other entries meeting requirements - 3 points&lt;br /&gt;
&lt;br /&gt;
=== Best Newcomer Award ===&lt;br /&gt;
If an entrant has not entered a Community Contest before, they qualify for the Best Newcomer Award. This award is given to the newcomer with the highest number of votes.&lt;br /&gt;
&lt;br /&gt;
=== Prizes ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Community_Contest_Prizes|Community Contest Prizes]]&lt;br /&gt;
&lt;br /&gt;
== Helpful Links ==&lt;br /&gt;
* [[Community_Contest_ID_Ranges|Reserve your string and GDA IDs here]]&lt;br /&gt;
* [[Community_Contest_Catalogue|Browse Catalogue content here]]&lt;br /&gt;
* [http://social.bioware.com/project/4161/ Community Contest 7 Framework] - includes a *very* useful readme (essential reading!)&lt;br /&gt;
* [[Module_tutorial|Module Tutorial]] - the CC7 framework readme supercedes much information here&lt;br /&gt;
&lt;br /&gt;
= Submitting an Entry = &lt;br /&gt;
&lt;br /&gt;
=== Entry File(s) ===&lt;br /&gt;
&lt;br /&gt;
'''Builder File Contents:'''&lt;br /&gt;
* dadbdata of your module (do not include core resources)&lt;br /&gt;
* any data/override files required. mike will be impressed if you put them in the correct folder... module/data is usually sufficient! core/override is usually over-the-top and conflict-prone)&lt;br /&gt;
&lt;br /&gt;
'''Player File:'''&lt;br /&gt;
(the player file is optional - we'll be bundling them all together)&lt;br /&gt;
&lt;br /&gt;
'''File Format:'''&lt;br /&gt;
.7z file (preferred)&lt;br /&gt;
&lt;br /&gt;
=== Checklist ===&lt;br /&gt;
&lt;br /&gt;
# Create your file (see above)&lt;br /&gt;
# Create a [http://www.dragonagenexus.com/ Dragon Age Nexus] page for your entry and upload the above file. Please include &amp;quot;Community Contest&amp;quot; in the title.&lt;br /&gt;
# Edit '''this''' page with a description and pictures of your content. &lt;br /&gt;
#* Please include pictures which are both functional as well as attractive (so your work can be seen clearly)&lt;br /&gt;
#* Link to your DA Nexus page. See the sample entry.&lt;br /&gt;
# Optionally, let us know in the [http://social.bioware.com/group/2535/#discussions Contest Discussion Thread] that you've entered&lt;br /&gt;
&lt;br /&gt;
For the general entry guidelines (as well as more detail on the above steps), please see the [[Community_Contest_Entry_FAQ|Entry FAQs]]&lt;br /&gt;
&lt;br /&gt;
For information on Judging, please see the [[Community_Contest_Judging|Judging]] page.&lt;br /&gt;
&lt;br /&gt;
== Consent to Share ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;font size=&amp;quot;5&amp;quot; color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;IMPORTANT - consent to share&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;By entering this competition you consent to share your work for other community members to benefit from.&lt;br /&gt;
 Where appropriate, source files should be shared (prop models, VFXProj files). &lt;br /&gt;
 The work *MUST* be your own (obviously you may use DA assets).&lt;br /&gt;
 Others may use and modify your work in their Dragon Age mods, though are encouraged to give credit. &lt;br /&gt;
 As the entries are judged, local copies will be saved If your work is taken down.&lt;br /&gt;
 If your work is taken down, you allow for it to be re-uploaded, crediting the work in your name. &amp;lt;/b&amp;gt; &amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Entries =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sample Entry Placeholder==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=1559 Dragon Age Nexus project page]'''&lt;br /&gt;
This slot will hopefully be replaced by a &amp;quot;proper&amp;quot; sample entry for you to examine.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CC5_mike_roomtop.jpg|303px|Room Plan]] [[File:CC5_mike_roomcorner.jpg|400px|Room Glamour Shot]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Spiders &amp;amp; Knives ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=2535 Dragon Age Nexus project page]'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
''&amp;quot;First catch your client&amp;quot;, to misquote Paragon Beeton.''&lt;br /&gt;
&lt;br /&gt;
''It seemed a simple enough job: earn a few coins by clearing a wandering band of darkspawn out of a Lothering Knight's home. Except that the client has gone missing!''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
Spiders &amp;amp; Knives takes place in and around Lothering, so it needs to be completed before Lothering is destroyed by the darkspawn. The mod is suitable for any class - the main reward item at the end of the main path is tailored to the main player character.&lt;br /&gt;
&lt;br /&gt;
As far as I can tell, the difficulty level is broadly similar to other Lothering quests, whilst the rewards are a little higher - although hopefully not to an unbalancing extent. The main quest path has around 30 minutes of gameplay; there is an alternative, shorter, path of around 15-20 minutes which also provides a nice item as a reward, but less gold.&lt;br /&gt;
&lt;br /&gt;
To begin the quest, look at either the new Job Board in Denerim or the Chanter's Board in Lothering. You might also stumble upon the starting point of the quest whilst exploring around Lothering.&lt;br /&gt;
&lt;br /&gt;
Note that this mod is silent. Instead of VO I have used timed silences, so I recommend you use subtitles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Thanks To/Resources Used:'''&lt;br /&gt;
&lt;br /&gt;
Nimee: for 'A place to call home', from CC5. With apologies for the mess the darkspawn have made of the place.&lt;br /&gt;
&lt;br /&gt;
Lord Uber Dowzen (uberdowzen): for Arbither, from CC3-mini. Also Vaylise whose character's nickname I nicked for her.&lt;br /&gt;
&lt;br /&gt;
Vaylise: The Valorous, armour from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Adonnay: Crow &amp;amp; Crane, twin swords from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Nattfodd: HjorrMikill, greatsword from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Helekanalaith: Knotwood Staff, mages staff from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Gisle Aune: Dagger of Ashyera's Cult, from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
mikemike37: Warhammer, from CC6.&lt;br /&gt;
&lt;br /&gt;
Note that whilst I have used the authors' models for these items, the actual items are mostly my handiwork - so if there's anything wrong it's likely my fault not theirs.&lt;br /&gt;
&lt;br /&gt;
Sunjammer: CC7 Framework, including the new Job Board, and his Builders' Guide.&lt;br /&gt;
&lt;br /&gt;
If I've forgotten anyone, please let me know &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CC7_Web2.jpg|400px|Spider Web]]     [[File:CC7-Knives.jpg|400px|Knives]]&lt;br /&gt;
&lt;br /&gt;
[[File:CC7_My_Home3.jpg|400px|Look what they have done to my home!]]     [[File:CC7_Storage_Chest.jpg|400px|Storage Chest]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Eye and Shadow by Mengtzu ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=2563 Dragon Age Nexus project page]'''&lt;br /&gt;
&lt;br /&gt;
'''For Players:'''&lt;br /&gt;
&lt;br /&gt;
* Challenging encounters designed to teach key skills (focus fire, target selection, burn phases and positioning) - though easier and a bit more accessible than my standalones.&lt;br /&gt;
* Tuned for geared, high level parties, but accessible early to any looking for a profitable challenge&lt;br /&gt;
* Supply-based rewards scaled with level, intended to be conveniently imported to DLC and the expansion&lt;br /&gt;
* A curious situation with some fun twists on Qunari and Elven lore.&lt;br /&gt;
* A total of four possible resolutions to the adventure.&lt;br /&gt;
&lt;br /&gt;
'''For Builders'''&lt;br /&gt;
&lt;br /&gt;
While this odd little scenario may not appeal to all players, the .dadbdata should be of interest to almost any builder.  The module features commented examples of some useful encounter design tricks and scripting practices, including:&lt;br /&gt;
&lt;br /&gt;
* Area heartbeats (timed encounter phases, periodic damage auras, boss health regen)&lt;br /&gt;
* Creature events (damage mitigation based on phase, add spawns on death)&lt;br /&gt;
* Solid basics like function and constant libraries, plot scripting etc.&lt;br /&gt;
&lt;br /&gt;
'''CC Resources used:'''&lt;br /&gt;
&lt;br /&gt;
* Community Contest #1: Lord of Fangs (&amp;quot;Hakkon's Gift&amp;quot;/Eight Knots)  &lt;br /&gt;
* Community Contest #3: Vaylise (&amp;quot;Knives&amp;quot;/Anaris), uberdowzen (&amp;quot;Saarebas&amp;quot;/Kithshok)&lt;br /&gt;
* Community Contest #6: Adonnay (&amp;quot;Crow &amp;amp; Crane&amp;quot;/Geldauran's swords)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Spiritsleli.jpg|400px|Leliana against the spirits]] [[File:Geldauran.jpg|400px|Geldauran]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=File:Geldauran.jpg&amp;diff=16050</id>
		<title>File:Geldauran.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=File:Geldauran.jpg&amp;diff=16050"/>
				<updated>2011-04-04T05:06:08Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Community_Contest_7:_Module_Contest&amp;diff=16049</id>
		<title>Community Contest 7: Module Contest</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Community_Contest_7:_Module_Contest&amp;diff=16049"/>
				<updated>2011-04-04T05:05:16Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Community_Contest_back.jpg|link=Community_Contest_Main_Page]] [[File:CC_BSN_GetInvolved.jpg|link=http://social.bioware.com/group/2535/&amp;amp;v=discussions]]&lt;br /&gt;
&lt;br /&gt;
== Brief ==&lt;br /&gt;
'''Create a short playable module'''. The module must be compatible with the Contest 7 Framework and must include content from at least three contests in the [[Community_Contest_Catalogue|Community Contest Catalogue]]. See requirements for more information.&lt;br /&gt;
&lt;br /&gt;
We're adding on to a &amp;quot;jobs board&amp;quot;-esque framework, so try and think of short modules which might make sense from that starting point.&lt;br /&gt;
&lt;br /&gt;
The contest discussion thread can be found [http://social.bioware.com/group/2535/discussion/13221/1496060/#post_1496060 here].&lt;br /&gt;
&lt;br /&gt;
'''DEADLINE: Monday 4 April''' - your entry must be ready for judging before midday GMT+0. It is strongly recommended you submit well before this time (sunday!) in case you run into troubles. Modifications to your submission are welcomed - the newest version of your entry will be judged, although modifications made ''after'' the submission date will not be judged.&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
All entries must:&lt;br /&gt;
* reserve a [[Community_Contest_ID_Ranges|string range]] before starting&lt;br /&gt;
* reserve all [[Community_Contest_ID_Ranges#2da_Ranges|M2DA ranges]] they use:&lt;br /&gt;
** Entrants '''will''' need to extend the [[Community_Contest_ID_Ranges#JobBoardPlots|JobBoardPlots]] M2DA&lt;br /&gt;
** Entrants '''may''' have to extend the [[Community_Contest_ID_Ranges#prcscr|PRCSCR]] M2DA&lt;br /&gt;
** Entrants '''may''' also extend other M2DAs - please also reserve these as needed, staying within the [[Community_Contest_ID_Ranges|community contest range]].&lt;br /&gt;
* use the [http://social.bioware.com/project/4161/&amp;amp;v=files Contest 7 Framework]&lt;br /&gt;
* use at least 1 piece of content from 3 or more of the following catalogue sections:&lt;br /&gt;
** settlement level&lt;br /&gt;
** room SEL&lt;br /&gt;
** prop model&lt;br /&gt;
** Character (party/merchant/quest giver)&lt;br /&gt;
** Head morph&lt;br /&gt;
** minigame script&lt;br /&gt;
** equipment&lt;br /&gt;
* '''must be a SHORT module''' - 5-15 minutes gameplay is a good target, but there is no &amp;quot;limit&amp;quot;&lt;br /&gt;
* fulfil the following as a minimum:&lt;br /&gt;
** at least 100 words dialogue&lt;br /&gt;
** a journal entry to track the progress of the quest from being visible on the job board through acceptance to completion&lt;br /&gt;
** at least one combat encounter&lt;br /&gt;
** reward the player, but do so appropriately (do not give a massive reward or overpowered gear for a small job)&lt;br /&gt;
* scale to all levels of player (preferred) OR include a &amp;quot;recommended level&amp;quot; in the job board description&lt;br /&gt;
* complete the [[Community_Contest_6:_Equipment_Contest#Checklist|entry checklist]] below and agree to the [[Community_Contest_6:_Equipment_Contest#Consent_to_Share|Consent to Share]]&lt;br /&gt;
&lt;br /&gt;
=== Guidelines ===&lt;br /&gt;
Strong entries will:&lt;br /&gt;
* not attempt an epic module - a '''smaller scope''' will allow you time to really polish your module.&lt;br /&gt;
* provide an engaging and interesting experience, favouring quality above quantity.&lt;br /&gt;
* avoid repetition and tiresome/uninteresting dialogues and combat.&lt;br /&gt;
* include one or more cutscenes to heighten drama&lt;br /&gt;
&lt;br /&gt;
=== Suggestions ===&lt;br /&gt;
* My *friend/relative* has gone missing while in the *dangerous area*, please investigate!&lt;br /&gt;
* Bounty hunt&lt;br /&gt;
* Any other short quest, really.&lt;br /&gt;
&lt;br /&gt;
=== Allowable ===&lt;br /&gt;
While no &amp;quot;bonus points&amp;quot; will be given for the following, entrants may: &lt;br /&gt;
* enter the contest several times.&lt;br /&gt;
* include new custom content provided it can be shared (see not allowable custom content below)&lt;br /&gt;
&lt;br /&gt;
=== Not Allowable ===&lt;br /&gt;
Please:&lt;br /&gt;
* do not use custom content for which you do not have permission to share, or you do not wish to be shared in the catalogue.&lt;br /&gt;
* do not override core resources unless under exceptional circumstances (if in doubt, ask in the contest thread)&lt;br /&gt;
&lt;br /&gt;
== Groups and Prizes ==&lt;br /&gt;
&lt;br /&gt;
=== Groups ===&lt;br /&gt;
This contest has one group, with higher prizes than normal!&lt;br /&gt;
&lt;br /&gt;
* 1st place - 30 points, chooses first&lt;br /&gt;
* 2nd place - 20 points, chooses second&lt;br /&gt;
* 3rd place - 10 points, chooses third&lt;br /&gt;
* Best Newcomer - 5 points (unless 1st, 2nd or 3rd place)&lt;br /&gt;
* All other entries meeting requirements - 3 points&lt;br /&gt;
&lt;br /&gt;
=== Best Newcomer Award ===&lt;br /&gt;
If an entrant has not entered a Community Contest before, they qualify for the Best Newcomer Award. This award is given to the newcomer with the highest number of votes.&lt;br /&gt;
&lt;br /&gt;
=== Prizes ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Community_Contest_Prizes|Community Contest Prizes]]&lt;br /&gt;
&lt;br /&gt;
== Helpful Links ==&lt;br /&gt;
* [[Community_Contest_ID_Ranges|Reserve your string and GDA IDs here]]&lt;br /&gt;
* [[Community_Contest_Catalogue|Browse Catalogue content here]]&lt;br /&gt;
* [http://social.bioware.com/project/4161/ Community Contest 7 Framework] - includes a *very* useful readme (essential reading!)&lt;br /&gt;
* [[Module_tutorial|Module Tutorial]] - the CC7 framework readme supercedes much information here&lt;br /&gt;
&lt;br /&gt;
= Submitting an Entry = &lt;br /&gt;
&lt;br /&gt;
=== Entry File(s) ===&lt;br /&gt;
&lt;br /&gt;
'''Builder File Contents:'''&lt;br /&gt;
* dadbdata of your module (do not include core resources)&lt;br /&gt;
* any data/override files required. mike will be impressed if you put them in the correct folder... module/data is usually sufficient! core/override is usually over-the-top and conflict-prone)&lt;br /&gt;
&lt;br /&gt;
'''Player File:'''&lt;br /&gt;
(the player file is optional - we'll be bundling them all together)&lt;br /&gt;
&lt;br /&gt;
'''File Format:'''&lt;br /&gt;
.7z file (preferred)&lt;br /&gt;
&lt;br /&gt;
=== Checklist ===&lt;br /&gt;
&lt;br /&gt;
# Create your file (see above)&lt;br /&gt;
# Create a [http://www.dragonagenexus.com/ Dragon Age Nexus] page for your entry and upload the above file. Please include &amp;quot;Community Contest&amp;quot; in the title.&lt;br /&gt;
# Edit '''this''' page with a description and pictures of your content. &lt;br /&gt;
#* Please include pictures which are both functional as well as attractive (so your work can be seen clearly)&lt;br /&gt;
#* Link to your DA Nexus page. See the sample entry.&lt;br /&gt;
# Optionally, let us know in the [http://social.bioware.com/group/2535/#discussions Contest Discussion Thread] that you've entered&lt;br /&gt;
&lt;br /&gt;
For the general entry guidelines (as well as more detail on the above steps), please see the [[Community_Contest_Entry_FAQ|Entry FAQs]]&lt;br /&gt;
&lt;br /&gt;
For information on Judging, please see the [[Community_Contest_Judging|Judging]] page.&lt;br /&gt;
&lt;br /&gt;
== Consent to Share ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;font size=&amp;quot;5&amp;quot; color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;IMPORTANT - consent to share&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;By entering this competition you consent to share your work for other community members to benefit from.&lt;br /&gt;
 Where appropriate, source files should be shared (prop models, VFXProj files). &lt;br /&gt;
 The work *MUST* be your own (obviously you may use DA assets).&lt;br /&gt;
 Others may use and modify your work in their Dragon Age mods, though are encouraged to give credit. &lt;br /&gt;
 As the entries are judged, local copies will be saved If your work is taken down.&lt;br /&gt;
 If your work is taken down, you allow for it to be re-uploaded, crediting the work in your name. &amp;lt;/b&amp;gt; &amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Entries =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sample Entry Placeholder==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=1559 Dragon Age Nexus project page]'''&lt;br /&gt;
This slot will hopefully be replaced by a &amp;quot;proper&amp;quot; sample entry for you to examine.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CC5_mike_roomtop.jpg|303px|Room Plan]] [[File:CC5_mike_roomcorner.jpg|400px|Room Glamour Shot]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Spiders &amp;amp; Knives ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=2535 Dragon Age Nexus project page]'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
''&amp;quot;First catch your client&amp;quot;, to misquote Paragon Beeton.''&lt;br /&gt;
&lt;br /&gt;
''It seemed a simple enough job: earn a few coins by clearing a wandering band of darkspawn out of a Lothering Knight's home. Except that the client has gone missing!''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
Spiders &amp;amp; Knives takes place in and around Lothering, so it needs to be completed before Lothering is destroyed by the darkspawn. The mod is suitable for any class - the main reward item at the end of the main path is tailored to the main player character.&lt;br /&gt;
&lt;br /&gt;
As far as I can tell, the difficulty level is broadly similar to other Lothering quests, whilst the rewards are a little higher - although hopefully not to an unbalancing extent. The main quest path has around 30 minutes of gameplay; there is an alternative, shorter, path of around 15-20 minutes which also provides a nice item as a reward, but less gold.&lt;br /&gt;
&lt;br /&gt;
To begin the quest, look at either the new Job Board in Denerim or the Chanter's Board in Lothering. You might also stumble upon the starting point of the quest whilst exploring around Lothering.&lt;br /&gt;
&lt;br /&gt;
Note that this mod is silent. Instead of VO I have used timed silences, so I recommend you use subtitles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Thanks To/Resources Used:'''&lt;br /&gt;
&lt;br /&gt;
Nimee: for 'A place to call home', from CC5. With apologies for the mess the darkspawn have made of the place.&lt;br /&gt;
&lt;br /&gt;
Lord Uber Dowzen (uberdowzen): for Arbither, from CC3-mini. Also Vaylise whose character's nickname I nicked for her.&lt;br /&gt;
&lt;br /&gt;
Vaylise: The Valorous, armour from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Adonnay: Crow &amp;amp; Crane, twin swords from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Nattfodd: HjorrMikill, greatsword from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Helekanalaith: Knotwood Staff, mages staff from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Gisle Aune: Dagger of Ashyera's Cult, from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
mikemike37: Warhammer, from CC6.&lt;br /&gt;
&lt;br /&gt;
Note that whilst I have used the authors' models for these items, the actual items are mostly my handiwork - so if there's anything wrong it's likely my fault not theirs.&lt;br /&gt;
&lt;br /&gt;
Sunjammer: CC7 Framework, including the new Job Board, and his Builders' Guide.&lt;br /&gt;
&lt;br /&gt;
If I've forgotten anyone, please let me know &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CC7_Web2.jpg|400px|Spider Web]]     [[File:CC7-Knives.jpg|400px|Knives]]&lt;br /&gt;
&lt;br /&gt;
[[File:CC7_My_Home3.jpg|400px|Look what they have done to my home!]]     [[File:CC7_Storage_Chest.jpg|400px|Storage Chest]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Eye and Shadow by Mengtzu ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=2563 Dragon Age Nexus project page]'''&lt;br /&gt;
&lt;br /&gt;
'''For Players:'''&lt;br /&gt;
&lt;br /&gt;
* Challenging encounters designed to teach key skills (focus fire, target selection, burn phases and positioning) - though easier and a bit more accessible than my standalones.&lt;br /&gt;
* Tuned for geared, high level parties, but accessible early to any looking for a profitable challenge&lt;br /&gt;
* Supply-based rewards scaled with level, intended to be conveniently imported to DLC and the expansion&lt;br /&gt;
* A curious situation with some fun twists on Qunari and Elven lore.&lt;br /&gt;
* A total of four possible resolutions to the adventure.&lt;br /&gt;
&lt;br /&gt;
'''For Builders'''&lt;br /&gt;
&lt;br /&gt;
While this odd little scenario may not appeal to all players, the .dadbdata should be of interest to almost any builder.  The module features commented examples of some useful encounter design tricks and scripting practices, including:&lt;br /&gt;
&lt;br /&gt;
* Area heartbeats (timed encounter phases, periodic damage auras, boss health regen)&lt;br /&gt;
* Creature events (damage mitigation based on phase, add spawns on death)&lt;br /&gt;
* Solid basics like function and constant libraries, plot scripting etc.&lt;br /&gt;
&lt;br /&gt;
'''CC Resources used:'''&lt;br /&gt;
&lt;br /&gt;
* Community Contest #1: Lord of Fangs (&amp;quot;Hakkon's Gift&amp;quot;/Eight Knots)  &lt;br /&gt;
* Community Contest #3: Vaylise (&amp;quot;Knives&amp;quot;/Anaris), uberdowzen (&amp;quot;Saarebas&amp;quot;/Kithshok)&lt;br /&gt;
* Community Contest #6: Adonnay (&amp;quot;Crow &amp;amp; Crane&amp;quot;/Geldauran's swords)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Spiritsleli.jpg|400px|Leliana against the spirits]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=File:Spiritsleli.jpg&amp;diff=16048</id>
		<title>File:Spiritsleli.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=File:Spiritsleli.jpg&amp;diff=16048"/>
				<updated>2011-04-04T05:04:25Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Community_Contest_7:_Module_Contest&amp;diff=16047</id>
		<title>Community Contest 7: Module Contest</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Community_Contest_7:_Module_Contest&amp;diff=16047"/>
				<updated>2011-04-04T00:50:45Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Community_Contest_back.jpg|link=Community_Contest_Main_Page]] [[File:CC_BSN_GetInvolved.jpg|link=http://social.bioware.com/group/2535/&amp;amp;v=discussions]]&lt;br /&gt;
&lt;br /&gt;
== Brief ==&lt;br /&gt;
'''Create a short playable module'''. The module must be compatible with the Contest 7 Framework and must include content from at least three contests in the [[Community_Contest_Catalogue|Community Contest Catalogue]]. See requirements for more information.&lt;br /&gt;
&lt;br /&gt;
We're adding on to a &amp;quot;jobs board&amp;quot;-esque framework, so try and think of short modules which might make sense from that starting point.&lt;br /&gt;
&lt;br /&gt;
The contest discussion thread can be found [http://social.bioware.com/group/2535/discussion/13221/1496060/#post_1496060 here].&lt;br /&gt;
&lt;br /&gt;
'''DEADLINE: Monday 4 April''' - your entry must be ready for judging before midday GMT+0. It is strongly recommended you submit well before this time (sunday!) in case you run into troubles. Modifications to your submission are welcomed - the newest version of your entry will be judged, although modifications made ''after'' the submission date will not be judged.&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
All entries must:&lt;br /&gt;
* reserve a [[Community_Contest_ID_Ranges|string range]] before starting&lt;br /&gt;
* reserve all [[Community_Contest_ID_Ranges#2da_Ranges|M2DA ranges]] they use:&lt;br /&gt;
** Entrants '''will''' need to extend the [[Community_Contest_ID_Ranges#JobBoardPlots|JobBoardPlots]] M2DA&lt;br /&gt;
** Entrants '''may''' have to extend the [[Community_Contest_ID_Ranges#prcscr|PRCSCR]] M2DA&lt;br /&gt;
** Entrants '''may''' also extend other M2DAs - please also reserve these as needed, staying within the [[Community_Contest_ID_Ranges|community contest range]].&lt;br /&gt;
* use the [http://social.bioware.com/project/4161/&amp;amp;v=files Contest 7 Framework]&lt;br /&gt;
* use at least 1 piece of content from 3 or more of the following catalogue sections:&lt;br /&gt;
** settlement level&lt;br /&gt;
** room SEL&lt;br /&gt;
** prop model&lt;br /&gt;
** Character (party/merchant/quest giver)&lt;br /&gt;
** Head morph&lt;br /&gt;
** minigame script&lt;br /&gt;
** equipment&lt;br /&gt;
* '''must be a SHORT module''' - 5-15 minutes gameplay is a good target, but there is no &amp;quot;limit&amp;quot;&lt;br /&gt;
* fulfil the following as a minimum:&lt;br /&gt;
** at least 100 words dialogue&lt;br /&gt;
** a journal entry to track the progress of the quest from being visible on the job board through acceptance to completion&lt;br /&gt;
** at least one combat encounter&lt;br /&gt;
** reward the player, but do so appropriately (do not give a massive reward or overpowered gear for a small job)&lt;br /&gt;
* scale to all levels of player (preferred) OR include a &amp;quot;recommended level&amp;quot; in the job board description&lt;br /&gt;
* complete the [[Community_Contest_6:_Equipment_Contest#Checklist|entry checklist]] below and agree to the [[Community_Contest_6:_Equipment_Contest#Consent_to_Share|Consent to Share]]&lt;br /&gt;
&lt;br /&gt;
=== Guidelines ===&lt;br /&gt;
Strong entries will:&lt;br /&gt;
* not attempt an epic module - a '''smaller scope''' will allow you time to really polish your module.&lt;br /&gt;
* provide an engaging and interesting experience, favouring quality above quantity.&lt;br /&gt;
* avoid repetition and tiresome/uninteresting dialogues and combat.&lt;br /&gt;
* include one or more cutscenes to heighten drama&lt;br /&gt;
&lt;br /&gt;
=== Suggestions ===&lt;br /&gt;
* My *friend/relative* has gone missing while in the *dangerous area*, please investigate!&lt;br /&gt;
* Bounty hunt&lt;br /&gt;
* Any other short quest, really.&lt;br /&gt;
&lt;br /&gt;
=== Allowable ===&lt;br /&gt;
While no &amp;quot;bonus points&amp;quot; will be given for the following, entrants may: &lt;br /&gt;
* enter the contest several times.&lt;br /&gt;
* include new custom content provided it can be shared (see not allowable custom content below)&lt;br /&gt;
&lt;br /&gt;
=== Not Allowable ===&lt;br /&gt;
Please:&lt;br /&gt;
* do not use custom content for which you do not have permission to share, or you do not wish to be shared in the catalogue.&lt;br /&gt;
* do not override core resources unless under exceptional circumstances (if in doubt, ask in the contest thread)&lt;br /&gt;
&lt;br /&gt;
== Groups and Prizes ==&lt;br /&gt;
&lt;br /&gt;
=== Groups ===&lt;br /&gt;
This contest has one group, with higher prizes than normal!&lt;br /&gt;
&lt;br /&gt;
* 1st place - 30 points, chooses first&lt;br /&gt;
* 2nd place - 20 points, chooses second&lt;br /&gt;
* 3rd place - 10 points, chooses third&lt;br /&gt;
* Best Newcomer - 5 points (unless 1st, 2nd or 3rd place)&lt;br /&gt;
* All other entries meeting requirements - 3 points&lt;br /&gt;
&lt;br /&gt;
=== Best Newcomer Award ===&lt;br /&gt;
If an entrant has not entered a Community Contest before, they qualify for the Best Newcomer Award. This award is given to the newcomer with the highest number of votes.&lt;br /&gt;
&lt;br /&gt;
=== Prizes ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Community_Contest_Prizes|Community Contest Prizes]]&lt;br /&gt;
&lt;br /&gt;
== Helpful Links ==&lt;br /&gt;
* [[Community_Contest_ID_Ranges|Reserve your string and GDA IDs here]]&lt;br /&gt;
* [[Community_Contest_Catalogue|Browse Catalogue content here]]&lt;br /&gt;
* [http://social.bioware.com/project/4161/ Community Contest 7 Framework] - includes a *very* useful readme (essential reading!)&lt;br /&gt;
* [[Module_tutorial|Module Tutorial]] - the CC7 framework readme supercedes much information here&lt;br /&gt;
&lt;br /&gt;
= Submitting an Entry = &lt;br /&gt;
&lt;br /&gt;
=== Entry File(s) ===&lt;br /&gt;
&lt;br /&gt;
'''Builder File Contents:'''&lt;br /&gt;
* dadbdata of your module (do not include core resources)&lt;br /&gt;
* any data/override files required. mike will be impressed if you put them in the correct folder... module/data is usually sufficient! core/override is usually over-the-top and conflict-prone)&lt;br /&gt;
&lt;br /&gt;
'''Player File:'''&lt;br /&gt;
(the player file is optional - we'll be bundling them all together)&lt;br /&gt;
&lt;br /&gt;
'''File Format:'''&lt;br /&gt;
.7z file (preferred)&lt;br /&gt;
&lt;br /&gt;
=== Checklist ===&lt;br /&gt;
&lt;br /&gt;
# Create your file (see above)&lt;br /&gt;
# Create a [http://www.dragonagenexus.com/ Dragon Age Nexus] page for your entry and upload the above file. Please include &amp;quot;Community Contest&amp;quot; in the title.&lt;br /&gt;
# Edit '''this''' page with a description and pictures of your content. &lt;br /&gt;
#* Please include pictures which are both functional as well as attractive (so your work can be seen clearly)&lt;br /&gt;
#* Link to your DA Nexus page. See the sample entry.&lt;br /&gt;
# Optionally, let us know in the [http://social.bioware.com/group/2535/#discussions Contest Discussion Thread] that you've entered&lt;br /&gt;
&lt;br /&gt;
For the general entry guidelines (as well as more detail on the above steps), please see the [[Community_Contest_Entry_FAQ|Entry FAQs]]&lt;br /&gt;
&lt;br /&gt;
For information on Judging, please see the [[Community_Contest_Judging|Judging]] page.&lt;br /&gt;
&lt;br /&gt;
== Consent to Share ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;font size=&amp;quot;5&amp;quot; color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;IMPORTANT - consent to share&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;By entering this competition you consent to share your work for other community members to benefit from.&lt;br /&gt;
 Where appropriate, source files should be shared (prop models, VFXProj files). &lt;br /&gt;
 The work *MUST* be your own (obviously you may use DA assets).&lt;br /&gt;
 Others may use and modify your work in their Dragon Age mods, though are encouraged to give credit. &lt;br /&gt;
 As the entries are judged, local copies will be saved If your work is taken down.&lt;br /&gt;
 If your work is taken down, you allow for it to be re-uploaded, crediting the work in your name. &amp;lt;/b&amp;gt; &amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Entries =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sample Entry Placeholder==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=1559 Dragon Age Nexus project page]'''&lt;br /&gt;
This slot will hopefully be replaced by a &amp;quot;proper&amp;quot; sample entry for you to examine.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CC5_mike_roomtop.jpg|303px|Room Plan]] [[File:CC5_mike_roomcorner.jpg|400px|Room Glamour Shot]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Spiders &amp;amp; Knives ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=2535 Dragon Age Nexus project page]'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
''&amp;quot;First catch your client&amp;quot;, to misquote Paragon Beeton.''&lt;br /&gt;
&lt;br /&gt;
''It seemed a simple enough job: earn a few coins by clearing a wandering band of darkspawn out of a Lothering Knight's home. Except that the client has gone missing!''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
Spiders &amp;amp; Knives takes place in and around Lothering, so it needs to be completed before Lothering is destroyed by the darkspawn. The mod is suitable for any class - the main reward item at the end of the main path is tailored to the main player character.&lt;br /&gt;
&lt;br /&gt;
As far as I can tell, the difficulty level is broadly similar to other Lothering quests, whilst the rewards are a little higher - although hopefully not to an unbalancing extent. The main quest path has around 30 minutes of gameplay; there is an alternative, shorter, path of around 15-20 minutes which also provides a nice item as a reward, but less gold.&lt;br /&gt;
&lt;br /&gt;
To begin the quest, look at either the new Job Board in Denerim or the Chanter's Board in Lothering. You might also stumble upon the starting point of the quest whilst exploring around Lothering.&lt;br /&gt;
&lt;br /&gt;
Note that this mod is silent. Instead of VO I have used timed silences, so I recommend you use subtitles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Thanks To/Resources Used:'''&lt;br /&gt;
&lt;br /&gt;
Nimee: for 'A place to call home', from CC5. With apologies for the mess the darkspawn have made of the place.&lt;br /&gt;
&lt;br /&gt;
Lord Uber Dowzen (uberdowzen): for Arbither, from CC3-mini. Also Vaylise whose character's nickname I nicked for her.&lt;br /&gt;
&lt;br /&gt;
Vaylise: The Valorous, armour from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Adonnay: Crow &amp;amp; Crane, twin swords from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Nattfodd: HjorrMikill, greatsword from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Helekanalaith: Knotwood Staff, mages staff from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Gisle Aune: Dagger of Ashyera's Cult, from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
mikemike37: Warhammer, from CC6.&lt;br /&gt;
&lt;br /&gt;
Note that whilst I have used the authors' models for these items, the actual items are mostly my handiwork - so if there's anything wrong it's likely my fault not theirs.&lt;br /&gt;
&lt;br /&gt;
Sunjammer: CC7 Framework, including the new Job Board, and his Builders' Guide.&lt;br /&gt;
&lt;br /&gt;
If I've forgotten anyone, please let me know &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CC7_Web2.jpg|400px|Spider Web]]     [[File:CC7-Knives.jpg|400px|Knives]]&lt;br /&gt;
&lt;br /&gt;
[[File:CC7_My_Home3.jpg|400px|Look what they have done to my home!]]     [[File:CC7_Storage_Chest.jpg|400px|Storage Chest]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Eye and Shadow by Mengtzu ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=2563 Dragon Age Nexus project page]'''&lt;br /&gt;
&lt;br /&gt;
'''For Players:'''&lt;br /&gt;
&lt;br /&gt;
* Challenging encounters designed to teach key skills (focus fire, target selection, burn phases and positioning) - though easier and a bit more accessible than my standalones.&lt;br /&gt;
* Tuned for geared, high level parties, but accessible early to any looking for a profitable challenge&lt;br /&gt;
* Supply-based rewards scaled with level, intended to be conveniently imported to DLC and the expansion&lt;br /&gt;
* A curious situation with some fun twists on Qunari and Elven lore.&lt;br /&gt;
* A total of four possible resolutions to the adventure.&lt;br /&gt;
&lt;br /&gt;
'''For Builders'''&lt;br /&gt;
&lt;br /&gt;
While this odd little scenario may not appeal to all players, the .dadbdata should be of interest to almost any builder.  The module features commented examples of some useful encounter design tricks and scripting practices, including:&lt;br /&gt;
&lt;br /&gt;
* Area heartbeats (timed encounter phases, periodic damage auras, boss health regen)&lt;br /&gt;
* Creature events (damage mitigation based on phase, add spawns on death)&lt;br /&gt;
* Solid basics like function and constant libraries, plot scripting etc.&lt;br /&gt;
&lt;br /&gt;
'''CC Resources used:'''&lt;br /&gt;
&lt;br /&gt;
* Community Contest #1: Lord of Fangs (&amp;quot;Hakkon's Gift&amp;quot;/Eight Knots)  &lt;br /&gt;
* Community Contest #3: Vaylise (&amp;quot;Knives&amp;quot;/Anaris), uberdowzen (&amp;quot;Saarebas&amp;quot;/Kithshok)&lt;br /&gt;
* Community Contest #6: Adonnay (&amp;quot;Crow &amp;amp; Crane&amp;quot;/Geldauran's swords)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Community_Contest_7:_Module_Contest&amp;diff=16046</id>
		<title>Community Contest 7: Module Contest</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Community_Contest_7:_Module_Contest&amp;diff=16046"/>
				<updated>2011-04-04T00:48:39Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* Eye and Shadow by Mengtzu */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Community_Contest_back.jpg|link=Community_Contest_Main_Page]] [[File:CC_BSN_GetInvolved.jpg|link=http://social.bioware.com/group/2535/&amp;amp;v=discussions]]&lt;br /&gt;
&lt;br /&gt;
== Brief ==&lt;br /&gt;
'''Create a short playable module'''. The module must be compatible with the Contest 7 Framework and must include content from at least three contests in the [[Community_Contest_Catalogue|Community Contest Catalogue]]. See requirements for more information.&lt;br /&gt;
&lt;br /&gt;
We're adding on to a &amp;quot;jobs board&amp;quot;-esque framework, so try and think of short modules which might make sense from that starting point.&lt;br /&gt;
&lt;br /&gt;
The contest discussion thread can be found [http://social.bioware.com/group/2535/discussion/13221/1496060/#post_1496060 here].&lt;br /&gt;
&lt;br /&gt;
'''DEADLINE: Monday 4 April''' - your entry must be ready for judging before midday GMT+0. It is strongly recommended you submit well before this time (sunday!) in case you run into troubles. Modifications to your submission are welcomed - the newest version of your entry will be judged, although modifications made ''after'' the submission date will not be judged.&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
All entries must:&lt;br /&gt;
* reserve a [[Community_Contest_ID_Ranges|string range]] before starting&lt;br /&gt;
* reserve all [[Community_Contest_ID_Ranges#2da_Ranges|M2DA ranges]] they use:&lt;br /&gt;
** Entrants '''will''' need to extend the [[Community_Contest_ID_Ranges#JobBoardPlots|JobBoardPlots]] M2DA&lt;br /&gt;
** Entrants '''may''' have to extend the [[Community_Contest_ID_Ranges#prcscr|PRCSCR]] M2DA&lt;br /&gt;
** Entrants '''may''' also extend other M2DAs - please also reserve these as needed, staying within the [[Community_Contest_ID_Ranges|community contest range]].&lt;br /&gt;
* use the [http://social.bioware.com/project/4161/&amp;amp;v=files Contest 7 Framework]&lt;br /&gt;
* use at least 1 piece of content from 3 or more of the following catalogue sections:&lt;br /&gt;
** settlement level&lt;br /&gt;
** room SEL&lt;br /&gt;
** prop model&lt;br /&gt;
** Character (party/merchant/quest giver)&lt;br /&gt;
** Head morph&lt;br /&gt;
** minigame script&lt;br /&gt;
** equipment&lt;br /&gt;
* '''must be a SHORT module''' - 5-15 minutes gameplay is a good target, but there is no &amp;quot;limit&amp;quot;&lt;br /&gt;
* fulfil the following as a minimum:&lt;br /&gt;
** at least 100 words dialogue&lt;br /&gt;
** a journal entry to track the progress of the quest from being visible on the job board through acceptance to completion&lt;br /&gt;
** at least one combat encounter&lt;br /&gt;
** reward the player, but do so appropriately (do not give a massive reward or overpowered gear for a small job)&lt;br /&gt;
* scale to all levels of player (preferred) OR include a &amp;quot;recommended level&amp;quot; in the job board description&lt;br /&gt;
* complete the [[Community_Contest_6:_Equipment_Contest#Checklist|entry checklist]] below and agree to the [[Community_Contest_6:_Equipment_Contest#Consent_to_Share|Consent to Share]]&lt;br /&gt;
&lt;br /&gt;
=== Guidelines ===&lt;br /&gt;
Strong entries will:&lt;br /&gt;
* not attempt an epic module - a '''smaller scope''' will allow you time to really polish your module.&lt;br /&gt;
* provide an engaging and interesting experience, favouring quality above quantity.&lt;br /&gt;
* avoid repetition and tiresome/uninteresting dialogues and combat.&lt;br /&gt;
* include one or more cutscenes to heighten drama&lt;br /&gt;
&lt;br /&gt;
=== Suggestions ===&lt;br /&gt;
* My *friend/relative* has gone missing while in the *dangerous area*, please investigate!&lt;br /&gt;
* Bounty hunt&lt;br /&gt;
* Any other short quest, really.&lt;br /&gt;
&lt;br /&gt;
=== Allowable ===&lt;br /&gt;
While no &amp;quot;bonus points&amp;quot; will be given for the following, entrants may: &lt;br /&gt;
* enter the contest several times.&lt;br /&gt;
* include new custom content provided it can be shared (see not allowable custom content below)&lt;br /&gt;
&lt;br /&gt;
=== Not Allowable ===&lt;br /&gt;
Please:&lt;br /&gt;
* do not use custom content for which you do not have permission to share, or you do not wish to be shared in the catalogue.&lt;br /&gt;
* do not override core resources unless under exceptional circumstances (if in doubt, ask in the contest thread)&lt;br /&gt;
&lt;br /&gt;
== Groups and Prizes ==&lt;br /&gt;
&lt;br /&gt;
=== Groups ===&lt;br /&gt;
This contest has one group, with higher prizes than normal!&lt;br /&gt;
&lt;br /&gt;
* 1st place - 30 points, chooses first&lt;br /&gt;
* 2nd place - 20 points, chooses second&lt;br /&gt;
* 3rd place - 10 points, chooses third&lt;br /&gt;
* Best Newcomer - 5 points (unless 1st, 2nd or 3rd place)&lt;br /&gt;
* All other entries meeting requirements - 3 points&lt;br /&gt;
&lt;br /&gt;
=== Best Newcomer Award ===&lt;br /&gt;
If an entrant has not entered a Community Contest before, they qualify for the Best Newcomer Award. This award is given to the newcomer with the highest number of votes.&lt;br /&gt;
&lt;br /&gt;
=== Prizes ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Community_Contest_Prizes|Community Contest Prizes]]&lt;br /&gt;
&lt;br /&gt;
== Helpful Links ==&lt;br /&gt;
* [[Community_Contest_ID_Ranges|Reserve your string and GDA IDs here]]&lt;br /&gt;
* [[Community_Contest_Catalogue|Browse Catalogue content here]]&lt;br /&gt;
* [http://social.bioware.com/project/4161/ Community Contest 7 Framework] - includes a *very* useful readme (essential reading!)&lt;br /&gt;
* [[Module_tutorial|Module Tutorial]] - the CC7 framework readme supercedes much information here&lt;br /&gt;
&lt;br /&gt;
= Submitting an Entry = &lt;br /&gt;
&lt;br /&gt;
=== Entry File(s) ===&lt;br /&gt;
&lt;br /&gt;
'''Builder File Contents:'''&lt;br /&gt;
* dadbdata of your module (do not include core resources)&lt;br /&gt;
* any data/override files required. mike will be impressed if you put them in the correct folder... module/data is usually sufficient! core/override is usually over-the-top and conflict-prone)&lt;br /&gt;
&lt;br /&gt;
'''Player File:'''&lt;br /&gt;
(the player file is optional - we'll be bundling them all together)&lt;br /&gt;
&lt;br /&gt;
'''File Format:'''&lt;br /&gt;
.7z file (preferred)&lt;br /&gt;
&lt;br /&gt;
=== Checklist ===&lt;br /&gt;
&lt;br /&gt;
# Create your file (see above)&lt;br /&gt;
# Create a [http://www.dragonagenexus.com/ Dragon Age Nexus] page for your entry and upload the above file. Please include &amp;quot;Community Contest&amp;quot; in the title.&lt;br /&gt;
# Edit '''this''' page with a description and pictures of your content. &lt;br /&gt;
#* Please include pictures which are both functional as well as attractive (so your work can be seen clearly)&lt;br /&gt;
#* Link to your DA Nexus page. See the sample entry.&lt;br /&gt;
# Optionally, let us know in the [http://social.bioware.com/group/2535/#discussions Contest Discussion Thread] that you've entered&lt;br /&gt;
&lt;br /&gt;
For the general entry guidelines (as well as more detail on the above steps), please see the [[Community_Contest_Entry_FAQ|Entry FAQs]]&lt;br /&gt;
&lt;br /&gt;
For information on Judging, please see the [[Community_Contest_Judging|Judging]] page.&lt;br /&gt;
&lt;br /&gt;
== Consent to Share ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;font size=&amp;quot;5&amp;quot; color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;IMPORTANT - consent to share&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;By entering this competition you consent to share your work for other community members to benefit from.&lt;br /&gt;
 Where appropriate, source files should be shared (prop models, VFXProj files). &lt;br /&gt;
 The work *MUST* be your own (obviously you may use DA assets).&lt;br /&gt;
 Others may use and modify your work in their Dragon Age mods, though are encouraged to give credit. &lt;br /&gt;
 As the entries are judged, local copies will be saved If your work is taken down.&lt;br /&gt;
 If your work is taken down, you allow for it to be re-uploaded, crediting the work in your name. &amp;lt;/b&amp;gt; &amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Entries =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sample Entry Placeholder==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=1559 Dragon Age Nexus project page]'''&lt;br /&gt;
This slot will hopefully be replaced by a &amp;quot;proper&amp;quot; sample entry for you to examine.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CC5_mike_roomtop.jpg|303px|Room Plan]] [[File:CC5_mike_roomcorner.jpg|400px|Room Glamour Shot]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Spiders &amp;amp; Knives ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=2535 Dragon Age Nexus project page]'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
''&amp;quot;First catch your client&amp;quot;, to misquote Paragon Beeton.''&lt;br /&gt;
&lt;br /&gt;
''It seemed a simple enough job: earn a few coins by clearing a wandering band of darkspawn out of a Lothering Knight's home. Except that the client has gone missing!''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
Spiders &amp;amp; Knives takes place in and around Lothering, so it needs to be completed before Lothering is destroyed by the darkspawn. The mod is suitable for any class - the main reward item at the end of the main path is tailored to the main player character.&lt;br /&gt;
&lt;br /&gt;
As far as I can tell, the difficulty level is broadly similar to other Lothering quests, whilst the rewards are a little higher - although hopefully not to an unbalancing extent. The main quest path has around 30 minutes of gameplay; there is an alternative, shorter, path of around 15-20 minutes which also provides a nice item as a reward, but less gold.&lt;br /&gt;
&lt;br /&gt;
To begin the quest, look at either the new Job Board in Denerim or the Chanter's Board in Lothering. You might also stumble upon the starting point of the quest whilst exploring around Lothering.&lt;br /&gt;
&lt;br /&gt;
Note that this mod is silent. Instead of VO I have used timed silences, so I recommend you use subtitles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Thanks To/Resources Used:'''&lt;br /&gt;
&lt;br /&gt;
Nimee: for 'A place to call home', from CC5. With apologies for the mess the darkspawn have made of the place.&lt;br /&gt;
&lt;br /&gt;
Lord Uber Dowzen (uberdowzen): for Arbither, from CC3-mini. Also Vaylise whose character's nickname I nicked for her.&lt;br /&gt;
&lt;br /&gt;
Vaylise: The Valorous, armour from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Adonnay: Crow &amp;amp; Crane, twin swords from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Nattfodd: HjorrMikill, greatsword from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Helekanalaith: Knotwood Staff, mages staff from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Gisle Aune: Dagger of Ashyera's Cult, from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
mikemike37: Warhammer, from CC6.&lt;br /&gt;
&lt;br /&gt;
Note that whilst I have used the authors' models for these items, the actual items are mostly my handiwork - so if there's anything wrong it's likely my fault not theirs.&lt;br /&gt;
&lt;br /&gt;
Sunjammer: CC7 Framework, including the new Job Board, and his Builders' Guide.&lt;br /&gt;
&lt;br /&gt;
If I've forgotten anyone, please let me know &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CC7_Web2.jpg|400px|Spider Web]]     [[File:CC7-Knives.jpg|400px|Knives]]&lt;br /&gt;
&lt;br /&gt;
[[File:CC7_My_Home3.jpg|400px|Look what they have done to my home!]]     [[File:CC7_Storage_Chest.jpg|400px|Storage Chest]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Eye and Shadow by Mengtzu ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=2563]'''&lt;br /&gt;
&lt;br /&gt;
'''For Players:'''&lt;br /&gt;
&lt;br /&gt;
* Challenging encounters designed to teach key skills (focus fire, target selection, burn phases and positioning) - though easier and a bit more accessible than my standalones.&lt;br /&gt;
* Tuned for geared, high level parties, but accessible early to any looking for a profitable challenge&lt;br /&gt;
* Supply-based rewards scaled with level, intended to be conveniently imported to DLC and the expansion&lt;br /&gt;
* A curious situation with some fun twists on Qunari and Elven lore.&lt;br /&gt;
* A total of four possible resolutions to the adventure.&lt;br /&gt;
&lt;br /&gt;
'''For Builders'''&lt;br /&gt;
&lt;br /&gt;
While this odd little scenario may not appeal to all players, the .dadbdata should be of interest to almost any builder.  The module features commented examples of some useful encounter design tricks and scripting practices, including:&lt;br /&gt;
&lt;br /&gt;
* Area heartbeats (timed encounter phases, periodic damage auras, boss health regen)&lt;br /&gt;
* Creature events (damage mitigation based on phase, add spawns on death)&lt;br /&gt;
* Solid basics like function and constant libraries, plot scripting etc.&lt;br /&gt;
&lt;br /&gt;
'''CC Resources used:'''&lt;br /&gt;
&lt;br /&gt;
Community Contest #1: Lord of Fangs (&amp;quot;Hakkon's Gift&amp;quot;/Eight Knots)  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Community Contest #3: Vaylise (&amp;quot;Knives&amp;quot;/Anaris), uberdowzen (&amp;quot;Saarebas&amp;quot;/Kithshok)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Community Contest #6: Adonnay (&amp;quot;Crow &amp;amp; Crane&amp;quot;/Geldauran's swords)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Community_Contest_7:_Module_Contest&amp;diff=16045</id>
		<title>Community Contest 7: Module Contest</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Community_Contest_7:_Module_Contest&amp;diff=16045"/>
				<updated>2011-04-04T00:47:22Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Community_Contest_back.jpg|link=Community_Contest_Main_Page]] [[File:CC_BSN_GetInvolved.jpg|link=http://social.bioware.com/group/2535/&amp;amp;v=discussions]]&lt;br /&gt;
&lt;br /&gt;
== Brief ==&lt;br /&gt;
'''Create a short playable module'''. The module must be compatible with the Contest 7 Framework and must include content from at least three contests in the [[Community_Contest_Catalogue|Community Contest Catalogue]]. See requirements for more information.&lt;br /&gt;
&lt;br /&gt;
We're adding on to a &amp;quot;jobs board&amp;quot;-esque framework, so try and think of short modules which might make sense from that starting point.&lt;br /&gt;
&lt;br /&gt;
The contest discussion thread can be found [http://social.bioware.com/group/2535/discussion/13221/1496060/#post_1496060 here].&lt;br /&gt;
&lt;br /&gt;
'''DEADLINE: Monday 4 April''' - your entry must be ready for judging before midday GMT+0. It is strongly recommended you submit well before this time (sunday!) in case you run into troubles. Modifications to your submission are welcomed - the newest version of your entry will be judged, although modifications made ''after'' the submission date will not be judged.&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
All entries must:&lt;br /&gt;
* reserve a [[Community_Contest_ID_Ranges|string range]] before starting&lt;br /&gt;
* reserve all [[Community_Contest_ID_Ranges#2da_Ranges|M2DA ranges]] they use:&lt;br /&gt;
** Entrants '''will''' need to extend the [[Community_Contest_ID_Ranges#JobBoardPlots|JobBoardPlots]] M2DA&lt;br /&gt;
** Entrants '''may''' have to extend the [[Community_Contest_ID_Ranges#prcscr|PRCSCR]] M2DA&lt;br /&gt;
** Entrants '''may''' also extend other M2DAs - please also reserve these as needed, staying within the [[Community_Contest_ID_Ranges|community contest range]].&lt;br /&gt;
* use the [http://social.bioware.com/project/4161/&amp;amp;v=files Contest 7 Framework]&lt;br /&gt;
* use at least 1 piece of content from 3 or more of the following catalogue sections:&lt;br /&gt;
** settlement level&lt;br /&gt;
** room SEL&lt;br /&gt;
** prop model&lt;br /&gt;
** Character (party/merchant/quest giver)&lt;br /&gt;
** Head morph&lt;br /&gt;
** minigame script&lt;br /&gt;
** equipment&lt;br /&gt;
* '''must be a SHORT module''' - 5-15 minutes gameplay is a good target, but there is no &amp;quot;limit&amp;quot;&lt;br /&gt;
* fulfil the following as a minimum:&lt;br /&gt;
** at least 100 words dialogue&lt;br /&gt;
** a journal entry to track the progress of the quest from being visible on the job board through acceptance to completion&lt;br /&gt;
** at least one combat encounter&lt;br /&gt;
** reward the player, but do so appropriately (do not give a massive reward or overpowered gear for a small job)&lt;br /&gt;
* scale to all levels of player (preferred) OR include a &amp;quot;recommended level&amp;quot; in the job board description&lt;br /&gt;
* complete the [[Community_Contest_6:_Equipment_Contest#Checklist|entry checklist]] below and agree to the [[Community_Contest_6:_Equipment_Contest#Consent_to_Share|Consent to Share]]&lt;br /&gt;
&lt;br /&gt;
=== Guidelines ===&lt;br /&gt;
Strong entries will:&lt;br /&gt;
* not attempt an epic module - a '''smaller scope''' will allow you time to really polish your module.&lt;br /&gt;
* provide an engaging and interesting experience, favouring quality above quantity.&lt;br /&gt;
* avoid repetition and tiresome/uninteresting dialogues and combat.&lt;br /&gt;
* include one or more cutscenes to heighten drama&lt;br /&gt;
&lt;br /&gt;
=== Suggestions ===&lt;br /&gt;
* My *friend/relative* has gone missing while in the *dangerous area*, please investigate!&lt;br /&gt;
* Bounty hunt&lt;br /&gt;
* Any other short quest, really.&lt;br /&gt;
&lt;br /&gt;
=== Allowable ===&lt;br /&gt;
While no &amp;quot;bonus points&amp;quot; will be given for the following, entrants may: &lt;br /&gt;
* enter the contest several times.&lt;br /&gt;
* include new custom content provided it can be shared (see not allowable custom content below)&lt;br /&gt;
&lt;br /&gt;
=== Not Allowable ===&lt;br /&gt;
Please:&lt;br /&gt;
* do not use custom content for which you do not have permission to share, or you do not wish to be shared in the catalogue.&lt;br /&gt;
* do not override core resources unless under exceptional circumstances (if in doubt, ask in the contest thread)&lt;br /&gt;
&lt;br /&gt;
== Groups and Prizes ==&lt;br /&gt;
&lt;br /&gt;
=== Groups ===&lt;br /&gt;
This contest has one group, with higher prizes than normal!&lt;br /&gt;
&lt;br /&gt;
* 1st place - 30 points, chooses first&lt;br /&gt;
* 2nd place - 20 points, chooses second&lt;br /&gt;
* 3rd place - 10 points, chooses third&lt;br /&gt;
* Best Newcomer - 5 points (unless 1st, 2nd or 3rd place)&lt;br /&gt;
* All other entries meeting requirements - 3 points&lt;br /&gt;
&lt;br /&gt;
=== Best Newcomer Award ===&lt;br /&gt;
If an entrant has not entered a Community Contest before, they qualify for the Best Newcomer Award. This award is given to the newcomer with the highest number of votes.&lt;br /&gt;
&lt;br /&gt;
=== Prizes ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Community_Contest_Prizes|Community Contest Prizes]]&lt;br /&gt;
&lt;br /&gt;
== Helpful Links ==&lt;br /&gt;
* [[Community_Contest_ID_Ranges|Reserve your string and GDA IDs here]]&lt;br /&gt;
* [[Community_Contest_Catalogue|Browse Catalogue content here]]&lt;br /&gt;
* [http://social.bioware.com/project/4161/ Community Contest 7 Framework] - includes a *very* useful readme (essential reading!)&lt;br /&gt;
* [[Module_tutorial|Module Tutorial]] - the CC7 framework readme supercedes much information here&lt;br /&gt;
&lt;br /&gt;
= Submitting an Entry = &lt;br /&gt;
&lt;br /&gt;
=== Entry File(s) ===&lt;br /&gt;
&lt;br /&gt;
'''Builder File Contents:'''&lt;br /&gt;
* dadbdata of your module (do not include core resources)&lt;br /&gt;
* any data/override files required. mike will be impressed if you put them in the correct folder... module/data is usually sufficient! core/override is usually over-the-top and conflict-prone)&lt;br /&gt;
&lt;br /&gt;
'''Player File:'''&lt;br /&gt;
(the player file is optional - we'll be bundling them all together)&lt;br /&gt;
&lt;br /&gt;
'''File Format:'''&lt;br /&gt;
.7z file (preferred)&lt;br /&gt;
&lt;br /&gt;
=== Checklist ===&lt;br /&gt;
&lt;br /&gt;
# Create your file (see above)&lt;br /&gt;
# Create a [http://www.dragonagenexus.com/ Dragon Age Nexus] page for your entry and upload the above file. Please include &amp;quot;Community Contest&amp;quot; in the title.&lt;br /&gt;
# Edit '''this''' page with a description and pictures of your content. &lt;br /&gt;
#* Please include pictures which are both functional as well as attractive (so your work can be seen clearly)&lt;br /&gt;
#* Link to your DA Nexus page. See the sample entry.&lt;br /&gt;
# Optionally, let us know in the [http://social.bioware.com/group/2535/#discussions Contest Discussion Thread] that you've entered&lt;br /&gt;
&lt;br /&gt;
For the general entry guidelines (as well as more detail on the above steps), please see the [[Community_Contest_Entry_FAQ|Entry FAQs]]&lt;br /&gt;
&lt;br /&gt;
For information on Judging, please see the [[Community_Contest_Judging|Judging]] page.&lt;br /&gt;
&lt;br /&gt;
== Consent to Share ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;font size=&amp;quot;5&amp;quot; color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;IMPORTANT - consent to share&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;By entering this competition you consent to share your work for other community members to benefit from.&lt;br /&gt;
 Where appropriate, source files should be shared (prop models, VFXProj files). &lt;br /&gt;
 The work *MUST* be your own (obviously you may use DA assets).&lt;br /&gt;
 Others may use and modify your work in their Dragon Age mods, though are encouraged to give credit. &lt;br /&gt;
 As the entries are judged, local copies will be saved If your work is taken down.&lt;br /&gt;
 If your work is taken down, you allow for it to be re-uploaded, crediting the work in your name. &amp;lt;/b&amp;gt; &amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Entries =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sample Entry Placeholder==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=1559 Dragon Age Nexus project page]'''&lt;br /&gt;
This slot will hopefully be replaced by a &amp;quot;proper&amp;quot; sample entry for you to examine.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CC5_mike_roomtop.jpg|303px|Room Plan]] [[File:CC5_mike_roomcorner.jpg|400px|Room Glamour Shot]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Spiders &amp;amp; Knives ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=2535 Dragon Age Nexus project page]'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
''&amp;quot;First catch your client&amp;quot;, to misquote Paragon Beeton.''&lt;br /&gt;
&lt;br /&gt;
''It seemed a simple enough job: earn a few coins by clearing a wandering band of darkspawn out of a Lothering Knight's home. Except that the client has gone missing!''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
Spiders &amp;amp; Knives takes place in and around Lothering, so it needs to be completed before Lothering is destroyed by the darkspawn. The mod is suitable for any class - the main reward item at the end of the main path is tailored to the main player character.&lt;br /&gt;
&lt;br /&gt;
As far as I can tell, the difficulty level is broadly similar to other Lothering quests, whilst the rewards are a little higher - although hopefully not to an unbalancing extent. The main quest path has around 30 minutes of gameplay; there is an alternative, shorter, path of around 15-20 minutes which also provides a nice item as a reward, but less gold.&lt;br /&gt;
&lt;br /&gt;
To begin the quest, look at either the new Job Board in Denerim or the Chanter's Board in Lothering. You might also stumble upon the starting point of the quest whilst exploring around Lothering.&lt;br /&gt;
&lt;br /&gt;
Note that this mod is silent. Instead of VO I have used timed silences, so I recommend you use subtitles.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
'''Thanks To/Resources Used:'''&lt;br /&gt;
&lt;br /&gt;
Nimee: for 'A place to call home', from CC5. With apologies for the mess the darkspawn have made of the place.&lt;br /&gt;
&lt;br /&gt;
Lord Uber Dowzen (uberdowzen): for Arbither, from CC3-mini. Also Vaylise whose character's nickname I nicked for her.&lt;br /&gt;
&lt;br /&gt;
Vaylise: The Valorous, armour from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Adonnay: Crow &amp;amp; Crane, twin swords from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Nattfodd: HjorrMikill, greatsword from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Helekanalaith: Knotwood Staff, mages staff from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
Gisle Aune: Dagger of Ashyera's Cult, from CC6.&amp;lt;br/&amp;gt;&lt;br /&gt;
mikemike37: Warhammer, from CC6.&lt;br /&gt;
&lt;br /&gt;
Note that whilst I have used the authors' models for these items, the actual items are mostly my handiwork - so if there's anything wrong it's likely my fault not theirs.&lt;br /&gt;
&lt;br /&gt;
Sunjammer: CC7 Framework, including the new Job Board, and his Builders' Guide.&lt;br /&gt;
&lt;br /&gt;
If I've forgotten anyone, please let me know &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CC7_Web2.jpg|400px|Spider Web]]     [[File:CC7-Knives.jpg|400px|Knives]]&lt;br /&gt;
&lt;br /&gt;
[[File:CC7_My_Home3.jpg|400px|Look what they have done to my home!]]     [[File:CC7_Storage_Chest.jpg|400px|Storage Chest]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Eye and Shadow by Mengtzu ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=2563]'''&lt;br /&gt;
&lt;br /&gt;
'''For Players:'''&lt;br /&gt;
&lt;br /&gt;
- Challenging encounters designed to teach key skills (focus fire, target selection, burn phases and positioning) - though easier and a bit more accessible than my standalones.&lt;br /&gt;
- Tuned for geared, high level parties, but accessible early to any looking for a profitable challenge&lt;br /&gt;
- Supply-based rewards scaled with level, intended to be conveniently imported to DLC and the expansion&lt;br /&gt;
- A curious situation with some fun twists on Qunari and Elven lore.&lt;br /&gt;
- A total of four possible resolutions to the adventure.&lt;br /&gt;
&lt;br /&gt;
'''For Builders'''&lt;br /&gt;
&lt;br /&gt;
While this odd little scenario may not appeal to all players, the .dadbdata should be of interest to almost any builder.  The module features commented examples of some useful encounter design tricks and scripting practices, including:&lt;br /&gt;
&lt;br /&gt;
- Area heartbeats (timed encounter phases, periodic damage auras, boss health regen)&lt;br /&gt;
- Creature events (damage mitigation based on phase, add spawns on death)&lt;br /&gt;
- Solid basics like function and constant libraries, plot scripting etc.&lt;br /&gt;
&lt;br /&gt;
'''CC Resources used:'''&lt;br /&gt;
&lt;br /&gt;
Community Contest #1: Lord of Fangs (&amp;quot;Hakkon's Gift&amp;quot;/Eight Knots)  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Community Contest #3: Vaylise (&amp;quot;Knives&amp;quot;/Anaris), uberdowzen (&amp;quot;Saarebas&amp;quot;/Kithshok)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Community Contest #6: Adonnay (&amp;quot;Crow &amp;amp; Crane&amp;quot;/Geldauran's swords)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Community_Contest_ID_Ranges&amp;diff=16035</id>
		<title>Community Contest ID Ranges</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Community_Contest_ID_Ranges&amp;diff=16035"/>
				<updated>2011-03-31T02:12:08Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Community_Contest_back.jpg|link=Community_Contest_Main_Page]] [[File:CC_BSN_GetInvolved.jpg|link=http://social.bioware.com/group/2535/&amp;amp;v=discussions]]&lt;br /&gt;
&lt;br /&gt;
So that all Community Contest entries are compatible with one another and also with other mods that are around, IDs must not conflict. To ensure this, we must reserve ID ranges for strings and 2da ranges.&lt;br /&gt;
&lt;br /&gt;
= String ranges = &lt;br /&gt;
&lt;br /&gt;
Please modify this table to reserve String IDs '''before you use them''' (to avoid lost work). Append within our range if required. Please do not use from outside this range.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''89000000''' &lt;br /&gt;
| '''89999999''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 89000000&lt;br /&gt;
| 89099999&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| ''89001000''&lt;br /&gt;
| ''89001999''&lt;br /&gt;
| ''CC6 bundle''&lt;br /&gt;
|-&lt;br /&gt;
| ''89002000''&lt;br /&gt;
| ''89002099''&lt;br /&gt;
| ''CC7 framework''&lt;br /&gt;
|-&lt;br /&gt;
| 89100000&lt;br /&gt;
| 89100999&lt;br /&gt;
| Cuvieronius&lt;br /&gt;
|-&lt;br /&gt;
| 89101000&lt;br /&gt;
| 89101999&lt;br /&gt;
| Vaylise&lt;br /&gt;
|-&lt;br /&gt;
| 89102000&lt;br /&gt;
| 89102999&lt;br /&gt;
| BAPACop&lt;br /&gt;
|-&lt;br /&gt;
| 89103000&lt;br /&gt;
| 89103999&lt;br /&gt;
| BloodsongVengeance&lt;br /&gt;
|-&lt;br /&gt;
| 89104000&lt;br /&gt;
| 89104999&lt;br /&gt;
| Jackkel Dragon&lt;br /&gt;
|-&lt;br /&gt;
| 89105000&lt;br /&gt;
| 89105999&lt;br /&gt;
| Lord Uber Dowzen (uberdowzen)&lt;br /&gt;
|-&lt;br /&gt;
| 89106000&lt;br /&gt;
| 89106999&lt;br /&gt;
| Shadow5973&lt;br /&gt;
|-&lt;br /&gt;
| 89107000&lt;br /&gt;
| 89107999&lt;br /&gt;
| Lobo&lt;br /&gt;
|-&lt;br /&gt;
| 89108000&lt;br /&gt;
| 89108999&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 89109000&lt;br /&gt;
| 89109999&lt;br /&gt;
| Mengtzu&lt;br /&gt;
|-&lt;br /&gt;
| 89110000&lt;br /&gt;
| 89110999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89111000&lt;br /&gt;
| 89111999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89112000&lt;br /&gt;
| 89112999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89113000&lt;br /&gt;
| 89113999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89114000&lt;br /&gt;
| 89114999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89115000&lt;br /&gt;
| 89115999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89116000&lt;br /&gt;
| 89116999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89117000&lt;br /&gt;
| 89117999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89118000&lt;br /&gt;
| 89118999&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|-&lt;br /&gt;
| 89119000&lt;br /&gt;
| 89122999&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| 89123000&lt;br /&gt;
| 89123999&lt;br /&gt;
| uberdowzen&lt;br /&gt;
|-&lt;br /&gt;
| 89124000&lt;br /&gt;
| 89124999&lt;br /&gt;
| Sunjammer&lt;br /&gt;
|-&lt;br /&gt;
| 89125000&lt;br /&gt;
| 89125999&lt;br /&gt;
| Mengtzu&lt;br /&gt;
|-&lt;br /&gt;
| 89126000&lt;br /&gt;
| 89126999&lt;br /&gt;
| Mengtzu&lt;br /&gt;
|-&lt;br /&gt;
| 89127000&lt;br /&gt;
| 89127999&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Why reserve an ID range? ===&lt;br /&gt;
This prevents the need for other modders to change your strings. This prevents any chance of overlapping IDs with other entries or other mods. This means that if you attach voice to conversations, or specify a StringID in a 2da, these connections will not be broken when others use your mod.&lt;br /&gt;
&lt;br /&gt;
=== How many do I reserve? ===&lt;br /&gt;
Just take 1000 unless you need more. Do not take less, we've got plenty to spare ;)&lt;br /&gt;
&lt;br /&gt;
=== How do I set my module to use those strings? ===&lt;br /&gt;
&lt;br /&gt;
* While logged in to builder wiki (same as login here), edit the page to put your name next to the range.&lt;br /&gt;
* In Toolset, go File &amp;gt; Manage Modules &amp;gt; (select your module) &amp;gt; Properties&lt;br /&gt;
* Set the following:&lt;br /&gt;
** StringID Begin&lt;br /&gt;
** StringID End&lt;br /&gt;
** StringID Last Used&lt;br /&gt;
* Hit OK and close dialogue.&lt;br /&gt;
&lt;br /&gt;
= 2da Ranges =&lt;br /&gt;
&lt;br /&gt;
We have reserved 24000 - 26000 in most 2das. Please reserve as many as you anticipate you will need, but don't be wasteful (reserving 200 when you only need 6 is wasteful). If you need hundreds, it's probably worth reserving your own range outside of the contest range.&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
=== M2DA_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24499&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| 24500&lt;br /&gt;
| 24509&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 24510&lt;br /&gt;
| 24519&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ABI_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24499&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| 24500&lt;br /&gt;
| 24509&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 24510&lt;br /&gt;
| 24513&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|-&lt;br /&gt;
| 24513&lt;br /&gt;
| 24519&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== placeable_types ===&lt;br /&gt;
&lt;br /&gt;
''nb a bug is causing the range of 24000 and above to not work in-game so we're using 14000-16000 instead.''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''14000''' &lt;br /&gt;
| '''16000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 14000&lt;br /&gt;
| 14499&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| 14500&lt;br /&gt;
| 14509&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 14510&lt;br /&gt;
| 14519&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| 14520&lt;br /&gt;
| 14529&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== areadata ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24009&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== BITM_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== guitypes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== itemprps ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24003&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== itemstats ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== JobBoardPlots ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| CC7 Framework&lt;br /&gt;
|-&lt;br /&gt;
| 24002&lt;br /&gt;
| 24006&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| 24007&lt;br /&gt;
| 24007&lt;br /&gt;
| Mengtzu&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== JobBoards ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24000&lt;br /&gt;
| CC7 Framework&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== materialrules ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== materialtypes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== prcscr ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|-&lt;br /&gt;
| 24002&lt;br /&gt;
| 24002&lt;br /&gt;
| CC7 Framework&lt;br /&gt;
|-&lt;br /&gt;
| 24003&lt;br /&gt;
| 24006&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| 24007&lt;br /&gt;
| 24007&lt;br /&gt;
| CC7 Framework&lt;br /&gt;
|-&lt;br /&gt;
| 24008&lt;br /&gt;
| 24019&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sound_item_materials ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sound_weapon_actions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sound_weapon_hits ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ts_material ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== vfx_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24003&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Variation sheets ==&lt;br /&gt;
&lt;br /&gt;
=== weapons and shields ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sheet&lt;br /&gt;
! ID reserved&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''All variations sheets'''&lt;br /&gt;
| '''140 - 160''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| mace_variation&lt;br /&gt;
| 140&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| mace_variation&lt;br /&gt;
| 141 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| mace_variation&lt;br /&gt;
| 142 &lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| staff_variation&lt;br /&gt;
| 140&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| staff_variation&lt;br /&gt;
| 141&lt;br /&gt;
| Helekanalaith&lt;br /&gt;
|-&lt;br /&gt;
| waraxe_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| maul_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| longsword_variation&lt;br /&gt;
| 150 - 151&lt;br /&gt;
| Adonnay&lt;br /&gt;
|-&lt;br /&gt;
| greatsword_variation&lt;br /&gt;
| 140 and 143 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| greatsword_variation&lt;br /&gt;
| 142 &lt;br /&gt;
| Nattfodd&lt;br /&gt;
|-&lt;br /&gt;
| dagger_variation&lt;br /&gt;
| 140-141 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| dagger_variation&lt;br /&gt;
| 142 &lt;br /&gt;
| Gisle Aune&lt;br /&gt;
|-&lt;br /&gt;
| battleaxe_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| bolt_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
=== armour and clothes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sheet&lt;br /&gt;
! ID reserved&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''All variations sheets'''&lt;br /&gt;
| '''140 - 160''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| armor_light_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| armor_light_variation&lt;br /&gt;
| 141&lt;br /&gt;
| example - delete me!&lt;br /&gt;
|-&lt;br /&gt;
| armor_light_variation&lt;br /&gt;
| 142&lt;br /&gt;
| Vaylise&lt;br /&gt;
|-&lt;br /&gt;
| helmet_light_variation&lt;br /&gt;
| 140&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| gloves_massive_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| example - delete me!&lt;br /&gt;
|-&lt;br /&gt;
| gloves_massive_variation&lt;br /&gt;
| 141 &lt;br /&gt;
| example - delete me!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= World Map Pins = &lt;br /&gt;
&lt;br /&gt;
Community Contest #7 requires map pins to be added to the existing Single Player maps.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Map !! X !! Y !! Used by &lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 605 || 570 || CC#7 Framework Tutorial&lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 371 || 424 || BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 600 || 278 || BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 699 || 293 || uberdowzen&lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 72 || 594 || Mengtzu&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Community_Contest_ID_Ranges&amp;diff=15987</id>
		<title>Community Contest ID Ranges</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Community_Contest_ID_Ranges&amp;diff=15987"/>
				<updated>2011-03-19T06:09:38Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Community_Contest_back.jpg|link=Community_Contest_Main_Page]] [[File:CC_BSN_GetInvolved.jpg|link=http://social.bioware.com/group/2535/&amp;amp;v=discussions]]&lt;br /&gt;
&lt;br /&gt;
So that all Community Contest entries are compatible with one another and also with other mods that are around, IDs must not conflict. To ensure this, we must reserve ID ranges for strings and 2da ranges.&lt;br /&gt;
&lt;br /&gt;
= String ranges = &lt;br /&gt;
&lt;br /&gt;
Please modify this table to reserve String IDs '''before you use them''' (to avoid lost work). Append within our range if required. Please do not use from outside this range.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''89000000''' &lt;br /&gt;
| '''89999999''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 89000000&lt;br /&gt;
| 89099999&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| ''89001000''&lt;br /&gt;
| ''89001999''&lt;br /&gt;
| ''CC6 bundle''&lt;br /&gt;
|-&lt;br /&gt;
| ''89002000''&lt;br /&gt;
| ''89002099''&lt;br /&gt;
| ''CC7 framework''&lt;br /&gt;
|-&lt;br /&gt;
| 89100000&lt;br /&gt;
| 89100999&lt;br /&gt;
| Cuvieronius&lt;br /&gt;
|-&lt;br /&gt;
| 89101000&lt;br /&gt;
| 89101999&lt;br /&gt;
| Vaylise&lt;br /&gt;
|-&lt;br /&gt;
| 89102000&lt;br /&gt;
| 89102999&lt;br /&gt;
| BAPACop&lt;br /&gt;
|-&lt;br /&gt;
| 89103000&lt;br /&gt;
| 89103999&lt;br /&gt;
| BloodsongVengeance&lt;br /&gt;
|-&lt;br /&gt;
| 89104000&lt;br /&gt;
| 89104999&lt;br /&gt;
| Jackkel Dragon&lt;br /&gt;
|-&lt;br /&gt;
| 89105000&lt;br /&gt;
| 89105999&lt;br /&gt;
| Lord Uber Dowzen (uberdowzen)&lt;br /&gt;
|-&lt;br /&gt;
| 89106000&lt;br /&gt;
| 89106999&lt;br /&gt;
| Shadow5973&lt;br /&gt;
|-&lt;br /&gt;
| 89107000&lt;br /&gt;
| 89107999&lt;br /&gt;
| Lobo&lt;br /&gt;
|-&lt;br /&gt;
| 89108000&lt;br /&gt;
| 89108999&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 89109000&lt;br /&gt;
| 89109999&lt;br /&gt;
| Mengtzu&lt;br /&gt;
|-&lt;br /&gt;
| 89110000&lt;br /&gt;
| 89110999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89111000&lt;br /&gt;
| 89111999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89112000&lt;br /&gt;
| 89112999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89113000&lt;br /&gt;
| 89113999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89114000&lt;br /&gt;
| 89114999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89115000&lt;br /&gt;
| 89115999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89116000&lt;br /&gt;
| 89116999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89117000&lt;br /&gt;
| 89117999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89118000&lt;br /&gt;
| 89118999&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|-&lt;br /&gt;
| 89119000&lt;br /&gt;
| 89122999&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| 89123000&lt;br /&gt;
| 89123999&lt;br /&gt;
| uberdowzen&lt;br /&gt;
|-&lt;br /&gt;
| 89124000&lt;br /&gt;
| 89124999&lt;br /&gt;
| Sunjammer&lt;br /&gt;
|-&lt;br /&gt;
| 89125000&lt;br /&gt;
| 89125999&lt;br /&gt;
| Mengtzu&lt;br /&gt;
|-&lt;br /&gt;
| 89126000&lt;br /&gt;
| 89126999&lt;br /&gt;
| Mengtzu&lt;br /&gt;
|-&lt;br /&gt;
| 89127000&lt;br /&gt;
| 89127999&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Why reserve an ID range? ===&lt;br /&gt;
This prevents the need for other modders to change your strings. This prevents any chance of overlapping IDs with other entries or other mods. This means that if you attach voice to conversations, or specify a StringID in a 2da, these connections will not be broken when others use your mod.&lt;br /&gt;
&lt;br /&gt;
=== How many do I reserve? ===&lt;br /&gt;
Just take 1000 unless you need more. Do not take less, we've got plenty to spare ;)&lt;br /&gt;
&lt;br /&gt;
=== How do I set my module to use those strings? ===&lt;br /&gt;
&lt;br /&gt;
* While logged in to builder wiki (same as login here), edit the page to put your name next to the range.&lt;br /&gt;
* In Toolset, go File &amp;gt; Manage Modules &amp;gt; (select your module) &amp;gt; Properties&lt;br /&gt;
* Set the following:&lt;br /&gt;
** StringID Begin&lt;br /&gt;
** StringID End&lt;br /&gt;
** StringID Last Used&lt;br /&gt;
* Hit OK and close dialogue.&lt;br /&gt;
&lt;br /&gt;
= 2da Ranges =&lt;br /&gt;
&lt;br /&gt;
We have reserved 24000 - 26000 in most 2das. Please reserve as many as you anticipate you will need, but don't be wasteful (reserving 200 when you only need 6 is wasteful). If you need hundreds, it's probably worth reserving your own range outside of the contest range.&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
=== M2DA_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24499&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| 24500&lt;br /&gt;
| 24509&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 24510&lt;br /&gt;
| 24519&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ABI_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24499&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| 24500&lt;br /&gt;
| 24509&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 24510&lt;br /&gt;
| 24513&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|-&lt;br /&gt;
| 24513&lt;br /&gt;
| 24519&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== placeable_types ===&lt;br /&gt;
&lt;br /&gt;
''nb a bug is causing the range of 24000 and above to not work in-game so we're using 14000-16000 instead.''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''14000''' &lt;br /&gt;
| '''16000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 14000&lt;br /&gt;
| 14499&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| 14500&lt;br /&gt;
| 14509&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 14510&lt;br /&gt;
| 14519&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| 14520&lt;br /&gt;
| 14529&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== areadata ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24009&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== BITM_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== guitypes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== itemprps ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24003&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== itemstats ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== JobBoardPlots ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| CC7 Framework&lt;br /&gt;
|-&lt;br /&gt;
| 24002&lt;br /&gt;
| 24006&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== JobBoards ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24000&lt;br /&gt;
| CC7 Framework&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== materialrules ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== materialtypes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== prcscr ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|-&lt;br /&gt;
| 24002&lt;br /&gt;
| 24002&lt;br /&gt;
| CC7 Framework&lt;br /&gt;
|-&lt;br /&gt;
| 24003&lt;br /&gt;
| 24006&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| 24007&lt;br /&gt;
| 24007&lt;br /&gt;
| CC7 Framework&lt;br /&gt;
|-&lt;br /&gt;
| 24008&lt;br /&gt;
| 24019&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sound_item_materials ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sound_weapon_actions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sound_weapon_hits ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ts_material ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== vfx_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24003&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Variation sheets ==&lt;br /&gt;
&lt;br /&gt;
=== weapons and shields ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sheet&lt;br /&gt;
! ID reserved&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''All variations sheets'''&lt;br /&gt;
| '''140 - 160''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| mace_variation&lt;br /&gt;
| 140&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| mace_variation&lt;br /&gt;
| 141 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| mace_variation&lt;br /&gt;
| 142 &lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| staff_variation&lt;br /&gt;
| 140&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| staff_variation&lt;br /&gt;
| 141&lt;br /&gt;
| Helekanalaith&lt;br /&gt;
|-&lt;br /&gt;
| waraxe_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| maul_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| longsword_variation&lt;br /&gt;
| 150 - 151&lt;br /&gt;
| Adonnay&lt;br /&gt;
|-&lt;br /&gt;
| greatsword_variation&lt;br /&gt;
| 140 and 143 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| greatsword_variation&lt;br /&gt;
| 142 &lt;br /&gt;
| Nattfodd&lt;br /&gt;
|-&lt;br /&gt;
| dagger_variation&lt;br /&gt;
| 140-141 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| dagger_variation&lt;br /&gt;
| 142 &lt;br /&gt;
| Gisle Aune&lt;br /&gt;
|-&lt;br /&gt;
| battleaxe_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| bolt_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
=== armour and clothes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sheet&lt;br /&gt;
! ID reserved&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''All variations sheets'''&lt;br /&gt;
| '''140 - 160''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| armor_light_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| armor_light_variation&lt;br /&gt;
| 141&lt;br /&gt;
| example - delete me!&lt;br /&gt;
|-&lt;br /&gt;
| armor_light_variation&lt;br /&gt;
| 142&lt;br /&gt;
| Vaylise&lt;br /&gt;
|-&lt;br /&gt;
| helmet_light_variation&lt;br /&gt;
| 140&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| gloves_massive_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| example - delete me!&lt;br /&gt;
|-&lt;br /&gt;
| gloves_massive_variation&lt;br /&gt;
| 141 &lt;br /&gt;
| example - delete me!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= World Map Pins = &lt;br /&gt;
&lt;br /&gt;
Community Contest #7 requires map pins to be added to the existing Single Player maps.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Map !! X !! Y !! Used by &lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 605 || 570 || CC#7 Framework Tutorial&lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 371 || 424 || BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 600 || 278 || BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 699 || 293 || uberdowzen&lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 72 || 594 || Mengtzu&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Community_Contest_ID_Ranges&amp;diff=15986</id>
		<title>Community Contest ID Ranges</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Community_Contest_ID_Ranges&amp;diff=15986"/>
				<updated>2011-03-19T04:11:02Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Community_Contest_back.jpg|link=Community_Contest_Main_Page]] [[File:CC_BSN_GetInvolved.jpg|link=http://social.bioware.com/group/2535/&amp;amp;v=discussions]]&lt;br /&gt;
&lt;br /&gt;
So that all Community Contest entries are compatible with one another and also with other mods that are around, IDs must not conflict. To ensure this, we must reserve ID ranges for strings and 2da ranges.&lt;br /&gt;
&lt;br /&gt;
= String ranges = &lt;br /&gt;
&lt;br /&gt;
Please modify this table to reserve String IDs '''before you use them''' (to avoid lost work). Append within our range if required. Please do not use from outside this range.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''89000000''' &lt;br /&gt;
| '''89999999''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 89000000&lt;br /&gt;
| 89099999&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| ''89001000''&lt;br /&gt;
| ''89001999''&lt;br /&gt;
| ''CC6 bundle''&lt;br /&gt;
|-&lt;br /&gt;
| ''89002000''&lt;br /&gt;
| ''89002099''&lt;br /&gt;
| ''CC7 framework''&lt;br /&gt;
|-&lt;br /&gt;
| 89100000&lt;br /&gt;
| 89100999&lt;br /&gt;
| Cuvieronius&lt;br /&gt;
|-&lt;br /&gt;
| 89101000&lt;br /&gt;
| 89101999&lt;br /&gt;
| Vaylise&lt;br /&gt;
|-&lt;br /&gt;
| 89102000&lt;br /&gt;
| 89102999&lt;br /&gt;
| BAPACop&lt;br /&gt;
|-&lt;br /&gt;
| 89103000&lt;br /&gt;
| 89103999&lt;br /&gt;
| BloodsongVengeance&lt;br /&gt;
|-&lt;br /&gt;
| 89104000&lt;br /&gt;
| 89104999&lt;br /&gt;
| Jackkel Dragon&lt;br /&gt;
|-&lt;br /&gt;
| 89105000&lt;br /&gt;
| 89105999&lt;br /&gt;
| Lord Uber Dowzen (uberdowzen)&lt;br /&gt;
|-&lt;br /&gt;
| 89106000&lt;br /&gt;
| 89106999&lt;br /&gt;
| Shadow5973&lt;br /&gt;
|-&lt;br /&gt;
| 89107000&lt;br /&gt;
| 89107999&lt;br /&gt;
| Lobo&lt;br /&gt;
|-&lt;br /&gt;
| 89108000&lt;br /&gt;
| 89108999&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 89109000&lt;br /&gt;
| 89109999&lt;br /&gt;
| Mengtzu&lt;br /&gt;
|-&lt;br /&gt;
| 89110000&lt;br /&gt;
| 89110999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89111000&lt;br /&gt;
| 89111999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89112000&lt;br /&gt;
| 89112999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89113000&lt;br /&gt;
| 89113999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89114000&lt;br /&gt;
| 89114999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89115000&lt;br /&gt;
| 89115999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89116000&lt;br /&gt;
| 89116999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89117000&lt;br /&gt;
| 89117999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89118000&lt;br /&gt;
| 89118999&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|-&lt;br /&gt;
| 89119000&lt;br /&gt;
| 89122999&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| 89123000&lt;br /&gt;
| 89123999&lt;br /&gt;
| uberdowzen&lt;br /&gt;
|-&lt;br /&gt;
| 89124000&lt;br /&gt;
| 89124999&lt;br /&gt;
| Sunjammer&lt;br /&gt;
|-&lt;br /&gt;
| 89125000&lt;br /&gt;
| 89125999&lt;br /&gt;
| Mengtzu&lt;br /&gt;
|-&lt;br /&gt;
| 89126000&lt;br /&gt;
| 89126999&lt;br /&gt;
| Mengtzu&lt;br /&gt;
|-&lt;br /&gt;
| 89127000&lt;br /&gt;
| 89127999&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Why reserve an ID range? ===&lt;br /&gt;
This prevents the need for other modders to change your strings. This prevents any chance of overlapping IDs with other entries or other mods. This means that if you attach voice to conversations, or specify a StringID in a 2da, these connections will not be broken when others use your mod.&lt;br /&gt;
&lt;br /&gt;
=== How many do I reserve? ===&lt;br /&gt;
Just take 1000 unless you need more. Do not take less, we've got plenty to spare ;)&lt;br /&gt;
&lt;br /&gt;
=== How do I set my module to use those strings? ===&lt;br /&gt;
&lt;br /&gt;
* While logged in to builder wiki (same as login here), edit the page to put your name next to the range.&lt;br /&gt;
* In Toolset, go File &amp;gt; Manage Modules &amp;gt; (select your module) &amp;gt; Properties&lt;br /&gt;
* Set the following:&lt;br /&gt;
** StringID Begin&lt;br /&gt;
** StringID End&lt;br /&gt;
** StringID Last Used&lt;br /&gt;
* Hit OK and close dialogue.&lt;br /&gt;
&lt;br /&gt;
= 2da Ranges =&lt;br /&gt;
&lt;br /&gt;
We have reserved 24000 - 26000 in most 2das. Please reserve as many as you anticipate you will need, but don't be wasteful (reserving 200 when you only need 6 is wasteful). If you need hundreds, it's probably worth reserving your own range outside of the contest range.&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
=== M2DA_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24499&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| 24500&lt;br /&gt;
| 24509&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 24510&lt;br /&gt;
| 24519&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ABI_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24499&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| 24500&lt;br /&gt;
| 24509&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 24510&lt;br /&gt;
| 24513&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|-&lt;br /&gt;
| 24513&lt;br /&gt;
| 24519&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== placeable_types ===&lt;br /&gt;
&lt;br /&gt;
''nb a bug is causing the range of 24000 and above to not work in-game so we're using 14000-16000 instead.''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''14000''' &lt;br /&gt;
| '''16000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 14000&lt;br /&gt;
| 14499&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| 14500&lt;br /&gt;
| 14509&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 14510&lt;br /&gt;
| 14519&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| 14520&lt;br /&gt;
| 14529&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== areadata ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24009&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== BITM_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== guitypes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== itemprps ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24003&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== itemstats ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== JobBoardPlots ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| CC7 Framework&lt;br /&gt;
|-&lt;br /&gt;
| 24002&lt;br /&gt;
| 24006&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== JobBoards ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24000&lt;br /&gt;
| CC7 Framework&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== materialrules ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== materialtypes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== prcscr ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|-&lt;br /&gt;
| 24002&lt;br /&gt;
| 24002&lt;br /&gt;
| CC7 Framework&lt;br /&gt;
|-&lt;br /&gt;
| 24003&lt;br /&gt;
| 24006&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| 24007&lt;br /&gt;
| 24007&lt;br /&gt;
| CC7 Framework&lt;br /&gt;
|-&lt;br /&gt;
| 24008&lt;br /&gt;
| 24019&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sound_item_materials ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sound_weapon_actions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sound_weapon_hits ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ts_material ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== vfx_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24003&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Variation sheets ==&lt;br /&gt;
&lt;br /&gt;
=== weapons and shields ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sheet&lt;br /&gt;
! ID reserved&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''All variations sheets'''&lt;br /&gt;
| '''140 - 160''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| mace_variation&lt;br /&gt;
| 140&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| mace_variation&lt;br /&gt;
| 141 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| mace_variation&lt;br /&gt;
| 142 &lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| staff_variation&lt;br /&gt;
| 140&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| staff_variation&lt;br /&gt;
| 141&lt;br /&gt;
| Helekanalaith&lt;br /&gt;
|-&lt;br /&gt;
| waraxe_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| maul_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| longsword_variation&lt;br /&gt;
| 150 - 151&lt;br /&gt;
| Adonnay&lt;br /&gt;
|-&lt;br /&gt;
| greatsword_variation&lt;br /&gt;
| 140 and 143 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| greatsword_variation&lt;br /&gt;
| 142 &lt;br /&gt;
| Nattfodd&lt;br /&gt;
|-&lt;br /&gt;
| dagger_variation&lt;br /&gt;
| 140-141 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| dagger_variation&lt;br /&gt;
| 142 &lt;br /&gt;
| Gisle Aune&lt;br /&gt;
|-&lt;br /&gt;
| battleaxe_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| bolt_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
=== armour and clothes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sheet&lt;br /&gt;
! ID reserved&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''All variations sheets'''&lt;br /&gt;
| '''140 - 160''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| armor_light_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| armor_light_variation&lt;br /&gt;
| 141&lt;br /&gt;
| example - delete me!&lt;br /&gt;
|-&lt;br /&gt;
| armor_light_variation&lt;br /&gt;
| 142&lt;br /&gt;
| Vaylise&lt;br /&gt;
|-&lt;br /&gt;
| helmet_light_variation&lt;br /&gt;
| 140&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| gloves_massive_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| example - delete me!&lt;br /&gt;
|-&lt;br /&gt;
| gloves_massive_variation&lt;br /&gt;
| 141 &lt;br /&gt;
| example - delete me!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= World Map Pins = &lt;br /&gt;
&lt;br /&gt;
Community Contest #7 requires map pins to be added to the existing Single Player maps.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Map !! X !! Y !! Used by &lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 605 || 570 || CC#7 Framework Tutorial&lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 371 || 424 || BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 600 || 278 || BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 699 || 293 || uberdowzen&lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 70 || 353 || Mengtzu&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Community_Contest_ID_Ranges&amp;diff=15985</id>
		<title>Community Contest ID Ranges</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Community_Contest_ID_Ranges&amp;diff=15985"/>
				<updated>2011-03-19T02:43:27Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Community_Contest_back.jpg|link=Community_Contest_Main_Page]] [[File:CC_BSN_GetInvolved.jpg|link=http://social.bioware.com/group/2535/&amp;amp;v=discussions]]&lt;br /&gt;
&lt;br /&gt;
So that all Community Contest entries are compatible with one another and also with other mods that are around, IDs must not conflict. To ensure this, we must reserve ID ranges for strings and 2da ranges.&lt;br /&gt;
&lt;br /&gt;
= String ranges = &lt;br /&gt;
&lt;br /&gt;
Please modify this table to reserve String IDs '''before you use them''' (to avoid lost work). Append within our range if required. Please do not use from outside this range.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''89000000''' &lt;br /&gt;
| '''89999999''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 89000000&lt;br /&gt;
| 89099999&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| ''89001000''&lt;br /&gt;
| ''89001999''&lt;br /&gt;
| ''CC6 bundle''&lt;br /&gt;
|-&lt;br /&gt;
| ''89002000''&lt;br /&gt;
| ''89002099''&lt;br /&gt;
| ''CC7 framework''&lt;br /&gt;
|-&lt;br /&gt;
| 89100000&lt;br /&gt;
| 89100999&lt;br /&gt;
| Cuvieronius&lt;br /&gt;
|-&lt;br /&gt;
| 89101000&lt;br /&gt;
| 89101999&lt;br /&gt;
| Vaylise&lt;br /&gt;
|-&lt;br /&gt;
| 89102000&lt;br /&gt;
| 89102999&lt;br /&gt;
| BAPACop&lt;br /&gt;
|-&lt;br /&gt;
| 89103000&lt;br /&gt;
| 89103999&lt;br /&gt;
| BloodsongVengeance&lt;br /&gt;
|-&lt;br /&gt;
| 89104000&lt;br /&gt;
| 89104999&lt;br /&gt;
| Jackkel Dragon&lt;br /&gt;
|-&lt;br /&gt;
| 89105000&lt;br /&gt;
| 89105999&lt;br /&gt;
| Lord Uber Dowzen (uberdowzen)&lt;br /&gt;
|-&lt;br /&gt;
| 89106000&lt;br /&gt;
| 89106999&lt;br /&gt;
| Shadow5973&lt;br /&gt;
|-&lt;br /&gt;
| 89107000&lt;br /&gt;
| 89107999&lt;br /&gt;
| Lobo&lt;br /&gt;
|-&lt;br /&gt;
| 89108000&lt;br /&gt;
| 89108999&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 89109000&lt;br /&gt;
| 89109999&lt;br /&gt;
| Mengtzu&lt;br /&gt;
|-&lt;br /&gt;
| 89110000&lt;br /&gt;
| 89110999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89111000&lt;br /&gt;
| 89111999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89112000&lt;br /&gt;
| 89112999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89113000&lt;br /&gt;
| 89113999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89114000&lt;br /&gt;
| 89114999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89115000&lt;br /&gt;
| 89115999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89116000&lt;br /&gt;
| 89116999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89117000&lt;br /&gt;
| 89117999&lt;br /&gt;
| Fenodsnacer (Fenod)&lt;br /&gt;
|-&lt;br /&gt;
| 89118000&lt;br /&gt;
| 89118999&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|-&lt;br /&gt;
| 89119000&lt;br /&gt;
| 89122999&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| 89123000&lt;br /&gt;
| 89123999&lt;br /&gt;
| uberdowzen&lt;br /&gt;
|-&lt;br /&gt;
| 89124000&lt;br /&gt;
| 89124999&lt;br /&gt;
| Sunjammer&lt;br /&gt;
|-&lt;br /&gt;
| 89125000&lt;br /&gt;
| 89125999&lt;br /&gt;
| Mengtzu&lt;br /&gt;
|-&lt;br /&gt;
| 89126000&lt;br /&gt;
| 89126999&lt;br /&gt;
| Mengtzu&lt;br /&gt;
|-&lt;br /&gt;
| 89127000&lt;br /&gt;
| 89127999&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Why reserve an ID range? ===&lt;br /&gt;
This prevents the need for other modders to change your strings. This prevents any chance of overlapping IDs with other entries or other mods. This means that if you attach voice to conversations, or specify a StringID in a 2da, these connections will not be broken when others use your mod.&lt;br /&gt;
&lt;br /&gt;
=== How many do I reserve? ===&lt;br /&gt;
Just take 1000 unless you need more. Do not take less, we've got plenty to spare ;)&lt;br /&gt;
&lt;br /&gt;
=== How do I set my module to use those strings? ===&lt;br /&gt;
&lt;br /&gt;
* While logged in to builder wiki (same as login here), edit the page to put your name next to the range.&lt;br /&gt;
* In Toolset, go File &amp;gt; Manage Modules &amp;gt; (select your module) &amp;gt; Properties&lt;br /&gt;
* Set the following:&lt;br /&gt;
** StringID Begin&lt;br /&gt;
** StringID End&lt;br /&gt;
** StringID Last Used&lt;br /&gt;
* Hit OK and close dialogue.&lt;br /&gt;
&lt;br /&gt;
= 2da Ranges =&lt;br /&gt;
&lt;br /&gt;
We have reserved 24000 - 26000 in most 2das. Please reserve as many as you anticipate you will need, but don't be wasteful (reserving 200 when you only need 6 is wasteful). If you need hundreds, it's probably worth reserving your own range outside of the contest range.&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
=== M2DA_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24499&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| 24500&lt;br /&gt;
| 24509&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 24510&lt;br /&gt;
| 24519&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ABI_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24499&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| 24500&lt;br /&gt;
| 24509&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 24510&lt;br /&gt;
| 24513&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|-&lt;br /&gt;
| 24513&lt;br /&gt;
| 24519&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== placeable_types ===&lt;br /&gt;
&lt;br /&gt;
''nb a bug is causing the range of 24000 and above to not work in-game so we're using 14000-16000 instead.''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''14000''' &lt;br /&gt;
| '''16000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 14000&lt;br /&gt;
| 14499&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| 14500&lt;br /&gt;
| 14509&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 14510&lt;br /&gt;
| 14519&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| 14520&lt;br /&gt;
| 14529&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== areadata ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24009&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== BITM_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== guitypes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== itemprps ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24003&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== itemstats ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== JobBoardPlots ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| CC7 Framework&lt;br /&gt;
|-&lt;br /&gt;
| 24002&lt;br /&gt;
| 24006&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== JobBoards ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24000&lt;br /&gt;
| CC7 Framework&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== materialrules ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== materialtypes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== prcscr ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|-&lt;br /&gt;
| 24002&lt;br /&gt;
| 24002&lt;br /&gt;
| CC7 Framework&lt;br /&gt;
|-&lt;br /&gt;
| 24003&lt;br /&gt;
| 24006&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| 24007&lt;br /&gt;
| 24007&lt;br /&gt;
| CC7 Framework&lt;br /&gt;
|-&lt;br /&gt;
| 24008&lt;br /&gt;
| 24019&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sound_item_materials ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sound_weapon_actions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== sound_weapon_hits ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ts_material ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24001&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== vfx_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24003&lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Variation sheets ==&lt;br /&gt;
&lt;br /&gt;
=== weapons and shields ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sheet&lt;br /&gt;
! ID reserved&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''All variations sheets'''&lt;br /&gt;
| '''140 - 160''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| mace_variation&lt;br /&gt;
| 140&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| mace_variation&lt;br /&gt;
| 141 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| mace_variation&lt;br /&gt;
| 142 &lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| staff_variation&lt;br /&gt;
| 140&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| staff_variation&lt;br /&gt;
| 141&lt;br /&gt;
| Helekanalaith&lt;br /&gt;
|-&lt;br /&gt;
| waraxe_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| maul_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| longsword_variation&lt;br /&gt;
| 150 - 151&lt;br /&gt;
| Adonnay&lt;br /&gt;
|-&lt;br /&gt;
| greatsword_variation&lt;br /&gt;
| 140 and 143 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| greatsword_variation&lt;br /&gt;
| 142 &lt;br /&gt;
| Nattfodd&lt;br /&gt;
|-&lt;br /&gt;
| dagger_variation&lt;br /&gt;
| 140-141 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| dagger_variation&lt;br /&gt;
| 142 &lt;br /&gt;
| Gisle Aune&lt;br /&gt;
|-&lt;br /&gt;
| battleaxe_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| Fenodsnalcer&lt;br /&gt;
|-&lt;br /&gt;
| bolt_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| InBleedingRapture&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
=== armour and clothes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sheet&lt;br /&gt;
! ID reserved&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''All variations sheets'''&lt;br /&gt;
| '''140 - 160''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| armor_light_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| armor_light_variation&lt;br /&gt;
| 141&lt;br /&gt;
| example - delete me!&lt;br /&gt;
|-&lt;br /&gt;
| armor_light_variation&lt;br /&gt;
| 142&lt;br /&gt;
| Vaylise&lt;br /&gt;
|-&lt;br /&gt;
| helmet_light_variation&lt;br /&gt;
| 140&lt;br /&gt;
| BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| gloves_massive_variation&lt;br /&gt;
| 140 &lt;br /&gt;
| example - delete me!&lt;br /&gt;
|-&lt;br /&gt;
| gloves_massive_variation&lt;br /&gt;
| 141 &lt;br /&gt;
| example - delete me!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= World Map Pins = &lt;br /&gt;
&lt;br /&gt;
Community Contest #7 requires map pins to be added to the existing Single Player maps.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Map !! X !! Y !! Used by &lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 605 || 570 || CC#7 Framework Tutorial&lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 371 || 424 || BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 600 || 278 || BlackPhi&lt;br /&gt;
|-&lt;br /&gt;
| Wide Open World || 699 || 293 || uberdowzen&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Community_Contest_4:_Minigame_Script&amp;diff=14106</id>
		<title>Community Contest 4: Minigame Script</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Community_Contest_4:_Minigame_Script&amp;diff=14106"/>
				<updated>2010-10-25T22:06:54Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Community_Contest_back.jpg|link=Community_Contest_Main_Page]] [[File:CC_BSN_GetInvolved.jpg|link=http://social.bioware.com/group/2535/&amp;amp;v=discussions]]&lt;br /&gt;
&lt;br /&gt;
== Brief ==&lt;br /&gt;
&lt;br /&gt;
Create a minigame or puzzle using scripting. The contest discussion thread can be found [http://social.bioware.com/group/2535/discussion/10583/916864/#post_916864 here].&lt;br /&gt;
&lt;br /&gt;
'''DEADLINE: Monday 1 November''' - your entry must be ready for judging before midday GMT+0. It is strongly recommended you submit well before this time (sunday!) in case you run into troubles. Modifications to your submission are welcomed - the newest version of your entry will be judged, although modifications made ''after'' the submission date will not be judged.&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
All entries must:&lt;br /&gt;
* Reserve and use a [[Community_Contest_ID_Ranges|StringID range]]&lt;br /&gt;
* Be thoroughly tested in-game&lt;br /&gt;
* Be submitted in a single, playable area (the level will not be &amp;quot;marked&amp;quot;)&lt;br /&gt;
* Include dadbdata export of all relevant resources&lt;br /&gt;
* Include a playable dazip of the mini-game - should be playable from the other campaigns menu&lt;br /&gt;
* Include a plain-text file detailing the mini-game implementation - the objective, customization options (if present) and solutions&lt;br /&gt;
* Use only DA assets (placeables, levels) ''unless the relevant files are included with the submission and author's permission has been given''&lt;br /&gt;
* Be submitted before Monday 1 November midday (GMT+0)&lt;br /&gt;
&lt;br /&gt;
=== Guidelines ===&lt;br /&gt;
Strong entries will:&lt;br /&gt;
* be easily adaptable to vary the minigame in other modules&lt;br /&gt;
* be unique and interesting&lt;br /&gt;
* use elegant and tidy scripting&lt;br /&gt;
* include well-written, detailed comments &lt;br /&gt;
* be well-designed and be free of bugs and discourage user error&lt;br /&gt;
* be significant as a piece of scripting: doing something new or expanding beyond the fundamentals of scripting&lt;br /&gt;
* make appropriate use of secondary resources (triggers, placeables, dialogues, floaty text, VFX, sound, etc)&lt;br /&gt;
&lt;br /&gt;
=== Allowable ===&lt;br /&gt;
While no &amp;quot;bonus points&amp;quot; will be given for the following, entries may: &lt;br /&gt;
* use custom levels provided that the level is shared with the submission (.lvl and exported files)&lt;br /&gt;
&lt;br /&gt;
== Groups and Prizes ==&lt;br /&gt;
&lt;br /&gt;
=== Groups ===&lt;br /&gt;
This contest has only one group.&lt;br /&gt;
&lt;br /&gt;
* 1st place - 15 points, chooses first&lt;br /&gt;
* 2nd place - 10 points, chooses second&lt;br /&gt;
* 3rd place - 5 points, chooses third&lt;br /&gt;
* Best Newcomer - 3 points (unless 1st, 2nd or 3rd place)&lt;br /&gt;
* All other entries meeting requirements - 1 point&lt;br /&gt;
&lt;br /&gt;
To receive an &amp;quot;entry point&amp;quot;, your submission must meet the requirements of the contest, listed at the top of this page&lt;br /&gt;
&lt;br /&gt;
=== Best Newcomer Award ===&lt;br /&gt;
Every judge may nominate one newcomer as their favourite newcomer entry. To qualify, the entrant must not have submitted to a community contest before. The winning newcomer will receive three points if they don't podium (in which case, theyll be getting more points anyway!).&lt;br /&gt;
&lt;br /&gt;
=== Prizes ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Community_Contest_Prizes|Community Contest Prizes]]&lt;br /&gt;
&lt;br /&gt;
== Helpful Links ==&lt;br /&gt;
* [[Scripting_overview|Scripting Overview]] - Builder Wiki&lt;br /&gt;
* [[Scripting_tutorial|Scripting Tutorial]] - Builder Wiki&lt;br /&gt;
* [http://dalexicon.net/index.php?title=Main_Page Dragon Age Lexicon] - Scripting Resource&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Entries = &lt;br /&gt;
&lt;br /&gt;
For information on how to enter, please see the [[Community_Contest_Entry_FAQ|Entry FAQs]]&lt;br /&gt;
&lt;br /&gt;
For information on Judging, please see the [[Community_Contest_Judging|Judging]] page.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;font size=&amp;quot;5&amp;quot; color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;IMPORTANT - consent to share&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;By entering this competition you consent to share your work for other community members to benefit from.&lt;br /&gt;
 Where appropriate, source files should be shared (dadbdata and any non-DA assets you have used including levels, props etc). &lt;br /&gt;
 The work *MUST* be your own (obviously you may use DA assets).&lt;br /&gt;
 Others may use and modify your work in their Dragon Age mods, though are encouraged to give credit. &lt;br /&gt;
 As the entries are judged, local copies will be saved If your work is taken down.&lt;br /&gt;
 If your work is taken down, you allow for it to be re-uploaded, crediting the work in your name. &amp;lt;/b&amp;gt; &amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Entry by YourNameHere ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=1559 Links here in this format]'''&lt;br /&gt;
&lt;br /&gt;
Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. &lt;br /&gt;
&lt;br /&gt;
Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible.&lt;br /&gt;
&lt;br /&gt;
[[File:terrainBlockExample.png|400px|example picture]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weighted RPS by Mengtzu ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=1850 Dragon Age Nexus project page]'''&lt;br /&gt;
&lt;br /&gt;
Rock, Paper, Scissors as a multi-round gambling game, with weighted moves to introduce strategy and customisable AI.  Multiple games with different settings may share an area, allowing a tournament/festival style implementation, as demonstrated in the sample module.  By default the player earns prize tokens which may be traded in for items.&lt;br /&gt;
&lt;br /&gt;
Modular functions and constants make the engine easy to extend or modify.&lt;br /&gt;
&lt;br /&gt;
[[File:Rps guanyin.jpg|400px|Game in progress]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Community_Contest_4:_Minigame_Script&amp;diff=14105</id>
		<title>Community Contest 4: Minigame Script</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Community_Contest_4:_Minigame_Script&amp;diff=14105"/>
				<updated>2010-10-25T22:04:41Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Community_Contest_back.jpg|link=Community_Contest_Main_Page]] [[File:CC_BSN_GetInvolved.jpg|link=http://social.bioware.com/group/2535/&amp;amp;v=discussions]]&lt;br /&gt;
&lt;br /&gt;
== Brief ==&lt;br /&gt;
&lt;br /&gt;
Create a minigame or puzzle using scripting. The contest discussion thread can be found [http://social.bioware.com/group/2535/discussion/10583/916864/#post_916864 here].&lt;br /&gt;
&lt;br /&gt;
'''DEADLINE: Monday 1 November''' - your entry must be ready for judging before midday GMT+0. It is strongly recommended you submit well before this time (sunday!) in case you run into troubles. Modifications to your submission are welcomed - the newest version of your entry will be judged, although modifications made ''after'' the submission date will not be judged.&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
All entries must:&lt;br /&gt;
* Reserve and use a [[Community_Contest_ID_Ranges|StringID range]]&lt;br /&gt;
* Be thoroughly tested in-game&lt;br /&gt;
* Be submitted in a single, playable area (the level will not be &amp;quot;marked&amp;quot;)&lt;br /&gt;
* Include dadbdata export of all relevant resources&lt;br /&gt;
* Include a playable dazip of the mini-game - should be playable from the other campaigns menu&lt;br /&gt;
* Include a plain-text file detailing the mini-game implementation - the objective, customization options (if present) and solutions&lt;br /&gt;
* Use only DA assets (placeables, levels) ''unless the relevant files are included with the submission and author's permission has been given''&lt;br /&gt;
* Be submitted before Monday 1 November midday (GMT+0)&lt;br /&gt;
&lt;br /&gt;
=== Guidelines ===&lt;br /&gt;
Strong entries will:&lt;br /&gt;
* be easily adaptable to vary the minigame in other modules&lt;br /&gt;
* be unique and interesting&lt;br /&gt;
* use elegant and tidy scripting&lt;br /&gt;
* include well-written, detailed comments &lt;br /&gt;
* be well-designed and be free of bugs and discourage user error&lt;br /&gt;
* be significant as a piece of scripting: doing something new or expanding beyond the fundamentals of scripting&lt;br /&gt;
* make appropriate use of secondary resources (triggers, placeables, dialogues, floaty text, VFX, sound, etc)&lt;br /&gt;
&lt;br /&gt;
=== Allowable ===&lt;br /&gt;
While no &amp;quot;bonus points&amp;quot; will be given for the following, entries may: &lt;br /&gt;
* use custom levels provided that the level is shared with the submission (.lvl and exported files)&lt;br /&gt;
&lt;br /&gt;
== Groups and Prizes ==&lt;br /&gt;
&lt;br /&gt;
=== Groups ===&lt;br /&gt;
This contest has only one group.&lt;br /&gt;
&lt;br /&gt;
* 1st place - 15 points, chooses first&lt;br /&gt;
* 2nd place - 10 points, chooses second&lt;br /&gt;
* 3rd place - 5 points, chooses third&lt;br /&gt;
* Best Newcomer - 3 points (unless 1st, 2nd or 3rd place)&lt;br /&gt;
* All other entries meeting requirements - 1 point&lt;br /&gt;
&lt;br /&gt;
To receive an &amp;quot;entry point&amp;quot;, your submission must meet the requirements of the contest, listed at the top of this page&lt;br /&gt;
&lt;br /&gt;
=== Best Newcomer Award ===&lt;br /&gt;
Every judge may nominate one newcomer as their favourite newcomer entry. To qualify, the entrant must not have submitted to a community contest before. The winning newcomer will receive three points if they don't podium (in which case, theyll be getting more points anyway!).&lt;br /&gt;
&lt;br /&gt;
=== Prizes ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Community_Contest_Prizes|Community Contest Prizes]]&lt;br /&gt;
&lt;br /&gt;
== Helpful Links ==&lt;br /&gt;
* [[Scripting_overview|Scripting Overview]] - Builder Wiki&lt;br /&gt;
* [[Scripting_tutorial|Scripting Tutorial]] - Builder Wiki&lt;br /&gt;
* [http://dalexicon.net/index.php?title=Main_Page Dragon Age Lexicon] - Scripting Resource&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Entries = &lt;br /&gt;
&lt;br /&gt;
For information on how to enter, please see the [[Community_Contest_Entry_FAQ|Entry FAQs]]&lt;br /&gt;
&lt;br /&gt;
For information on Judging, please see the [[Community_Contest_Judging|Judging]] page.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;font size=&amp;quot;5&amp;quot; color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;IMPORTANT - consent to share&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;By entering this competition you consent to share your work for other community members to benefit from.&lt;br /&gt;
 Where appropriate, source files should be shared (dadbdata and any non-DA assets you have used including levels, props etc). &lt;br /&gt;
 The work *MUST* be your own (obviously you may use DA assets).&lt;br /&gt;
 Others may use and modify your work in their Dragon Age mods, though are encouraged to give credit. &lt;br /&gt;
 As the entries are judged, local copies will be saved If your work is taken down.&lt;br /&gt;
 If your work is taken down, you allow for it to be re-uploaded, crediting the work in your name. &amp;lt;/b&amp;gt; &amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Entry by YourNameHere ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=1559 Links here in this format]'''&lt;br /&gt;
&lt;br /&gt;
Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. &lt;br /&gt;
&lt;br /&gt;
Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible.&lt;br /&gt;
&lt;br /&gt;
[[File:terrainBlockExample.png|400px|example picture]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weighted RPS by Mengtzu ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=1850 Dragon Age Nexus project page]'''&lt;br /&gt;
&lt;br /&gt;
Rock, Paper, Scissors as a multi-round gambling game, with weighted moves to introduce strategy and customisable AI.  Multiple games with different settings may share an area, allowing a tournament/festival style implementation, as demonstrated in the sample module.  By default the player earns prize tokens which may be traded in for items.&lt;br /&gt;
&lt;br /&gt;
Modular functions and constants make the engine easy to extend or modify.&lt;br /&gt;
&lt;br /&gt;
[[File:Rps guanyin.jpg|400px|Game in progress]] [[File:Rps tutor.jpg|400px|Rules tutor]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=File:Rps_tutor.jpg&amp;diff=14104</id>
		<title>File:Rps tutor.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=File:Rps_tutor.jpg&amp;diff=14104"/>
				<updated>2010-10-25T22:03:06Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: Rules tutor for Weighted RPS game&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Rules tutor for Weighted RPS game&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Community_Contest_4:_Minigame_Script&amp;diff=14103</id>
		<title>Community Contest 4: Minigame Script</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Community_Contest_4:_Minigame_Script&amp;diff=14103"/>
				<updated>2010-10-25T22:02:21Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Community_Contest_back.jpg|link=Community_Contest_Main_Page]] [[File:CC_BSN_GetInvolved.jpg|link=http://social.bioware.com/group/2535/&amp;amp;v=discussions]]&lt;br /&gt;
&lt;br /&gt;
== Brief ==&lt;br /&gt;
&lt;br /&gt;
Create a minigame or puzzle using scripting. The contest discussion thread can be found [http://social.bioware.com/group/2535/discussion/10583/916864/#post_916864 here].&lt;br /&gt;
&lt;br /&gt;
'''DEADLINE: Monday 1 November''' - your entry must be ready for judging before midday GMT+0. It is strongly recommended you submit well before this time (sunday!) in case you run into troubles. Modifications to your submission are welcomed - the newest version of your entry will be judged, although modifications made ''after'' the submission date will not be judged.&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
All entries must:&lt;br /&gt;
* Reserve and use a [[Community_Contest_ID_Ranges|StringID range]]&lt;br /&gt;
* Be thoroughly tested in-game&lt;br /&gt;
* Be submitted in a single, playable area (the level will not be &amp;quot;marked&amp;quot;)&lt;br /&gt;
* Include dadbdata export of all relevant resources&lt;br /&gt;
* Include a playable dazip of the mini-game - should be playable from the other campaigns menu&lt;br /&gt;
* Include a plain-text file detailing the mini-game implementation - the objective, customization options (if present) and solutions&lt;br /&gt;
* Use only DA assets (placeables, levels) ''unless the relevant files are included with the submission and author's permission has been given''&lt;br /&gt;
* Be submitted before Monday 1 November midday (GMT+0)&lt;br /&gt;
&lt;br /&gt;
=== Guidelines ===&lt;br /&gt;
Strong entries will:&lt;br /&gt;
* be easily adaptable to vary the minigame in other modules&lt;br /&gt;
* be unique and interesting&lt;br /&gt;
* use elegant and tidy scripting&lt;br /&gt;
* include well-written, detailed comments &lt;br /&gt;
* be well-designed and be free of bugs and discourage user error&lt;br /&gt;
* be significant as a piece of scripting: doing something new or expanding beyond the fundamentals of scripting&lt;br /&gt;
* make appropriate use of secondary resources (triggers, placeables, dialogues, floaty text, VFX, sound, etc)&lt;br /&gt;
&lt;br /&gt;
=== Allowable ===&lt;br /&gt;
While no &amp;quot;bonus points&amp;quot; will be given for the following, entries may: &lt;br /&gt;
* use custom levels provided that the level is shared with the submission (.lvl and exported files)&lt;br /&gt;
&lt;br /&gt;
== Groups and Prizes ==&lt;br /&gt;
&lt;br /&gt;
=== Groups ===&lt;br /&gt;
This contest has only one group.&lt;br /&gt;
&lt;br /&gt;
* 1st place - 15 points, chooses first&lt;br /&gt;
* 2nd place - 10 points, chooses second&lt;br /&gt;
* 3rd place - 5 points, chooses third&lt;br /&gt;
* Best Newcomer - 3 points (unless 1st, 2nd or 3rd place)&lt;br /&gt;
* All other entries meeting requirements - 1 point&lt;br /&gt;
&lt;br /&gt;
To receive an &amp;quot;entry point&amp;quot;, your submission must meet the requirements of the contest, listed at the top of this page&lt;br /&gt;
&lt;br /&gt;
=== Best Newcomer Award ===&lt;br /&gt;
Every judge may nominate one newcomer as their favourite newcomer entry. To qualify, the entrant must not have submitted to a community contest before. The winning newcomer will receive three points if they don't podium (in which case, theyll be getting more points anyway!).&lt;br /&gt;
&lt;br /&gt;
=== Prizes ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Community_Contest_Prizes|Community Contest Prizes]]&lt;br /&gt;
&lt;br /&gt;
== Helpful Links ==&lt;br /&gt;
* [[Scripting_overview|Scripting Overview]] - Builder Wiki&lt;br /&gt;
* [[Scripting_tutorial|Scripting Tutorial]] - Builder Wiki&lt;br /&gt;
* [http://dalexicon.net/index.php?title=Main_Page Dragon Age Lexicon] - Scripting Resource&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Entries = &lt;br /&gt;
&lt;br /&gt;
For information on how to enter, please see the [[Community_Contest_Entry_FAQ|Entry FAQs]]&lt;br /&gt;
&lt;br /&gt;
For information on Judging, please see the [[Community_Contest_Judging|Judging]] page.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;font size=&amp;quot;5&amp;quot; color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;IMPORTANT - consent to share&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;By entering this competition you consent to share your work for other community members to benefit from.&lt;br /&gt;
 Where appropriate, source files should be shared (dadbdata and any non-DA assets you have used including levels, props etc). &lt;br /&gt;
 The work *MUST* be your own (obviously you may use DA assets).&lt;br /&gt;
 Others may use and modify your work in their Dragon Age mods, though are encouraged to give credit. &lt;br /&gt;
 As the entries are judged, local copies will be saved If your work is taken down.&lt;br /&gt;
 If your work is taken down, you allow for it to be re-uploaded, crediting the work in your name. &amp;lt;/b&amp;gt; &amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Entry by YourNameHere ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=1559 Links here in this format]'''&lt;br /&gt;
&lt;br /&gt;
Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. &lt;br /&gt;
&lt;br /&gt;
Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible.&lt;br /&gt;
&lt;br /&gt;
[[File:terrainBlockExample.png|400px|example picture]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weighted RPS by Mengtzu ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=1850 Dragon Age Nexus project page]'''&lt;br /&gt;
&lt;br /&gt;
Rock, Paper, Scissors as a multi-round gambling game, with weighted moves to introduce strategy and customisable AI.  Multiple games with different settings may share an area, allowing a tournament/festival style implementation, as demonstrated in the sample module.  By default the player earns prize tokens which may be traded in for items.&lt;br /&gt;
&lt;br /&gt;
Modular functions and constants make the engine easy to extend or modify.&lt;br /&gt;
&lt;br /&gt;
[[File:Rps guanyin.jpg|400px|Game in progress]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=File:Rps_guanyin.jpg&amp;diff=14102</id>
		<title>File:Rps guanyin.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=File:Rps_guanyin.jpg&amp;diff=14102"/>
				<updated>2010-10-25T22:01:04Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: Weighted Rock, Paper, Scissors game in progress&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Weighted Rock, Paper, Scissors game in progress&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Community_Contest_4:_Minigame_Script&amp;diff=14101</id>
		<title>Community Contest 4: Minigame Script</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Community_Contest_4:_Minigame_Script&amp;diff=14101"/>
				<updated>2010-10-25T22:00:33Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Community_Contest_back.jpg|link=Community_Contest_Main_Page]] [[File:CC_BSN_GetInvolved.jpg|link=http://social.bioware.com/group/2535/&amp;amp;v=discussions]]&lt;br /&gt;
&lt;br /&gt;
== Brief ==&lt;br /&gt;
&lt;br /&gt;
Create a minigame or puzzle using scripting. The contest discussion thread can be found [http://social.bioware.com/group/2535/discussion/10583/916864/#post_916864 here].&lt;br /&gt;
&lt;br /&gt;
'''DEADLINE: Monday 1 November''' - your entry must be ready for judging before midday GMT+0. It is strongly recommended you submit well before this time (sunday!) in case you run into troubles. Modifications to your submission are welcomed - the newest version of your entry will be judged, although modifications made ''after'' the submission date will not be judged.&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
All entries must:&lt;br /&gt;
* Reserve and use a [[Community_Contest_ID_Ranges|StringID range]]&lt;br /&gt;
* Be thoroughly tested in-game&lt;br /&gt;
* Be submitted in a single, playable area (the level will not be &amp;quot;marked&amp;quot;)&lt;br /&gt;
* Include dadbdata export of all relevant resources&lt;br /&gt;
* Include a playable dazip of the mini-game - should be playable from the other campaigns menu&lt;br /&gt;
* Include a plain-text file detailing the mini-game implementation - the objective, customization options (if present) and solutions&lt;br /&gt;
* Use only DA assets (placeables, levels) ''unless the relevant files are included with the submission and author's permission has been given''&lt;br /&gt;
* Be submitted before Monday 1 November midday (GMT+0)&lt;br /&gt;
&lt;br /&gt;
=== Guidelines ===&lt;br /&gt;
Strong entries will:&lt;br /&gt;
* be easily adaptable to vary the minigame in other modules&lt;br /&gt;
* be unique and interesting&lt;br /&gt;
* use elegant and tidy scripting&lt;br /&gt;
* include well-written, detailed comments &lt;br /&gt;
* be well-designed and be free of bugs and discourage user error&lt;br /&gt;
* be significant as a piece of scripting: doing something new or expanding beyond the fundamentals of scripting&lt;br /&gt;
* make appropriate use of secondary resources (triggers, placeables, dialogues, floaty text, VFX, sound, etc)&lt;br /&gt;
&lt;br /&gt;
=== Allowable ===&lt;br /&gt;
While no &amp;quot;bonus points&amp;quot; will be given for the following, entries may: &lt;br /&gt;
* use custom levels provided that the level is shared with the submission (.lvl and exported files)&lt;br /&gt;
&lt;br /&gt;
== Groups and Prizes ==&lt;br /&gt;
&lt;br /&gt;
=== Groups ===&lt;br /&gt;
This contest has only one group.&lt;br /&gt;
&lt;br /&gt;
* 1st place - 15 points, chooses first&lt;br /&gt;
* 2nd place - 10 points, chooses second&lt;br /&gt;
* 3rd place - 5 points, chooses third&lt;br /&gt;
* Best Newcomer - 3 points (unless 1st, 2nd or 3rd place)&lt;br /&gt;
* All other entries meeting requirements - 1 point&lt;br /&gt;
&lt;br /&gt;
To receive an &amp;quot;entry point&amp;quot;, your submission must meet the requirements of the contest, listed at the top of this page&lt;br /&gt;
&lt;br /&gt;
=== Best Newcomer Award ===&lt;br /&gt;
Every judge may nominate one newcomer as their favourite newcomer entry. To qualify, the entrant must not have submitted to a community contest before. The winning newcomer will receive three points if they don't podium (in which case, theyll be getting more points anyway!).&lt;br /&gt;
&lt;br /&gt;
=== Prizes ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Community_Contest_Prizes|Community Contest Prizes]]&lt;br /&gt;
&lt;br /&gt;
== Helpful Links ==&lt;br /&gt;
* [[Scripting_overview|Scripting Overview]] - Builder Wiki&lt;br /&gt;
* [[Scripting_tutorial|Scripting Tutorial]] - Builder Wiki&lt;br /&gt;
* [http://dalexicon.net/index.php?title=Main_Page Dragon Age Lexicon] - Scripting Resource&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Entries = &lt;br /&gt;
&lt;br /&gt;
For information on how to enter, please see the [[Community_Contest_Entry_FAQ|Entry FAQs]]&lt;br /&gt;
&lt;br /&gt;
For information on Judging, please see the [[Community_Contest_Judging|Judging]] page.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;font size=&amp;quot;5&amp;quot; color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;IMPORTANT - consent to share&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;By entering this competition you consent to share your work for other community members to benefit from.&lt;br /&gt;
 Where appropriate, source files should be shared (dadbdata and any non-DA assets you have used including levels, props etc). &lt;br /&gt;
 The work *MUST* be your own (obviously you may use DA assets).&lt;br /&gt;
 Others may use and modify your work in their Dragon Age mods, though are encouraged to give credit. &lt;br /&gt;
 As the entries are judged, local copies will be saved If your work is taken down.&lt;br /&gt;
 If your work is taken down, you allow for it to be re-uploaded, crediting the work in your name. &amp;lt;/b&amp;gt; &amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Entry by YourNameHere ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=1559 Links here in this format]'''&lt;br /&gt;
&lt;br /&gt;
Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. &lt;br /&gt;
&lt;br /&gt;
Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible.&lt;br /&gt;
&lt;br /&gt;
[[File:terrainBlockExample.png|400px|example picture]]&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weighted RPS by Mengtzu ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=1850 Dragon Age Nexus project page]'''&lt;br /&gt;
&lt;br /&gt;
Rock, Paper, Scissors as a multi-round gambling game, with weighted moves to introduce strategy and customisable AI.  Multiple games with different settings may share an area, allowing a tournament/festival style implementation, as demonstrated in the sample module.  By default the player earns prize tokens which may be traded in for items.&lt;br /&gt;
&lt;br /&gt;
Modular functions and constants make the engine easy to extend or modify.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Judges' Comments ===&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Community_Contest_4:_Minigame_Script&amp;diff=14100</id>
		<title>Community Contest 4: Minigame Script</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Community_Contest_4:_Minigame_Script&amp;diff=14100"/>
				<updated>2010-10-25T21:59:53Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Community_Contest_back.jpg|link=Community_Contest_Main_Page]] [[File:CC_BSN_GetInvolved.jpg|link=http://social.bioware.com/group/2535/&amp;amp;v=discussions]]&lt;br /&gt;
&lt;br /&gt;
== Brief ==&lt;br /&gt;
&lt;br /&gt;
Create a minigame or puzzle using scripting. The contest discussion thread can be found [http://social.bioware.com/group/2535/discussion/10583/916864/#post_916864 here].&lt;br /&gt;
&lt;br /&gt;
'''DEADLINE: Monday 1 November''' - your entry must be ready for judging before midday GMT+0. It is strongly recommended you submit well before this time (sunday!) in case you run into troubles. Modifications to your submission are welcomed - the newest version of your entry will be judged, although modifications made ''after'' the submission date will not be judged.&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
All entries must:&lt;br /&gt;
* Reserve and use a [[Community_Contest_ID_Ranges|StringID range]]&lt;br /&gt;
* Be thoroughly tested in-game&lt;br /&gt;
* Be submitted in a single, playable area (the level will not be &amp;quot;marked&amp;quot;)&lt;br /&gt;
* Include dadbdata export of all relevant resources&lt;br /&gt;
* Include a playable dazip of the mini-game - should be playable from the other campaigns menu&lt;br /&gt;
* Include a plain-text file detailing the mini-game implementation - the objective, customization options (if present) and solutions&lt;br /&gt;
* Use only DA assets (placeables, levels) ''unless the relevant files are included with the submission and author's permission has been given''&lt;br /&gt;
* Be submitted before Monday 1 November midday (GMT+0)&lt;br /&gt;
&lt;br /&gt;
=== Guidelines ===&lt;br /&gt;
Strong entries will:&lt;br /&gt;
* be easily adaptable to vary the minigame in other modules&lt;br /&gt;
* be unique and interesting&lt;br /&gt;
* use elegant and tidy scripting&lt;br /&gt;
* include well-written, detailed comments &lt;br /&gt;
* be well-designed and be free of bugs and discourage user error&lt;br /&gt;
* be significant as a piece of scripting: doing something new or expanding beyond the fundamentals of scripting&lt;br /&gt;
* make appropriate use of secondary resources (triggers, placeables, dialogues, floaty text, VFX, sound, etc)&lt;br /&gt;
&lt;br /&gt;
=== Allowable ===&lt;br /&gt;
While no &amp;quot;bonus points&amp;quot; will be given for the following, entries may: &lt;br /&gt;
* use custom levels provided that the level is shared with the submission (.lvl and exported files)&lt;br /&gt;
&lt;br /&gt;
== Groups and Prizes ==&lt;br /&gt;
&lt;br /&gt;
=== Groups ===&lt;br /&gt;
This contest has only one group.&lt;br /&gt;
&lt;br /&gt;
* 1st place - 15 points, chooses first&lt;br /&gt;
* 2nd place - 10 points, chooses second&lt;br /&gt;
* 3rd place - 5 points, chooses third&lt;br /&gt;
* Best Newcomer - 3 points (unless 1st, 2nd or 3rd place)&lt;br /&gt;
* All other entries meeting requirements - 1 point&lt;br /&gt;
&lt;br /&gt;
To receive an &amp;quot;entry point&amp;quot;, your submission must meet the requirements of the contest, listed at the top of this page&lt;br /&gt;
&lt;br /&gt;
=== Best Newcomer Award ===&lt;br /&gt;
Every judge may nominate one newcomer as their favourite newcomer entry. To qualify, the entrant must not have submitted to a community contest before. The winning newcomer will receive three points if they don't podium (in which case, theyll be getting more points anyway!).&lt;br /&gt;
&lt;br /&gt;
=== Prizes ===&lt;br /&gt;
&lt;br /&gt;
Please see [[Community_Contest_Prizes|Community Contest Prizes]]&lt;br /&gt;
&lt;br /&gt;
== Helpful Links ==&lt;br /&gt;
* [[Scripting_overview|Scripting Overview]] - Builder Wiki&lt;br /&gt;
* [[Scripting_tutorial|Scripting Tutorial]] - Builder Wiki&lt;br /&gt;
* [http://dalexicon.net/index.php?title=Main_Page Dragon Age Lexicon] - Scripting Resource&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Entries = &lt;br /&gt;
&lt;br /&gt;
For information on how to enter, please see the [[Community_Contest_Entry_FAQ|Entry FAQs]]&lt;br /&gt;
&lt;br /&gt;
For information on Judging, please see the [[Community_Contest_Judging|Judging]] page.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;font size=&amp;quot;5&amp;quot; color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;IMPORTANT - consent to share&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;lt;b&amp;gt;By entering this competition you consent to share your work for other community members to benefit from.&lt;br /&gt;
 Where appropriate, source files should be shared (dadbdata and any non-DA assets you have used including levels, props etc). &lt;br /&gt;
 The work *MUST* be your own (obviously you may use DA assets).&lt;br /&gt;
 Others may use and modify your work in their Dragon Age mods, though are encouraged to give credit. &lt;br /&gt;
 As the entries are judged, local copies will be saved If your work is taken down.&lt;br /&gt;
 If your work is taken down, you allow for it to be re-uploaded, crediting the work in your name. &amp;lt;/b&amp;gt; &amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Entry by YourNameHere ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=1559 Links here in this format]'''&lt;br /&gt;
&lt;br /&gt;
Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. &lt;br /&gt;
&lt;br /&gt;
Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible. Description here. Try to keep it short, but include as many relevant details as possible.&lt;br /&gt;
&lt;br /&gt;
[[File:terrainBlockExample.png|400px|example picture]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weighted RPS by Mengtzu ==&lt;br /&gt;
&lt;br /&gt;
* '''[http://www.dragonagenexus.com/downloads/file.php?id=1850 Dragon Age Nexus project page]'''&lt;br /&gt;
&lt;br /&gt;
Rock, Paper, Scissors as a multi-round gambling game, with weighted moves to introduce strategy and customisable AI.  Multiple games with different settings may share an area, allowing a tournament/festival style implementation, as demonstrated in the sample module.  By default the player earns prize tokens which may be traded in for items.&lt;br /&gt;
&lt;br /&gt;
Modular functions and constants make the engine easy to extend or modify.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Judges Comments ===&lt;br /&gt;
&lt;br /&gt;
Judges will leave comments both as contructive suggestions for the entrant and also as impartial guidance for any looking to make use of your work.&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Community_Contest_ID_Ranges&amp;diff=14098</id>
		<title>Community Contest ID Ranges</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Community_Contest_ID_Ranges&amp;diff=14098"/>
				<updated>2010-10-25T06:50:36Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Community_Contest_back.jpg|link=Community_Contest_Main_Page]] [[File:CC_BSN_GetInvolved.jpg|link=http://social.bioware.com/group/2535/&amp;amp;v=discussions]]&lt;br /&gt;
&lt;br /&gt;
So that all Community Contest entries are compatible with one another and also with other mods that are around, IDs must not conflict. To ensure this, we must reserve ID ranges for strings and 2da ranges.&lt;br /&gt;
&lt;br /&gt;
= String ranges = &lt;br /&gt;
&lt;br /&gt;
Please modify this table to reserve String IDs '''before you use them''' (to avoid lost work). Append within our range if required. Please do not use from outside this range.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''89000000''' &lt;br /&gt;
| '''89999999''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 89000000&lt;br /&gt;
| 89099999&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| 89100000&lt;br /&gt;
| 89100999&lt;br /&gt;
| Cuvieronius&lt;br /&gt;
|-&lt;br /&gt;
| 89101000&lt;br /&gt;
| 89101999&lt;br /&gt;
| Vaylise&lt;br /&gt;
|-&lt;br /&gt;
| 89102000&lt;br /&gt;
| 89102999&lt;br /&gt;
| BAPACop&lt;br /&gt;
|-&lt;br /&gt;
| 89103000&lt;br /&gt;
| 89103999&lt;br /&gt;
| BloodsongVengeance&lt;br /&gt;
|-&lt;br /&gt;
| 89104000&lt;br /&gt;
| 89104999&lt;br /&gt;
| Jackkel Dragon&lt;br /&gt;
|-&lt;br /&gt;
| 89105000&lt;br /&gt;
| 89105999&lt;br /&gt;
| Lord Uber Dowzen (uberdowzen)&lt;br /&gt;
|-&lt;br /&gt;
| 89106000&lt;br /&gt;
| 89106999&lt;br /&gt;
| Shadow5973&lt;br /&gt;
|-&lt;br /&gt;
| 89107000&lt;br /&gt;
| 89107999&lt;br /&gt;
| Lobo&lt;br /&gt;
|-&lt;br /&gt;
| 89108000&lt;br /&gt;
| 89108999&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 89109000&lt;br /&gt;
| 89109999&lt;br /&gt;
| Mengtzu&lt;br /&gt;
|-&lt;br /&gt;
| 89110000&lt;br /&gt;
| 89110999&lt;br /&gt;
| Available&lt;br /&gt;
|-&lt;br /&gt;
| 89111000&lt;br /&gt;
| 89111999&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Why reserve an ID range? ===&lt;br /&gt;
This prevents the need for other modders to change your strings. This prevents any chance of overlapping IDs with other entries or other mods. This means that if you attach voice to conversations, or specify a StringID in a 2da, these connections will not be broken when others use your mod.&lt;br /&gt;
&lt;br /&gt;
=== How many do I reserve? ===&lt;br /&gt;
Just take 1000 unless you need more. Do not take less, we've got plenty to spare ;)&lt;br /&gt;
&lt;br /&gt;
=== How do I set my module to use those strings? ===&lt;br /&gt;
&lt;br /&gt;
* While logged in to builder wiki (same as login here), edit the page to put your name next to the range.&lt;br /&gt;
* In Toolset, go File &amp;gt; Manage Modules &amp;gt; (select your module) &amp;gt; Properties&lt;br /&gt;
* Set the following:&lt;br /&gt;
** StringID Begin&lt;br /&gt;
** StringID End&lt;br /&gt;
** StringID Last Used&lt;br /&gt;
* Hit OK and close dialogue.&lt;br /&gt;
&lt;br /&gt;
= 2da Ranges =&lt;br /&gt;
&lt;br /&gt;
We have reserved 24000 - 26000 in most 2das. Please reserve as many as you anticipate you will need, but don't be wasteful (reserving 200 when you only need 6 is wasteful). If you need hundreds, it's probably worth reserving your own range outside of the contest range.&lt;br /&gt;
&lt;br /&gt;
=== M2DA_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24499&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| 24500&lt;br /&gt;
| 24509&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 24510&lt;br /&gt;
| 24519&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ABI_base ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24499&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| 24500&lt;br /&gt;
| 24509&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 24510&lt;br /&gt;
| 24519&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== placeable_types ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Range Begin&lt;br /&gt;
! Range End&lt;br /&gt;
! Used by&lt;br /&gt;
|- style=&amp;quot;color:#ff6666;&amp;quot;&lt;br /&gt;
| '''24000''' &lt;br /&gt;
| '''26000''' &lt;br /&gt;
| '''Entire CC Range (to be divided up)'''&lt;br /&gt;
|-&lt;br /&gt;
| 24000&lt;br /&gt;
| 24499&lt;br /&gt;
| Organiser reserved range&lt;br /&gt;
|-&lt;br /&gt;
| 24500&lt;br /&gt;
| 24509&lt;br /&gt;
| mikemike37&lt;br /&gt;
|-&lt;br /&gt;
| 24510&lt;br /&gt;
| 24519&lt;br /&gt;
| (please keep extending this list as requried)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9387</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9387"/>
				<updated>2010-01-08T01:11:20Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* Override char_stage */&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 (you will probably need to right-click it and select &amp;quot;Check Out&amp;quot; first):&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;
=== 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\toolsetexport).  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;
=== 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 module script.  &lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''&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;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));   //Ensures follower appears at PC's location.&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;
&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;
&lt;br /&gt;
Remember to save and export your module script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''  The module script is in the General category, as seen below:&lt;br /&gt;
&lt;br /&gt;
[[File:module_script.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can set this to any script you've created.  See [[Scripting tutorial]] and [[Character generation]] for more background and some simple examples of event-handling scripts.  In general, you will want to make sure standalone module scripts pass events through to module_core (as in the [[Character generation]] examples) and add-in scripts do not (as in the example above).&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;
&lt;br /&gt;
The easiest way to use this script is directly from conversation, putting it as an action on a line of dialogue where the PC invites the follower to join them.  If you're not sure how to associate a script with a dialogue line, see the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:hire_conv.jpg]]&lt;br /&gt;
&lt;br /&gt;
Create your dialogue as normal, select the line you want to fire the script, and click the '''Plots and Scripting''' tab.  Use the '''Script''' file chooser in the Action section to browse to the script you created.&lt;br /&gt;
&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;
== 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;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));   //Ensures follower appears at PC's location.&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;
=== 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 that the character will buy, 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;
==== 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;
&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;
====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;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9386</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9386"/>
				<updated>2010-01-08T01:10:22Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* Create m2DAs for the Party Picker */&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\toolsetexport).  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;
=== 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 module script.  &lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''&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;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));   //Ensures follower appears at PC's location.&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;
&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;
&lt;br /&gt;
Remember to save and export your module script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''  The module script is in the General category, as seen below:&lt;br /&gt;
&lt;br /&gt;
[[File:module_script.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can set this to any script you've created.  See [[Scripting tutorial]] and [[Character generation]] for more background and some simple examples of event-handling scripts.  In general, you will want to make sure standalone module scripts pass events through to module_core (as in the [[Character generation]] examples) and add-in scripts do not (as in the example above).&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;
&lt;br /&gt;
The easiest way to use this script is directly from conversation, putting it as an action on a line of dialogue where the PC invites the follower to join them.  If you're not sure how to associate a script with a dialogue line, see the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:hire_conv.jpg]]&lt;br /&gt;
&lt;br /&gt;
Create your dialogue as normal, select the line you want to fire the script, and click the '''Plots and Scripting''' tab.  Use the '''Script''' file chooser in the Action section to browse to the script you created.&lt;br /&gt;
&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;
== 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;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));   //Ensures follower appears at PC's location.&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;
=== 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 that the character will buy, 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;
==== 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;
&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;
====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;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9385</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9385"/>
				<updated>2010-01-08T01:05:22Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* Capture the EVENT_TYPE_PARTYMEMBER_ADDED Event */&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 module script.  &lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''&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;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));   //Ensures follower appears at PC's location.&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;
&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;
&lt;br /&gt;
Remember to save and export your module script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''  The module script is in the General category, as seen below:&lt;br /&gt;
&lt;br /&gt;
[[File:module_script.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can set this to any script you've created.  See [[Scripting tutorial]] and [[Character generation]] for more background and some simple examples of event-handling scripts.  In general, you will want to make sure standalone module scripts pass events through to module_core (as in the [[Character generation]] examples) and add-in scripts do not (as in the example above).&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;
&lt;br /&gt;
The easiest way to use this script is directly from conversation, putting it as an action on a line of dialogue where the PC invites the follower to join them.  If you're not sure how to associate a script with a dialogue line, see the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:hire_conv.jpg]]&lt;br /&gt;
&lt;br /&gt;
Create your dialogue as normal, select the line you want to fire the script, and click the '''Plots and Scripting''' tab.  Use the '''Script''' file chooser in the Action section to browse to the script you created.&lt;br /&gt;
&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;
== 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;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));   //Ensures follower appears at PC's location.&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;
=== 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 that the character will buy, 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;
==== 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;
&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;
====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;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9384</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9384"/>
				<updated>2010-01-08T01:02:49Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* Add Plot Flags to Party Picker Event Intercept */&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 module script.  &lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''&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;
&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;
&lt;br /&gt;
Remember to save and export your module script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''  The module script is in the General category, as seen below:&lt;br /&gt;
&lt;br /&gt;
[[File:module_script.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can set this to any script you've created.  See [[Scripting tutorial]] and [[Character generation]] for more background and some simple examples of event-handling scripts.  In general, you will want to make sure standalone module scripts pass events through to module_core (as in the [[Character generation]] examples) and add-in scripts do not (as in the example above).&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;
&lt;br /&gt;
The easiest way to use this script is directly from conversation, putting it as an action on a line of dialogue where the PC invites the follower to join them.  If you're not sure how to associate a script with a dialogue line, see the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:hire_conv.jpg]]&lt;br /&gt;
&lt;br /&gt;
Create your dialogue as normal, select the line you want to fire the script, and click the '''Plots and Scripting''' tab.  Use the '''Script''' file chooser in the Action section to browse to the script you created.&lt;br /&gt;
&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;
== 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;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));   //Ensures follower appears at PC's location.&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;
=== 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 that the character will buy, 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;
==== 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;
&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;
====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;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9381</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9381"/>
				<updated>2010-01-07T23:16:30Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* Setting Talent and Skill Priorities */&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 module script.  &lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''&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;
&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;
&lt;br /&gt;
Remember to save and export your module script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''  The module script is in the General category, as seen below:&lt;br /&gt;
&lt;br /&gt;
[[File:module_script.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can set this to any script you've created.  See [[Scripting tutorial]] and [[Character generation]] for more background and some simple examples of event-handling scripts.  In general, you will want to make sure standalone module scripts pass events through to module_core (as in the [[Character generation]] examples) and add-in scripts do not (as in the example above).&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;
&lt;br /&gt;
The easiest way to use this script is directly from conversation, putting it as an action on a line of dialogue where the PC invites the follower to join them.  If you're not sure how to associate a script with a dialogue line, see the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:hire_conv.jpg]]&lt;br /&gt;
&lt;br /&gt;
Create your dialogue as normal, select the line you want to fire the script, and click the '''Plots and Scripting''' tab.  Use the '''Script''' file chooser in the Action section to browse to the script you created.&lt;br /&gt;
&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;
== 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 that the character will buy, 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;
==== 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;
&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;
====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;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9380</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9380"/>
				<updated>2010-01-07T22:51:46Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* Capture the EVENT_TYPE_PARTYMEMBER_ADDED Event */&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 module script.  &lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''&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;
&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;
&lt;br /&gt;
Remember to save and export your module script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''  The module script is in the General category, as seen below:&lt;br /&gt;
&lt;br /&gt;
[[File:module_script.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can set this to any script you've created.  See [[Scripting tutorial]] and [[Character generation]] for more background and some simple examples of event-handling scripts.  In general, you will want to make sure standalone module scripts pass events through to module_core (as in the [[Character generation]] examples) and add-in scripts do not (as in the example above).&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;
&lt;br /&gt;
The easiest way to use this script is directly from conversation, putting it as an action on a line of dialogue where the PC invites the follower to join them.  If you're not sure how to associate a script with a dialogue line, see the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:hire_conv.jpg]]&lt;br /&gt;
&lt;br /&gt;
Create your dialogue as normal, select the line you want to fire the script, and click the '''Plots and Scripting''' tab.  Use the '''Script''' file chooser in the Action section to browse to the script you created.&lt;br /&gt;
&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;
== 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;
&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;
====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;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9379</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9379"/>
				<updated>2010-01-07T22:50:47Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* Capture the EVENT_TYPE_PARTYMEMBER_ADDED Event */&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 module script.  &lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''&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;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''  The module script is in the General category, as seen below:&lt;br /&gt;
&lt;br /&gt;
[[File:module_script.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can set this to any script you've created.  See [[Scripting tutorial]] and [[Character generation]] for more background and some simple examples of event-handling scripts.  In general, you will want to make sure standalone module scripts pass events through to module_core (as in the [[Character generation]] examples) and add-in scripts do not (as in the example above).&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;
&lt;br /&gt;
The easiest way to use this script is directly from conversation, putting it as an action on a line of dialogue where the PC invites the follower to join them.  If you're not sure how to associate a script with a dialogue line, see the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:hire_conv.jpg]]&lt;br /&gt;
&lt;br /&gt;
Create your dialogue as normal, select the line you want to fire the script, and click the '''Plots and Scripting''' tab.  Use the '''Script''' file chooser in the Action section to browse to the script you created.&lt;br /&gt;
&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;
== 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;
&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;
====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;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9378</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9378"/>
				<updated>2010-01-07T22:44:12Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* When I choose followers from the Party Picker, they spawn into the area but do not join. */&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 module script.  &lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''&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;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''  The module script is in the General category, as seen below:&lt;br /&gt;
&lt;br /&gt;
[[File:module_script.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can set this to any script you've created.&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;
&lt;br /&gt;
The easiest way to use this script is directly from conversation, putting it as an action on a line of dialogue where the PC invites the follower to join them.  If you're not sure how to associate a script with a dialogue line, see the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:hire_conv.jpg]]&lt;br /&gt;
&lt;br /&gt;
Create your dialogue as normal, select the line you want to fire the script, and click the '''Plots and Scripting''' tab.  Use the '''Script''' file chooser in the Action section to browse to the script you created.&lt;br /&gt;
&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;
== 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;
&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;
====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;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=File:Hire_conv.jpg&amp;diff=9377</id>
		<title>File:Hire conv.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=File:Hire_conv.jpg&amp;diff=9377"/>
				<updated>2010-01-07T22:33:54Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9376</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9376"/>
				<updated>2010-01-07T22:33:31Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* Create Your Hiring Script */&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 module script.  &lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''&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;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''  The module script is in the General category, as seen below:&lt;br /&gt;
&lt;br /&gt;
[[File:module_script.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can set this to any script you've created.&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;
&lt;br /&gt;
The easiest way to use this script is directly from conversation, putting it as an action on a line of dialogue where the PC invites the follower to join them.  If you're not sure how to associate a script with a dialogue line, see the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:hire_conv.jpg]]&lt;br /&gt;
&lt;br /&gt;
Create your dialogue as normal, select the line you want to fire the script, and click the '''Plots and Scripting''' tab.  Use the '''Script''' file chooser in the Action section to browse to the script you created.&lt;br /&gt;
&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;
== 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;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=File:Module_script.jpg&amp;diff=9375</id>
		<title>File:Module script.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=File:Module_script.jpg&amp;diff=9375"/>
				<updated>2010-01-07T22:10:56Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9374</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9374"/>
				<updated>2010-01-07T22:06:28Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* Capture the EVENT_TYPE_PARTYMEMBER_ADDED Event */&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 module script.  &lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''&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;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''  The module script is in the General category, as seen below:&lt;br /&gt;
&lt;br /&gt;
[[File:module_script.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can set this to any script you've created.&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;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Tutorials&amp;diff=9368</id>
		<title>Tutorials</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Tutorials&amp;diff=9368"/>
				<updated>2010-01-07T12:28:02Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* Other Tutorials */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introductory tutorials ==&lt;br /&gt;
&lt;br /&gt;
In the course of these tutorials we'll go through all the steps needed to create a basic adventure.&lt;br /&gt;
&lt;br /&gt;
{{sidebox|&lt;br /&gt;
*Boxes like this contain a checklist of important steps.&lt;br /&gt;
*They're intended as a reminder and as a navigational aid.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
*[[Introductory tutorial]] - An overview of the toolset as a whole&lt;br /&gt;
*[[Module tutorial]] - how to create a module to work in.&lt;br /&gt;
&lt;br /&gt;
This set of tutorials forms a series, each building on or filling in omissions by the last:&lt;br /&gt;
*[[Area tutorial]]&lt;br /&gt;
*[[Placeable tutorial]]&lt;br /&gt;
*[[Item tutorial]]&lt;br /&gt;
*[[Creature tutorial]]&lt;br /&gt;
*[[Conversation tutorial]]&lt;br /&gt;
&lt;br /&gt;
Once you've become familiar with the basics introduced on those tutorials you might have a better grounding for:&lt;br /&gt;
*[[Cutscene tutorial]]&lt;br /&gt;
*[[Map tutorial]] (which also introduces you to [[2DA]] editing)&lt;br /&gt;
*[[Level Editor Tutorial]]&lt;br /&gt;
*[[Scripting tutorial]]&lt;br /&gt;
&lt;br /&gt;
== Demo module ==&lt;br /&gt;
&lt;br /&gt;
The toolset currently ships with a simple demo module pre-loaded into its database.&lt;br /&gt;
&lt;br /&gt;
*[[Demo module]] - how to export and run the demo module.&lt;br /&gt;
&lt;br /&gt;
== Custom content tutorials == &lt;br /&gt;
*[[Tutorial: Idiots guide to make special objects]]&lt;br /&gt;
*[[Tutorial: idiots guide to adding custom items to singleplayer]]&lt;br /&gt;
*[[Tutorial: Adding a Custom Model to Toolset]]&lt;br /&gt;
*[[Tutorial: Creating a custom placeable from a model]]&lt;br /&gt;
*[[Tutorial: Reskinning an Item]]&lt;br /&gt;
*[[Adding a New Spell Tutorial]]&lt;br /&gt;
&lt;br /&gt;
== Character generation tutorials ==&lt;br /&gt;
*[[Backgrounds tutorial]]&lt;br /&gt;
*[[Add A New Class Tutorial]]&lt;br /&gt;
&lt;br /&gt;
== Other Tutorials ==&lt;br /&gt;
*[[ToolSet: Area Layouts]]&lt;br /&gt;
*[[Adding a Location to the Single Player Campaign Tutorial]]&lt;br /&gt;
*[[Follower tutorial]] (Simple and advanced, requires scripting knowledge)&lt;br /&gt;
&lt;br /&gt;
== External Tutorials ==&lt;br /&gt;
*[http://lerlek.se/Video+Tutorials Lerlek Dragon Age Origins Toolset Video Tutorials Collection] has collected many in-depth video tutorials.&lt;br /&gt;
*[http://dragonagemodding.wordpress.com Beyond Ferelden] has many in-depth tutorials by jwvanderbeck.&lt;br /&gt;
*[http://www.youtube.com/watch?v=TwQNRBFLhrE Playable Area and Conversation] video tutorial by [http://social.bioware.com/64020/ st4rdog].&lt;br /&gt;
*[http://www.youtube.com/watch?v=CaHldJcUTz8 Simple Conversation Cameras] video tutorial by [http://social.bioware.com/64020/ st4rdog].&lt;br /&gt;
*[http://www.youtube.com/watch?v=QOQJ2heQto4 Cutscene and Trigger] video tutorial by [http://social.bioware.com/64020/ st4rdog].&lt;br /&gt;
*[http://www.youtube.com/watch?v=szWKgj2ZuXo Custom Level and Room Building] video tutorial by [http://social.bioware.com/64020/ st4rdog].&lt;br /&gt;
*[http://www.youtube.com/watch?v=DKJ7F14n8o8 Downloading and Installing the Toolset] video tutorial by [http://social.bioware.com/74287/ DragonAge22].&lt;br /&gt;
*[http://www.youtube.com/watch?v=iMPBsulv9xI Creating a Room] video tutorial by [http://social.bioware.com/74287/ DragonAge22].&lt;br /&gt;
*[http://www.youtube.com/watch?v=g3kx2CaarHo How to Make an Interior Level with Lighting] video tutorial by [http://social.bioware.com/group/60/ Darkworld Development Team].&lt;br /&gt;
*[http://www.youtube.com/watch?v=O6TeZeE1Lc8 Making a Room] video tutorial by BigDrip681.&lt;br /&gt;
*[http://social.bioware.com/5339/blog/576/ Custom Player Items In Single Player] by [http://social.bioware.com/5339/ weriK].&lt;br /&gt;
*[http://social.bioware.com/5339/blog/651/ The Secret Behind Item Statistics] by [http://social.bioware.com/5339/ weriK].&lt;br /&gt;
*[http://social.bioware.com/project/923/ Guide for installing/uninstalling/updating Mods] Beginner Guide to get started with using Mods by [http://social.bioware.com/237411/ Alexspeed].&lt;br /&gt;
*[http://www.jezelf.co.uk/tutorials.htm Photoshop Map making tutorials] Credits to Jason Elford, brought to DAT wiki by [http://social.bioware.com/48156/ Arixsus]&lt;br /&gt;
*[http://social.bioware.com/project/527/ Video Tutorials by SilentCid] Multiple in-depth video tutorials of the DA Toolset&lt;br /&gt;
*[http://www.youtube.com/view_play_list?p=EF29DD1AACEBA92A Qkrch's Video Tutorials] Toolset tutorial complete series for the experienced builder (Spanish &amp;amp; English)&lt;br /&gt;
[[Category:Tutorials| ]]&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9364</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9364"/>
				<updated>2010-01-06T20:39:03Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &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;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9350</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9350"/>
				<updated>2010-01-06T05:59:58Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* Common Follower Problems &amp;amp; FAQ */&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;
&lt;br /&gt;
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;
&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>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9349</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9349"/>
				<updated>2010-01-06T05:59:20Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* When I choose followers from the Party Picker, they spawn into the area but do not join. */&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;
&lt;br /&gt;
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;
&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;
====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>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9348</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9348"/>
				<updated>2010-01-06T05:59:08Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: /* 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;
&lt;br /&gt;
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>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9347</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9347"/>
				<updated>2010-01-06T05:47:49Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &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;
&lt;br /&gt;
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;
&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>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9346</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9346"/>
				<updated>2010-01-06T05:37:31Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &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;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=File:Picker_advanced.jpg&amp;diff=9345</id>
		<title>File:Picker advanced.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=File:Picker_advanced.jpg&amp;diff=9345"/>
				<updated>2010-01-06T05:35:52Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9344</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9344"/>
				<updated>2010-01-06T05:35:31Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &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;
- Class and specialisation chosen via script&lt;br /&gt;
- Any starting state&lt;br /&gt;
- Level higher than the PC&lt;br /&gt;
- Starts with a specialisation point rather than a specific specialisation&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;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9343</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9343"/>
				<updated>2010-01-06T05:27:41Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &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;
- Class and specialisation chosen via script&lt;br /&gt;
- Any starting state&lt;br /&gt;
- Level higher than the PC&lt;br /&gt;
- Starts with a specialisation point rather than a specific specialisation&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;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9342</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9342"/>
				<updated>2010-01-06T05:00:30Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &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;
- Class and specialisation chosen via script&lt;br /&gt;
- Any starting state&lt;br /&gt;
- Level higher than the PC&lt;br /&gt;
- Starts with a specialisation point rather than a specific specialisation&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;
&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 Script 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;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=File:M2da_base_fofbc.jpg&amp;diff=9341</id>
		<title>File:M2da base fofbc.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=File:M2da_base_fofbc.jpg&amp;diff=9341"/>
				<updated>2010-01-06T04:51:48Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9340</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9340"/>
				<updated>2010-01-06T04:51:16Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &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;
- Class and specialisation chosen via script&lt;br /&gt;
- Any starting state&lt;br /&gt;
- Level higher than the PC&lt;br /&gt;
- Starts with a specialisation point rather than a specific specialisation&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;
&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;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=File:ALMori_paste.jpg&amp;diff=9339</id>
		<title>File:ALMori paste.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=File:ALMori_paste.jpg&amp;diff=9339"/>
				<updated>2010-01-06T04:43:51Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9338</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9338"/>
				<updated>2010-01-06T04:43:07Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &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;
- Class and specialisation chosen via script&lt;br /&gt;
- Any starting state&lt;br /&gt;
- Level higher than the PC&lt;br /&gt;
- Starts with a specialisation point rather than a specific specialisation&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;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=File:ALMori_copy.jpg&amp;diff=9337</id>
		<title>File:ALMori copy.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=File:ALMori_copy.jpg&amp;diff=9337"/>
				<updated>2010-01-06T04:40:40Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9336</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=9336"/>
				<updated>2010-01-06T04:40:25Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &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;
- Class and specialisation chosen via script&lt;br /&gt;
- Any starting state&lt;br /&gt;
- Level higher than the PC&lt;br /&gt;
- Starts with a specialisation point rather than a specific specialisation&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;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=File:AlMori_talent_pref.jpg&amp;diff=9335</id>
		<title>File:AlMori talent pref.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=File:AlMori_talent_pref.jpg&amp;diff=9335"/>
				<updated>2010-01-06T04:37:01Z</updated>
		
		<summary type="html">&lt;p&gt;Mengtzu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mengtzu</name></author>	</entry>

	</feed>