Skip to content

Conditions for Conversations

nwfan87nwfan87 Member Posts: 99
edited June 2023 in Builders - Toolset
fingers crossed,

After puzzling for an entire evening over getting conditions working for conversations, thought I would share at least one script that appears to work in the game without fault. This will hopefully save you a lot of time messing around trying to get it working correctly.

This one is a check for nFirstTimeTalked, one of the most useful conditions to have in a conversation. This is when the player is speaking to the NPC (or whatever it is they are talking to) for the first time.

int StartingConditional()
{

// Inspect local variables
if(!(GetLocalInt(GetPCSpeaker(), "nFirstTimeTalked") == 0))
return FALSE;

SetLocalInt(GetPCSpeaker(), "nFirstTimeTalked", 1);
return TRUE;
}

Still trying to figure out how to get other conditions working as it seems that the Script Wizard in the conversation editor does not produce reliable scripts - at least from my experience.
Post edited by nwfan87 on

Comments

  • TarotRedhandTarotRedhand Member Posts: 1,481
    edited June 2023
    You could have saved yourself some time here if you had checked out the Newbie Scripting FAQ #2, part of the Just The FAQs, ma'am package (FAQ = Frequently Asked Questions with answers). Your above problem amongst around 100 other common problems are answered in there. Note it includes actual code solutions to most of those problems. And no, I don't know why it is numbered as number 2, nor what happened to number 1.

    TR
  • nwfan87nwfan87 Member Posts: 99
    @TarotRedhand Ah very helpful, thank you, as always, its knowing where to look and find the info.
  • MelkiorMelkior Member Posts: 203
    edited June 2023
    Another way of doing the same thing (using three commands instead of four):
    int StartingConditional()
    {
      // Get local variable.
      int iTalked=GetLocalInt(GetPCSpeaker(), "nFirstTimeTalked");
      // Always should be TRUE after this.
      SetLocalInt(GetPCSpeaker(), "nFirstTimeTalked", TRUE);
      // Return what it used to be before being set to TRUE.
      return iTalked;
    }
    
    Now, how about a version which will work for multiple NPCs (presuming they're tagged differently)?
    It takes five commands, but that's just because I used two "setup" lines for readability.
    int StartingConditional()
    {
      object oPC=GetPCSpeaker();// Who the NPC is talking to.
      string sSelf=GetTag(OBJECT_SELF);// Tag of this NPC.
      int iTalked=GetLocalInt(oPC, sSelf+"FirstTalk");// Use this NPC's tag as part of the variable name.
      SetLocalInt(oPC,sSelf+"FirstTalk",TRUE);// Set the variable to TRUE.
      return iTalked;// Return its previous setting.
    }
    
  • nwfan87nwfan87 Member Posts: 99
    edited June 2023
    @Melkior Thank you for this! Tearing my hair out, hour after hour wasting away, trying to find out why the script isn't working properly :# That second script was quite good because if I'm right, you can just have one script to deal with all the instances that you need to use it in a conversation right?

    Tried using the script and low and behold, still getting the same behavior, the NPC will not speak the other dialogue tree at all, its triggering the opposite dialogue tree to what I'm hoping for. p.s I gave up on the FirstTimeTalked as it was just too much. Just using Journal checks for now. :D
  • MelkiorMelkior Member Posts: 203
    edited June 2023
    You're correct that, so long as all your conversation NPCs have different tags, the script should work for all NPCs.

    If it doesn't work, my first guess is that you might have the logic mixed up. Think of it like this: If a NPC line has a conditional and it returns TRUE for any reason, then that line is selected for the conversation and any later lines do not run. if it returns FALSE then that line is not selected and it tries the conditional for the next line. Make sure that the last line does not have a conditional and is the line which should run if none of the conditions have been met.
    In this case, the first conversation line should be the "we've spoken before" line, while the second (and last) line should be the "we've never spoken before" line.

    Another guess would be that you somehow made the NPC de-spawn, or he's being killed. If either is the case, then when he respawns he won't have any of the variables which were set on his previous instance. The easiest way of handling this would be to use the PC (in single player) or an undroppable item on the PC (in multiplayer) to save the variables to.

    Single-player version:
    int StartingConditional()
    {
      object oPC=GetPCSpeaker();
      string sSelf=GetTag(OBJECT_SELF);
      // Get local variable.
      int iTalked=GetLocalInt(oPC, sSelf+"FirstTalk");
      // Always should be TRUE after this.
      SetLocalInt(oPC, sSelf+"FirstTalk", TRUE);
      // Return what it used to be before being set to TRUE.
      return iTalked;
    }
    

    Multiplayer version (assuming the PC is carrying an item tagged "ToolBox"):
    int StartingConditional()
    {
      object oPC=GetPCSpeaker();
      object oToolBox=GetItemPossessedBy(oPC,"ToolBox");
      string sSelf=GetTag(OBJECT_SELF);
      // Get local variable.
      int iTalked=GetLocalInt(oToolBox, sSelf+"FirstTalk");
      // Always should be TRUE after this.
      SetLocalInt(oToolBox, sSelf+"FirstTalk", TRUE);
      // Return what it used to be before being set to TRUE.
      return iTalked;
    }
    

    (Oh, and it's "lo" short for "hello" which was once an expression of surprise, not a greeting; hence "lo and behold" is a short but deliberately grandiose way of saying "this is surprising, look here")

    Now I'm to the point of wishing I could see the conversation so that I could help you to figure out the problem and fix it, but I hope that the information I've given here helps.
  • nwfan87nwfan87 Member Posts: 99
    edited June 2023
    @Melkior Thank you for such a detailed comment! The best thing for me to do perhaps is to copy and paste some scripts. Nothing special about them, just very basic scripts.

    Thing deteriorated even more to the point where the scripts won't compile, so now relying on triggers, which isn't ideal and causes problems.

    It would be good to have scripts (before have too much to change) that:

    journals checks,
    int checks
    item checks

    As a question, do you need checks on every starting NPC line in a conversation file? NPC's are always starts with the non conditional option, rather than the ones which have checks.

    Here are the scripts that I've tried to use.

    In advance, thank you so much for your help!! :smile:




    journal check

    int StartingConditional()
    {
    if (GetLocalInt(GetPCSpeaker, "NW_JOURNAL_ENTRYratkiller")==2);
    }



    int check

    int StartingConditional()
    {

    // Inspect local variables
    if(!(GetLocalInt(GetPCSpeaker(), "has_spoken_to_the_zombie") == 1))
    return FALSE;

    return TRUE;
    }



    item check

    #include "nw_i0_tool"

    int StartingConditional()
    {

    // Make sure the PC speaker has these items in their inventory
    if(!HasItem(GetPCSpeaker(), "rat_tail"))
    return FALSE;

    return TRUE;
    }
  • meaglynmeaglyn Member Posts: 151
    The conversation will show the first line starting at the top at any given level which either has a conditional which returns TRUE or does not have a conditional. You do need to make sure you order them correctly. All the ones with conditionals should be before the one with no condition. And if the conditions relate to each other you may need to control that order.

    That first one won't compile because you don't have return statements.

    It sounds like you may want to look at the scripting faq and maybe the toolset guide. I don't have links handy but Tarot linked the faq above. The lexicon is also useful. But the things you are trying to do are very common and are covered (with examples) in some of those docs I'm sure.
  • nwfan87nwfan87 Member Posts: 99
    @meaglyn Thank you very much for these comments. I hadn't thought of the order at all, so that might be something for me to try in the next conv. file. Instead of having all these triggers.

    I will have to do some hunting around to find some good scripting things. Tarot already posted some links to some good resources.
  • MelkiorMelkior Member Posts: 203
    In a conversation file, the NPC greeting is the "first level." You can have several greetings at the first level, and the game will select either the first one with a conditional which returns TRUE (which is any non-zero integer) or it will select the first line which does not have a conditional attached. This allows you to make the NPC have completely different conversations depending on which line is the first one to have a conditional which returns TRUE. (And btw, FALSE is the same as zero)

    Putting it another way, when the NPC conversation comes up, the game looks at the first conversation line and checks if there's a conditional attached. If there isn't, it selects that line. If there is, then it runs the conditional and only selects that line of conversation if the result is TRUE, otherwise it drops down to the next line of conversation at that level and does the whole thing over again. Take the following conversation for example (NPC lines have a single dash while PC lines have a double dash):

    - Hello again, <name>, nice to see you again. Would you like to see my shop?
    - - Yes, thanks.
    - - Not this time.
    - Hello, you seem to be new here, but it's nice to meet you. Would you like to buy or sell things?
    - - Yes, thanks.
    - - Not this time.

    Here's the single-player version of the script, again:
    int StartingConditional()
    {
      object oPC=GetPCSpeaker();
      string sSelf=GetTag(OBJECT_SELF);
      // Get local variable.
      int iTalked=GetLocalInt(oPC, sSelf+"FirstTalk");
      // Always should be TRUE after this.
      SetLocalInt(oPC, sSelf+"FirstTalk", TRUE);
      // Return what it used to be before being set to TRUE.
      return iTalked;
    }
    
    If you place the above script into the Appears When of the line "Hello again" then that should do what you want.

    You don't put anything into the "Hello, you seem to be new..." line, because you want it to be selected if the "Hello again" line isn't selected.

    Both the "Hello" lines are at the first level, but the first line only runs if the script returns TRUE. The second "Hello" line does not run at all if the first line is selected.
  • nwfan87nwfan87 Member Posts: 99
    edited June 2023
    @Melkior So in terms of a very sketchy flowchart, this would be my understanding of the process:

    better version:
    d52lmqjlazcu.png

    In that case, that would also reflect why it is important to put non conditional lines as the last line. If it was the first, it would only return that line, ever, regardless of any changes to conditionals?
  • meaglynmeaglyn Member Posts: 151
    Yes. That's what I said too...
  • MelkiorMelkior Member Posts: 203
    @meaglyn We each said the same thing, but in different ways. I've sometimes found one person's explanation unintelligible until someone else has explained it in a different way, then the first explanation suddenly makes sense. :)

    @nwfan87 Yes, you have correctly understood how the game processes a conversation file in order to decide which line the NPC should speak.

    It gets even more fun when you apply an "appears when" script to player lines. Doing this allows you to deny a player certain options (if the PC does not qualify for them, for example) by making them never appear in the conversation at all, so they can't be selected. If the conditional returns FALSE then the player conversation line does not even show up at all. Be careful that there is always at least one valid option for the player to select, though.
  • nwfan87nwfan87 Member Posts: 99
    edited June 2023
    @meaglyn Glad to have got it and I was thinking about what you said in the reply :smile:

    @Melkior That is good then, glad I got the logic right. Don't think I'll be doing any appears when options. Comes down mostly to how much I can tolerate my own lack of skills with scripting and conversations. If its taking too much time, I'll find some other solution which present less problems. Better that way than spend 100 hours working on one conversation and losing motivation, sacrificing all the work done thus far. Even with all this help, I'm still having issues, but I'll just do my best from here on out and see what works and doesn't - the joy of scripting :smile:
  • TarotRedhandTarotRedhand Member Posts: 1,481
    It gets even more fun when you apply an "appears when" script to player lines. Doing this allows you to deny a player certain options (if the PC does not qualify for them, for example) by making them never appear in the conversation at all, so they can't be selected.

    There is a large list of the built-in functions of that type, included with the FAQs I linked to early in this thread.

    TR
  • nwfan87nwfan87 Member Posts: 99
    @TarotRedhand Thanks for that!

    @Melkior @meaglyn I managed to make some progress with the conversation files. It was just a matter of reorganizing the logic of it, which can be difficult if you have the same NPC with say, 50 starting lines or so, or, you've never made a conversation file larger than one thread. Really have to take the time, working out the order. I think I read somewhere else other than this thread, working 'backwards' in terms of where you expect the NPC to use a particular thread in a plot, helps, which it has for me.

    With this, I'll hope to be able to make some more progress as I get to grips with this system. :smile:
Sign In or Register to comment.