Page 1 of 1

How to show node only if one child evaluates true

Posted: Sun Sep 24, 2017 5:42 am
by kyuubi
Hi,
How can I avoid showing a dialog line if all the children nodes evaluate false?
For example if I have a tree "Tell me about you" with a bunch of different nodes, I only want to show that while there are still nodes to show. After I asked all of it t should not be displayed.
So far I am doing this by hardcoding all the child IDs in the conditions of the parent but it makes this hard to manage with changes.
Any way to do something like, get all child node and check if they evaluate true or false?
Thanks,
Duarte

Re: How to show node only if one child evaluates true

Posted: Sun Sep 24, 2017 9:45 am
by Tony Li
That's a tough one. A lot of games, even pro games like KoToR and Witcher 1, use a fallback node like "Tell me about you." --> "There's nothing more to tell.", like this:
  • Player: "Tell me about you."
    • NPC: "I'm a warrior." {Condition: Variable["Said_Warrior"] == false}
    • NPC: "I'm a dwarf." {Condition: Variable["Said_Dwarf"] == false}
    • NPC: "There's nothing more to tell."
You could duplicate those conditions on the "Tell me about you" node:
  • Player: "Tell me about you." {Condition: Variable["Said_Warrior"] == false or Variable["Said_Dwarf"] == false}
    • NPC: "I'm a warrior." {Condition: Variable["Said_Warrior"] == false}
    • NPC: "I'm a dwarf." {Condition: Variable["Said_Dwarf"] == false}
But I can see that if you're checking SimStatus this would be an extra pain. Fortunately, the Dialogue System does have a feature that may help. You can assign a delegate to DialogueManager.IsDialogueEntryValid. In this, you can add your own logic. Return true if the entry is valid, false if not. Something like:

Code: Select all

void Start() {
    DialogueManager.IsDialogueEntryValid = IsDialogueEntryValidCustom;
}

bool IsDialogueEntryValidCustom(DialogueEntry entry) {
    return (/* your logic here */);
}
In "your logic here", you can return true if the entry has no children, or if it has at least one child whose conditions are true:

Code: Select all

bool IsDialogueEntryValidCustom(DialogueEntry entry) {
    if (entry.outgoingLinks.Count == 0) return true; // No children. Return true.
    foreach (var link in entry.outgoingLinks) {
        var destination = DialogueManager.MasterDatabase.GetDialogueEntry(link);
        if (Lua.IsTrue(destination.conditionsString)) return true; // A child is true. Return true.
    }
    return false; // All children false. Return false.
}

Re: How to show node only if one child evaluates true

Posted: Wed Sep 27, 2017 6:57 am
by kyuubi
Hi Tony,
Thanks for getting back.
I do use a fallback "nothing more to tell as well" and in fact I like that user experience.
This works well up to the point where I have said all the child dialogs and that's the issue I'm facing.
So for example:
- Tell me about you
- How long you been on the Island
- What do you think of the Sheriff
- Why are there no boats in the Wharf?
- I want to talk about something else.

The issue here is, when I already said all the child dialogs this will happen:

1) Tell me about you.
2) I want to talk about something else.

Will the solution you posted address this?
Cheers,

Re: How to show node only if one child evaluates true

Posted: Wed Sep 27, 2017 11:08 am
by Tony Li
The code I provided above is just a framework that you can add your own code to; it's not a solution by itself.

What if you use actor fields or variables to track this instead?

For example:
  • "Can I ask you something?" {Condition: Actor["Adam"].ToldAbout==false or Actor["Adam"].HowLong==false or Actor["Adam"].WhyNoBoats==false}
    • "Tell me about you." {Condition: Actor["Adam"].ToldAbout==false} {Script: Actor["Adam"].ToldAbout=true}
    • "How long have you been on the island?" {Condition: Actor["Adam"].HowLong==false} {Script: Actor["Adam"].HowLong=true}
    • "Why are there no boats in the wharf?" {Condition: Actor["Adam"].WhyNoBoats==false} {Script: Actor["Adam"].WhyNoBoats=true}
    • "I want to talk about something else."
If the player has chosen the first three responses (tell me about you, how long on the island, why no boats), then "Can I ask you something?" will not be offered.

Will that help?