Larian Banner: Baldur's Gate Patch 9
Previous Thread
Next Thread
Print Thread
Joined: Jul 2014
Noaloha Offline OP
enthusiast
OP Offline
enthusiast
Joined: Jul 2014
Okay, yet another kindergarten level question from me. Get used to them! I'm 99% certain that I shouldn't be struggling with this specific problem as much as I am.

Say my hero is in a dialog with an NPC and, after I select a specific option in the conversation, I want the NPC to perform an in-game action -- let's say walk from point A to B -- once the dialog is finished. Can anyone provide a sample StoryEditor code to achieve this?

Annoyingly, I haven't been able to get 'DialogEnded' to work. But, even if I had, I can't figure out how to pair together 'IF' events with 'AND's before the 'THEN'. It seems like the StoryEditor only allows one 'event' type function before the THEN. If I try to build, for example, IF ItemEvent AND TimerFinished THEN blahblahblah, the editor throws up an error.

The closest I've gotten is to set the Flag/Event in the dialog node as normal -- an 'IF GlobalEventSet(blahblah)' function picks that up and processes the THEN part. Unfortunately, it does so immediately upon activation of the dialog node. This makes for a rather rude NPC who walks from A to B before you've had a chance to leave the dialog window.

Any help would be greatly appreciated!


Escape From Smalcatraz: Steam/Nexus. Forum thread.
Joined: Jul 2014
R
addict
Offline
addict
R
Joined: Jul 2014
Code
IF
DialogEnded("NPC Dialog name", INT InstanceID)
THEN
GlobalSetEvent("blahblah")

IF
GlobalEventSet("blahblah")
THEN
CharacterMoveToTrigger("NPC name", TRIGGER name, INT running, "NPC is moving")   


Something like that might work. The way that the Story functions appear to work is that all of the relevent IF's get called sequentially from the same event. In the sequential order, it then checks whether the ANDs are fulfilled as well for each IF.

In your case, you might want to set a global event after the dialog ends. That event setting then triggers the IF statement that it is checking for, which is what moves the character.

Joined: Jul 2014
Noaloha Offline OP
enthusiast
OP Offline
enthusiast
Joined: Jul 2014
A problem there is that the event/flag/whatever that causes the NPC to move needs to be contained within the dialog itself and be optional. Which is to say, I need to also be able to finish the same conversation without triggering the NPC movement if the relevant dialog choices are made. Like, a guard in front of a door. You can talk to him and suggest he investigates a fire behind the building, or you can just compliment his stylin' uniform and leave him where he is. This all occurs in the same conversation, but one option leads to the NPC moving to a different point after the dialog ends. The code above would cause the movement unconditionally once the Dialog finishes.

And I have no idea what's going wrong with 'DialogEnded()'. I'm almost certain I've entered my code correctly:
[Linked Image]
Haven't been able to get this to work! frown The 'THEN' part is fine, as I've successfully called into it using a SetGlobalFlag command within the dialog itself.

The 'InstanceID' was mentioned in one of the Larian Tutorials and it was explained that you can leave it as '0' with no problems as it then effectively ignores that part of the function, unless I'm misremembering something.

Last edited by Noaloha; 02/08/14 04:21 PM.

Escape From Smalcatraz: Steam/Nexus. Forum thread.
Joined: Jul 2014
R
addict
Offline
addict
R
Joined: Jul 2014
Ah, in that case-
Code
IF
DialogEnded("NPC Dialog name", INT InstanceID)
AND
GlobalEventSet("This was set by the correct choice in-dialog")
THEN
GlobalSetEvent("blahblah")

IF
GlobalEventSet("blahblah")
THEN
CharacterMoveToTrigger("NPC name", TRIGGER name, INT running, "NPC is moving")


Try using two GlobalEvents; one that is set within the dialog (and is checked when the DialogEnds), and another that is triggered by the previous THEN statement.

Edit:
Try using a _ in place of a 0 for DialogEnded. I'm looking through a script file right now and that's able to be done. The _ should mean anything works for that slot.

Last edited by Rhidian; 02/08/14 04:34 PM.
Joined: Jul 2014
Noaloha Offline OP
enthusiast
OP Offline
enthusiast
Joined: Jul 2014
Using two 'event' type functions paired with AND before the THEN brings up this specific error, which is one of the main roadblocks I'm running into,

[Linked Image]

It isn't specific to these two functions, it seems to happen whenever you combine like this,

Code
IF
[event-type function](blahblah)
AND
[event-type function](blahblah)
THEN
...


I've tried reverse-engineering from Main Campaign code, but I'll be honest, I'm finding it nigh-on-impossible to separate out the relevant pieces. I thought I could check out the Wulfram/Mysterious Stranger/Archeologist code (he's the early escort quest outside of Cyseal) but yeesh, no joy.


