Updated Release Archive. Fixed Mage-killer prereqs. Removed old LETO & ConvoCC related files. Added organized spell scroll store. Fixed Gloura spellbook. Various TLK fixes. Reorganized Repo. Removed invalid user folders. Added DocGen back in.
710 lines
28 KiB
Plaintext
710 lines
28 KiB
Plaintext
//:://////////////////////////////////////////////
|
|
//:: Dynamic Conversation System include
|
|
//:: inc_dynconv
|
|
//:://////////////////////////////////////////////
|
|
/** @file
|
|
|
|
|
|
|
|
@author Primogenitor
|
|
@date 2005.09.23 - Rebuilt the system - Ornedan
|
|
*/
|
|
//:://////////////////////////////////////////////
|
|
//:://////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Constant definitions */
|
|
//////////////////////////////////////////////////
|
|
|
|
const int DYNCONV_EXITED = -2;
|
|
const int DYNCONV_ABORTED = -3;
|
|
const int DYNCONV_SETUP_STAGE = -1;
|
|
|
|
const int DYNCONV_TOKEN_HEADER = 99;
|
|
const int DYNCONV_TOKEN_REPLY_0 = 100;
|
|
const int DYNCONV_TOKEN_REPLY_1 = 101;
|
|
const int DYNCONV_TOKEN_REPLY_2 = 102;
|
|
const int DYNCONV_TOKEN_REPLY_3 = 103;
|
|
const int DYNCONV_TOKEN_REPLY_4 = 104;
|
|
const int DYNCONV_TOKEN_REPLY_5 = 105;
|
|
const int DYNCONV_TOKEN_REPLY_6 = 106;
|
|
const int DYNCONV_TOKEN_REPLY_7 = 107;
|
|
const int DYNCONV_TOKEN_REPLY_8 = 108;
|
|
const int DYNCONV_TOKEN_REPLY_9 = 109;
|
|
const int DYNCONV_TOKEN_EXIT = 110;
|
|
const int DYNCONV_TOKEN_WAIT = 111;
|
|
const int DYNCONV_TOKEN_NEXT = 112;
|
|
const int DYNCONV_TOKEN_PREV = 113;
|
|
const int DYNCONV_MIN_TOKEN = 99;
|
|
const int DYNCONV_MAX_TOKEN = 113;
|
|
|
|
const int DYNCONV_STRREF_PLEASE_WAIT = 16824202; // "Please wait"
|
|
const int DYNCONV_STRREF_PREVIOUS = 16824203; // "Previous"
|
|
const int DYNCONV_STRREF_NEXT = 16824204; // "Next"
|
|
const int DYNCONV_STRREF_ABORT_CONVO = 16824212; // "Abort"
|
|
const int DYNCONV_STRREF_EXIT_CONVO = 78; // "Exit"
|
|
|
|
const string DYNCONV_SCRIPT = "DynConv_Script";
|
|
const string DYNCONV_VARIABLE = "DynConv_Var";
|
|
const string DYNCONV_STAGE = "DynConv_Stage";
|
|
const string DYNCONV_TOKEN_BASE = "DynConv_TOKEN";
|
|
const string DYNCONV_CHOICEOFFSET = "ChoiceOffset";
|
|
|
|
/**
|
|
* Exiting the conversation is not allowed. The exit
|
|
* choice is not shown
|
|
*/
|
|
const int DYNCONV_EXIT_NOT_ALLOWED = 0;
|
|
/**
|
|
* Exiting the conversation is allowed and it is
|
|
* forced to exit due to no nodes being shown.
|
|
*/
|
|
const int DYNCONV_EXIT_FORCE_EXIT = -1;
|
|
/**
|
|
* Exiting the conversation is allowed and the exit
|
|
* choice is shown.
|
|
*/
|
|
const int DYNCONV_EXIT_ALLOWED_SHOW_CHOICE = 1;
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Function prototypes */
|
|
//////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Sets the header token and reply tokens for the PC to values stored
|
|
* via SetHeader and AddChoice, respectively.
|
|
*
|
|
* @param oPC The PC involved in the conversation. If left
|
|
* to default, GetPCSpeaker is used
|
|
*/
|
|
void SetupTokens(object oPC = OBJECT_INVALID);
|
|
|
|
/**
|
|
* Builds the local variable name for a token.
|
|
*
|
|
* @param nTokenID One of the DYNCONV_TOKEN_* constants
|
|
*/
|
|
string GetTokenIDString(int nTokenID);
|
|
|
|
/**
|
|
* Sets the dynamic conversation header. ie, the "NPC"'s reply.
|
|
*
|
|
* @param sText The text to set the header to
|
|
* @param oPC The PC involved in the conversation. If left
|
|
* to default, GetPCSpeaker is used
|
|
*/
|
|
void SetHeader(string sText, object oPC = OBJECT_INVALID);
|
|
|
|
/**
|
|
* A wrapper for SetHeader() that uses TLK references.
|
|
*
|
|
* @param nStrRef The TLK entry to use
|
|
* @param oPC The PC involved in the conversation. If left
|
|
* to default, GetPCSpeaker is used
|
|
*/
|
|
void SetHeaderStrRef(int nStrRef, object oPC = OBJECT_INVALID);
|
|
|
|
/**
|
|
* Add a reply choice to be displayed. The replies are displayed in
|
|
* the same order as they are added.
|
|
*
|
|
* @param sText The text of the choice
|
|
* @param nValue The numeric value of the choice. This is what will be
|
|
* returned by GetChoice()
|
|
* @param oPC The PC involved in the conversation. If left
|
|
* to default, GetPCSpeaker is used
|
|
*/
|
|
void AddChoice(string sText, int nValue, object oPC = OBJECT_INVALID);
|
|
|
|
/**
|
|
* A wrapper for AddChoice() that uses TLK references.
|
|
*
|
|
* @param nStrRef The TLK entry to use
|
|
* @param nValue The numeric value of the choice. This is what will be
|
|
* returned by GetChoice()
|
|
* @param oPC The PC involved in the conversation. If left
|
|
* to default, GetPCSpeaker is used
|
|
*/
|
|
void AddChoiceStrRef(int nStrRef, int nValue, object oPC = OBJECT_INVALID);
|
|
|
|
/**
|
|
* Sets the custom token at nTokenID to be the given string and stores
|
|
* the value in a local variable on OBJECT_SELF.
|
|
* Used by the dyynamic onversation system to track token assignment.
|
|
*
|
|
* @param nTokenID The custom token number to store the string in
|
|
* @param sString The string to store
|
|
* @param oPC The PC whose conversation this token belongs to
|
|
*/
|
|
void SetToken(int nTokenID, string sString, object oPC = OBJECT_SELF);
|
|
|
|
/**
|
|
* Sets the default values for the Exit, Wait, Next and Previous
|
|
* tokens. The values will be as follows, or their translated
|
|
* equivalents should a non-english TLK be used.
|
|
*
|
|
* Exit = "Exit"
|
|
* Wait = "Please wait"
|
|
* Next = "Next"
|
|
* Previous = "Previous"
|
|
*/
|
|
void SetDefaultTokens();
|
|
|
|
/**
|
|
* Changes the conversation stage. If the new stage given is
|
|
* the same as the current, nothing happens. Otherwise
|
|
* the stage is changed and the choices stored for the old
|
|
* stage are deleted.
|
|
*
|
|
* @param nNewStage The stage to enter
|
|
* @param oPC The PC involved in the conversation. If left
|
|
* to default, GetPCSpeaker is used
|
|
*/
|
|
void SetStage(int nNewStage, object oPC = OBJECT_INVALID);
|
|
|
|
/**
|
|
* Gets the current stage of the conversation.
|
|
*
|
|
* @param oPC The PC involved in the conversation. If left
|
|
* to default, GetPCSpeaker is used
|
|
* @return The current stage of the conversation, as previously
|
|
* set via SetStage() or 0 if no calls to SetStage()
|
|
* have been done yet.
|
|
*/
|
|
int GetStage(object oPC = OBJECT_INVALID);
|
|
|
|
/**
|
|
* Gets the value of the choice selected by the PC.
|
|
*
|
|
* @param oPC The PC involved in the conversation. If left
|
|
* to default, GetPCSpeaker is used
|
|
* @return The value of the choice the PC made, as set
|
|
* by a call to AddChoice().
|
|
*/
|
|
int GetChoice(object oPC = OBJECT_INVALID);
|
|
|
|
/**
|
|
* Gets the text of the choice selected by the PC.
|
|
*
|
|
* @param oPC The PC involved in the conversation. If left
|
|
* to default, GetPCSpeaker is used
|
|
* @return The text of the choice the PC made, as set
|
|
* by a call to AddChoice().
|
|
*/
|
|
string GetChoiceText(object oPC = OBJECT_INVALID);
|
|
|
|
/**
|
|
* Starts a dynamic conversation. Results are unspecified if called while
|
|
* already inside a dynamic conversation.
|
|
*
|
|
* @param sConversationScript The script to use for controlling the conversation.
|
|
* @param oPC The PC that is to be doing the responding in the conversation.
|
|
* @param bAllowExit One of the DYNCONV_EXIT_* constants.
|
|
* @param bAllowAbort If TRUE, the PC is allowed to aborts the conversation by moving / doing
|
|
* some other action or being involved in combat. This can be changed later
|
|
* on using AllowAbort()
|
|
* @param bForceStart If TRUE, the PC's actions are cleared, so the conversation starts immediately
|
|
* and cannot be avoided by the PC cancelling the action while it is in the queue.
|
|
* @param oConverseWith The object to speak the "NPC" side of the conversation. Usually, this is also
|
|
* the PC, which will be used when this parameter is left to it's default value.
|
|
* NOTE: If this parameter is given a value other than OBJECT_INVALID, no validity
|
|
* testing is performed upon that object. The function caller needs to make sure
|
|
* the object exists.
|
|
*/
|
|
void StartDynamicConversation(string sConversationScript, object oPC,
|
|
int nAllowExit = DYNCONV_EXIT_ALLOWED_SHOW_CHOICE, int bAllowAbort = FALSE,
|
|
int bForceStart = FALSE, object oConverseWith = OBJECT_INVALID);
|
|
|
|
/**
|
|
* Starts using another dynamic conversation script while inside a
|
|
* dynamic conversation. Should only be called from a dynamic conversation
|
|
* script.
|
|
* The current conversation's script and allow exit/abort variables are
|
|
* saved. When the conversation entered via this call exits, the system
|
|
* returns to the current conversation, with stage being the one specified
|
|
* in the call to this function.
|
|
* NOTE: Any stage setup markers are not stored for the return.
|
|
*
|
|
* @param sConversationToEnter The conversation script to use in the branch
|
|
* @param nStageToReturnTo The value of stage variable upong return
|
|
* from the branch.
|
|
* @param bAllowExit The branch's initial exit allowance state. See
|
|
* StartDynamicConversation() for more details.
|
|
* @param bAllowAbort The branch's initial abort allowance state. See
|
|
* StartDynamicConversation() for more details.
|
|
* @param oPC The PC involved in the conversation. If left
|
|
* to default, GetPCSpeaker is used.
|
|
*/
|
|
void BranchDynamicConversation(string sConversationToEnter, int nStageToReturnTo,
|
|
int bAllowExit = TRUE, int bAllowAbort = FALSE,
|
|
object oPC = OBJECT_INVALID);
|
|
|
|
/**
|
|
* Marks the current dynconvo as exitable via the exit conversation
|
|
* choice.
|
|
*
|
|
* @param nNewValue One of the DYNCONV_EXIT_* constants
|
|
* @param bChangeExitTokenText If this is TRUE, then changes the text on
|
|
* DYNCONV_TOKEN_EXIT to "Exit"
|
|
* @param oPC The PC involved in the conversation. If left
|
|
* to default, GetPCSpeaker is used.
|
|
*/
|
|
void AllowExit(int nNewValue = DYNCONV_EXIT_ALLOWED_SHOW_CHOICE, int bChangeExitTokenText = TRUE, object oPC = OBJECT_INVALID);
|
|
|
|
/**
|
|
* Marks the conversation as abortable, meaning that the player is
|
|
* allowed to leave the conversation via means other than the
|
|
* exit conversation choice.
|
|
*
|
|
* @param oPC The PC involved in the conversation. If left to
|
|
* default, GetPCSpeaker is used.
|
|
*/
|
|
void AllowAbort(object oPC = OBJECT_INVALID);
|
|
|
|
/**
|
|
* Checks whether the given stage is marked as already set up.
|
|
*
|
|
* @param nStage The stage to check
|
|
* @param oPC The PC involved in the conversation. If left to
|
|
* default, GetPCSpeaker is used.
|
|
*/
|
|
int GetIsStageSetUp(int nStage, object oPC = OBJECT_INVALID);
|
|
|
|
/**
|
|
* Marks a stage as being set up. This means that when
|
|
* the conversation script is called to set up the
|
|
* stage, nothing is done and old values are used instead.
|
|
* This is useful for scrolling lists, as CPU is not
|
|
* wasted on rebuilding the exact same list.
|
|
*
|
|
* @param nStage The stage to set marker for
|
|
* @param oPC The PC involved in the conversation. If left to
|
|
* default, GetPCSpeaker is used.
|
|
*/
|
|
void MarkStageSetUp(int nStage, object oPC = OBJECT_INVALID);
|
|
|
|
/**
|
|
* Marks the stage as not set up. This is used to undo
|
|
* the effects of MarkStageSetUp() when there is
|
|
* need to rerun the stage's builder.
|
|
* An example of such situation would be returning to
|
|
* a stage from another.
|
|
*
|
|
* @param nStage The stage to unset marker for
|
|
* @param oPC The PC involved in the conversation. If left to
|
|
* default, GetPCSpeaker is used.
|
|
*/
|
|
void MarkStageNotSetUp(int nStage, object oPC = OBJECT_INVALID);
|
|
|
|
/**
|
|
* Clears the current stage's choices and marks it not set up.
|
|
*
|
|
* @param oPC The PC involved in the conversation. If left to
|
|
* default, GetPCSpeaker is used.
|
|
*/
|
|
void ClearCurrentStage(object oPC = OBJECT_INVALID);
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Include section */
|
|
//////////////////////////////////////////////////
|
|
|
|
#include "inc_array"
|
|
#include "inc_debug"
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Internal function prototypes */
|
|
//////////////////////////////////////////////////
|
|
|
|
void _DynConvInternal_ExitedConvo(object oPC, int bAbort);
|
|
void _DynConvInternal_RunScript(object oPC, int nDynConvVar);
|
|
void _DynConvInternal_PreScript(object oPC);
|
|
void _DynConvInternal_PostScript(object oPC);
|
|
object _DynConvInternal_ResolvePC(object oPC);
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Function Definitions */
|
|
//////////////////////////////////////////////////
|
|
|
|
void SetupTokens(object oPC = OBJECT_INVALID)
|
|
{
|
|
oPC = _DynConvInternal_ResolvePC(oPC);
|
|
// Set header
|
|
SetCustomToken(DYNCONV_TOKEN_HEADER, GetLocalString(oPC, "DynConv_HeaderText"));
|
|
|
|
// Set reply tokens. Assumes that the tokens used are a continuous block.
|
|
int nOffset = GetLocalInt(oPC, DYNCONV_CHOICEOFFSET);
|
|
int i;
|
|
for (i = 0; i < 10; i++)
|
|
{
|
|
SetToken(DYNCONV_TOKEN_REPLY_0 + i, array_get_string(oPC, "ChoiceTokens", nOffset + i), oPC);
|
|
}
|
|
}
|
|
|
|
void SetHeader(string sText, object oPC = OBJECT_INVALID)
|
|
{
|
|
oPC = _DynConvInternal_ResolvePC(oPC);
|
|
SetLocalString(oPC, "DynConv_HeaderText", sText);
|
|
}
|
|
|
|
void SetHeaderStrRef(int nStrRef, object oPC = OBJECT_INVALID)
|
|
{
|
|
SetHeader(GetStringByStrRef(nStrRef), oPC);
|
|
}
|
|
|
|
string GetTokenIDString(int nTokenID)
|
|
{
|
|
return DYNCONV_TOKEN_BASE + IntToString(nTokenID);
|
|
}
|
|
|
|
void AddChoice(string sText, int nValue, object oPC = OBJECT_INVALID)
|
|
{
|
|
oPC = _DynConvInternal_ResolvePC(oPC);
|
|
if(!array_exists(oPC, "ChoiceTokens"))
|
|
array_create(oPC, "ChoiceTokens");
|
|
if(!array_exists(oPC, "ChoiceValues"))
|
|
array_create(oPC, "ChoiceValues");
|
|
array_set_string(oPC, "ChoiceTokens", array_get_size(oPC, "ChoiceTokens"), sText);
|
|
array_set_int (oPC, "ChoiceValues", array_get_size(oPC, "ChoiceValues"), nValue);
|
|
}
|
|
|
|
void AddChoiceStrRef(int nStrRef, int nValue, object oPC = OBJECT_INVALID)
|
|
{
|
|
AddChoice(GetStringByStrRef(nStrRef), nValue, oPC);
|
|
}
|
|
|
|
void SetToken(int nTokenID, string sString, object oPC = OBJECT_SELF)
|
|
{
|
|
// Set the token
|
|
SetCustomToken(nTokenID, sString);
|
|
// Set a marker on the PC for the reply conditional scripts to check
|
|
SetLocalString(oPC, GetTokenIDString(nTokenID), sString);
|
|
}
|
|
|
|
string GetToken(int nTokenID, object oPC = OBJECT_SELF)
|
|
{
|
|
// Set a marker on the PC for the reply conditional scripts to check
|
|
return GetLocalString(oPC, GetTokenIDString(nTokenID));
|
|
}
|
|
|
|
void SetDefaultTokens()
|
|
{
|
|
SetCustomToken(DYNCONV_TOKEN_EXIT, GetStringByStrRef(DYNCONV_STRREF_EXIT_CONVO));
|
|
SetCustomToken(DYNCONV_TOKEN_WAIT, GetStringByStrRef(DYNCONV_STRREF_PLEASE_WAIT));
|
|
SetCustomToken(DYNCONV_TOKEN_NEXT, GetStringByStrRef(DYNCONV_STRREF_NEXT));
|
|
SetCustomToken(DYNCONV_TOKEN_PREV, GetStringByStrRef(DYNCONV_STRREF_PREVIOUS));
|
|
}
|
|
|
|
void _DynConvInternal_ExitedConvo(object oPC, int bAbort)
|
|
{
|
|
// Restart convo if not allowed to leave yet
|
|
if(bAbort && !GetLocalInt(oPC, "DynConv_AllowAbort")) // Allowed to abort?
|
|
{
|
|
if(DEBUG) DoDebug("_DynConvInternal_ExitedConvo(): Conversation aborted, restarting.");
|
|
AssignCommand(oPC, ClearAllActions(TRUE));
|
|
AssignCommand(oPC, ActionStartConversation(oPC, "dyncov_base", TRUE, FALSE));
|
|
SetLocalInt(oPC, "DynConv_RestartMarker", TRUE);
|
|
}
|
|
// Allowed to exit? Technically, the only way this branch should ever be run is by there not being any response choices available
|
|
else if(!bAbort &&
|
|
(GetLocalInt(oPC, "DynConv_AllowExit") == DYNCONV_EXIT_NOT_ALLOWED))
|
|
{
|
|
if(DEBUG) DoDebug("_DynConvInternal_ExitedConvo(): ERROR: Conversation exited via exit node while exiting not allowed!\n"
|
|
+ "DYNCONV_SCRIPT = '" + GetLocalString(oPC, DYNCONV_SCRIPT) + "'\n"
|
|
);
|
|
|
|
AssignCommand(oPC, ClearAllActions(TRUE));
|
|
AssignCommand(oPC, ActionStartConversation(oPC, "dyncov_base", TRUE, FALSE));
|
|
SetLocalInt(oPC, "DynConv_RestartMarker", TRUE);
|
|
}
|
|
else{
|
|
// Run the conversation script's exit handler
|
|
SetLocalInt(oPC, DYNCONV_VARIABLE, bAbort ? DYNCONV_ABORTED : DYNCONV_EXITED);
|
|
ExecuteScript(GetLocalString(oPC, DYNCONV_SCRIPT), OBJECT_SELF);
|
|
|
|
// If there are entries remaining in the stack, pop the previous conversation
|
|
if(GetLocalInt(oPC, "DynConv_Stack"))
|
|
{
|
|
if(DEBUG) DoDebug("_DynConvInternal_ExitedConvo(): Exited a branch");
|
|
// Clean up after the previous conversation
|
|
array_delete(oPC, "ChoiceTokens");
|
|
array_delete(oPC, "ChoiceValues");
|
|
array_delete(oPC, "StagesSetup");
|
|
DeleteLocalInt(oPC, "ChoiceOffset");
|
|
|
|
// Pop the data from the stack
|
|
int nStack = GetLocalInt(oPC, "DynConv_Stack");
|
|
int nStage = GetLocalInt(oPC, "DynConv_Stack_ReturnToStage_" + IntToString(nStack));
|
|
int nAllowExit = GetLocalInt(oPC, "DynConv_Stack_AllowExit_" + IntToString(nStack));
|
|
int nAllowAbort = GetLocalInt(oPC, "DynConv_Stack_AllowAbort_" + IntToString(nStack));
|
|
string sScript = GetLocalString(oPC, "DynConv_Stack_Script_" + IntToString(nStack));
|
|
|
|
// Delete the stack level
|
|
DeleteLocalInt(oPC, "DynConv_Stack_ReturnToStage_" + IntToString(nStack));
|
|
DeleteLocalInt(oPC, "DynConv_Stack_AllowExit_" + IntToString(nStack));
|
|
DeleteLocalInt(oPC, "DynConv_Stack_AllowAbort_" + IntToString(nStack));
|
|
DeleteLocalString(oPC, "DynConv_Stack_Script_" + IntToString(nStack));
|
|
if(nStack - 1 > 0) SetLocalInt(oPC, "DynConv_Stack", nStack - 1);
|
|
else DeleteLocalInt(oPC, "DynConv_Stack");
|
|
|
|
// Store the date in the conversation variables
|
|
SetLocalInt(oPC, DYNCONV_STAGE, nStage);
|
|
SetLocalInt(oPC, "DynConv_AllowExit", nAllowExit);
|
|
SetLocalInt(oPC, "DynConv_AllowAbort", nAllowAbort);
|
|
SetLocalString(oPC, DYNCONV_SCRIPT, sScript);
|
|
|
|
// Restart the conversation
|
|
AssignCommand(oPC, ClearAllActions(TRUE));
|
|
AssignCommand(oPC, ActionStartConversation(oPC, "dyncov_base", TRUE, FALSE));
|
|
}
|
|
// Fully exited the conversation. Clean up
|
|
else
|
|
{
|
|
if(DEBUG) DoDebug("_DynConvInternal_ExitedConvo(): Fully exited conversation");
|
|
array_delete(oPC, "ChoiceTokens");
|
|
array_delete(oPC, "ChoiceValues");
|
|
array_delete(oPC, "StagesSetup");
|
|
|
|
DeleteLocalInt(oPC, "ChoiceOffset");
|
|
DeleteLocalInt(oPC, "DynConv_AllowExit");
|
|
DeleteLocalInt(oPC, "DynConv_AllowAbort");
|
|
|
|
DeleteLocalInt(oPC, DYNCONV_VARIABLE);
|
|
DeleteLocalInt(oPC, DYNCONV_STAGE);
|
|
DeleteLocalString(oPC, DYNCONV_SCRIPT);
|
|
DeleteLocalString(oPC, "DynConv_HeaderText");
|
|
int i;
|
|
for(i = DYNCONV_MIN_TOKEN; i <= DYNCONV_MAX_TOKEN; i++)
|
|
DeleteLocalString(oPC, GetTokenIDString(i));
|
|
}
|
|
}
|
|
}
|
|
|
|
void _DynConvInternal_RunScript(object oPC, int nDynConvVar)
|
|
{
|
|
if(!GetLocalInt(oPC, "DynConv_RestartMarker"))
|
|
{
|
|
_DynConvInternal_PreScript(oPC);
|
|
string sScript = GetLocalString(oPC, DYNCONV_SCRIPT);
|
|
SetLocalInt(oPC, DYNCONV_VARIABLE, nDynConvVar);
|
|
ExecuteScript(sScript, OBJECT_SELF);
|
|
_DynConvInternal_PostScript(oPC);
|
|
}
|
|
else
|
|
{
|
|
SetupTokens(oPC);
|
|
DeleteLocalInt(oPC, "DynConv_RestartMarker");
|
|
}
|
|
}
|
|
|
|
void _DynConvInternal_PreScript(object oPC)
|
|
{
|
|
// Create the choice arrays
|
|
array_create(oPC, "ChoiceTokens");
|
|
array_create(oPC, "ChoiceValues");
|
|
}
|
|
|
|
void _DynConvInternal_PostScript(object oPC)
|
|
{
|
|
// If debugging is active, check that the conversations have at least one response node
|
|
// when exiting is off
|
|
if(DEBUG)
|
|
{
|
|
if(GetLocalInt(oPC, DYNCONV_VARIABLE) == DYNCONV_SETUP_STAGE &&
|
|
GetLocalInt(oPC, "DynConv_AllowExit") == DYNCONV_EXIT_NOT_ALLOWED &&
|
|
array_get_size(oPC, "ChoiceTokens") == 0
|
|
)
|
|
{
|
|
DoDebug("Dynconvo ERROR: No response tokens set up and exiting not allowed!");
|
|
}
|
|
}
|
|
}
|
|
|
|
object _DynConvInternal_ResolvePC(object oPC)
|
|
{
|
|
return oPC == OBJECT_INVALID ? GetPCSpeaker() : oPC; // If no valid PC reference was passed, get it via GetPCSpeaker
|
|
}
|
|
|
|
void SetStage(int nNewStage, object oPC = OBJECT_INVALID)
|
|
{
|
|
oPC = _DynConvInternal_ResolvePC(oPC);
|
|
// No need to act if the stage wasn't changed
|
|
if(nNewStage != GetStage(oPC))
|
|
{
|
|
|
|
SetLocalInt(oPC, DYNCONV_STAGE, nNewStage);
|
|
|
|
// Clear the choice data
|
|
array_delete(oPC, "ChoiceTokens");
|
|
array_delete(oPC, "ChoiceValues");
|
|
DeleteLocalInt(oPC, "ChoiceOffset");
|
|
}
|
|
}
|
|
|
|
int GetStage(object oPC = OBJECT_INVALID)
|
|
{
|
|
oPC = _DynConvInternal_ResolvePC(oPC);
|
|
return GetLocalInt(oPC, DYNCONV_STAGE);
|
|
}
|
|
|
|
int GetChoice(object oPC = OBJECT_INVALID)
|
|
{
|
|
oPC = _DynConvInternal_ResolvePC(oPC);
|
|
return array_get_int(oPC, "ChoiceValues", GetLocalInt(oPC, DYNCONV_VARIABLE) // Number of choice
|
|
- 1 // Which begins at index 1 instead of the index 0 we need here
|
|
+ GetLocalInt(oPC, "ChoiceOffset"));
|
|
}
|
|
|
|
string GetChoiceText(object oPC = OBJECT_INVALID)
|
|
{
|
|
oPC = _DynConvInternal_ResolvePC(oPC);
|
|
return array_get_string(oPC, "ChoiceTokens", GetLocalInt(oPC, DYNCONV_VARIABLE) // Number of choice
|
|
- 1 // Which begins at index 1 instead of the index 0 we need here
|
|
+ GetLocalInt(oPC, "ChoiceOffset"));
|
|
}
|
|
|
|
void StartDynamicConversation(string sConversationScript, object oPC,
|
|
int nAllowExit = DYNCONV_EXIT_ALLOWED_SHOW_CHOICE, int bAllowAbort = FALSE,
|
|
int bForceStart = FALSE, object oConverseWith = OBJECT_INVALID)
|
|
{
|
|
if(IsInConversation(oPC))
|
|
{
|
|
if(DEBUG) DoDebug("StartDynamicConversation(): Aborting--already in conversation");
|
|
return;
|
|
}
|
|
|
|
if(DEBUG) DoDebug("StartDynamicConversation(): Starting new dynamic conversation, parameters:\n"
|
|
+ "sConversationScript = '" + sConversationScript + "'\n"
|
|
+ "oPC = " + DebugObject2Str(oPC) + "\n"
|
|
+ "nAllowExit = " + (nAllowExit == DYNCONV_EXIT_NOT_ALLOWED ? "DYNCONV_EXIT_NOT_ALLOWED" :
|
|
nAllowExit == DYNCONV_EXIT_FORCE_EXIT ? "DYNCONV_EXIT_FORCE_EXIT" :
|
|
nAllowExit == DYNCONV_EXIT_ALLOWED_SHOW_CHOICE ? "DYNCONV_EXIT_ALLOWED_SHOW_CHOICE" :
|
|
"ERROR: Unsupported value: " + IntToString(nAllowExit)
|
|
) + "\n"
|
|
+ "bAllowAbort = " + DebugBool2String(bAllowAbort) + "\n"
|
|
+ "bForceStart = " + DebugBool2String(bForceStart) + "\n"
|
|
+ "oConverseWith = " + DebugObject2Str(oConverseWith) + "\n"
|
|
);
|
|
// By default, the PC converses with itself
|
|
oConverseWith = oConverseWith == OBJECT_INVALID ? oPC : oConverseWith;
|
|
if(DEBUG) if(!GetIsObjectValid(oConverseWith)) DoDebug("StartDynamicConversation(): ERROR: oConverseWith is not valid!");
|
|
|
|
// Store the exit control variables
|
|
SetLocalInt(oPC, "DynConv_AllowExit", nAllowExit);
|
|
SetLocalInt(oPC, "DynConv_AllowAbort", bAllowAbort);
|
|
|
|
// Initiate conversation
|
|
if(bForceStart) AssignCommand(oPC, ClearAllActions(TRUE));
|
|
SetLocalString(oPC, DYNCONV_SCRIPT, sConversationScript);
|
|
AssignCommand(oPC, ActionStartConversation(oConverseWith, "dyncov_base", TRUE, FALSE));
|
|
}
|
|
|
|
void BranchDynamicConversation(string sConversationToEnter, int nStageToReturnTo,
|
|
int nAllowExit = DYNCONV_EXIT_ALLOWED_SHOW_CHOICE, int bAllowAbort = FALSE,
|
|
object oPC = OBJECT_INVALID)
|
|
{
|
|
if(DEBUG) DoDebug("BranchDynamicConversation(): Entering another dynamic conversation, parameters:\n"
|
|
+ "sConversationToEnter = '" + sConversationToEnter + "'\n"
|
|
+ "nStageToReturnTo = " + IntToString(nStageToReturnTo) + "\n"
|
|
+ "nAllowExit = " + (nAllowExit == DYNCONV_EXIT_NOT_ALLOWED ? "DYNCONV_EXIT_NOT_ALLOWED" :
|
|
nAllowExit == DYNCONV_EXIT_FORCE_EXIT ? "DYNCONV_EXIT_FORCE_EXIT" :
|
|
nAllowExit == DYNCONV_EXIT_ALLOWED_SHOW_CHOICE ? "DYNCONV_EXIT_ALLOWED_SHOW_CHOICE" :
|
|
"ERROR: Unsupported value: " + IntToString(nAllowExit)
|
|
) + "\n"
|
|
+ "bAllowAbort = " + DebugBool2String(bAllowAbort) + "\n"
|
|
+ "oPC = " + DebugObject2Str(oPC) + "\n "
|
|
);
|
|
oPC = _DynConvInternal_ResolvePC(oPC);
|
|
// Get current stack level
|
|
int nStack = GetLocalInt(oPC, "DynConv_Stack") + 1;
|
|
|
|
// Push the return data onto the stack
|
|
SetLocalInt(oPC, "DynConv_Stack_ReturnToStage_" + IntToString(nStack), nStageToReturnTo);
|
|
SetLocalInt(oPC, "DynConv_Stack_AllowExit_" + IntToString(nStack),
|
|
GetLocalInt(oPC, "DynConv_AllowExit"));
|
|
SetLocalInt(oPC, "DynConv_Stack_AllowAbort_" + IntToString(nStack),
|
|
GetLocalInt(oPC, "DynConv_AllowAbort"));
|
|
SetLocalString(oPC, "DynConv_Stack_Script_" + IntToString(nStack),
|
|
GetLocalString(oPC, DYNCONV_SCRIPT));
|
|
SetLocalInt(oPC, "DynConv_Stack", nStack);
|
|
|
|
// Clean the current conversation data
|
|
array_delete(oPC, "ChoiceTokens");
|
|
array_delete(oPC, "ChoiceValues");
|
|
array_delete(oPC, "StagesSetup");
|
|
DeleteLocalInt(oPC, "ChoiceOffset");
|
|
DeleteLocalInt(oPC, DYNCONV_STAGE);
|
|
|
|
// Set the new conversation as active
|
|
SetLocalString(oPC, DYNCONV_SCRIPT, sConversationToEnter);
|
|
SetLocalInt(oPC, "DynConv_AllowExit", nAllowExit);
|
|
SetLocalInt(oPC, "DynConv_AllowAbort", bAllowAbort);
|
|
}
|
|
|
|
/// @todo Rename to SetExitable
|
|
void AllowExit(int nNewValue = DYNCONV_EXIT_ALLOWED_SHOW_CHOICE, int bChangeExitTokenText = TRUE, object oPC = OBJECT_INVALID)
|
|
{
|
|
if(DEBUG) DoDebug("AllowExit():\n"
|
|
+ "nNewValue = " + (nNewValue == DYNCONV_EXIT_NOT_ALLOWED ? "DYNCONV_EXIT_NOT_ALLOWED" :
|
|
nNewValue == DYNCONV_EXIT_FORCE_EXIT ? "DYNCONV_EXIT_FORCE_EXIT" :
|
|
nNewValue == DYNCONV_EXIT_ALLOWED_SHOW_CHOICE ? "DYNCONV_EXIT_ALLOWED_SHOW_CHOICE" :
|
|
"ERROR: Unsupported value: " + IntToString(nNewValue)
|
|
) + "\n"
|
|
+ "bChangeExitTokenText = " + DebugBool2String(bChangeExitTokenText) + "\n"
|
|
+ "oPC = " + DebugObject2Str(_DynConvInternal_ResolvePC(oPC)) + "\n"
|
|
);
|
|
|
|
SetLocalInt(_DynConvInternal_ResolvePC(oPC), "DynConv_AllowExit", nNewValue);
|
|
if(bChangeExitTokenText)
|
|
SetCustomToken(DYNCONV_TOKEN_EXIT, GetStringByStrRef(DYNCONV_STRREF_EXIT_CONVO));
|
|
}
|
|
|
|
/// @todo Replace with SetAbortable(int bAllow, object oPC = OBJECT_INVALID)
|
|
void AllowAbort(object oPC = OBJECT_INVALID)
|
|
{
|
|
SetLocalInt(_DynConvInternal_ResolvePC(oPC), "DynConv_AllowAbort", TRUE);
|
|
}
|
|
|
|
int GetIsStageSetUp(int nStage, object oPC = OBJECT_INVALID)
|
|
{
|
|
oPC = _DynConvInternal_ResolvePC(oPC);
|
|
|
|
if(!array_exists(oPC, "StagesSetup"))
|
|
return FALSE;
|
|
return array_get_int(oPC, "StagesSetup", nStage);
|
|
}
|
|
|
|
void MarkStageSetUp(int nStage, object oPC = OBJECT_INVALID)
|
|
{
|
|
oPC = _DynConvInternal_ResolvePC(oPC);
|
|
|
|
if(!array_exists(oPC, "StagesSetup"))
|
|
array_create(oPC, "StagesSetup");
|
|
array_set_int(oPC, "StagesSetup", nStage, TRUE);
|
|
}
|
|
|
|
void MarkStageNotSetUp(int nStage, object oPC = OBJECT_INVALID)
|
|
{
|
|
oPC = _DynConvInternal_ResolvePC(oPC);
|
|
|
|
if(!array_exists(oPC, "StagesSetup"))
|
|
return;
|
|
array_set_int(oPC, "StagesSetup", nStage, FALSE);
|
|
}
|
|
|
|
void ClearCurrentStage(object oPC = OBJECT_INVALID)
|
|
{
|
|
oPC = _DynConvInternal_ResolvePC(oPC);
|
|
|
|
// Clear the choice data
|
|
array_delete(oPC, "ChoiceTokens");
|
|
array_delete(oPC, "ChoiceValues");
|
|
DeleteLocalInt(oPC, "ChoiceOffset");
|
|
|
|
MarkStageNotSetUp(GetStage(oPC), oPC);
|
|
}
|