Skip to content

Help Requested: dialog.tlk and event-triggered character comments

karnagekarnage Member Posts: 92
The next thing I'd like to do with my new NPC, "Vondo", is to have him respond to events in the game.

Example: When accepting the mission to expose Mae'Var's treachery, Vondo would say something like: "I pledged my life and my sword to striking out against injustice and evil, not to become a part of it, . I will follow for now, but I will be ever watchful".

Now, these kinds of comments aren't in the .dlg files; they are in the dialog.tlk file (I have discovered); none of this triggering seems to be in the .ARE files; so, how do I do this? What file or files can I look at or decompile to see how this is done?

Comments

  • prophet1prophet1 Member Posts: 172
    You're looking for the "joined" version of npc dialog files, they have J as the last character (ViconiJ, AnomenJ, etc.). When the NPC joins player party, the game engine automatically changes their assigned dialog to the "J" version, as long as you did append the entries to PDIALOG.2DA (that should be in the guide you're following).
  • karnagekarnage Member Posts: 92
    Okay, got that.

    Clear as mud, though, LoL.

    I decompile Aerie's dialog file so I could look at it. Here is an excerpt to what I see:

    IF ~~ THEN BEGIN 84 // from:
    SAY #49493 /* ~We're... we're just going to go and kill someone? Because he tells us to? This... this doesn't feel right, . We're not really going to do this, are we?~ */
    IF ~!IsValidForPartyDialog("Anomen")
    !IsValidForPartyDialog("Korgan")
    !IsValidForPartyDialog("Keldorn")
    !IsValidForPartyDialog("Yoshimo")~ THEN EXIT
    IF ~IsValidForPartyDialog("Anomen")~ THEN EXTERN ~ANOMENJ~ 217
    IF ~!IsValidForPartyDialog("Anomen")
    IsValidForPartyDialog("Korgan")~ THEN EXTERN ~KORGANJ~ 88
    IF ~!IsValidForPartyDialog("Anomen")
    !IsValidForPartyDialog("Korgan")
    IsValidForPartyDialog("Keldorn")~ THEN EXTERN ~KELDORJ~ 144
    IF ~!IsValidForPartyDialog("Anomen")
    !IsValidForPartyDialog("Korgan")
    !IsValidForPartyDialog("Keldorn")
    IsValidForPartyDialog("Yoshimo")~ THEN EXTERN ~YOSHJ~ 70
    END

    I recognize the dialog as when the party is told by Edwin to slay the cowled wizard.

    So, supposing I add this to Vondo:

    -------------
    BEGIN J#VondoJ

    IF ~~ THEN BEGIN 84 // from:

    SAY ~There is no Cowled Wizard who does not have innocent blood on their hands. But the path you are setting us on is a path towards evil. Tread lightly or I will intervene.~
    -------------

    By adding those lines, would that cause Vondo to say "There is no Cowled Wizard who does not have innocent blood on their hands. But the path you are setting us on is a path towards evil. Tread lightly or I will intervene." when Edwin instructs the party to kill kill the cowled wizard?

    If so, that doesn't make much sense to me because I'm not seeing the trigger. It's like looking at only part of a script.
  • WispWisp Member Posts: 1,102
    Have a look at the INTERJECT* series of D actions.
  • prophet1prophet1 Member Posts: 172
    edited December 2013
    karnage said:

    By adding those lines, would that cause Vondo to say ... ?

    If so, that doesn't make much sense to me because I'm not seeing the trigger. It's like looking at only part of a script.

    The J file is the dialog file where your actual interjection text goes. The trigger for it must be inserted into whatever dialog you're interjecting into. In your example case, the trigger for Aerie's interjection (among others) is in Edwin's dialog - EDWIN.DLG, state 8:
    IF ~~ THEN BEGIN 8 SAY #6284 /* ~Good. Don't linger about then, get going! (Ugh, motivating these sloths is like pulling teeth)~ */ IF ~!IsValidForPartyDialog("Valygar") !IsValidForPartyDialog("Aerie") !IsValidForPartyDialog("Keldorn") !IsValidForPartyDialog("Yoshimo")~ THEN DO ~SetGlobal("EdwinJob","GLOBAL",1) ~ UNSOLVED_JOURNAL #34211 EXIT IF ~IsValidForPartyDialog("Valygar")~ THEN DO ~SetGlobal("EdwinJob","GLOBAL",1)~ UNSOLVED_JOURNAL #34211 EXTERN ~VALYGARJ~ 57 IF ~!IsValidForPartyDialog("Valygar") IsValidForPartyDialog("Aerie")~ THEN DO ~SetGlobal("EdwinJob","GLOBAL",1)~ UNSOLVED_JOURNAL #34211 EXTERN ~AERIEJ~ 84 IF ~!IsValidForPartyDialog("Valygar") !IsValidForPartyDialog("Aerie") IsValidForPartyDialog("Keldorn")~ THEN DO ~SetGlobal("EdwinJob","GLOBAL",1)~ UNSOLVED_JOURNAL #34211 EXTERN ~KELDORJ~ 144 IF ~!IsValidForPartyDialog("Valygar") !IsValidForPartyDialog("Aerie") !IsValidForPartyDialog("Keldorn") IsValidForPartyDialog("Yoshimo")~ THEN DO ~SetGlobal("EdwinJob","GLOBAL",1)~ UNSOLVED_JOURNAL #34211 EXTERN ~YOSHJ~ 70 END

    So if you want Vondo to interject into the same dialog, you have to append your interjection transition to Edwin's state 8.

    The best way to do that with WeiDU is probably using INTERJECT_COPY_TRANS actions in a D file, as Wysp pointed out above:
    INTERJECT_COPY_TRANS EDWIN 8 J#VondoEdwinIJ1TreadLightly == J#VondoJ IF ~InParty("J#Vondo") InMyArea("J#Vondo") !StateCheck("J#Vondo",CD_STATE_NOTVALID)~ THEN ~There is no Cowled Wizard who does not have innocent blood on their hands. But the path you are setting us on is a path towards evil. Tread lightly or I will intervene.~ END

    Here:
    - EDWIN is the dialog file you're interjecting into
    - 8 is the state label in that file
    - "J#VondoEdwinIJ1TreadLightly" is the global variable name that will be automatically used to restrict the interjection from showing up more than once (you can pick whatever name you want for it, just make sure it's unique by using your own coding prefix)
    - J#VindoJ is the joined dialog file of your NPC
    - IF ~ ... ~ is the script trigger for your interjection

    I_C_T will do all the heavy-lifting work for you by appending the provided interjection trigger to specified Edwin's dialog state, AND appending the interjection SAY state into the specified J file, AND correctly linking the two. As a nice bonus, it will also copy the full list of original transitions from the source Edwin's dialog state, so that Aerie will get her turn to speak after Vondo.

    See the WeiDU documentation for more details on full syntax and some examples of how those I_C_T actions should be used.

    Some more tips:
    - CD_STATE_NOTVALID in the code above is a custom state (you need to append it to STATE.IDS to compile the code). Using it is generally accepted as a more reliable replacement for Bioware's default IsValidForPartyDialog() triggers. You can read more on it here: http://www.shsforums.net/topic/36779-using-cd-state-notvalid/
    - Refer to IESDP for a list of script triggers and actions that can be used in compilable D/BAF files: http://iesdp.gibberlings3.net/scripting/triggers/bg2triggers.htm
    - A useful and up-to-date tutorial on NPC scripting/dialogue coding can be found here: http://www.shsforums.net/topic/36780-coding-friendships-and-romances/
  • karnagekarnage Member Posts: 92
    Whow, thanks a lot for all that great info! It'll take some time to absorb all that ...

    But, if the triggers are already set, that's a real reduction in the workload.

    What is I_C_T btw?
  • prophet1prophet1 Member Posts: 172
    karnage said:

    What is I_C_T btw?

    Short way of writing INTERJECT_COPY_TRANS. :)

Sign In or Register to comment.