Difference between revisions of "Event override"

From Dragon Age Toolset Wiki
Jump to: navigation, search
m (Add languages template)
m
 
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
{{Infobox script}}
 
{{Infobox script}}
  
== How to override an event? ==
+
The broadest definition of [[Event override|overriding an event]] means redirecting an event from the default handler (or script) to some form of a custom handler.
  
=== Via a wrapper script ===
+
== Via a wrapper script ==
  
The safest and most common way to override an event is to create an event script for the resource whose event-handling you want to override, and use that script to handle the specific event you want to override while passing on all other events to the default script to handle.
+
The normal, and safest, way to override an event is to create an event script for the resource whose event-handling you want to override, and use that script to handle the specific events you want to override while passing on all other events to the core script to handle.
  
For example, if you have a creature called a "Death Tyrant" that does something special when it receives [[EVENT_TYPE_DEATH]], you could create a script named death_tyrant_events with the following layout:
+
For example, if you have a creature called "Death Tyrant" that does something special when it receives the [[EVENT_TYPE_DEATH]] event, you could create a script named <code>death_tyrant</code> with the following code:
  
 
<dascript>
 
<dascript>
Line 16: Line 16:
 
void main()
 
void main()
 
{
 
{
     event ev = GetCurrentEvent();
+
    int nEventHandled;
     int nEventType = GetEventType(ev);
+
 
     string sDebug;   
+
    // decompose the event
     object oPC = GetHero();
+
     event evCurrent = GetCurrentEvent();
     object oParty = GetParty(oPC);   
+
     int nEventType = GetEventType(evCurrent);
    int nEventHandled = FALSE;
+
 
 +
     // common variable
 +
     object oHero = GetHero();
 +
     object oParty = GetParty(oHero);   
  
 
     switch(nEventType)
 
     switch(nEventType)
Line 27: Line 30:
 
         case EVENT_TYPE_DEATH:
 
         case EVENT_TYPE_DEATH:
 
         {
 
         {
             ...
+
             // your custom code goes here
             nEventHandled = TRUE; //set this if no further action is required for this event
+
 
 +
             // set nEventHandled if no further action is required for this event
 +
            nEventHandled = TRUE;
 +
 
 
             break;
 
             break;
 
         }
 
         }
 
     }
 
     }
     if (!nEventHandled) //If this event wasn't handled by this script, let the core script try
+
 
 +
     // if this event wasn't handled by this script, let the core script try
 +
    if(!nEventHandled)
 
     {
 
     {
         HandleEvent(ev, RESOURCE_SCRIPT_CREATURE_CORE);
+
         HandleEvent(evCurrent, RESOURCE_SCRIPT_CREATURE_CORE);
 
     }
 
     }
 +
 
}
 
}
 
</dascript>
 
</dascript>
  
And set this script as the event-handling script for Death Tyrants. When the game sends the Death Tyrant any event other than EVENT_TYPE_DEATH, it'll get sent to the default creature_core event-handling script by the function call HandleEvent(ev, RESOURCE_SCRIPT_CREATURE_CORE). EVENT_TYPE_DEATH, on the other hand, will get intercepted and handled by your own code.
+
This script is then assigned to the Script property on the Death Tyrant resource.  
  
=== Via the Events 2DA ===
+
When the game engine sends a Death Tyrant creature an event other than <code>EVENT_TYPE_DEATH</code> it will get sent to the core <code>creature_core</code> script by the<code>HandleEvent(evCurrent, RESOURCE_SCRIPT_CREATURE_CORE)</code>  function call. However <code>EVENT_TYPE_DEATH</code> will be intercepted and handled by your custom code.
  
This is how you can do the same thing on a global scale, catching and overriding an event for all resources in the game.
+
== Via the engineevents 2DA ==
  
