As far as I understand, its only job is to return a TRUE or FALSE: do I show this conversation line or not? As long as you have a way to differentiate who is speaking in the switch-case statement, I don't see why not.
int NPC_NUM = GetLocalInt(OBJECT_SELF,"NPC_SPEAKER_NUMBER");
switch( NPC_NUM )
{
case 1: if( GetLocalInt(GetPCSpeaker(),"QUEST_GORDYS_FOLLY") < 1 ) return TRUE;
else return FALSE;
case 2: ...
default: return TRUE;
}
I haven't used the conversation parameter function yet, so I'm not sure if there's an opportunity there to extend how far you can go with a single case statement. Maybe someone familiar with that will weigh in.
EDIT - I may have misunderstood the OP - I now see it's talking about multiple "text appears when" rather than muliple "action taken". See better reply later in the thread!
A conditional script can contain a switch with multiple cases of ExecuteScript() so that the "action taken" varies according to the parameters or other conditions. The ActionTaken script in the conversation can than be omitted.
Alternatively, since both the Conditional and the ActionTaken scripts can access the same parameters / conditions, the Conditional can simply focus on whether the line should be spoken, true or false. The switch can be in the ActionTaken script, with each case executing a different snippet or function. This eliminates the need for lots of scripts, and allows the use of common code for related cases, so it's quicker to write, and less error-prone.
Agreed. BTW You forgot to break in your code like this -
int NPC_NUM = GetLocalInt(OBJECT_SELF,"NPC_SPEAKER_NUMBER");
switch( NPC_NUM )
{
case 1: if( GetLocalInt(GetPCSpeaker(),"QUEST_GORDYS_FOLLY") < 1 ) return TRUE;
else return FALSE;
break;
case 2: ...
break;
...
default:
return TRUE;
}
TR
No, you don't need breaks when there are returns. Once you hit case 1 you either return TRUE or FALSE. You will never get to the break statement so it's not needed.
Im not a scripter by any means, but this is working. Ha,ha.
//PC and Item to check for
int GetNumItems(object oPC,string sItem)
{
//Number of items
int nNumItems = 0;
//Check for items
object oItem = GetFirstItemInInventory(oPC);
//Is the item in the inventory
while (GetIsObjectValid(oItem) == TRUE)
{
if (GetTag(oItem) == sItem)
{
//Get number of items in the inventory
nNumItems = nNumItems + GetNumStackedItems(oItem);
}
//Loop through inventory
oItem = GetNextItemInInventory(oPC);
}
return nNumItems;
}
int StartingConditional()
{
object oPC = GetPCSpeaker();
Won't that always return TRUE if the PC has any "Stone" items?
To use the same script for each case, you need to pass a parameter in the conversation lines, specifying the number of stones required to trigger that line. They need to be in the order 3, 2, 1, because if 3 is true, 2 and 1 are also.
For example, if the parameter in the conversation is called StoneCount,
int StartingConditional()
{
object oPC = GetPCSpeaker();
string sStonesRequired = GetScriptParam("StoneCount");
int nStonesRequired = StringToInt(sStonesRequired);
if (GetNumItems(oPC, "Stone") >= nStonesRequired)
return TRUE;
return FALSE;
}
Incidentally, scripts are easier to read when you use the [code] BBCode.
Yes . It is just a generic "StartingConditional scipt". It can be used in all three of the "TextAppearsWhen" conversation nodes. I didnt even think of trying to write it to need an exact amount. Like i said, Im not much of a scripter.
@TheTinman I have gone through and tidied your code up. In doing so I changed your 3 if() statements to a single switch() statement. In line with current programming practice I have reduced the number of return statements to a single one which is the last line of actual code. In your original script you called GetNumItems() up to 3 times when in reality it only needs calling once - fixed.
//PC and Item to check for
int GetNumItems(object oPC,string sItem)
{
//Number of items
int nNumItems = 0;
//Check for items
object oItem = GetFirstItemInInventory(oPC);
//Is the item in the inventory
while (GetIsObjectValid(oItem) == TRUE)
{
if (GetTag(oItem) == sItem)
//Get number of items in the inventory
nNumItems += GetNumStackedItems(oItem);
//Loop through inventory
oItem = GetNextItemInInventory(oPC);
}
return nNumItems;
}
int StartingConditional()
{
object oPC = GetPCSpeaker();
int iHowMany = GetNumItems(oPC, "Stone");
int bReturnValue;
switch(iHowMany)
(
case 1: bReturnValue = TRUE;
break;
case 2: bReturnValue = TRUE;
break;
case 3: bReturnValue = TRUE;
break;
default:
bReturnValue = FALSE;
}
return bReturnValue;
}
BTW, In order to get your code into a code box you need to use a slightly hidden feature of the editor in here. In the editing tools above the box you type in there are a number of tools which have an inverted triangle next to them. These have drop down menus. The one you want is immediately to the left of the smiley/emoji. In there you will find one that says code. Simply highlight your code and then select that menu option.
FWIW if you are unfamiliar with the compound += operator see my tutorial (shameless plug) - TR's Basics - Mostly Operators.
Comments
I haven't used the conversation parameter function yet, so I'm not sure if there's an opportunity there to extend how far you can go with a single case statement. Maybe someone familiar with that will weigh in.
TR
A conditional script can contain a switch with multiple cases of ExecuteScript() so that the "action taken" varies according to the parameters or other conditions. The ActionTaken script in the conversation can than be omitted.
Alternatively, since both the Conditional and the ActionTaken scripts can access the same parameters / conditions, the Conditional can simply focus on whether the line should be spoken, true or false. The switch can be in the ActionTaken script, with each case executing a different snippet or function. This eliminates the need for lots of scripts, and allows the use of common code for related cases, so it's quicker to write, and less error-prone.
No, you don't need breaks when there are returns. Once you hit case 1 you either return TRUE or FALSE. You will never get to the break statement so it's not needed.
//PC and Item to check for
int GetNumItems(object oPC,string sItem)
{
//Number of items
int nNumItems = 0;
//Check for items
object oItem = GetFirstItemInInventory(oPC);
//Is the item in the inventory
while (GetIsObjectValid(oItem) == TRUE)
{
if (GetTag(oItem) == sItem)
{
//Get number of items in the inventory
nNumItems = nNumItems + GetNumStackedItems(oItem);
}
//Loop through inventory
oItem = GetNextItemInInventory(oPC);
}
return nNumItems;
}
int StartingConditional()
{
object oPC = GetPCSpeaker();
if (GetNumItems(oPC, "Stone") >= 1)
return TRUE;
return FALSE;
{
}
if (GetNumItems(oPC, "Stone") >= 2)
return TRUE;
return FALSE;
{
}
if (GetNumItems(oPC, "Stone") >=3)
return TRUE;
return FALSE;
}
To use the same script for each case, you need to pass a parameter in the conversation lines, specifying the number of stones required to trigger that line. They need to be in the order 3, 2, 1, because if 3 is true, 2 and 1 are also.
For example, if the parameter in the conversation is called StoneCount,
Incidentally, scripts are easier to read when you use the [code] BBCode.
Should I have used == instead of >=
BTW, In order to get your code into a code box you need to use a slightly hidden feature of the editor in here. In the editing tools above the box you type in there are a number of tools which have an inverted triangle next to them. These have drop down menus. The one you want is immediately to the left of the smiley/emoji. In there you will find one that says code. Simply highlight your code and then select that menu option.
FWIW if you are unfamiliar with the compound += operator see my tutorial (shameless plug) - TR's Basics - Mostly Operators.
Hope you find this useful.
TR