Jump to content

Photo

Dialog Files and How They Are Referenced

tutorial dialog coding pdialog.2da interdia.2da crossmod

11 replies to this topic

#1 cmorgan

cmorgan

    journeyman investigator

  • Gibberlings
  • 7097 posts
  • Gender:Male
  • Location:Glencoe, IL, USA

Posted 20 October 2008 - 08:54 AM

Note: I expect that K'aeloree will create another darned good and simple-to-follow tutorial on this in the relatively near future, correctly outlined, and hopefully he will loot and pillage this attempt in the process. These materials are a consolidation and reference on the subject often passed quickly through on the way to getting dialog in the game. As a side benefit, they provide cut & paste template materials as "code shortcuts". -cmorgan

There are many different dialog files the engine calls on when the game is unfolding. There are some great tutorials out there, but since I like to prep stuff beforehand, perhaps this breakdown will be a useful addition and save some folks some work coding their mods.

Preparation
Tutorial links useful to follow before/while/after reading this investigation of dialog file usage: The Road to Banter - by Blue, the Immortal Bard gives you a clue about some of the dialog files and their use, WeiDU Basics - by Japheth you basic IF THEN END states, a series of short tutorials/examples by Kulyok on PPG and several other sites gives you basic examples, and Definitions, Tools and Resources, NPC Creation Series, part 1, by berelinde and the follow up parts 2 and 3 give you a solid basis for all NPC creation including dialog files. A follow up with Theaceface's Ace's very long NPC creation guide should give you a crosscheck on ideas, so that you can get a handle on much of the syntax. Check out K'aeloree's new materials on SHS as well for follow-up and step-by-step breakdowns on things like "What is CD_STATE_NOTVALID and how do I use it?" or "Coding Interjections" or "Coding Friendships and Romances". If you are looking for item dialogs before I get there, there already is a great tutorial available on that: Easy Item Dialogs, for BG2 SoA and ToB by Smoketest.

To organize the basic concepts, check out NPC Dialogue 101 by Ghreyfain, also found in a repost at SHS. This tutorial is an expansion of Ghreyfain's original work.

After you have finished this tutorial, I suggest a quick visit to a pair of posts/tutorials, for the folks struggling with the whole "why does the order of states in a file matter" thing (or "why does my dialog not play correctly") which often has to do with the order that the engine 'sees' the various states in order to evaluate whether they are true or false. Weights -
State Weights - by Japheth and the follow-up Another look at WEIGHT, by JCompton.

So now you have some basics down, let's review again exactly what a state is, and what a dialog file is.

Introduction: A review of States and Dialog Files

Primary concept:
dialog files are lists of states.

At the most elementary logic level, a dialog file is no more than a list of possible text lines for the game to present.

IF ~some_condition_exists~ THEN PRINT_TO_SCREEN ~some_text_with_or_without_additional_links~ END
IF ~some_other_condition_exists~ THEN PRINT_TO_SCREEN ~some_text_with_or_without_additional_links~ END
IF ~no_condition~ THEN PRINT_TO_SCREEN ~some_text_with_or_without_additional_links~ END

Brought into the game by WeiDU reading in the file myMod.tp2, a dialog state is added when WeiDU compiles an IF THEN END code block through a ".d file" into a new or existing game resource designated by the extension .dlg

Examples of usage in myMod.tp2:
COMPILE ~myMod/c-aran.d~

COMPILE EVALUATE_BUFFER ~myMod/dlg/AnyNameYouwWant.d~


Reminder: when WeiDU compiles a .d file, it does not automatically add or start or set up references, or create a .dlg file. WeiDU still needs entries in the .tp2 file and .d file to set this into the game. So

/* standard .d file with dialog */
COMPILE ~myMod/c-aran.d~

/* "evaluated" .d file with dialog  and in-file variables that need to be evaluated before adding strings to the dialog.tlk */
COMPILE EVALUATE_BUFFER ~myMod/dlg/AnyNameYouwWant.d~


does not add the dialog files
c-aran.dlg
AnyNameYouwWant.dlg

it just processes those files to find out what you *do* want added to the game. To add specific dialogs to the game, the .d file needs to have some entries. Why don't we start with adding a .dlg file so that the game will recognize a valid dialog:
in myMod.tp2:
COMPILE ~myMod/c-aran.d~

in the related
c-aran.d:
BEGIN ~c-aran~

So that gives the i.e. engine a chance at identifying and reading a new .dlg.
Let's go on and add three states to c-aran.d. To keep things separated and simplified, we have begun a .dlg, and now we are going to add states to that .dlg - to "append" new materials to the existing file.
BEGIN ~c-aran~

APPEND ~c-aran~
END

The APPEND block contains all of the states that relate to a single dialog file, "c-aran". Now we add some actual states:
BEGIN ~c-aran~

APPEND ~c-aran~

IF ~NumTimesTalkedTo(0)~ THEN BEGIN c-aranstarts
  SAY ~Aye, welcome, then. This is a fine day on Trade Way."
  IF ~~ THEN EXIT
END

IF ~NumTimesTalkedTo(1)~ THEN BEGIN c-aranagain
  SAY ~I do remember you - we talked before, didn't we..."
  IF ~~ THEN GOTO c-aranends
END

IF ~~ c-aranends
  SAY ~No matter. Welcome again, then. This is a fine day on Trade Way."
  IF ~~ THEN EXIT
END

END

The only difference in the above three states is what brings them up to the engine's "use this now" list. While that's a whole other topic, we can shortcut to the following breakdown;
When the game engine looks in the .dlg file c-aran, and begins evaluating each state in order. It checks agains State 1, and if it finds the condition NumTimesTalkedTo(0) is true, it fires off State 1 - and in the dialog box in-game, the player sees the text string "Aye, welcome, then. This is a fine day on Trade Way".
If it finds State 1 is false (for example, if this is the second time we have called on the dialog file "c-aran.dlg"), then the engine skips State 1 and moves to State 2. It tries again; if it finds " number of times talked to = 1", then state 2 is fired, and the player sees the text string "I do remember you - we talked before, didn't we...".
If this is the third time we have talked to the NPC assigned the .dlg "c-aran", then we have a problem. State 1 evaluates false and is skipped, state 2 evaluates false and is skipped, and state 3 has no condition - it literally cannot be evaluated. State 3 can only be linked from another state (in this case it is linked from State 2), so the dialog fails. What happens at this point depends on several factors not for discussion in this tutorial. For now, let's go back and fix this so there is no chance of failure:
BEGIN ~c-aran~

APPEND ~c-aran~

IF ~NumTimesTalkedTo(0)~ THEN BEGIN c-aranstarts
  SAY ~Aye, welcome, then. This is a fine day on Trade Way."
  IF ~~ THEN EXIT
END

IF ~NumTimesTalkedToGT(0)~ THEN BEGIN c-aranagain
  SAY ~I do remember you - we talked before, didn't we..."
  IF ~~ THEN GOTO c-aranends
END

IF ~~ c-aranends
  SAY ~No matter. Welcome again, then. This is a fine day on Trade Way."
  IF ~~ THEN EXIT
END

END

Now, either State 1 or State 2 will always be true, and we can look at the reply section of State 2. It creates a direct link to State 3. So the game evaluates State 2, then follows the reply, and we get two separate dialog boxes:
I do remember you - we talked before, didn't we...
No matter. Welcome again, then. This is a fine day on Trade Way.

For great information on how to use and manipulate states, there are a large number of in-depth and beginner-friendly tutorials. So let's move on to the subject of this tutorial, which is more about organizing groups of states and forming and manipulating dialog file references. Here, we contextualize states, and break down what .dlg files are - what they do for our NPC.

Edited by cmorgan, 18 November 2011 - 09:08 PM.

I love deadlines. I love the whooshing noise they make as they go by. - Douglas Adams

#2 cmorgan

cmorgan

    journeyman investigator

  • Gibberlings
  • 7097 posts
  • Gender:Male
  • Location:Glencoe, IL, USA

Posted 20 October 2008 - 08:59 AM

The Heart of the Matter: Dialog Files and How They Are Referenced
The question that seems to drive some folks crazy when building an NPC - What tells the engine what pile of states to scan through to find what to present? And what the heck are all these NPC.DLG, JNPC.DLG, BNPC.DLG, etc. that I find lying around the game?

OK, easy enough to explain, and it will help me out too, as I like to have quick templates to use for copy/paste.

The i.e. engine can see a couple of possibilities for your NPC. It actually sees all calls to the engine equally, processes them in a hierarchical manner, activates and deactivates many different scripts at once, internally subdivides these into several different categories... but that is way DeepCode™ stuff that really does not concern most modders. If you already know this stuff then you are not here for the tutorial, you are here for the templates. Grab 'em and go, and skip all this talk. But for most of us, we can see the engine as "seeing" two families of dialog states,
the Interact() family of called dialog, on the Banter files, and the Dialog() family of called dialog, on the other dialog files.

You could use a telephone system analogy here. Each NPC has several different ways of being called, but it all breaks down into the question "cell phone" or "land line". For the purposes of this discussion, Interact() works as dialing a cell phone number, while Dialog() works as a home telephone.

Dialog Files and Your NPC
The engine can "see" several possible things that you want to do with dialog files assigned to NPCs.
  • a participant NPC exists in the game resources, and is talking primarily with other joined NPCs - called by Interact() in some script, run off of the banter scripting.
OR
  • a participant NPC exists in the game resources, and has joined the party, and is no longer in the party.
  • a participant NPC exists in the game resources, and has joined the party, and is talking primarily with the PC.
  • a participant NPC doesn't exist in the game resources.
  • a participant NPC exists in the game resources, and has not joined the party - or is not a joinable NPC at all and will never join the party.