Create a [[Events.xls|Events]] M2DA File - for instructions look [[2DA#Extending_the_game_via_M2DAs|here]]:
+
An alternative, and more advanced, way to override an event is to use the  [[engineevents 2da]]. Overriding an event in this way does it "global" scale, catching and redirecting an event for all resources in the game.
  
[[File:Events.png]]
+
Create an [[engineevents 2da]] fragment (see [[2DA#Extending_the_game_via_M2DAs|extending the game via m2da files]] for further details) to override, for example,  the <code>EVENT_TYPE_INVENTORY_ADDED</code> event so that it will be handled by the custom <code>my_event_override</code> script.
  
In this case i used the "EVENT_TYPE_INVENTORY_ADDED" Event and Handle it in my custom Event-Handler-Script: my_event_override
+
[[File:Events.png]]
  
Now just handle the event in your script as you like.
+
'''NOTE''': this is a substitution fragment (i.e. one that replaces an  original entry) rather than an extension fragment (i.e. one that adds a  new entry) and will cause compatibility issues with any other mod that also attempts to override the same event using this technique.  
  
For example i want to have a screen-message every time i pick up an item (or steal one):
+
The custom script can be constructed to do whatever is required, for example, displaying a message on screen every time the Player picks up (or steals) an item:
  
 
<dascript>
 
<dascript>
// --- script start ---
 
// file: my_event_override.nss
 
// author: Pheelon
 
 
 
#include "utility_h"
 
#include "utility_h"
 
#include "wrappers_h"
 
#include "wrappers_h"
 
#include "events_h"
 
#include "events_h"
 +
 
void main()
 
void main()
 
{
 
{
     event ev  = GetCurrentEvent();
+
     // decompose the event
     int nEvent = GetEventType(ev);
+
    event evCurrent = GetCurrentEvent();
     object oOwner = GetEventCreator(ev);
+
     int nEventType = GetEventType(evCurrent);
 +
     object oOwner = GetEventCreator(evCurrent);
  
     switch (nEvent)
+
     switch(nEventType)
 
     {
 
     {
 
         case EVENT_TYPE_INVENTORY_ADDED:
 
         case EVENT_TYPE_INVENTORY_ADDED:
 
         {
 
         {
             object oItem = GetEventObject(ev, 0);
+
             // only show if the item went into the player's inventory
            if (IsPartyMember(oOwner)) // only show if the item went into the player's inventory
+
            if(IsPartyMember(oOwner))
 
             {
 
             {
 +
                object oItem = GetEventObject(evCurrent, 0);
 +
 
                 DisplayFloatyMessage(oOwner, GetName(oItem) + " added", FLOATY_MESSAGE, 14654488, 10.0);
 
                 DisplayFloatyMessage(oOwner, GetName(oItem) + " added", FLOATY_MESSAGE, 14654488, 10.0);
 
             }
 
             }
             //Now we didn't handle the event itself but just displayed a floaty --> let the original event handler take over.
+
 
             HandleEvent(ev); // this passes the event to the default handler of the event's target object
+
             // Since this script doesn't handle the event itself, but merely adds functionality (displaying the message),
 +
             // the event is passed back to its default event handler for the event's target object
 +
            HandleEvent(evCurrent);
 +
 
 
             break;
 
             break;
 
         }
 
         }
 
 
     }
 
     }
}
 
  
// --- script end ---
+
}
 
</dascript>
 
</dascript>
 +
 +
'''NOTE''': the "default handler" is the script specified on the resource, therefore even if engineevents 2da is used to make a global change, calling <code>HandleEvent(evCurrent)</code> ensures that the script assigned to the resources '''Script''' property is still executed.
  
 
{{Languages}}
 
{{Languages}}
 
[[Category:Events]]
 
[[Category:Events]]

Latest revision as of 19:59, 8 May 2014

Scripting

The broadest definition of overriding an event means redirecting an event from the default handler (or script) to some form of a custom handler.

Via a wrapper script

The normal, and safest, way to override an event is to create an event script for the resource whose event-handling you want to override, and use that script to handle the specific events you want to override while passing on all other events to the core script to handle.

For example, if you have a creature called "Death Tyrant" that does something special when it receives the EVENT_TYPE_DEATH event, you could create a script named death_tyrant with the following code:

#include "utility_h"
#include "wrappers_h" 
#include "events_h"
 
void main()
{
    int nEventHandled;
 
    // decompose the event
    event evCurrent = GetCurrentEvent();
    int nEventType = GetEventType(evCurrent);
 
    // common variable
    object oHero = GetHero();
    object oParty = GetParty(oHero);   
 
    switch(nEventType)
    {
         case EVENT_TYPE_DEATH:
         {
             // your custom code goes here
 
             // set nEventHandled if no further action is required for this event
             nEventHandled = TRUE; 
 
             break;
         }
    }
 
    // if this event wasn't handled by this script, let the core script try
    if(!nEventHandled)
    {
        HandleEvent(evCurrent, RESOURCE_SCRIPT_CREATURE_CORE);
    }
 
}

This script is then assigned to the Script property on the Death Tyrant resource.

When the game engine sends a Death Tyrant creature an event other than EVENT_TYPE_DEATH it will get sent to the core creature_core script by theHandleEvent(evCurrent, RESOURCE_SCRIPT_CREATURE_CORE) function call. However EVENT_TYPE_DEATH will be intercepted and handled by your custom code.

Via the engineevents 2DA

An alternative, and more advanced, way to override an event is to use the engineevents 2da. Overriding an event in this way does it "global" scale, catching and redirecting an event for all resources in the game.

Create an engineevents 2da fragment (see extending the game via m2da files for further details) to override, for example, the EVENT_TYPE_INVENTORY_ADDED event so that it will be handled by the custom my_event_override script.

Events.png

NOTE: this is a substitution fragment (i.e. one that replaces an original entry) rather than an extension fragment (i.e. one that adds a new entry) and will cause compatibility issues with any other mod that also attempts to override the same event using this technique.

The custom script can be constructed to do whatever is required, for example, displaying a message on screen every time the Player picks up (or steals) an item:

#include "utility_h"
#include "wrappers_h"
#include "events_h"
 
void main()
{
    // decompose the event
    event evCurrent = GetCurrentEvent();
    int nEventType = GetEventType(evCurrent);
    object oOwner = GetEventCreator(evCurrent);
 
    switch(nEventType)
    {
        case EVENT_TYPE_INVENTORY_ADDED:
        {
            // only show if the item went into the player's inventory
            if(IsPartyMember(oOwner))
            {
                object oItem = GetEventObject(evCurrent, 0);
 
                DisplayFloatyMessage(oOwner, GetName(oItem) + " added", FLOATY_MESSAGE, 14654488, 10.0);
            }
 
            // Since this script doesn't handle the event itself, but merely adds functionality (displaying the message),
            // the event is passed back to its default event handler for the event's target object
            HandleEvent(evCurrent); 
 
            break;
        }
    }
 
}

NOTE: the "default handler" is the script specified on the resource, therefore even if engineevents 2da is used to make a global change, calling HandleEvent(evCurrent) ensures that the script assigned to the resources Script property is still executed.


Language: English  • русский