Escape From Smalcatraz: Steam/Nexus. Forum thread.
Joined: Jul 2014
F
stranger
Offline
stranger
F
Joined: Jul 2014
I actually just scripted this yesterday. I did it slightly differently, but along the same lines as how Rhidian is explaining it. I can just copy/paste my example. So my script is that when my character enters a trigger within the town, my NPC "Town_Blacksmith" runs straight toward my characters, displays a text(outside of dialog), and then starts a dialog with the character. Now these dialog choices are all for a first time encounter with the NPC, so I have an initial flag enabled. Once the dialog finishes, the flag is turned off. When this flag is turned off, two things happen.

1) The NPC turns around and walks to a specified trigger.
2) The dialog options change so that return visits to the NPC have a different greeting.

So just ignore the bits with "SmithTrigger_Script" if you don't care about the part about him running up to the character and initiating dialog(the 2 first INIT and the first IF/THEN).

INIT
TriggerRegisterForCharacter(TRIGGER_SmithTrigger_Script_start,CHARACTER_Player1);
TriggerRegisterForCharacter(TRIGGER_SmithTrigger_Script_start,CHARACTER_Player2);
GlobalSetEvent("blacksmithFlag");

KB
IF
CharacterEnteredTrigger(_char,TRIGGER_SmithTrigger_Script_start)
THEN
TriggerUnregisterForCharacter(TRIGGER_SmithTrigger_Script_start,CHARACTER_Player1);
TriggerUnregisterForCharacter(TRIGGER_SmithTrigger_Script_start,CHARACTER_Player2);
CharacterDisplayText(CHARACTER_Town_Blacksmith,"smithIntro");
CharacterMoveToCharacter(CHARACTER_Town_Blacksmith,_char,1,"smithJog");
StartDefaultDialog(CHARACTER_Town_Blacksmith,_char);

IF
GlobalEventCleared("blacksmithFlag")
THEN
CharacterMoveToTrigger(CHARACTER_Town_Blacksmith,TRIGGER_BlackSmithPointTrigger,0,"smithWalkBack");

Now, in the dialog editor, the initial greeting for when he forces dialog has this condition:
CONDITION IsFlag("blacksmithFlag", 1)
CHECK c

And the final dialog option that causes the NPC to move is
ACTION SetFlag("blacksmithFlag",0)

And then the returning visit options have :
CONDITION IsFlag("blacksmithFlag", 0)
CHECK c

Now, this was my first attempt at doing this, so I'm not sure if this is optimal, but basically my trigger sets the flag and causes the NPC to initiate dialog. Then when the dialog choice is selected, it clears the flag. And clearing the flag causes the NPC to walk away. I could do what Rhidian did and choose the flag being enabled to cause the trigger, and also the DialogEnded option too, but I wanted the NPC to say his piece and walk away before I had a chance to say goodbye(END).

Hope this helps.

Joined: Jul 2014
Noaloha Offline OP
enthusiast
OP Offline
enthusiast
Joined: Jul 2014
Originally Posted by Rhidian
Edit:
Try using a _ in place of a 0 for DialogEnded. I'm looking through a script file right now and that's able to be done. The _ should mean anything works for that slot.

Ah-ha! That worked! Sort of.... :p

The NPC moved to his trigger (all the THEN functions processed), but the final dialog screen stayed on the screen and the camera was locked to the NPC (the camera lock thing is a result of the dialog box still being up I think). I may just have made a boo-boo in my KeywordEditor.


Escape From Smalcatraz: Steam/Nexus. Forum thread.
Joined: Jul 2014
Noaloha Offline OP
enthusiast
OP Offline
enthusiast
Joined: Jul 2014
Thanks for sharing that Bob. If I'm understanding your code correctly, your NPC behaviour occurs while you're still in the dialog right? So, as soon as the final conversation node appears on screen, he moves away and (after a certain distance of travel) breaks the conversation himself?

In my scenario, I want to wait until the player ends the conversation, then have the NPC move. The DialogEnded function might be a likely candidate (thanks Rhidian!) if I can figure out how to avoid this text box glitch, but I still need to work out how to make the DialogEnded() conditional, have it only fire when a specific dialog flag was chosen mid-dialog.


Escape From Smalcatraz: Steam/Nexus. Forum thread.
Joined: Jul 2014
F
stranger
Offline
stranger
F
Joined: Jul 2014
Ah, yeah. I haven't tried that yet. I wanted him to break conversation with me. Sort of get sick of me and walk away. I tried to do what you wanted just now and I get the same error about a DIV only being allowed as the first instance.

Joined: Jul 2014
L
stranger
Offline
stranger
L
Joined: Jul 2014
Random new guy question. What exactly does the "InstanceID" in the DialogEnded event (and various other Dialog functions) refer to?

Joined: Jul 2014
Noaloha Offline OP
enthusiast
OP Offline
enthusiast
Joined: Jul 2014
I may have found something!