Breaking these down:
  • a participant NPC exists and has joined the party, and is talking primarily with other joined NPCs.
    Here is the "B-File", or "Banter File"; all the materials called for by use of the Interact() set of commands. This is reserved by BioWare™ primarily for NPC to NPC banter, called through INTERDIA.2DA. More on that below.
OR
  • a participant NPC exists and has joined the party, but is no longer in the party. Referenced via PDIALOG.2DA.
    This, the "P-file", or "Post Dialog File", gives you a dialog file for NPCs who have joined and left (or been kicked out, or been removed via script by the game) and now you are re-encountering them.
  • a participant NPC exists and has joined the party, and is talking primarily with the PC. Referenced via PDIALOG.2DA.
    This one is the most commonly used, and is called on with commands in the Dialog() and StartDialogNoSet() family. Called the "J-file", or "Joined File", this one is set up for when you click on the joined NPC and force-talk them, and is the home of Love Talks, Friend Talks, and most of the dialog between PC and NPC - with or without other NPCs. It usually contains the most "conditioned" talks.
  • a participant NPC doesn't exist. (You forgot to create the references in PDIALOG.2DA, or the NPC is not installed).
    Well this one seems just silly - if an NPC doesn't exist in the game, well, duh! Unfortunately, it really isn't silly at all - it is quite common for folks to misunderstand how dialog and dialog files interact in the game. Just because you have built a dialog and compiled it doesn't mean that it exists according to the game. You may have created a dialog file, made sure it includes BEGIN ~MyFile~, added some states, put it into the game, and still the dialog doesn't get called, because there is still a link missing. You haven't told the game how to reference these new structures; you have not added your NPC to the INTERDIA.2DA and PDIALOG.2DA files. More on that later, but basically, you have created an entire new subdivision and forgotten to tell the mapmakers and EMS squad it exists.
  • a participant NPC exists and has not joined the party, or will never join the party... NOT referenced via PDIALOG.2DA
    The game has a file for all these states, usually named similarly to the NPC's name. Example: AERIE.DLG. These are called all sorts of things, but let's name this the "Pre-Joined Dialog File" for now. When an NPC has not joined the party, this set of states is available to call on. For most NPCs, this is as far as a dialog goes. All those dialog files in NI or DLTCEP or other editors, like BGT's BGWILLA.DLHG, or mod added ones like C-ARAN.DLG, or vanilla ones like JAHEIRA.DLG and such - all of these are simple dialog files for NPCs that are out of the party. All regular non-joinable NPCs work through this dialog file, so we could name it other things, like "standard dialog file" but since we are playing with a specific subset of NPCs (ones that can join the party) let's not. This "Pre-Joined Dialog File" is set up in the .cre file as the primary dialog. For Joinable NPCs, this set of states is designed to be dumped in favor of the J-File when an NPC joins, and the P-File when an NPC is kicked out or leaves the party.
