User:Sunjammer/Items with codex entries tutorial (draft)

From Dragon Age Toolset Wiki
< User:Sunjammer
Revision as of 17:37, 27 April 2020 by Sunjammer (Talk | contribs) (Editing)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

This tutorial illustrates how to create items with codex entries for both a new standalone module or an extension to the Single Player Campaign. Additionally it will show you how to destroy, or avoid destroying, the item once the codex entry has been created.

Goal

The goal of this tutorial is to create two items that with codex entries. The first, a book, will be automatically removed from the Player's inventory and destroyed. The second, a longsword, will remain in the Player's inventory so they can use it.


This tutorial assumes, you are familiar with creating a standalone module or an extension to the Single Player Campaign and is only focused on the steps and explaining the considerations surrounding creating items with codex entries.

This process shares some similarities with, but is more complex than, creating placeables with codex entries.


Steps

The the initial steps are the same regardless of whether you are creating a standalone module or an extension to the Single Player Campaign.


Scripting

Standalone module

If your module is still using module_core as it's module script then open the module's properties and create a new module script:

  • Select the File > Manage Modules menu option
  • In the Manage Modules window, select your module (if not already selected)
  • Click the Properties... button
  • In the Object Inspector window, select the Script property
  • Click the Browse (Ellipsis.png) button
  • In the Resource Open/Save window, click the New button
  • Create new resource.png
  • Enter the


and assign a new script, for example, xx_codex_module. 

Open the new script in the Script Editor and double click on the

        case EVENT_TYPE_CAMPAIGN_ITEM_ACQUIRED:
        {
            // Decompose event.
            object oAcquirer = GetEventCreator(ev);
            object oItem = GetEventObject(ev, 0);
            string sItem = GetTag(oItem);
 
            // Does the item have a codex flag? We can ignore any items with default value (-1) as
            // plot flags have values of 0 and above.
            int nFlag = GetLocalInt(oItem, ITEM_CODEX_FLAG);
            if(nFlag > -1)
            {
                // Was the item acquired by a party member? We ignore any items acquired by someone
                // other than a party member.
                if(IsFollower(oAcquirer))
                {
                    // Is the item one of ours? Other items can satify the first two conditions but
                    // will be handled by their author's code therefore we must ensure it is ours.
                    if(sItem == "xx_codex_itm_longsword")
                    {
                        // Trigger the standard codex tutorial (it only shows once).
                        // NOTE: requires #include "plt_tut_codex_item" directive.
                        WR_SetPlotFlag(PLT_TUT_CODEX_ITEM, TUT_CODEX_ITEM, TRUE);
 
                        // Trigger the codex entry.
                        // NOTE: unlike Placeables there is no equivalent of the PLC_CODEX_PLOT
                        // variable therefore we name the plot resource using the item's tag.
                        WR_SetPlotFlag(sItem, nFlag, TRUE, TRUE);
 
                        // Raise the "event handled" flag to prevent the default script running for
                        // this item and event.
                        nEventHandled = TRUE;
                    }
                }
            }
            break;
        }

Since we are using the standard module script template we don't have to


    if(!nEventHandled)
    {
        HandleEvent(ev, RESOURCE_SCRIPT_MODULE_CORE);
    }

- why we can't fall through

module_core:

        case EVENT_TYPE_CAMPAIGN_ITEM_ACQUIRED:
        {
 
            // [ignoring some code here]
 
            int nCodexItem = GetLocalInt(oItem, ITEM_CODEX_FLAG);
            if (nCodexItem > -1 && IsFollower(oAcquirer))
            {
 
                WR_SetPlotFlag(PLT_TUT_CODEX_ITEM, TUT_CODEX_ITEM, TRUE);
                Log_Trace(LOG_CHANNEL_SYSTEMS, GetCurrentScriptName(), "Got a codex item: " + GetTag(oItem));
                WR_SetPlotFlag(GetTag(oItem), nCodexItem, TRUE, TRUE);
                WR_DestroyObject(oItem);
            }
 
            // [ignoring some code here]
 
            break;
        }


Single Player Campaign

Normally for a module extending the Single Player Campaign we don't need

Considerations

sp_module:

        case EVENT_TYPE_CAMPAIGN_ITEM_ACQUIRED:
        {
            HandleEvent(ev, RESOURCE_SCRIPT_MODULE_ITEM_ACQUIRED);
            bEventHandled = TRUE;
            break;
        }

sp_module_item_acq:

        case EVENT_TYPE_CAMPAIGN_ITEM_ACQUIRED:
        {
            :
 
            else if(sItemTag == "gen_im_acc_rng_bld")
            {
                WR_SetPlotFlag(PLT_COD_ITM_BLOOD_RING, COD_ITM_BLOOD_RING, TRUE, TRUE);
            }
            else if(sItemTag == "gen_im_wep_rng_lbw_sun")
            {
                WR_SetPlotFlag(PLT_COD_ITM_BOW_GOLDEN_SUN, COD_ITM_BOW_GOLDEN_SUN, TRUE, TRUE);
            }
            else if(sItemTag == "gen_im_acc_amu_am6")
            {
                WR_SetPlotFlag(PLT_COD_ITM_LIFE_DRINKER, COD_ITM_LIFE_DRINKER, TRUE, TRUE);
            }
 
            :
 
        }

There's no catch all. There's no fall through. So if we're extending the Single Player Campaign we're on our own!

Solution

        case EVENT_TYPE_CAMPAIGN_ITEM_ACQUIRED:
        {
            // Decompose event.
            object oAcquirer = GetEventCreator(ev);
            object oItem = GetEventObject(ev, 0);
            string sItem = GetTag(oItem);
 
            // Does the item have a codex flag? We can ignore any items with default value (-1) as
            // plot flags have values of 0 and above.
            int nFlag = GetLocalInt(oItem, ITEM_CODEX_FLAG);
            if(nFlag > -1)
            {
                // Was the item acquired by a party member? We ignore any items acquired by someone
                // other than a party member.
                if(IsFollower(oAcquirer))
                {
                    // Is the item one of ours? Other items can satify the first two conditions but
                    // will be handled by their author's code therefore we must ensure it is ours.
                    if(sItem == "xx_codex_itm_book" || sItem == "xx_codex_itm_longsword")
                    {
                        // Trigger the standard codex tutorial (it only shows once).
                        // NOTE: requires #include "plt_tut_codex_item" directive.
                        WR_SetPlotFlag(PLT_TUT_CODEX_ITEM, TUT_CODEX_ITEM, TRUE);
 
                        // Trigger the codex entry.
                        // NOTE: unlike Placeables there is no equivalent of the PLC_CODEX_PLOT
                        // variable therefore we name the plot resource using the item's tag.
                        WR_SetPlotFlag(sItem, nFlag, TRUE, TRUE);
 
                        // Do we want the item to persist? If not then we can delete it here.
                        if(sItem == "xx_codex_itm_book") 
                        {
                            WR_DestroyObject(oItem);
                        }
 
                    }
                }
            }
            break;
        }

See also

  • TODO