[Linked Image]

I'm supposed to be sitting down for a movie soon so I don't know if I have time to test, :P


Originally Posted by Lemenhead
Random new guy question. What exactly does the "InstanceID" in the DialogEnded event (and various other Dialog functions) refer to?


I'm wondering this too. In the .lsx files, a unique billion-digit-long ID is given for every individual dialog node in the game (<attribute id="keywordContentMapKey" value="0b2227b4-442b-46d8-bf03-70e334279270" type="22" /> as an example), but I don't think it's that since the description clearly states 'integer'.

The Larian video where it's mentioned, he just kind of glosses over it, says "I'll explain more about it later", but doesn't.


Escape From Smalcatraz: Steam/Nexus. Forum thread.
Joined: Jul 2014
F
stranger
Offline
stranger
F
Joined: Jul 2014

Joined: Jul 2014
F
stranger
Offline
stranger
F
Joined: Jul 2014
Ok, I got it to work. Now he won't leave until dialog is over and the correct flag is issued. I just did a workaround so that I don't call two events in an IF/AND/THEN statement. Instead I check the dialog ending, then query the result of the flag as follows.

Now, inside the keyword editor it has:
ACTION SetLocalFlag("blacksmithFlag",1)

for the dialog trigger I want to flag. Then, in the story editor I use this function:

IF
DialogEnded("blacksmith2",_smithdiag)
AND
DialogGetLocalEvent(_smithdiag,"blacksmithFlag", 1)
THEN
CharacterMoveToTrigger(CHARACTER_Town_Blacksmith,TRIGGER_BlackSmithPointTrigger,0,"smithWalkBack");

which works. Now, if you change either of the 1's to 0's, you'll see it does not work. SO I believe the query function gets the value of "blacksmithFlag" and compares ot to the integer in the 3rd spot of the function.

Joined: Jul 2014
L
stranger
Offline
stranger
L
Joined: Jul 2014
Farmer Bob: Thanks for the response, I've seen those videos...He doesn't really go into any detail in the usefulness of the InstanceID. He just says there's a unique number assigned to every dialog.

Joined: Jul 2014
F
stranger
Offline
stranger
F
Joined: Jul 2014
Correct. I don't know that much about it myself, but each dialog has its own ID. So if you want to reference an instance ID, you need to create a variable to do so. Look at the script I provided above. The DialogGetLocalEvent requires the DialogInstanceID from the DialogEnded, which I have used a variable "_smithdiag" for:

IF
DialogEnded("blacksmith2",_smithdiag)
AND
DialogGetLocalEvent(_smithdiag,"blacksmithFlag", 1)
THEN
CharacterMoveToTrigger(CHARACTER_Town_Blacksmith,TRIGGER_BlackSmithPointTrigger,0,"smithWalkBack");

Now, if I change it to:
IF
DialogEnded("blacksmith2",_smithdiag)
AND
DialogGetLocalEvent(0,"blacksmithFlag", 1)
THEN
CharacterMoveToTrigger(CHARACTER_Town_Blacksmith,TRIGGER_BlackSmithPointTrigger,0,"smithWalkBack");

then the THEN statement won't fire because DialogGetLocalEvent is not being directed to the same DialogID from the IF statement above it. So you need to have the correct DialogID to point to the correct dialog, if I'm understanding it correctly.

Joined: Jul 2014
Noaloha Offline OP
enthusiast
OP Offline
enthusiast
Joined: Jul 2014
Thanks for your help on this Bob!


Escape From Smalcatraz: Steam/Nexus. Forum thread.
Joined: Jul 2014
L
stranger
Offline
stranger
L
Joined: Jul 2014
Nice explanation, thanks

Joined: Jul 2014
member
Offline
member
Joined: Jul 2014
You know the fact that we have to put so much effort into something so simple is astounding.

I got here a little late but i should say i haven't had any problems with dialogended() in my story.

The whole editor seems a little buggy to me, I've worked with a lot of editors before but ive never seen something so touchy. Sometimes i find i have everything right and things still dont work. However if i try to play through it in the actual game it works perfectly. Sometimes it wont work in the editor but if i restart the entire editor it works. Thats even after i reload the story and the level.

Anyways. I used dialogended differently as i needed to add an ability point at the end of the conversation. As far as i know it worked perfectly. I cant be for sure that it actually does it at the end of the conversation however.

IF DialogEnded("default", _Instance)

THEN
CharacterSetHasDefaultDialog(CHARACTER_Companion_Madora_000, 0);
CharacterAddAbilityPoint(CHARACTER_Player2, 1);

I was a little lazy on the keyword as its my first dialog in the game and i just called it default. lol.

Last edited by Demonata08; 02/08/14 09:38 PM.

Link Copied to Clipboard
Powered by UBB.threads™ PHP Forum Software 7.7.5