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

From Dragon Age Toolset Wiki
< User:Sunjammer
Revision as of 00:13, 27 April 2020 by Sunjammer (Talk | contribs) (Created)

(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.

Background

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.

  • Create new a plot resource (because duplicating a plot duplicates the uneditable GUID)
    • Set the plot type to one with a "Codex - " prefix
    • Add a single Main Flag: remember the number (usually 0 as it is the only flag)
  • Create a placeable and place it in an area
  • Open the placeable's variables
  • Set PLC_CODEX_PLOT to the name of the plot resource
  • Set PLC_CODEX_FLAG to the number of the plot flag

When the Player clicks on the placeable the following script runs:

void Placeable_ShowCodexEntry(object oPlc)
{
    string sCodexPlot = GetLocalString(oPlc, PLC_CODEX_PLOT);
    int nCodexFlag    = GetLocalInt(oPlc, PLC_CODEX_FLAG);
 
    if (sCodexPlot != "" && nCodexFlag >= 0)
    {
        string sSummary = GetPlotSummary(sCodexPlot, nCodexFlag);
 
        // :
 
        if (!WR_GetPlotFlag(sCodexPlot, nCodexFlag))
        {
            WR_SetPlotFlag(sCodexPlot, nCodexFlag, TRUE, TRUE);
            RewardXPParty(XP_CODEX, XP_TYPE_CODEX, OBJECT_INVALID, GetHero());
        }
        UI_DisplayCodexMessage(oPlc, sSummary);
        SetObjectInteractive(oPlc, FALSE);
    }
}


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.

Set up

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

  • Create the book item and set it's tag to something unique, e.g. xx_codex_itm_book
  • Create a plot
  • Create the longsword item and set it's tag to something unique, e.g. xx_codex_itm_book
  • item's variables


Standalone module

Considerations

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

- why we can't fall through

module_core:

        case EVENT_TYPE_CAMPAIGN_ITEM_ACQUIRED:
        {
 
            :
 
            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);
            }
 
            :
 
            break;
        }

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_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;
        }


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);
 
            // Debug.
            PrintToLog("------> MODULE CAMPAIGN ITEM ACQUIRED: " + sItem);
 
            // 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;
        }