OK, let's knock these off one at a time. Before we mess about telling the game new information, we should look at what entries already exist, and how they interact. So, here is the easiest one to work with, the "B-File". Banter, or primarily NPC <-> NPC interaction (whether one, two, or many more NPCs) lives in this set of files. A call via script or through the game's banter script (accellerated if you use JCompton's Banter Accellerator) using Interact("myNPCsDV") references the game's INTERDIA.2DA file. We pick up the cell phone (Interact()) and call our NPC. The game acts as a switchboard, and connects our call using a specific file to look up locations of our NPC's dialog file.

For SoA and ToB, we have a two dimentional array of choices for the game, in INTERDIA.2DA:

interdia.2da
2DAV1.0
NONE
FILE25FILE
AERIEBAERIEBAERIE25
ANOMENBANOMENBANOME25
CERNDBCERNDBCERND25
EDWINBEDWINBEDWIN25
HAERDALISBHAERDABHAERD25
JAHEIRABJAHEIRBJAHEI25
JANBJANBJAN25
KELDORNBKELDORBKELDO25
KORGANBKORGANBKORGA25
MAZZYBMAZZYBMAZZY25
MINSCBMINSCBMINSC25
NALIABNALIABNALIA25
VALYGARBVALYGABVALYG25
VICONIABVICONIBVICON25
YOSHIMOBYOSHIMBYOSHIM
IMOEN2NONEBIMOEN25
SAREVOKNONEBSAREV25


What this breaks down to is that for death variable "aerie", when processing a call using Interact(), the game will look for the dialog file BAERIE.DLG if it is processing in SoA, and BAERIE25.DLG if it is playing ToB. Notice Sarevok: no entry for the SoA column! Well we know he can't be an NPC in vanilla unmodded SoA. So there is no file assigned. The telephone call cannot be placed, because he doesn't exist as a joinable NPC.

The same for Imoen - for some reason, long discussed and buried in ancient forum posts, BioWare™ decided that Imoen really didn't need banter in SoA. After all, she isn't around for a good chunk of the game. Don't worry: lots of mods fix that situation. But to be very careful, let's see if we can fix that ourselves if it hasn't been fixed yet...

Checking and Adding Imoen's Banter File

There are several ways of doing this. Here is what Feuille and Miss Sakaki use for The Luxley Family (like most folks, they adapt from the BG2 Fixpack code):
//Giving Imoen a banter file if the Fixpack isn't installed

ACTION_IF NOT FILE_EXISTS_IN_GAME ~cdbehbla.pro~ //makes sure the fixpack isn't already installed
THEN BEGIN
ACTION_IF FILE_EXISTS_IN_GAME ~saradush.mve~ THEN BEGIN
  COPY_EXISTING ~interdia.2da~ ~override~
	SET_2DA_ENTRY 17 1 2 ~BIMOEN2~ // fixes ToB version
	BUT_ONLY_IF_IT_CHANGES
END ELSE BEGIN
  APPEND ~interdia.2da~ ~IMOEN	   BIMOEN2~ // fixes SoA version
	UNLESS ~BIMOEN2~
END
END

side note; the UNLESS is used in the second block to check if BIMOEN2 has already been added to the interdia.2da

So for ToB, they look for the movie file for Saradush, and if they find it they read the .2da file and set the specific entry using SET_2DA_ENTRY (follow the link for documentation). If they don't find ToB, it is even easier, as SoA only has a two-column entry; they just add Imoen directly to the bottom of the file.

On BG1NPC, CamDawg used regexp instead, after defining some variables so that tabs and/or spaces won't throw off our patching;
COPY_EXISTING ~interdia.2da~ ~override~
	  REPLACE_TEXTUALLY CASE_INSENSITIVE ~IMOEN2[ %whitespace%]+NONE[ %whitespace%]+BIMOEN25~
		~IMOEN2	  BIMOEN2	   BIMOEN25~
	BUT_ONLY_IF_IT_CHANGES



For SoA, a regexp example designed to add the BIMOEN2 if it doesn't exist, regardless of case:
APPEND ~interdia.2da~ ~IMOEN  BIMOEN2~ UNLESS ~_\(BIMOEN2\|bimoen2\)~


A quick reminder, too - the game doesn't care if it is a space, or a tab, or anything dividing up the columns. So "ugly" columns don't matter. The problem comes when you forget to add an entry like "***" or "BLANK" or "NONE" -
on ToB,
IMOEN2						   BIMOEN25

is read not as
IMOEN2 {space for blank entry }   BIMOEN25

but as
/* column 1 */ /* column 2 */ /* column 3 */
IMOEN2			 BIMOEN25

That is why you see the "NONE" in the ToB INTERDIA.2DA.

Of course, remember the INTERDIA.2DA entries are only for the initial "conditioned" states, called through Interact() - you could *not* patch in and use BIMOEN2 if you wanted, and just store those materials on the J-file, since they are directly called states. More on that when we see jcompton's use of the "invisible creature trick" later. For now, here is what Theaceface does in Sarah to avoid having problems:

K#AurenB.d, lines 649 - 664
// AurenImoen

CHAIN
IF ~Global("AurenImoenBanter1","AR2200",1)~ THEN K#AurenB AI1
~(Auren speaks softly so that she is not heard by other Drow in the city.)~
DO ~SetGlobal("AurenImoenBanter1","AR2200",2)~
== K#AurenB ~You doing all right, Imoen?~ [K#AureBd]
== IMOEN2J ~I...I think so.  Thank you for asking...um...~
== K#AurenB ~Auren.~
== IMOEN2J ~Right...sorry.~
== K#AurenB ~So...you're a Child of Bhaal, too?~
== IMOEN2J ~I guess.  I'm sort of just in shock over this whole thing.  I just hope that when we reach Irenicus and Bodhi that it's not too late.~
== K#AurenB ~Don't worry.~
== K#AurenB ~We'll make it in time.~
== IMOEN2J ~I hope so, Auren.~
EXIT
Here, Theaceface has simply assigned all Imoen banter lines to the joined file, IMOEN2J. As long as she avoids starting the banter with Imoen's line form the non-existent SoA B-file via Interact(), she can freely reference other files as storage. Many other mods use this idea; it means Imoen can't initiate a banter, but it also means compatibility protection.

So now the modded INTERDIA.2DA says

interdia.2da
2DA V1.0
NONE
FILE25FILE
AERIEBAERIEBAERIE25
ANOMENBANOMENBANOME25
CERNDBCERNDBCERND25
EDWINBEDWINBEDWIN25
HAERDALISBHAERDABHAERD25
JAHEIRABJAHEIRBJAHEI25
JANBJANBJAN25
KELDORNBKELDORBKELDO25
KORGANBKORGANBKORGA25
MAZZYBMAZZYBMAZZY25
MINSCBMINSCBMINSC25
NALIABNALIABNALIA25
VALYGARBVALYGABVALYG25
VICONIABVICONIBVICON25
YOSHIMOBYOSHIMBYOSHIM
IMOEN2BIMOEN2BIMOEN25
SAREVOKNONEBSAREV25


This means that any time the game decides it is time for a banter, it goes to it's list of NPC death variables (script names) and can now look up BIMOEN2.

Of course, that means we probably should add our own entries for our own NPC, so that banters work. A pretty straightforward additional line in the .tp2 file adds our new entry in:
APPEND ~interdia.2da~ ~C-ARAN C-ARANB C-ARNB25~ UNLESS ~C-ARAN~


side note; a quick reminder that while a death variable/script name can be longer than 8 characters, the file references are restricted to 8. So the BioWare™ designers BAERIE25 is the maximum file resource name. Instead of following BioWare™ conventions of <<designation>><<name>> and <<designation>><<name>>25, we are using <<community_prefix>><<name>><<designation>>, <<C->> <<ARAN>> <<B>>. The name gets truncated to fit within the 8 character limit for the ToB file, <<community_prefix>><<name>><<designation>>25, or "C- ARN B 25"

So now, Aran has his own banter file entry:

interdia.2da
2DA V1.0
NONE
FILE25FILE
AERIEBAERIEBAERIE25
ANOMENBANOMENBANOME25
CERNDBCERNDBCERND25
EDWINBEDWINBEDWIN25
HAERDALISBHAERDABHAERD25
JAHEIRABJAHEIRBJAHEI25
JANBJANBJAN25
KELDORNBKELDORBKELDO25
KORGANBKORGANBKORGA25
MAZZYBMAZZYBMAZZY25
MINSCBMINSCBMINSC25
NALIABNALIABNALIA25
VALYGARBVALYGABVALYG25
VICONIABVICONIBVICON25
YOSHIMOBYOSHIMBYOSHIM
IMOEN2BIMOEN2BIMOEN25
SAREVOKNONEBSAREV25
C-ARANC-ARANBC-ARNB25



We can process this file into a whole set of templates for use in APPEND and CHAIN construction.
Templates for Canonical BioWare™ NPCs Banter File entries
/////////////////////////////////SoA B FILE /////////////////////////////////
CHAIN entry construction
== ~BAERIE~ IF ~InParty("Aerie") InMyArea("Aerie") !StateCheck("Aerie",CD_STATE_NOTVALID)~ THEN ~[AERIE]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~
 
== ~BANOMEN~ IF ~InParty("Anomen") InMyArea("Anomen") !StateCheck("Anomen",CD_STATE_NOTVALID)~ THEN ~[ANOMEN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ 

== ~BCERND~ IF ~InParty("Cernd") InMyArea("Cernd") !StateCheck("Cernd",CD_STATE_NOTVALID)~ THEN ~[CERND]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ 

== ~BEDWIN~ IF ~InParty("Edwin") InMyArea("Edwin") !StateCheck("Edwin",CD_STATE_NOTVALID)~ THEN ~[EDWIN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ 

== ~BHAERDA~ IF ~InParty("HaerDalis") InMyArea("HaerDalis") !StateCheck("HaerDalis",CD_STATE_NOTVALID)~ THEN ~[HAERDALIS] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ 

== ~BIMOEN2~ IF ~InParty("Imoen2") InMyArea("Imoen2") !StateCheck("Imoen2",CD_STATE_NOTVALID)~ THEN ~[IMOEN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~
 
== ~BJAHEIR~ IF ~InParty("Jaheira") InMyArea("Jaheira") !StateCheck("Jaheira",CD_STATE_NOTVALID)~ THEN ~[JAHEIRA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ 

== ~BJAN~ IF ~InParty("Jan") InMyArea("Jan") !StateCheck("Jan",CD_STATE_NOTVALID)~ THEN ~[JAN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ 

== ~BKELDOR~ IF ~InParty("Keldorn") InMyArea("Keldorn") !StateCheck("Keldorn",CD_STATE_NOTVALID)~ THEN ~[KELDORN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ 

== ~BKORGAN~ IF ~InParty("Korgan") InMyArea("Korgan") !StateCheck("Korgan",CD_STATE_NOTVALID)~ THEN ~[KORGAN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ 

== ~BMAZZY~ IF ~InParty("Mazzy") InMyArea("Mazzy") !StateCheck("Mazzy",CD_STATE_NOTVALID)~ THEN ~[MAZZY] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ 

== ~BMINSC~ IF ~InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ 

== ~BNALIA~ IF ~InParty("Nalia") InMyArea("Nalia") !StateCheck("Nalia",CD_STATE_NOTVALID)~ THEN ~[NALIA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ 

== ~BVALYGA~ IF ~InParty("Valygar") InMyArea("Valygar") !StateCheck("Valygar",CD_STATE_NOTVALID)~ THEN ~[VALYGAR] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DOO ~ <<DO_ACTION>> ~ 

== ~BVICONI~ IF ~InParty("Viconia") InMyArea("Viconia") !StateCheck("Viconia",CD_STATE_NOTVALID)~ THEN ~[VICONIA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ 

== ~BYOSHIM~ IF ~InParty("Yoshimo") InMyArea("Yoshimo") !StateCheck("Yoshimo",CD_STATE_NOTVALID)~ THEN ~[YOSHIMO] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~

and add in Aran's values,
Mod-Added Template for SoA B FILE
== ~C-ARANB~ IF ~InParty("c-aran") InMyArea("c-aran") !StateCheck("c-aran",CD_STATE_NOTVALID)~ THEN ~[ARAN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~

Sample usage:
HERE


For more traditional coding where you EXTERN directly to another banter file if an NPC is present or to take advantage of the relatively small size of the banter file and toss directly linked states into the banter file,

REPLY construction template
remember to remove the optional portion, i.e. /* options: DO ~ <<DO_ACTION>> ~ */
IF ~InParty("Aerie") InMyArea("Aerie") !StateCheck("Aerie",CD_STATE_NOTVALID)~ THEN ~[AERIE]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~BAERIE~ <<newstate>>

IF ~InParty("Anomen") InMyArea("Anomen") !StateCheck("Anomen",CD_STATE_NOTVALID)~ THEN ~[ANOMEN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~BANOMEN~ <<newstate>>

IF ~InParty("Cernd") InMyArea("Cernd") !StateCheck("Cernd",CD_STATE_NOTVALID)~ THEN ~[CERND]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~BCERND~ <<newstate>>

IF ~InParty("Edwin") InMyArea("Edwin") !StateCheck("Edwin",CD_STATE_NOTVALID)~ THEN ~[EDWIN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~BEDWIN~ <<newstate>>

IF ~InParty("HaerDalis") InMyArea("HaerDalis") !StateCheck("HaerDalis",CD_STATE_NOTVALID)~ THEN ~[HAERDALIS] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~BHAERDA~  <<newstate>>

IF ~InParty("Imoen2") InMyArea("Imoen2") !StateCheck("Imoen2",CD_STATE_NOTVALID)~ THEN ~[IMOEN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~BIMOEN2~ <<newstate>>

IF ~InParty("Jaheira") InMyArea("Jaheira") !StateCheck("Jaheira",CD_STATE_NOTVALID)~ THEN ~[JAHEIRA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~BJAHEIR~ <<newstate>>

IF ~InParty("Jan") InMyArea("Jan") !StateCheck("Jan",CD_STATE_NOTVALID)~ THEN ~[JAN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~BJAN~ <<newstate>>

IF ~InParty("Keldorn") InMyArea("Keldorn") !StateCheck("Keldorn",CD_STATE_NOTVALID)~ THEN ~[KELDORN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~BKELDOR~ <<newstate>>

IF ~InParty("Korgan") InMyArea("Korgan") !StateCheck("Korgan",CD_STATE_NOTVALID)~ THEN ~[KORGAN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~BKORGAN~ <<newstate>>

IF ~InParty("Mazzy") InMyArea("Mazzy") !StateCheck("Mazzy",CD_STATE_NOTVALID)~ THEN ~[MAZZY] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~BMAZZY~ <<newstate>>

IF ~InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~BMINSC~ <<newstate>>

IF ~InParty("Nalia") InMyArea("Nalia") !StateCheck("Nalia",CD_STATE_NOTVALID)~ THEN ~[NALIA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~BNALIA~ <<newstate>>

IF ~InParty("Valygar") InMyArea("Valygar") !StateCheck("Valygar",CD_STATE_NOTVALID)~ THEN ~[VALYGAR] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~BVALYGA~ <<newstate>>

IF ~InParty("Viconia") InMyArea("Viconia") !StateCheck("Viconia",CD_STATE_NOTVALID)~ THEN ~[VICONIA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~BVICONI~ <<newstate>>

IF ~InParty("Yoshimo") InMyArea("Yoshimo") !StateCheck("Yoshimo",CD_STATE_NOTVALID)~ THEN ~[YOSHIMO] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~BYOSHIM~ <<newstate>>

and add in Aran's values,
Mod-Added Template for SoA B FILE
IF ~InParty("c-aran") InMyArea("c-aran") !StateCheck("c-aran",CD_STATE_NOTVALID)~ THEN ~[ARAN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ /* options:  DO ~ <<DO_ACTION>> ~ */ EXTERN ~C-ARANB~

Sample usage:
HERE

I love deadlines. I love the whooshing noise they make as they go by. - Douglas Adams

#3 cmorgan

cmorgan

    journeyman investigator

  • Gibberlings
  • 7097 posts
  • Gender:Male
  • Location:Glencoe, IL, USA

Posted 20 October 2008 - 09:05 AM

To create new states in each Banter file, we can append the new states directly.
APPEND construction templates
APPEND ~BHAERDA~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY ~[HAERDALIS] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END

END // of APPEND
APPEND ~BJAHEIR~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY ~[JAHEIRA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~
  IF ~~ THEN DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END

END // of APPEND
APPEND ~BJAN~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY ~InParty("Jan") InMyArea("Jan") !StateCheck("Jan",CD_STATE_NOTVALID)~ THEN ~[JAN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~
  IF ~~ THEN DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END

END // of APPEND
APPEND ~BKELDOR~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY ~[KELDORN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~  IF ~~ THEN DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END

END // of APPEND
APPEND ~BKORGAN~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY  ~[KORGAN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~
  IF ~~ THEN DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END

END // of APPEND
APPEND ~BMAZZY~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY  ~[MAZZY] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~
  IF ~~ THEN DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END

END // of APPEND
APPEND ~BMINSC~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY ~[MINSC] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~
  IF ~~ THEN DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END
  
END // of APPEND
APPEND ~BNALIA~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY ~[NALIA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ 
  IF ~~ THEN DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END

END // of APPEND
APPEND ~BVALYGA~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY ~[VALYGAR] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~
  IF ~~ THEN DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END

END // of APPEND
APPEND ~BVICONI~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY ~[VICONIA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~
  IF ~~ THEN DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END

END // of APPEND
APPEND ~BYOSHIM~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY ~[YOSHIMO] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~
  IF ~~ THEN DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END

END // of APPEND
APPEND ~BIMOEN2~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY ~[IMOEN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~
  IF ~~ THEN DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END

END // of APPEND
APPEND ~BCERND~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY ~[CERND]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~
  IF ~~ THEN DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END

END // of APPEND
APPEND ~BEDWIN~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY ~[EDWIN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ 
  IF ~~ THEN DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END

END // of APPEND
APPEND ~BAERIE~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY ~[AERIE]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~
  IF ~~ THEN DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END

END // of APPEND
APPEND ~BANOMEN~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY ~[ANOMEN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~
  IF ~~ THEN DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END

END // of APPEND

Adding Aran's template,
APPEND ~C-ARANB~ 

IF ~ <<CONDITION>> ~ THEN BEGIN <<statename>>
  SAY ~[ANOMEN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~
  IF ~~ THEN DO ~ <<CLOSE_CONDITION>> ~ EXIT
  IF ~~ THEN REPLY ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
  IF ~ <<CONDITION>> ~ THEN REPLY  ~ <<TEXT>> ~ DO ~ <<CLOSE_CONDITION>> ~ EXTERN <<DIALOG_FILE>> <<statename>>
END

END // of APPEND


Sample usage:

HERE


and the last permutation initiating a Banter File CHAIN :

CHAIN IF ~ <<CONDITION>> ~ THEN ~BAERIE~ << statename>>
~[AERIE]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ DO ~ <<DO_ACTION>> ~ 
==
END

CHAIN IF ~ <<CONDITION>> ~ THEN ~BANOMEN~  << statename>>
~[ANOMEN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~  DO ~ <<DO_ACTION>> ~ 
==
END

CHAIN IF ~ <<CONDITION>> ~ THEN ~BCERND~  << statename>>
~[CERND]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~  DO ~ <<DO_ACTION>> ~ 
==
END

CHAIN IF ~ <<CONDITION>> ~ THEN ~BEDWIN~  << statename>>
~[EDWIN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~  DO ~ <<DO_ACTION>> ~ 
==
END

CHAIN IF ~ <<CONDITION>> ~ THEN ~BHAERDA~  << statename>>
~[HAERDALIS] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~  DO ~ <<DO_ACTION>> ~ 
==
END

CHAIN IF ~ <<CONDITION>> ~ THEN ~BIMOEN2~  << statename>>
~[IMOEN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~  DO ~ <<DO_ACTION>> ~ 
==
END

CHAIN IF ~ <<CONDITION>> ~ THEN ~BJAHEIR~  << statename>>
~[JAHEIRA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~  DO ~ <<DO_ACTION>> ~ 
==
END

CHAIN IF ~ <<CONDITION>> ~ THEN ~BJAN~ << statename>>
~[JAN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~  DO ~ <<DO_ACTION>> ~ 
==
END
 
CHAIN IF ~ <<CONDITION>> ~ THEN ~BKELDOR~ << statename>>
~[KELDORN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~  DO ~ <<DO_ACTION>> ~ 
==
END
 
CHAIN IF ~ <<CONDITION>> ~ THEN ~BKORGAN~ << statename>> 
~[KORGAN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ DO ~ <<DO_ACTION>> ~ 
==
END

CHAIN IF ~ <<CONDITION>> ~ THEN ~BMAZZY~ << statename>> 
~[MAZZY] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ DO ~ <<DO_ACTION>> ~ 
==
END

CHAIN IF ~ <<CONDITION>> ~ THEN ~BMINSC~ << statename>> 
~[MINSC] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ DO ~ <<DO_ACTION>> ~ 
==
END

CHAIN IF ~ <<CONDITION>> ~ THEN ~BNALIA~ << statename>> 
~[NALIA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ DO ~ <<DO_ACTION>> ~ 
==
END

CHAIN IF ~ <<CONDITION>> ~ THEN ~BVALYGA~ << statename>> 
~[VALYGAR] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ DO ~ <<DO_ACTION>> ~ 
==
END

CHAIN IF ~ <<CONDITION>> ~ THEN ~BVICONI~ << statename>>
~[VICONIA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ DO ~ <<DO_ACTION>> ~ 
==
END

CHAIN IF ~ <<CONDITION>> ~ THEN ~BYOSHIM~ << statename>>
~[YOSHIMO] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ DO ~ <<DO_ACTION>> ~ 
==
END


Sample usage:

HERE



Now for ToB's banters. BioWare uses a "25" designation for these:

/////////////////////////////////ToB B - FILE /////////////////////////////////

== ~BHAERD25~ IF ~InParty("HaerDalis") InMyArea("HaerDalis") !StateCheck("HaerDalis",CD_STATE_NOTVALID)~ THEN ~[HAERDALIS] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ DO ~ <<DO_ACTION>> ~ 

== ~BJAHEI25~ IF ~InParty("Jaheira") InMyArea("Jaheira") !StateCheck("Jaheira",CD_STATE_NOTVALID)~ THEN ~[JAHEIRA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options: DO ~ <<DO_ACTION>> ~ 

== ~BJAN25~ IF ~InParty("Jan") InMyArea("Jan") !StateCheck("Jan",CD_STATE_NOTVALID)~ THEN ~[JAN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options: DO ~ <<DO_ACTION>> ~

== ~BKELDO25~ IF ~InParty("Keldorn") InMyArea("Keldorn") !StateCheck("Keldorn",CD_STATE_NOTVALID)~ THEN ~[KELDORN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options: DO ~ <<DO_ACTION>> ~ 

== ~BKORGA25~ IF ~InParty("Korgan") InMyArea("Korgan") !StateCheck("Korgan",CD_STATE_NOTVALID)~ THEN ~[KORGAN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options: DO ~ <<DO_ACTION>> ~

== ~BMAZZY25~ IF ~InParty("Mazzy") InMyArea("Mazzy") !StateCheck("Mazzy",CD_STATE_NOTVALID)~ THEN ~[MAZZY] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options: DO ~ <<DO_ACTION>> ~

== ~BMINSC25~ IF ~InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options: DO ~ <<DO_ACTION>> ~

== ~BNALIA25~ IF ~InParty("Nalia") InMyArea("Nalia") !StateCheck("Nalia",CD_STATE_NOTVALID)~ THEN ~[NALIA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options: DO ~ <<DO_ACTION>> ~

== ~BVALYG25~ IF ~InParty("Valygar") InMyArea("Valygar") !StateCheck("Valygar",CD_STATE_NOTVALID)~ THEN ~[VALYGAR] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options: DO ~ <<DO_ACTION>> ~ 

== ~BVICON25~ IF ~InParty("Viconia") InMyArea("Viconia") !StateCheck("Viconia",CD_STATE_NOTVALID)~ THEN ~[VICONIA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options: DO ~ <<DO_ACTION>> ~ 

== ~BYOSHIM~ IF ~InParty("Yoshimo") InMyArea("Yoshimo") !StateCheck("Yoshimo",CD_STATE_NOTVALID)~ THEN ~[YOSHIMO] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options: DO ~ <<DO_ACTION>> ~ 

== ~BIMOEN25~ IF ~InParty("Imoen2") InMyArea("Imoen2") !StateCheck("Imoen2",CD_STATE_NOTVALID)~ THEN ~[IMOEN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options: DO ~ <<DO_ACTION>> ~

== ~BCERND25~ IF ~InParty("Cernd") InMyArea("Cernd") !StateCheck("Cernd",CD_STATE_NOTVALID)~ THEN ~[CERND]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ 

== ~BEDWIN25~ IF ~InParty("Edwin") InMyArea("Edwin") !StateCheck("Edwin",CD_STATE_NOTVALID)~ THEN ~[EDWIN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ 

== ~BAERIE25~ IF ~InParty("Aerie") InMyArea("Aerie") !StateCheck("Aerie",CD_STATE_NOTVALID)~ THEN ~[AERIE]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ 

== ~BANOME25~ IF ~InParty("Anomen") InMyArea("Anomen") !StateCheck("Anomen",CD_STATE_NOTVALID)~ THEN ~[ANOMEN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ 

== ~BSAREV25~ IF ~InParty("Sarevok") InMyArea("Sarevok") !StateCheck("Sarevok",CD_STATE_NOTVALID)~ THEN ~[SAREVOK] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~


Mod-Added Template for ToB B FILE
== ~C-ARNB25~ IF ~InParty("c-aran") InMyArea("c-aran") !StateCheck("c-aran",CD_STATE_NOTVALID)~ THEN ~[ARAN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~


To create the remaining templates in this series, copy and paste the SoA entries, swapping the values present for dialog files in the code above. The only thing that changes is the dialog file designated, as the game indexes the resources on the death variable/script name. The InParty("myDV"), etc. are static across the whole game.
I love deadlines. I love the whooshing noise they make as they go by. - Douglas Adams

#4 cmorgan

cmorgan

    journeyman investigator

  • Gibberlings
  • 7097 posts
  • Gender:Male
  • Location:Glencoe, IL, USA

Posted 20 October 2008 - 09:13 AM

Post Dialog File

Next in order of complexity, the set of dialogs called by the regular game scripts, rather than the banter scripts. This is the "land-line", or home telephone call. Here, we find the "POST_DIALOG_FILE" and the "JOIN_DIALOG_FILE" linkages for both SoA and ToB. Called by Dialog(), StartDialogNoSet(), etc. via a character's (or area or the main override) script, we find two (SoA) to four (SoA + ToB) dialog files referenced. The game uses PDIALOG.2DA, a two-dimentional array of dialog files and scripts referenced against the death-variables (script names) of joinable NPCs as a telephone directory:


pdialog.2da
2DA V1.0
multig
POST_DIALOG_FILEJOIN_DIALOG_FILEDREAM_SCRIPT_FILE25POST_DIALOG_FILE25JOIN_DIALOG_FILE25DREAM_SCRIPT_FILE25OVERRIDE_SCRIPT_FILE
AERIEAERIEPAERIEJAERIEDAERIE25PAERIE25JAERIE25Daeri25
ANOMENANOMENPANOMENJANOMENDANOME25PANOME25JANOME25Danom25
CERNDCERNDPCERNDJCERNDDCERND25PCERND25JCERNDDcern25
EDWINEDWINPEDWINJEDWINDEDWIN25PEDWIN25JEDWINDedwi25
HAERDALISHAERDAPHAERDAJHAERDADHAERD25PHAERD25JHAERDADhaer25
IMOENIMOENPIMOENJIMOENDIMOENPIMOENJIMOENDimoe25
IMOEN2IMOEN2PIMOEN2JIMOEN2DIMOEN25PIMOEN25JIMOEN2Dimoe25
JAHEIRAJAHEIRAPJAHEIRAJJAHEIRADJAHEI25PJAHEI25JJAHEI25Djahe25
JANJANPJANJJANDJAN25PJAN25JJANDjan25
KELDORNKELDORPKELDORJKELDORDKELDO25PKELDO25JKELDORDkeld25
KORGANKORGANPKORGANJKORGANDKORGA25PKORGA25JKORGANDkorg25
MAZZYMAZZYPMAZZYJMAZZYDMAZZY25PMAZZY25JMAZZYDmazz25
MINSCMINSCPMINSCJMINSCDMINSC25PMINSC25JMINSCDmins25
NALIANALIAPNALIAJNALIADNALIA25PNALIA25JNALIADnali25
VALYGARVALYGARPVALYGARJVALYGARDVALYG25PVALYG25JVALYGARDvaly25
VICONIAVICONIPVICONIJVICONDVICON25PVICON25JVICON25Dvico25
YOSHIMOYOSHPYOSHJYOSHDYOSHPYOSHJYOSHDyosh25
TTXANTTXANPTTXANJTTXANDTTXANPTTXANJTTXAND***
TTBRANTTBRANPTTBRANJTTBRANDTTBRANPTTBRANJTTBRAND***
TTIMOENTTIMOENPTTIMOENJTTIMOENDTTIMOENPTTIMOENJTTIMOEND***
TTJAHEIRTTJAHEIPTTJAHEIJTTJAHEIDTTJAHEIPTTJAHEIJTTJAHEID***
TTMINSCTTMINSCPTTMINSCJTTMINSCDTTMINSCPTTMINSCJTTMINSCD***
SAREVOKSAREV25PSAREV25JSAREV25DSAREV25PSAREV25JSAREV25D***
IDIOT01IDIOTPIDIOTP***IDIOTPIDIOTP******



Referencing this as a chart, we see that Minsc has the dv "MINSC", the POST_DIALOG_FILE entry "MINSCP", the JOIN_DIALOG_FILE entry "MINSCJ", and some other entries. For the ToB entries, he has 25POST_DIALOG_FILE = "MINSC25P" and the 25JOIN_DIALOG_FILE = "MINSC25J". If the game engine is referencing the dialogs in SoA, it will choose MINSCP and MINSCJ files, if in ToB, it will choose the MINSC25P and MINSC25J files.

The other entries help the game reference specific scripts, not dialogs. Because this is a primary workhorse of the game, the telephone directory (PDIALOG.2DA) contains other information, including the DREAM_SCRIPT_FILE (a script only run following a call via Rest() or RestParty(), where the "dreams" and "At Rest Talks" are triggered); 25DREAM_SCRIPT_FILE, (the same resource for ToB); and 25OVERRIDE_SCRIPT_FILE (which sets the override file for the NPC in ToB). These entries allow actions and triggers to be tailored to to the specific game and run only there.

Adding a Mod NPC to the List
Again, without your NPC having a listing here, the game doesn't really know what to do with him or her. So, the blanket "add on" commands in the file myMod.tp2 to add your NPC are

APPEND ~pdialog.2da~

~C-ARAN C-ARANP C-ARANJ C-ARAND C-ARN25P C-ARN25J C-ARN25D C-ARN25~

UNLESS ~C-ARN25~


There is a more detailed way of doing this, detecting differences between SoA installs and ToB installs. This uses the power of UNLESS/IF in WeiDU:

/* pdialog SoA style */
APPEND ~pdialog.2da~
~C-ARAN C-ARANP C-ARANJ C-ARAND ~
UNLESS ~C-ARN25~
UNLESS ~25POST~

/* pdialog ToB style */
APPEND ~pdialog.2da~
~C-ARAN C-ARANP C-ARANJ C-ARAND C-ARN25P C-ARN25J C-ARN25D C-ARN25~
UNLESS ~C-ARN25~
IF ~25POST~


In these cases, WeiDU looks for the UNLESS string. If it finds it, it does not add the materials - the current PDIALOG.2DA already has been patched to include that NPC. It also looks for the IF string, and if it finds it, adds the materials. Since 25POST only occurs in the ToB pdialog.2da, it serves as a screen to make sure the entries added to SoA are not added ToB. From one of the Grand Master Modders, the original dude, Weimer, we see this setup:

Setup-Solaufein.tp2
/* Here we add SOLA to PDIALOG.2DA. We're being extra cautious since this
 * file changes between SOA and TOB. In SOA it has 4 columns, in TOB it has
 * more. */
APPEND ~pdialog.2da~ // SOA append
~SOLA SOLA SOLA  SOLA
SOLAUFEIN  SOLA SOLA SOLA~
UNLESS ~SOLA~ // somehow we are already there, skip it
UNLESS ~25POST~ // means TOB is installed, skip it

APPEND ~pdialog.2da~ // TOB append
~SOLA  SOLA SOLA  SOLA SOLA SOLA  SOLA SOLA
SOLAUFEIN  SOLA SOLA  SOLA SOLA SOLA SOLA SOLA~
UNLESS ~SOLA~ // we are already there, skip it
IF	 ~25POST~ // requires TOB to be installed


Here he is adding both "Sola" and "Solaufein". From testing on EasyTutu/Tutu, we found that UNLESS and IF are case sensitive, so you may have to use regular expressions (regexp) to determine case sensitivity. Otherwise, if someone patches in

"Sola Sola... etc."

and you use

UNLESS ~SOLA~

you will get

SOLA SOLA SOLA SOLA
Sola Sola Sola

Luckily, this seems to be a cosmetic error. The game reads through and finds the first one, and uses it without case-sensitivity.

It should also be noted that there are several modern mods out there which add ToB - style entries to the pdialog.2da, and skip this cautious check for and they appear to work successfully on SoA installs. The i.e. engine does not care about spacing or having extra columns on the pdialog.2da - SoA seems to ignore them.

Post Dialog files are usually short and sweet; for a full line-by line breakdown see Aran's Phat P-File Phun . They are called when an NPC has been in the party and is kicked out or "reformed" out, and either a script call or a player click sends a Dialog() [or within that family of commands] call the NPC's way. While it is possible to code these into CHAIN constructions, it is very seldom done. This is also not usually the place for long discussions. In fact, the only thing usually done to P-files of NPCs (besides creating their own and adding the entries to the PDIALOG.2DA) is the addition of kicked-out dialog that allows an NPC to be moved to a new area to wait for the party later. Most P-files only contain three or four states.

The primary usages will be for APPENDing to existing states for specialized responses, but technically if you use a condition you can add CHAIN dialog. To do either, instead of detecting the NPC in question as "in the party" and "in the area" and NOT state=notvalid, you could use a modified

NOT inparty IN my area NOT state=notvalid:

InParty("c-aran") InMyArea("c-aran") !StateCheck("c-aran",CD_STATE_NOTVALID)

////// NOT IN PARTY BUT AROUND CONDITIONS //////

// Cernd
~!InParty("Cernd") InMyArea("Cernd") !StateCheck("Cernd",CD_STATE_NOTVALID)~
//Edwin
~!InParty("Edwin") InMyArea("Edwin") !StateCheck("Edwin",CD_STATE_NOTVALID)~
// HaerDalis
~!InParty("HaerDalis") InMyArea("HaerDalis") !StateCheck("HaerDalis",CD_STATE_NOTVALID)~
// Jaheira
~!InParty("Jaheira") InMyArea("Jaheira") !StateCheck("Jaheira",CD_STATE_NOTVALID)~
// Jan
~!InParty("Jan") InMyArea("Jan") !StateCheck("Jan",CD_STATE_NOTVALID)~
// Keldorn
~!InParty("Keldorn") InMyArea("Keldorn") !StateCheck("Keldorn",CD_STATE_NOTVALID)~
// Korgan
~!InParty("Korgan") InMyArea("Korgan") !StateCheck("Korgan",CD_STATE_NOTVALID)~
// Mazzy
~!InParty("Mazzy") InMyArea("Mazzy") !StateCheck("Mazzy",CD_STATE_NOTVALID)~
// Minsc
~!InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~
// Nalia
~!InParty("Nalia") InMyArea("Nalia") !StateCheck("Nalia",CD_STATE_NOTVALID)~
// Valygar
~!InParty("Valygar") InMyArea("Valygar") !StateCheck("Valygar",CD_STATE_NOTVALID)~
// Viconia
~!InParty("Viconia") InMyArea("Viconia") !StateCheck("Viconia",CD_STATE_NOTVALID)~
// Yoshimo
~!InParty("Yoshimo") InMyArea("Yoshimo") !StateCheck("Yoshimo",CD_STATE_NOTVALID)~
// Imoen2
~!InParty("Imoen2") InMyArea("Imoen2") !StateCheck("Imoen2",CD_STATE_NOTVALID)~
// Aerie
~!InParty("Aerie") InMyArea("Aerie") !StateCheck("Aerie",CD_STATE_NOTVALID)~
// Anomen
~!InParty("Anomen") InMyArea("Anomen") !StateCheck("Anomen",CD_STATE_NOTVALID)~

// MOD ADDED
~!InParty("c-aran") InMyArea("c-aran") !StateCheck("c-aran",CD_STATE_NOTVALID)~


Next up, Joined dialog files.
I love deadlines. I love the whooshing noise they make as they go by. - Douglas Adams

#5 cmorgan

cmorgan

    journeyman investigator

  • Gibberlings
  • 7097 posts
  • Gender:Male
  • Location:Glencoe, IL, USA

Posted 20 October 2008 - 10:54 AM

Joined Dialog Files

The workhorse of NPCs, both BioWare™ and Mod-Added, the "J-file" is the storehouse for quest materials, Player-Initiated-Dialogs ("PID"s), friendship talks, and romances. Regardless of how your mod is organized from a file-read-on-install standpoint, these dialog files are not called by the banter engine, so they need to be either

a. a conditioned state followed up by directly linked states, either within the same file using GOTO (+) or referencing another available dialog file via EXTERN.
or
b. a no-conditioned state designed to be linked from either of the above.

Often, the Joined Dialog File is referenced via a specific script that you have added to your mod. So, a basic script setup for a friendtalk, added to MyNPC.bcs in your WeiDU command file (myMod.tp2)
EXTEND_BOTTOM ~c-aran.bcs~ ~aranw/aransfriendtalks.baf~

And (for conceptualization, a simplified code block in) AransFriendTalks.baf
IF
  Global("MyFriendTalk","GLOBAL",0)
THEN RESPONSE #100
  SetGlobal("MyFriendTalk","GLOBAL",1)
  StartDialogNoSet("c-aran")
END

results in a check of Aran's joined dialog file and a check for the first state which meets all conditions and returns True.

If we have a state on C-ARANJ that has this true, then we get a reply:

IF ~Global("MyFriendTalk","GLOBAL",1)~ THEN c-aransayhi
  SAY ~[ARAN] Clangedden's Beard, a FriendTalk!~
  IF ~~ THEN DO ~SetGlobal("MyFriendTalk","GLOBAL",1)~ EXIT
END


If we do not, we get a big problem, as the engine finds nothing true. Player-Initiated-Dialogs take advantage of this behavior by creating an "almost always true" condition, using IsGabber(Player1) or another similar command with no other conditions, so that if the player force-talks the NPC the related dialog file will return one big state with a whole bunch of conditioned replies:

IF ~IsGabber(Player1)~ THEN BEGIN c-arantobpid
  SAY ~You decide to speak to Aran.~
  ++ ~There's something wrong with your voice, Aran.~ + c-aranvoicefix
  /* Inn Flirts */
  + ~Global("c-arantobromance","GLOBAL",2) RandomNum(4,1) OR(2) AreaCheck("AR5003") AreaCheck("AR5501") ~ + ~ <<TEXT >> ~ + c-aranrom25innA
  + ~Global("c-arantobromance","GLOBAL",2) RandomNum(4,2) OR(2) AreaCheck("AR5003") AreaCheck("AR5501") ~ + ~ <<TEXT >> ~ + c-aranrom25innB
  + ~Global("c-arantobromance","GLOBAL",2) RandomNum(4,3) OR(2) AreaCheck("AR5003") AreaCheck("AR5501") ~ + ~ <<TEXT >> ~ + c-aranrom25innC
  + ~Global("c-arantobromance","GLOBAL",2) RandomNum(4,4) OR(2) AreaCheck("AR5003") AreaCheck("AR5501") ~ + ~ <<TEXT >> ~ + c-aranrom25innD

  /* Outside Flirts */
  + ~Global("c-arantobromance","GLOBAL",2) RandomNum(4,1) OR(3) AreaCheck("AR5200") AreaCheck("AR5203") AreaCheck("AR6400") ~ + ~(A sharp pain lances through your ankle, and you lean quickly against a nearby rock)~ + c-aranrom25hikeA
  + ~Global("c-arantobromance","GLOBAL",2) RandomNum(4,2) OR(3) AreaCheck("AR5200") AreaCheck("AR5203") AreaCheck("AR6400") ~ + ~(You poke gently at your meal, but you are unsatisfied. You stand up and walk to the edge of the glade.~ + c-aranrom25campB
  + ~Global("c-arantobromance","GLOBAL",2) RandomNum(4,3) OR(3) AreaCheck("AR5200") AreaCheck("AR5203") AreaCheck("AR6400") TimeoDay(DAY)~ + ~(The swiftly flowing water glistens in the sunlight, and you think you might want to swim.)~ + c-aranrom25swimday
  + ~Global("c-arantobromance","GLOBAL",2) RandomNum(4,4) OR(3) AreaCheck("AR5200") AreaCheck("AR5203") AreaCheck("AR6400") TimeoDay(NIGHT)~ + ~(The swiftly flowing water glistens in the moonlight, and you think you might want to swim.)~ + c-aranrom25swimnight
END

/* Voice Fixer Resolved */
IF ~~ c-aranvoicefix
	<< INSERT SOUNDSET FIXER HERE >>
END


If the player force-talks the NPC and something else returns true, it will fire instead, of course, which means force-talking an NPC is a great way to clear and identify "loopholes" in code or script that have variables hanging open. BioWare™ sets this up (and gives us a minor headache in the modding world) with a HappinessLT() or BreakingPoint() conditioned dialog, too, so that if an NPC is not happy they will leave instead of continuing their association with the party. If we had a PID like this in place, the game sees "force-talk" and "call from script via Dialog()" as the same thing - so Aran's PID would fire instead of the friend talk we wanted.

Technically, any file can actually be used to store directly called states. The engine will happily retrieve the following:
CHAIN ~C-ARANJ~
~[ARAN] Hey, I'm starting in Joined  because it is not a Banter, but we could technically switch back and forth...~
== ~CERNDJ~ IF ~InParty("Cernd") InMyArea("Cernd") !StateCheck("Cernd",CD_STATE_NOTVALID)~ THEN ~[CERND]  I am talking from my Joined File ~
== ~C-ARANJ~ IF ~InParty("Cernd") InMyArea("Cernd") !StateCheck("Cernd",CD_STATE_NOTVALID)~ THEN ~[ARAN]  Oh yeah? ~
== ~BCERND~ IF ~InParty("Cernd") InMyArea("Cernd") !StateCheck("Cernd",CD_STATE_NOTVALID)~ THEN ~[CERND]  I am now talking from my Banter File ~
== ~C-ARANB~ IF ~InParty("Cernd") InMyArea("Cernd") !StateCheck("Cernd",CD_STATE_NOTVALID)~ THEN ~[ARAN]  Me too! Selune's Silvery Gaze, what tricks can be played.~ EXIT


It will also allow you to move freely between banter and joined files once the initial state is called from the correct file, or even create a completely different temporary file, but in practice there are very few examples of this in currently existing mods. Most modders keep joined dialogs together with their reply states, and banter with their banter. Exceptions we can come up with later, in the entries on Items (ITEMDIAL.2da) and Special Topics, like JCompton's use of the "invisible creature trick" to create a temporary shell dialog, applied to the Lilacor/Jaheira/etc. banters. But for standard practice, Joined with Joined, and Banter with Banter.

Why not use the Banter Files for more, and just use Interact()?
Well, you can, technically. Some mods do - for example, in Taisha Remix, Lord Ernie and Bri follow original modeling after BioWare™ and put Love Talks on the Banter file, conditioned and weighted:

Btashia.d, lines 1005 - 1013
IF ~!Global("TashiaRomanceActive","GLOBAL",3)
Global("TashiaMatch","GLOBAL",1)
Global("LoveTalk","LOCALS",34)
!StateCheck(Player1,STATE_SLEEPING)
GlobalGT("TashiaInterestMatch","GLOBAL",2)~ THEN BEGIN 152 // from:
  SAY ~<CHARNAME>, I have been giving much thought to what happened with Arilistan, and how I feel about him...~
  IF ~~ THEN REPLY ~Oh?~ GOTO 154
  IF ~~ THEN REPLY ~Not now, Tashia.~ GOTO 153
END


The trouble is that using the banter file means you are subjecting your conditioned states to evaluation on a timed script interval (go decode/reverse-engineer JCompton's Banter Accellerator and you will see exactly what scripts where and how the timer evidences). If you are strong enough a coder to figure out how to mess with the weights in the original dialog files and *not* mess up the states that BioWare expected to be availabel in their original ordering and weighting, go for it - but most modders don't even want to open that can of worms. It is much simpler to work from carefully constructed script blocks on the NPC's .bcs (or an area script, or at absolutely last resort and with the knowledge that you are playing with Civil-War Era loaded handguns in the middle of a nuclear reactor chamber covered in C4, on baldur[25].bcs, but don't tell anyone I said anything about that...). The joined file gets called only when the PC is force-talked or specifically instructed by an NPC script.

So, the breakdown for the Joined Dialog materials:

Joined Dialog File Templates for SoA and ToB Canonical Bioware™ Characters


////SoA J FILE TEMPLATE////
/////////////////////////////////SoA J FILE TEMPLATE/////////////////////////////////

== ~CERNDJ~ IF ~InParty("Cernd") InMyArea("Cernd") !StateCheck("Cernd",CD_STATE_NOTVALID)~ THEN ~[CERND]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~EDWINJ~ IF ~InParty("Edwin") InMyArea("Edwin") !StateCheck("Edwin",CD_STATE_NOTVALID)~ THEN ~[EDWIN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~HAERDAJ~ IF ~InParty("HaerDalis") InMyArea("HaerDalis") !StateCheck("HaerDalis",CD_STATE_NOTVALID)~ THEN ~[HAERDALIS]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~JAHEIRAJ~ IF ~InParty("Jaheira") InMyArea("Jaheira") !StateCheck("Jaheira",CD_STATE_NOTVALID)~ THEN ~[JAHEIRA]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~JANJ~ IF ~InParty("Jan") InMyArea("Jan") !StateCheck("Jan",CD_STATE_NOTVALID)~ THEN ~[JAN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~KELDORJ~ IF ~InParty("Keldorn") InMyArea("Keldorn") !StateCheck("Keldorn",CD_STATE_NOTVALID)~ THEN ~[KELDORN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~KORGANJ~ IF ~InParty("Korgan") InMyArea("Korgan") !StateCheck("Korgan",CD_STATE_NOTVALID)~ THEN ~[KORGAN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~MAZZYJ~ IF ~InParty("Mazzy") InMyArea("Mazzy") !StateCheck("Mazzy",CD_STATE_NOTVALID)~ THEN ~[MAZZY]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~MINSCJ~ IF ~InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~NALIAJ~ IF ~InParty("Nalia") InMyArea("Nalia") !StateCheck("Nalia",CD_STATE_NOTVALID)~ THEN ~[NALIA]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~VALYGARJ~ IF ~InParty("Valygar") InMyArea("Valygar") !StateCheck("Valygar",CD_STATE_NOTVALID)~ THEN ~[VALYGAR]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~VICONIJ~ IF ~InParty("Viconia") InMyArea("Viconia") !StateCheck("Viconia",CD_STATE_NOTVALID)~ THEN ~[VICONIA]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~YOSHJ~ IF ~InParty("Yoshimo") InMyArea("Yoshimo") !StateCheck("Yoshimo",CD_STATE_NOTVALID)~ THEN ~[YOSHIMO]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~IMOEN2J~ IF ~InParty("Imoen2") InMyArea("Imoen2") !StateCheck("Imoen2",CD_STATE_NOTVALID)~ THEN ~[IMOEN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~AERIEJ~ IF ~InParty("Aerie") InMyArea("Aerie") !StateCheck("Aerie",CD_STATE_NOTVALID)~ THEN ~[AERIE]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~ANOMENJ~ IF ~InParty("Anomen") InMyArea("Anomen") !StateCheck("Anomen",CD_STATE_NOTVALID)~ THEN ~[ANOMEN]  <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>


/////ToB J FILE TEMPLATE/////
/////////////////////////////////ToB J FILE TEMPLATE/////////////////////////////////

== ~AERIE25J~ IF ~InParty("Aerie") InMyArea("Aerie") !StateCheck("Aerie",CD_STATE_NOTVALID)~ THEN ~[AERIE] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~ANOME25P~ IF ~InParty("Anomen") InMyArea("Anomen") !StateCheck("Anomen",CD_STATE_NOTVALID)~ THEN ~[ANOMEN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~CERND25J~ IF ~InParty("Cernd") InMyArea("Cernd") !StateCheck("Cernd",CD_STATE_NOTVALID)~ THEN ~[CERND] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~EDWIN25J~ IF ~InParty("Edwin") InMyArea("Edwin") !StateCheck("Edwin",CD_STATE_NOTVALID)~ THEN ~[EDWIN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~HAERD25J~ IF ~InParty("HaerDalis") InMyArea("HaerDalis") !StateCheck("HaerDalis",CD_STATE_NOTVALID)~ THEN ~[HAERDALIS] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~JAHEI25J~ IF ~InParty("Jaheira") InMyArea("Jaheira") !StateCheck("Jaheira",CD_STATE_NOTVALID)~ THEN ~[JAHEIRA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~JAN25J~ IF ~InParty("Jan") InMyArea("Jan") !StateCheck("Jan",CD_STATE_NOTVALID)~ THEN ~[JAN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~KELDO25J~ IF ~InParty("Keldorn") InMyArea("Keldorn") !StateCheck("Keldorn",CD_STATE_NOTVALID)~ THEN ~[KELDORN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~KORGA25J~ IF ~InParty("Korgan") InMyArea("Korgan") !StateCheck("Korgan",CD_STATE_NOTVALID)~ THEN ~[KORGAN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~MAZZY25J~ IF ~InParty("Mazzy") InMyArea("Mazzy") !StateCheck("Mazzy",CD_STATE_NOTVALID)~ THEN ~[MAZZY] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~MINSC25J~ IF ~InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~NALIA25J~ IF ~InParty("Nalia") InMyArea("Nalia") !StateCheck("Nalia",CD_STATE_NOTVALID)~ THEN ~[NALIA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~VALYG25J~ IF ~InParty("Valygar") InMyArea("Valygar") !StateCheck("Valygar",CD_STATE_NOTVALID)~ THEN ~[VALYGAR] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~VICON25J~ IF ~InParty("Viconia") InMyArea("Viconia") !StateCheck("Viconia",CD_STATE_NOTVALID)~ THEN ~[VICONIA] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~IMOEN25J~ IF ~InParty("Imoen2") InMyArea("Imoen2") !StateCheck("Imoen2",CD_STATE_NOTVALID)~ THEN ~[IMOEN] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>

== ~SAREV25J~ IF ~InParty("Sarevok") InMyArea("Sarevok") !StateCheck("Sarevok",CD_STATE_NOTVALID)~ THEN ~[SAREVOK] <<SPOKEN_TEXT>> ( <<ACTION_TEXT>> ) ~ //options:  DO ~ <<DO_ACTION>> ~ <<TERMINATION_PLACEHOLDER>>



And since we are here, some quick useful templates for "the BioWare™ NPC is not available, or the BioWare™ NPC is available,
///// NOT AVAILABLE CONDITIONS //////

// Cernd
OR(3) !InParty("Cernd") !InMyArea("Cernd") StateCheck("Cernd",CD_STATE_NOTVALID)

//Edwin
OR(3) !InParty("Edwin") !InMyArea("Edwin") StateCheck("Edwin",CD_STATE_NOTVALID)

// HaerDalis
OR(3) !InParty("HaerDalis") !InMyArea("HaerDalis") StateCheck("HaerDalis",CD_STATE_NOTVALID)

// Jaheira
OR(3) !InParty("Jaheira") !InMyArea("Jaheira") StateCheck("Jaheira",CD_STATE_NOTVALID)

// Jan
OR(3) !InParty("Jan") !InMyArea("Jan") StateCheck("Jan",CD_STATE_NOTVALID)

// Keldorn
OR(3) !InParty("Keldorn") !InMyArea("Keldorn") StateCheck("Keldorn",CD_STATE_NOTVALID)

// Korgan
OR(3) !InParty("Korgan") !InMyArea("Korgan") StateCheck("Korgan",CD_STATE_NOTVALID)

// Mazzy
OR(3) !InParty("Mazzy") !InMyArea("Mazzy") StateCheck("Mazzy",CD_STATE_NOTVALID)

// Minsc
OR(3) !InParty("Minsc") !InMyArea("Minsc") StateCheck("Minsc",CD_STATE_NOTVALID)

// Nalia
OR(3) !InParty("Nalia") !InMyArea("Nalia") StateCheck("Nalia",CD_STATE_NOTVALID)

// Valygar
OR(3) !InParty("Valygar") !InMyArea("Valygar") StateCheck("Valygar",CD_STATE_NOTVALID)

// Viconia
OR(3) !InParty("Viconia") !InMyArea("Viconia") StateCheck("Viconia",CD_STATE_NOTVALID)

// Yoshimo
OR(3) !InParty("Yoshimo") !InMyArea("Yoshimo") StateCheck("Yoshimo",CD_STATE_NOTVALID)

// Imoen2
OR(3) !InParty("Imoen2") !InMyArea("Imoen2") StateCheck("Imoen2",CD_STATE_NOTVALID)

// Aerie
OR(3) !InParty("Aerie") !InMyArea("Aerie") StateCheck("Aerie",CD_STATE_NOTVALID)

// Anomen
OR(3) !InParty("Anomen") !InMyArea("Anomen") StateCheck("Anomen",CD_STATE_NOTVALID)

// MOD ADDED

OR(3) !InParty("c-aran") !InMyArea("c-aran") StateCheck("c-aran",CD_STATE_NOTVALID)


////// IN PARTY AND AVAILABLE CONDITIONS //////

// Cernd
InParty("Cernd") InMyArea("Cernd") !StateCheck("Cernd",CD_STATE_NOTVALID)

//Edwin
InParty("Edwin") InMyArea("Edwin") !StateCheck("Edwin",CD_STATE_NOTVALID)

// HaerDalis
InParty("HaerDalis") InMyArea("HaerDalis") !StateCheck("HaerDalis",CD_STATE_NOTVALID)

// Jaheira
InParty("Jaheira") InMyArea("Jaheira") !StateCheck("Jaheira",CD_STATE_NOTVALID)

// Jan
InParty("Jan") InMyArea("Jan") !StateCheck("Jan",CD_STATE_NOTVALID)

// Keldorn
InParty("Keldorn") InMyArea("Keldorn") !StateCheck("Keldorn",CD_STATE_NOTVALID)

// Korgan
InParty("Korgan") InMyArea("Korgan") !StateCheck("Korgan",CD_STATE_NOTVALID)

// Mazzy
InParty("Mazzy") InMyArea("Mazzy") !StateCheck("Mazzy",CD_STATE_NOTVALID)

// Minsc
InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)

// Nalia
InParty("Nalia") InMyArea("Nalia") !StateCheck("Nalia",CD_STATE_NOTVALID)

// Valygar
InParty("Valygar") InMyArea("Valygar") !StateCheck("Valygar",CD_STATE_NOTVALID)

// Viconia
InParty("Viconia") InMyArea("Viconia") !StateCheck("Viconia",CD_STATE_NOTVALID)

// Yoshimo
InParty("Yoshimo") InMyArea("Yoshimo") !StateCheck("Yoshimo",CD_STATE_NOTVALID)

// Imoen2
InParty("Imoen2") InMyArea("Imoen2") !StateCheck("Imoen2",CD_STATE_NOTVALID)

// Aerie
InParty("Aerie") InMyArea("Aerie") !StateCheck("Aerie",CD_STATE_NOTVALID)

// Anomen
InParty("Anomen") InMyArea("Anomen") !StateCheck("Anomen",CD_STATE_NOTVALID)

// MOD ADDED

InParty("c-aran") InMyArea("c-aran") !StateCheck("c-aran",CD_STATE_NOTVALID)


Again, constructing your own reply, CHAIN, and APPEND templates are just a matter of taking the banter entries found earlier in this tutorial and swapping the resource reference to the ~AERIEJ~/~AERIE25J~ references.
I love deadlines. I love the whooshing noise they make as they go by. - Douglas Adams

#6 cmorgan

cmorgan

    journeyman investigator

  • Gibberlings
  • 7097 posts
  • Gender:Male
  • Location:Glencoe, IL, USA

Posted 24 October 2008 - 09:13 PM

PDIALOG.2DA & INTERDIA.2DA: Standard BG2 Mod - Added Joinable NPCs
Defining "standard" as "currently available and following close to standard format for these entries"


BG2 pdialog/interdia standard format NPCs
DeathVariable SoA-P SoA-J SoA-D ToB-P ToB-J ToB-D ToB-script SoA-B ToB-B
Alassa(SimDing0)------------------------
D0AlassaD0AlasPD0AlasJD0AlasDD0Ala25PD0Ala25JD0Ala25DD0Alas25BD0AlasBD0Ala25
Allison(Rastor)------------------------
R#ALLISR#ALLISPR#ALLISJR#ALLISDR#ALL25PR#ALLISJR#ALLISD***R#ALLISBR#ALLISB
Alora(Com_Solaufein)------------------------
CMALORACMALORAPCMALORAJCMALORADCMALO25PCMALO25JCMALO25DCMALOR25BCMALORBCMALO25
Amber(Miera & Darios)------------------------
M#AMBERM#AMBERPM#AMBERJM#AMBERDM#AMB25PM#AMB25JM#AMB25Dm#amb25BM#AMBERBM#AMB25
Angelo(Sister Vigilante)------------------------
ADANGELADANGELPADANGELJADANGELDADANG25PADANG25JADANG25DADANG25BADANGELBADANG25

Edited by cmorgan, 20 November 2011 - 02:02 PM.

I love deadlines. I love the whooshing noise they make as they go by. - Douglas Adams

#7 cmorgan

cmorgan

    journeyman investigator

  • Gibberlings
  • 7097 posts
  • Gender:Male
  • Location:Glencoe, IL, USA

Posted 24 October 2008 - 09:23 PM

PDIALOG.2DA & INTERDIA.2DA: Non-Standard Mod - Added Joinable NPCs

Defining "non-standard" as "currently available and not following standard format for these entries"


Azure (Victor)
Azure Azurep azurej *** Azurep Azurej *** *** Azurep azurej *uses p and j files for banter*

Hessa (llamababe) SUHESSA SUHESSP SUHESSJ SUHES25P SUHES25J SUHES25D SUHES25 | BSUHESS BSUHES25 *entries misaligned due to missing dreamscript entry*

Shyhinworunto Chende (MajorTomSawyer)
MTS#Shy MTS#ShyE MTS#ShyD MTS#ShyJ MTS#Shy25 Shy25E | *error in interdia.2da, mirrors pdialog.2da entries*

Tortured Souls (Vlad & Domi)
COPY_EXISTING ~PDIALOG.2da~ ~override/PDIALOG.2da~
REPLACE_TEXTUALLY ~yosh25~ ~yoshimo~

PPBODHI3 PPBODHI3 PPBODHI3 *** PPBODHI3 PPBODHI3 *** *** | *** ***
SIME SIMEP SIMEJ SIMED SIME25P SIME25J *** sime25 | BSIME BSIME25
KACHIKO KACHIP KACHIJ KACHID KACHI25P KACHI25J KACHI25D *** | BKACHI BKACHI25
DYNAHEIR DYNAP DYNAJ *** DYNAP DYNA25J *** *** | *** ***
CORAN CORANP CORANJ *** CORAN25P CORAN25J *** *** | BCORAN ***

Valen (Weimer)
Valen ValenP ValenJ ValenD ValenP ValenJ Valen Valen | *no interdia.2da entries *

Solaufein (Weimer)
SOLA SOLA SOLA SOLA SOLA SOLA SOLA SOLA | *no interdia.2da entries *
SOLAUFEIN SOLA SOLA SOLA SOLA SOLA SOLA SOLA | *no interdia.2da entries *

I love deadlines. I love the whooshing noise they make as they go by. - Douglas Adams

#8 cmorgan

cmorgan

    journeyman investigator

  • Gibberlings
  • 7097 posts
  • Gender:Male
  • Location:Glencoe, IL, USA

Posted 27 February 2009 - 08:38 AM

updated February 27, 2009 (Xulaye, Jonathan, Kari)
I love deadlines. I love the whooshing noise they make as they go by. - Douglas Adams

#9 Guest_Guest_*

Guest_Guest_*
  • Guests

Posted 06 August 2009 - 03:52 AM

Hi guys.
May be it's off the topic, but still i dunno whom to ask anyways...
I got an idea of translating the whole BG series to my native language (russian), so ye, thats only a translation project no modding included. So is there any user-friendly program for me to use in that case? I tried WeiDU and IDWorkshop.. well first one seems too complicated and the second one works only for dialogs while i want to translate ALL game texts including item/character stats, various comments and everything else..

If u guys can advice me something, that would be great.
Thanks

#10 Mike1072

Mike1072
  • Gibberling Poobah
  • 2531 posts
  • Gender:Male
  • Location:Canada

Posted 07 August 2009 - 04:40 PM

Hi guys.
May be it's off the topic, but still i dunno whom to ask anyways...
I got an idea of translating the whole BG series to my native language (russian), so ye, thats only a translation project no modding included. So is there any user-friendly program for me to use in that case? I tried WeiDU and IDWorkshop.. well first one seems too complicated and the second one works only for dialogs while i want to translate ALL game texts including item/character stats, various comments and everything else..

If u guys can advice me something, that would be great.
Thanks

You could use WeiDU's --traify-tlk command to put all strings that might be used by the game into a text file, translate them, then use WeiDU's --make-tlk command to turn the translated text file into a patch for your language.

You'll want to start this on a clean install, as having installed mods previously might leave mod-added strings in your dialog.tlk.

Here's more detailed instructions assuming you're a Windows user:
  • Grab this.
  • Extract WeiDU.exe from the .zip to your BG directory (in this example, C:\Program Files\Black Isle\Baldur's Gate II - SoA\)
  • Open a command window (Start Menu -> Run -> "cmd")
  • Navigate to your BG directory:
    cd C:\Program Files\Black Isle\Baldur's Gate II - SoA\
  • Run the WeiDU command:
    weidu.exe --traify-tlk --out new_dialog.tra

After translating some or all of the file, you can use this command to create an entire new dialog.tlk from it:
weidu.exe --make-tlk new_dialog.tra --tlkout new_dialog.tlk

Note that some of strings in this file are probably not used by the game... you'd have to do more digging if you wanted to determine which ones are used and which are not.

Edited by Mike1072, 07 August 2009 - 04:48 PM.


#11 Guest_Guest_*

Guest_Guest_*
  • Guests

Posted 11 August 2009 - 03:56 AM

thanks a lot ill try that out

#12 Pomacanthus

Pomacanthus
  • Members
  • 15 posts
  • Gender:Male
  • Location:England

Posted 19 January 2013 - 01:44 PM

Hello modding genius guys and gals!

I am really struggling with this! I have spent best part of three days just trying to make a NPC, get it into the game, and give it some dialog.

I have followed all of the tutorials I can find, and have my NPC joined the party, given it it's own soundset, and I am able to converse with it using the J dialog file. That is where it ends, I cannot cannot get any banters to work. I have followed two tutorials and read loads of posts, but the answer does not seem to be anywhere!

I understand that banters are supposed to be read using the interdia.2da, but the filename there is MYNPCB. In the tutorials, the banter files are BMYNPC. So how does the TP2 recognise and act/ read the banter? I don't get it.

What do I put in the TP2 to get banters to work?

Do I compile both the .d file and the .baf?

It seems that some people have gone to all of the trouble of writing guides for this stuff (Which is great and really appreciated!), without actually telling you how to get it into the game!

I know, because I am an expert at marine aquariums and I take many complicated things for granted, thinking that people know and understand what I'm talking about when really they don't have a clue and what I'm saying sounds like gibberish!
Trust me, there is a good bit of that going on here, so please, I implore someone, to speak to me like the idiot I am and give me some simple answers!

Thank you I hope, by the way, bg2 IS such an amazing game, and I would love to be able to expand my gaming experience of it by contributing some of my own mods, IF I can understand how to do some seemingly basic things!



Reply to this topic



  



Also tagged with one or more of these keywords: tutorial, dialog coding, pdialog.2da, interdia.2da, crossmod

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users