Useful Scripts

From Dragon Age Toolset Wiki
Revision as of 08:37, 25 January 2010 by Eshme (Talk | contribs)

Jump to: navigation, search

This page lists how to accomplish tasks that are relatively simple and commonly needed, but that otherwise require deep scripting knowledge to figure out intuitively how to do.

Feel free to add new sections describing any tricks or techniques you think is worth documenting. If the page becomes too large it can be split up into specific topics.

Run a cutscene from a trigger

Create a script:

#include "events_h"
#include "global_objects_h"
#include "utility_h"
 
void main ()
{
    event ev = GetCurrentEvent();
    int nEventType = GetEventType(ev);
    int bEventHandled = FALSE;
    switch (nEventType)
    {
        case EVENT_TYPE_ENTER:
        {
            object oCreature = GetEventCreator(ev);
            if(GetObjectActive(OBJECT_SELF)
               && IsPartyMember(oCreature)) 
            { 
                resource rCutscene = R"my_cutscene.cut";
                CS_LoadCutscene(rCutscene);
                SetObjectActive(OBJECT_SELF, FALSE);
            }         
         }
         break;
    }
    if (!bEventHandled) //If this event wasn't handled by this script, let the core script try
    {
        HandleEvent(ev, RESOURCE_SCRIPT_TRIGGER_CORE);
    }
}

And set it as the event script for the trigger that you want to have run the cutscene.

Add a follower to the player's party

if(IsPlayer(oCreature)) {
  object oFollower = GetObjectByTag("myfollower");
  UT_HireFollower(oCreature, oFollower);
 }

Note that with Toolset v1.0.982.0, calling UT_HireFollower() will result in a follower who's unable to gain xp. This happens due to the call of

 WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, TRUE);

to the function

 void WR_SetFollowerState(object oCreature, int nState, int nSendEvent = TRUE, int nMinLevel = 0, int bPreventLevelup = FALSE)

To enable the xp gain, the flag CREATURE_REWARD_FLAGS needs to be cleared from the follower after the hired event was processed (there the flag is set). For now the best/easiest approach to take might be to make a copy of UT_HireFollower in an include file and rename it something like UT_HireFollower_Fixed, then make the following change:

   WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, TRUE);

to

   WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, bPreventLevelup);

Have an enemy play possum and then get up to fight

Set the creature's CREATURE_SPAWN_DEAD variable to 2.

When it's time for the creature to rise and attack, execute the following script commands:

#include "wrappers_h"
...
WR_SetObjectActive(oCreature, TRUE);
SetCommandable(oCreature, TRUE);
// Make sure to set this flag back to 0 to avoid problems with savegames.
SetLocalInt(oCreature, CREATURE_SPAWN_DEAD, 0);
UT_CombatStart(oCreature, oPC);

Insert content into an existing area

If you want to add new content on to an existing area (for example, putting a new character or area transition door into an area that exists in the single-player campaign) there are two different ways to do it. One is to override the existing area with a new area of your own design that duplicates the original with the exception of your additions. This is straightforward to do but can interact poorly with other add-ons - you can only have one version of an area active at a time. [To Editor: Edit in a Custom Module or the existing Single Player Campaign Module?]

A more elegant and extensible approach is to use a PRCSCR_-prefixed M2DA. The PRCSCR M2DA has a very simple structure and a simple but profound effect:

  • ID - a unique integer identifier for each row
  • AreaListName - a string that identifies a specific area list, or the special keyword "any".
  • Script - the name of a script file.

Whenever a player enters an area in an area list in this M2DA the associated script will be run. A modder can therefore include a script with his mod that will be run when the player enters an existing area that he didn't create. This script can freely add or remove placeables and creatures and perform whatever other modifications to the area that a script is capable of doing.

Note that the script will be run every time the player enters the area, so you'll want to have an associated plot flag to ensure that the changes are only made once.

The following example is a script that adds a new character from an add-on module to an existing area in the main game:

// this is the name of a precreated plot file "joblos_quest" prefixed with the special "plt_"
// "plt_" + quest name allows you to reference the flag names as constants.
#include "plt_joblos_quest" 
#include "wrappers_h"
 
void main()
{
    //Check whether we've added Joblo already.
    if (WR_GetPlotFlag(PLT_JOBLOS_QUEST, JOBLO_ADDED_TO_TOWN) == FALSE)
    {
        object oTown = GetObjectByTag("lot100ar_lothering"); //An area's tag is the same as its resource name
        vector vJobloLocation = Vector(126.745f, 120.724f, 0.460568f); // See below for how to get these coordinates
 
        CreateObject(
            OBJECT_TYPE_CREATURE,
            R"joblo.utc",
            Location(oTown, vJobloLocation, 180.0f) //See below for how to get the value for orientation
        )
 
        WR_SetPlotFlag("joblos_quest", JOBLO_ADDED_TO_TOWN, TRUE);
    }
}

Since you can't add waypoints to an existing area you'll need to enter the position and orientation values for the target location manually. You can find them by creating a local copy of the area in question and temporarily adding a waypoint to copy down the coordinates and orientation you'll need.