Difference between revisions of "User:Sunjammer/Items with codex entries tutorial (draft)"

From Dragon Age Toolset Wiki
Jump to: navigation, search
m
m (Editing)
 
Line 1: Line 1:
 
This tutorial illustrates how to create [[items with codex entries tutorial|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.
 
This tutorial illustrates how to create [[items with codex entries tutorial|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 ==
+
== 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 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.
Line 7: Line 10:
 
This process shares some similarities with, but is more complex than, creating placeables 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 [[Bug:_Duplicating_a_plot_duplicates_the_uneditable_GUID|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#Variables|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:
+
== Steps ==
  
<dascript>
 
void Placeable_ShowCodexEntry(object oPlc)
 
{
 
    string sCodexPlot = GetLocalString(oPlc, PLC_CODEX_PLOT);
 
    int nCodexFlag    = GetLocalInt(oPlc, PLC_CODEX_FLAG);
 
  
    if (sCodexPlot != "" && nCodexFlag >= 0)
+
The the initial steps are the same regardless of whether you are creating a standalone module or an extension to the Single Player Campaign.
    {
+
        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);
 
    }
 
}
 
</dascript>
 
 
 
== 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 the book item and set it's tag to something unique, e.g. xx_codex_itm_book
* Create a plot
+
* Create '''new''' a plot resource (because [[Bug:_Duplicating_a_plot_duplicates_the_uneditable_GUID|duplicating a plot duplicates the uneditable GUID]])
 
* Create the longsword item and set it's tag to something unique, e.g. xx_codex_itm_book
 
* Create the longsword item and set it's tag to something unique, e.g. xx_codex_itm_book
 
*[[Item#Variables|item's variables]]
 
*[[Item#Variables|item's variables]]
  
 +
== Scripting ==
  
 
== Standalone module ==
 
== Standalone module ==
  
=== Considerations ===
+
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''' ([[File:Ellipsis.png]]) button
 +
* In the Resource Open/Save window, click the New button
 +
* [[File:Create_new_resource.png]]
 +
* Enter the
  
<dascript>
 
    if(!nEventHandled)
 
    {
 
        HandleEvent(ev, RESOURCE_SCRIPT_MODULE_CORE);
 
    }
 
</dascript>
 
  
- why we can't fall through
+
and assign a new script, for example, xx_codex_module.
 
+
module_core:
+
 
+
<dascript>
+
 
+
        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;
+
        }
+
 
+
 
+
 
+
</dascript>
+
  
=== Solution ===
+
Open the new script in the [[Script editor window|Script Editor]] and double click on the
  
 
<dascript>
 
<dascript>
Line 137: Line 81:
 
         }
 
         }
 
</dascript>
 
</dascript>
 +
 +
Since we are using the standard module script template we don't have to
 +
 +
 +
<dascript>
 +
    if(!nEventHandled)
 +
    {
 +
        HandleEvent(ev, RESOURCE_SCRIPT_MODULE_CORE);
 +
    }
 +
</dascript>
 +
 +
- why we can't fall through
 +
 +
module_core:
 +
 +
<dascript>
 +
        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;
 +
        }
 +
</dascript>
 +
  
  

Latest revision as of 17:37, 27 April 2020

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