
Familiar conversation
#1
Posted 09 July 2007 - 10:20 AM
Also, can anyone point me to a good tutorial on PID's?
Many thanks! (And many, many questions to come, I'm quite sure).
#2
Posted 09 July 2007 - 12:14 PM
Example of simple PID code:
D:\BaldursGateTutu\BG1NPC\Phase3\PID\X#PCINIT.D
APPEND ~VICONJ~ IF ~IsGabber(Player1)~ THEN BEGIN VICH SAY @0 ++ @1 EXIT END END
This gives you a Player-Initiated Dialogue on the J file. When you force-talk/click-talk Viconia, it fires if nothing else is available.
The extent of your singe talk is pretty huge. A "small" PID from The BG1 NPC Project has 30+ potential responses, all controlled by conditions to be met - Class of Player1, globals set by other mods or your own mod, gender, alignment, combinations - the sky is the limit. All of it takes place within the single dialogue. Berelinde will be alonng in a minute or so to make this simpler, but i will jump to the end and post a working sample and break some of it down:
/* PI DIALOGUES */ APPEND ~VICONJ~ IF ~IsGabber(Player1)~ THEN BEGIN VICH SAY @0 ++ @1 EXIT //Always allowed, like "Oh, nothing." /* This set shows one of the four following random responses to a conversation completed in the game */ + ~Global("VICHdone","GLOBAL",1) RandomNum(4,1)~ + @2 + VICHFailure1 + ~Global("VICHdone","GLOBAL",1) RandomNum(4,2)~ + @2 + VICHFailure2 + ~Global("VICHdone","GLOBAL",1) RandomNum(4,3)~ + @2 + VICHFailure3 + ~Global("VICHdone","GLOBAL",1) RandomNum(4,4)~ + @2 + VICHFailure4 /* This set shows one of the five following random responses if that conversation has not happened yet in the game */ + ~!Global("VICHdone","GLOBAL",1) RandomNum(5,1)~ + @3 + VICHSuccess + ~!Global("VICHdone","GLOBAL",1) RandomNum(5,2)~ + @3 + VICHFailure1 + ~!Global("VICHdone","GLOBAL",1) RandomNum(5,3)~ + @3 + VICHFailure2 + ~!Global("VICHdone","GLOBAL",1) RandomNum(5,4)~ + @3 + VICHFailure3 + ~!Global("VICHdone","GLOBAL",1) RandomNum(5,5)~ + @3 + VICHFailure4 /* These show up only for highly intelligent PCs */ + ~!Global("VICHdone","GLOBAL",1) CheckStatGT(Player1,15,INT) RandomNum(2,1)~ + @4 + VICHSuccess + ~!Global("VICHdone","GLOBAL",1) CheckStatGT(Player1,15,INT) RandomNum(2,2)~ + @4 + VICHFailure1 /* These for dummies */ + ~!Global("VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,INT) RandomNum(5,1)~ + @4 + VICHSuccess + ~!Global("VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,INT) RandomNum(5,2)~ + @4 + VICHFailure1 + ~!Global("VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,INT) RandomNum(5,3)~ + @4 + VICHFailure2 + ~!Global("VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,INT) RandomNum(5,4)~ + @4 + VICHFailure3 + ~!Global("VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,INT) RandomNum(5,5)~ + @4 + VICHFailure4 /* These for wise Player1s */ + ~!Global("VICHdone","GLOBAL",1) CheckStatGT(Player1,15,WIS) RandomNum(2,1)~ + @5 + VICHSuccess + ~!Global("VICHdone","GLOBAL",1) CheckStatGT(Player1,15,WIS) RandomNum(2,2)~ + @5 + VICHFailure2 + ~!Global("VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,WIS) RandomNum(5,1)~ + @5 + VICHSuccess + ~!Global("VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,WIS) RandomNum(5,2)~ + @5 + VICHFailure1 + ~!Global("VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,WIS) RandomNum(5,3)~ + @5 + VICHFailure2 + ~!Global("VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,WIS) RandomNum(5,4)~ + @5 + VICHFailure3 + ~!Global("VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,WIS) RandomNum(5,5)~ + @5 + VICHFailure4 /* These for charismatic */ + ~!Global("VICHdone","GLOBAL",1) CheckStatGT(Player1,15,CHR) RandomNum(2,1)~ + @6 + VICHSuccess + ~!Global("VICHdone","GLOBAL",1) CheckStatGT(Player1,15,CHR) RandomNum(2,2)~ + @6 + VICHFailure3 /* These for UGLY. UGLY. */ + ~!Global("VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,CHR) RandomNum(5,1)~ + @6 + VICHSuccess + ~!Global("VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,CHR) RandomNum(5,2)~ + @6 + VICHFailure1 + ~!Global("VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,CHR) RandomNum(5,3)~ + @6 + VICHFailure3 + ~!Global("VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,CHR) RandomNum(5,4)~ + @6 + VICHFailure2 + ~!Global("VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,CHR) RandomNum(5,5)~ + @6 + VICHFailure4 /* This is a set of standard responses. Only one of the eight will show up each time, randomly */ + ~RandomNum(8,1)~ + @7 + ViconiaPID1.1 + ~RandomNum(8,2)~ + @7 + ViconiaPID1.2 + ~RandomNum(8,3)~ + @7 + ViconiaPID1.3 + ~RandomNum(8,4)~ + @7 + ViconiaPID1.4 + ~RandomNum(8,5)~ + @7 + ViconiaPID1.5 + ~RandomNum(8,6)~ + @7 + ViconiaPID1.6 + ~RandomNum(8,7)~ + @7 + ViconiaPID1.7 + ~RandomNum(8,8)~ + @7 + ViconiaPID1.8 /* This is a second set of standard responses. Only one of the eight will show up each time, randomly */ + ~RandomNum(8,1)~ + @8 + ViconiaPID2.1 + ~RandomNum(8,2)~ + @8 + ViconiaPID2.2 + ~RandomNum(8,3)~ + @8 + ViconiaPID2.3 + ~RandomNum(8,4)~ + @8 + ViconiaPID2.4 + ~RandomNum(8,5)~ + @8 + ViconiaPID2.5 + ~RandomNum(8,6)~ + @8 + ViconiaPID2.6 + ~RandomNum(8,7)~ + @8 + ViconiaPID2.7 + ~RandomNum(8,8)~ + @8 + ViconiaPID2.8 /* You get it now - males only! */ + ~RandomNum(8,1) Gender(Player1,MALE)~ + @9 + ViconiaPID3.1 + ~RandomNum(8,2) Gender(Player1,MALE)~ + @9 + ViconiaPID3.2 + ~RandomNum(8,3) Gender(Player1,MALE)~ + @9 + ViconiaPID3.3 + ~RandomNum(8,4) Gender(Player1,MALE)~ + @9 + ViconiaPID3.4 + ~RandomNum(8,5) Gender(Player1,MALE)~ + @9 + ViconiaPID3.5 + ~RandomNum(8,6) Gender(Player1,MALE)~ + @9 + ViconiaPID3.6 + ~RandomNum(8,7) Gender(Player1,MALE)~ + @9 + ViconiaPID3.7 + ~RandomNum(8,8) Gender(Player1,MALE)~ + @9 + ViconiaPID3.8 /* This one shows up all the time and allows a stringfixer to run, resetting Viconia's soundset if it gets scrambled */ ++ @10 + ViconiaVoice
The most extreme version is Ajantis - looking at those PID entries, off of one response are literally hundreds of carefully tailored, crafted responses, set up to closely mirror the progress of the game, alignmemts, reputation, gender, class, attributes, chapter, number in the party, you name it - a game within a game. All designed to make the NPC appear to have something directly on point to say about any subject available.
Domi's K & D mod has a similar setup; but the most extreme implementation of this idea so far is Ajantis.
As for the familiars, I will take a look, but I think either they can e set up as independent creatures with a D file (wolves, for example, can be assigned a D file and be engaged in conversation just like an NPC) or they can be scripted into a banter.
OK , I can't find it in either BanterPack or Flirtpack, but I know it is there - somewhere, someone handles Boo with SetName(). It has to be jcompton - we will have to search his mods. i just can't find the reference right now...
Edited by cmorgan, 09 July 2007 - 12:46 PM.
#3
Posted 09 July 2007 - 12:25 PM
Edited by Bookwyrme, 09 July 2007 - 09:21 PM.
#4
Posted 12 July 2007 - 06:42 PM
#5
Posted 12 July 2007 - 07:21 PM
A quick read of the .cre for familiar shows two versions of each, one for SoA, the other for oB. A quick example:
FAMPSD.cre Allegiance = Ally - 4 dv = fampsd dlg = FAMIL1.DLG
FAMPDS25.cre Allegiance = Ally - 4 dv = fampsd dlg = FAMIL125.DLG
The file FAMIL125.DLG decompiled:
// creator : DLTCEP_enhanced_WeiDU (version 199) // argument : FAMIL125.DLG // game : . // source : ./DATA/25DIALOG.BIF // dialog : ./dialog.tlk // dialogF : (none) BEGIN ~FAMIL125~ IF ~!InPartySlot(LastTalkedToBy,0)~ THEN BEGIN 0 // from: SAY #72066 /* ~The small dragon-like creature purrs quizzically with wide eyes. Nervously it backs away towards <CHARNAME>. Obviously it doesn't want to talk to you.~ */ IF ~~ THEN DO ~MoveToObject(Player1)~ EXIT END IF ~InPartySlot(LastTalkedToBy,0)~ THEN BEGIN 1 // from: SAY #72067 /* ~The small dragon-like creature flutters its wings happily, looking at you with almost kaleidoscopic eyes. "You wish something?" It awaits your attention, tail flicking.~ */ IF ~!InventoryFull(Player1) OR(2) Alignment(Player1,MASK_LAWFUL) Alignment(Player1,MASK_LCNEUTRAL) ~ THEN REPLY #72068 /* ~Come here. I want to pick you up and put you in my pack where it's a bit safer.~ */ GOTO 2 IF ~~ THEN REPLY #72070 /* ~(pet and play with it)~ */ GOTO 3 IF ~CombatCounter(0) !HPPercentLT(Myself,100)~ THEN REPLY #73426 /* ~(feed the familiar)~ */ GOTO 17 IF ~CombatCounter(0) HPPercentLT(Myself,100)~ THEN REPLY #73432 /* ~(feed the familiar)~ */ GOTO 18 IF ~~ THEN REPLY #72095 /* ~You wouldn't happen to have any advice, would you?~ */ GOTO 4 IF ~~ THEN REPLY #72096 /* ~How are you? Everything okay down there?~ */ GOTO 5 IF ~!InventoryFull(Player1) Alignment(Player1,MASK_CHAOTIC) ~ THEN REPLY #72098 /* ~Come here. I want to pick you up and put you in my pack where it's a bit safer.~ */ GOTO 13 IF ~~ THEN REPLY #72097 /* ~No, it's alright. Let's just keep going.~ */ GOTO 12 END IF ~~ THEN BEGIN 2 // from: 3.0 1.0 SAY #72069 /* ~Its eyes brighten, and it practically leaps into your arms, ready to be stowed amongst your belongings where it can sleep and occasionally poke its head out.~ */ IF ~~ THEN DO ~GiveItemCreate("FAMPSD25",Player1,0,0,0) DestroySelf() ~ EXIT END IF ~~ THEN BEGIN 3 // from: 1.1 SAY #72071 /* ~The dragon coos with delight, it's multicolored eyes whirling as you pat its warm, leathery hide. "You are very kind to me, my <PRO_LADYLORD>," it purrs.~ */ IF ~!InventoryFull(Player1) OR(2) Alignment(Player1,MASK_LAWFUL) Alignment(Player1,MASK_LCNEUTRAL) ~ THEN REPLY #72072 /* ~Come here. I want to pick you up and put you in my pack where it's a bit safer.~ */ GOTO 2 IF ~~ THEN REPLY #72073 /* ~You wouldn't happen to have any advice, would you?~ */ GOTO 4 IF ~~ THEN REPLY #72083 /* ~How are you? Everything okay down there?~ */ GOTO 5 IF ~~ THEN REPLY #72091 /* ~Let's just keep going, then.~ */ GOTO 12 IF ~!InventoryFull(Player1) Alignment(Player1,MASK_CHAOTIC) ~ THEN REPLY #72093 /* ~Come here. I want to pick you up and put you in my pack where it's a bit safer.~ */ GOTO 13 END IF ~~ THEN BEGIN 4 // from: 3.1 1.4 SAY #72074 /* ~The familiar cranes its neck back and looks up at you with a slightly bewildered expression. "You wish to ask *me* for advice, my <PRO_LADYLORD>?"~ */ IF ~True()~ THEN EXIT IF ~Global("chapter","GLOBAL",8)~ THEN GOTO 14 IF ~Global("chapter","GLOBAL",9)~ THEN GOTO 15 IF ~Global("chapter","GLOBAL",10)~ THEN GOTO 16 END IF ~~ THEN BEGIN 5 // from: 3.2 1.5 SAY #72084 /* ~The dragon flicks its tail with pleasure and gazes up at you with colorful eyes. "So long as you are well, my <PRO_LADYLORD>, then I am well."~ */ IF ~HPLT("famil1",48) !HPLT("famil1",24)~ THEN GOTO 6 IF ~HPLT("famil1",24)~ THEN GOTO 7 IF ~!HPLT("famil1",48) RandomNum(4,1)~ THEN GOTO 8 IF ~!HPLT("famil1",48) RandomNum(4,2)~ THEN GOTO 9 IF ~!HPLT("famil1",48) RandomNum(4,3)~ THEN GOTO 10 IF ~!HPLT("famil1",48) RandomNum(4,4)~ THEN GOTO 11 END IF ~~ THEN BEGIN 6 // from: 5.0 SAY #72085 /* ~"I... I am a little hurt, though, my <PRO_LADYLORD>. The cuts sting, and I am bleeding. It... it is not pleasant."~ */ IF ~~ THEN EXIT END IF ~~ THEN BEGIN 7 // from: 5.1 SAY #72086 /* ~"I...I am hurt badly, my <PRO_LADYLORD>. I don't want to die, my <PRO_LADYLORD>. I want to stay with you." The dragon whimpers a little and curls its tail around your leg.~ */ IF ~~ THEN EXIT END IF ~~ THEN BEGIN 8 // from: 5.2 SAY #72087 /* ~"But since you are asking, I could use a snack. Perhaps a nice gopher. Or some pie... ooooh, yes, I *like* pie!"~ */ IF ~~ THEN EXIT END IF ~~ THEN BEGIN 9 // from: 5.3 SAY #72088 /* ~"I do like traveling with you. Very much, my <PRO_LADYLORD>. Do you have an apple? I could roast the apple a little and then eat it down. Apples are good!"~ */ IF ~~ THEN EXIT END IF ~~ THEN BEGIN 10 // from: 5.4 SAY #72089 /* ~I am amazed at all the new places I see with you. Everything is so wonderful and so colorful! Is all of the world like this, my <PRO_LADYLORD>?"~ */ IF ~~ THEN EXIT END IF ~~ THEN BEGIN 11 // from: 5.5 SAY #72090 /* ~"I feel wonderful, myself, my <PRO_LADYLORD>. My hide is clean and I stand ready to aid you against danger!"~ */ IF ~~ THEN EXIT END IF ~~ THEN BEGIN 12 // from: 3.3 1.7 SAY #72092 /* ~The dragon flicks its tail contentedly and then turns its eyes back to the path before you. "As you wish, my <PRO_LADYLORD>."~ */ IF ~~ THEN EXIT END IF ~~ THEN BEGIN 13 // from: 3.4 1.6 SAY #72094 /* ~Its eyes brighten, and it practically leaps into your arms, ready to be stowed amongst your belongings where it can sleep and occasionally poke its head out.~ */ IF ~~ THEN DO ~GiveItemCreate("FAMFAI25",Player1,0,0,0) DestroySelf() ~ EXIT END IF ~~ THEN BEGIN 14 // from: 4.1 SAY #72694 /* ~The little dragon looks up at you for a moment, its eyes shimmering. "You must survive, my <PRO_LADYLORD>. Your heritage places you in great danger!" It whips its tail about agitatedly.~ */ IF ~~ THEN EXIT END IF ~~ THEN BEGIN 15 // from: 4.2 SAY #72695 /* ~Its bright eyes look piercingly into yours. "There has been so much death, my <LADYLORD>. So much destruction. But I trust you will find the way to do what is right."~ */ IF ~~ THEN EXIT END IF ~~ THEN BEGIN 16 // from: 4.3 SAY #72696 /* ~For a moment, the dragon growls fiercely. "The imposter must die, my <LADYLORD>! You must somehow go into the Throne of Bhaal and confront her!"~ */ IF ~~ THEN EXIT END IF ~~ THEN BEGIN 17 // from: 1.2 SAY #73428 /* ~You offer the little dragon some nuts and berries that you have stored, and the dragon nibbles on a few of them but doesn't really seem all that hungry.~ */ IF ~~ THEN EXIT END IF ~~ THEN BEGIN 18 // from: 1.3 SAY #73430 /* ~The dragon's eyes swirl with pleasure as it noisily gulps down a large quantity of nuts and berries that you have collected. It's wounds visibly start healing immediately.~ */ IF ~~ THEN DO ~ApplySpell(Myself,CLERIC_CURE_MODERATE_WOUNDS)~ EXIT END
so the banter would have to be different calls for the familiar assigned/game started, I think. It doesn't matter that the current file acts as a PID - the banter states are called directly, so basically they are just storhouses to be drawn directly in via indexed call (a fancy way of saying "this should work like any other NPC").
If you are creating your own, you only need one. A banter chain would just call on the familiar file, but you would have to test what happens if the familiar is in the backpack. I don't know if CD_STATE_NOTVALID or other dialogue checks would fail if the familiar is in inventoory or not...
there was a person awhile back (someone with some good skills, too, I think ) playing with rebuilding an alternate set of familiars. You might do a forum search on several sites to see if they have more concrete, tested information!
#6
Posted 04 September 2007 - 06:45 PM
#7
Posted 04 September 2007 - 07:06 PM
from a PID (originally coded by Domi/Ashara)
/* PI DIALOGUES */ APPEND ~%VICONIA_JOINED%~ IF ~IsGabber(Player1) %BGT_VAR%~ THEN BEGIN VICH SAY @0 ++ @1 EXIT + ~Global("X#VICHdone","GLOBAL",1) RandomNum(4,1)~ + @2 + VICHFailure1 + ~Global("X#VICHdone","GLOBAL",1) RandomNum(4,2)~ + @2 + VICHFailure2 + ~Global("X#VICHdone","GLOBAL",1) RandomNum(4,3)~ + @2 + VICHFailure3 + ~Global("X#VICHdone","GLOBAL",1) RandomNum(4,4)~ + @2 + VICHFailure4 + ~!Global("X#VICHdone","GLOBAL",1) RandomNum(5,1)~ + @3 + VICHSuccess + ~!Global("X#VICHdone","GLOBAL",1) RandomNum(5,2)~ + @3 + VICHFailure1 + ~!Global("X#VICHdone","GLOBAL",1) RandomNum(5,3)~ + @3 + VICHFailure2 + ~!Global("X#VICHdone","GLOBAL",1) RandomNum(5,4)~ + @3 + VICHFailure3 + ~!Global("X#VICHdone","GLOBAL",1) RandomNum(5,5)~ + @3 + VICHFailure4 + ~!Global("X#VICHdone","GLOBAL",1) CheckStatGT(Player1,15,INT) RandomNum(2,1)~ + @4 + VICHSuccess + ~!Global("X#VICHdone","GLOBAL",1) CheckStatGT(Player1,15,INT) RandomNum(2,2)~ + @4 + VICHFailure1 + ~!Global("X#VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,INT) RandomNum(5,1)~ + @4 + VICHSuccess + ~!Global("X#VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,INT) RandomNum(5,2)~ + @4 + VICHFailure1 + ~!Global("X#VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,INT) RandomNum(5,3)~ + @4 + VICHFailure2 + ~!Global("X#VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,INT) RandomNum(5,4)~ + @4 + VICHFailure3 + ~!Global("X#VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,INT) RandomNum(5,5)~ + @4 + VICHFailure4 + ~!Global("X#VICHdone","GLOBAL",1) CheckStatGT(Player1,15,WIS) RandomNum(2,1)~ + @5 + VICHSuccess + ~!Global("X#VICHdone","GLOBAL",1) CheckStatGT(Player1,15,WIS) RandomNum(2,2)~ + @5 + VICHFailure2 + ~!Global("X#VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,WIS) RandomNum(5,1)~ + @5 + VICHSuccess + ~!Global("X#VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,WIS) RandomNum(5,2)~ + @5 + VICHFailure1 + ~!Global("X#VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,WIS) RandomNum(5,3)~ + @5 + VICHFailure2 + ~!Global("X#VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,WIS) RandomNum(5,4)~ + @5 + VICHFailure3 + ~!Global("X#VICHdone","GLOBAL",1) !CheckStatGT(Player1,15,WIS) RandomNum(5,5)~ + @5 + VICHFailure4 etc.
The PID goes on for a good long time. In each case, RandomNum(#totalstatespossible,#forrandomstate)
gives you a supposedly equal chance of the numbers. These allow several possible responses to the given initial condition. The most common way to get the condition is to set it via I_C_T into another state if it is responding to an existing encounter or condition, or by setting the "blocking" or "activating" variable in your own added banter or dialogue.Then you can code normally, and when the PID or banter is called it can reflect what has happened before, and do it (using the RandomNum() ) slightly differently each time.
For a full treatment of this, see BG1NPC Project SharTeel Romance D fles and all the Phase3 PIDs. Other code inproject uses this as well, but the most extensive use of RandomNum() is probably SharTeel and the PID responses of several of the NPCs.
Technically, this is close to setting 1d2, 1d3, 1d4, etc. I do not know how you would weight the statistical probabilities differently to match 1d6+1, or 1d6+1d4 - I wouldn't bother, myself.
Edited by cmorgan, 04 September 2007 - 07:08 PM.
#8
Posted 04 September 2007 - 07:48 PM
CHAIN IF ~~ THEN TM#Larj ~blah-blah-blah~ END +~RandomNum(4,1) RandomNum(2,1)~+ ~answer1~ EXIT +~RandomNum(4,2) RandomNum(2,2)~+ ~answer2~ EXIT +~RandomNum(4,3) RandomNum(2,1)~+ ~answer3~ EXIT +~RandomNum(4,4) RandomNum(2,2)~+ ~answer4~ EXIT
You see, I need to code PID that looks like this:
NPC1: ~hello~
Player: ~hello yourself~
NPC1:
//random answers
~answer1~
~answer2~
~answer3~
//additional answers, if certain NPC is in party. Also random.
(If NPC2 in party) ~answer4~
(If NPC3 in party) ~answer5~
(If NPC4 in party) ~answer6~
If I understand right, to use RandomNum and make these answers truly random, I need a set of answers for every possible combination of NPC2-4 in party. That's not a problem, while there are 3 of them - it would result in 6 sets. But actually there are 6 of them, and amount of sets grows tremendously (720, if I'm right). Or am I missing something?
Edited by Gort, 04 September 2007 - 07:57 PM.
#9
Posted 05 September 2007 - 03:18 PM
CHAIN //blah blah END /* Answer set 1 - always shown one possible */ + ~RandomNum(4,1)~ + ~Answer1NPC1~ + NewNPC1State1 + ~RandomNum(4,2)~ + ~Answer2NPC1~ + NewNPC1State2 + ~RandomNum(4,3)~ + ~Answer3NPC1~ + NewNPC1State3 + ~RandomNum(4,4)~ + ~Answer4NPC1~ + NewNPC1State4 /* Answer set 2 */ + ~InParty("MyNPC1") RandomNum(4,1)~ + ~Answer1NPC1~ + NewNPC1State1 + ~InParty("MyNPC1") RandomNum(4,2)~ + ~Answer2NPC1~ + NewNPC1State2 + ~InParty("MyNPC1") RandomNum(4,3)~ + ~Answer3NPC1~ + NewNPC1State3 + ~InParty("MyNPC1") RandomNum(4,4)~ + ~Answer4NPC1~ + NewNPC1State4 /* Answer set 3 */ + ~InParty("MyNPC2") RandomNum(4,1)~ + ~Answer1NPC1~ + NewNPC2State1 + ~InParty("MyNPC2") RandomNum(4,2)~ + ~Answer2NPC1~ + NewNPC2State2 + ~InParty("MyNPC2") RandomNum(4,3)~ + ~Answer3NPC1~ + NewNPC2State3 + ~InParty("MyNPC2") RandomNum(4,4)~ + ~Answer4NPC1~ + NewNPC2State4 /* Answer set 4 */ + ~InParty("MyNPC3") RandomNum(4,1)~ + ~Answer1NPC3~ + NewNPC3State1 + ~InParty("MyNPC3") RandomNum(4,2)~ + ~Answer2NPC3~ + NewNPC3State2 + ~InParty("MyNPC3") RandomNum(4,3)~ + ~Answer3NPC3~ + NewNPC3State3 + ~InParty("MyNPC3") RandomNum(4,4)~ + ~Answer4NPC3~ + NewNPC3State4
gives you one answer randomly determined per NPC in party (and would of course need other options if none of the NPCs were in the party.
You would want to add the checks to make sure they were ok to talk.
This CHAIN would display one option from answer set 1 (randomly chosen from the 4 available),
one from answer set 2 if the NPC1 was in party,
one from answer set 3 if the NPC2 was in party,
one from answer set 4 if the NPC3 was in party.
It sounds like you want something even more complicated, though; to get even more randomness, you would code each of these into subset CHAINS (though I don't see what it gains you from a stoyrtelling perspective) - simply apply the next level on the responses. For example, following the above code if you follow NewNPC1State1,
CHAIN ~banterfile~ NewNPC1State1 ~wow, this is getting a little chaotic~ END + ~RandomNum(8,1)~ + ~Answer1NPC1~ + NewNPC1State1.1 + ~RandomNum(8,2)~ + ~Answer2NPC1~ + NewNPC1State2.1 + ~RandomNum(8,3)~ + ~Answer3NPC1~ + NewNPC1State3.1 + ~RandomNum(8,4)~ + ~Answer4NPC1~ + NewNPC1State4.1 etc...
The engine is *supposed* to give an equal chance for each group set {#,firstInSeries to #,#} to fire. There are some older posts that throw soem statistical doubt on it, but I have not seen that anyone has really done an in-depth study - it works well enough for any storytelling purposes. I do not think that adding additional random number calls to the first random number call will get you what you want (if it even works; it might be that the first one would just get reset by the second one).
Edited by cmorgan, 05 September 2007 - 03:23 PM.
#10
Posted 05 September 2007 - 07:26 PM
(NPC1 reply) > (several condition-dependent PC replies) > (random NPC1 reply)
But I need
(NPC1 reply) > (1 constant PC reply) > (random NPC1 answers, several of which are condition-dependent)
Edited by Gort, 05 September 2007 - 11:55 PM.
#11
Posted 05 September 2007 - 08:34 PM
#12
Posted 05 September 2007 - 11:02 PM
IF ~IsGabber("Player1") Global("PIDNotAllowed","GLOBAL",1)~ PIDDisabled SAY ~I'm in no mood to talk to you now.~ IF ~~ THEN EXIT END IF ~IsGabber("Player1") !Global("PIDNotAllowed","GLOBAL",1)~ PIDEnabled SAY ~You wanted to speak to me?~ + ~Global("Chapter","GLOBAL",2) AreaType(OUTDOOR) RandomNum(4,1)~ + ~I wondered if you had any advice.~ + NewNPC1State1 + ~Global("Chapter","GLOBAL",2) AreaType(OUTDOOR) RandomNum(4,2)~ + ~I wondered if you had any advice.~ + NewNPC1State2 + ~Global("Chapter","GLOBAL",2) AreaType(OUTDOOR) RandomNum(4,3)~ + ~I wondered if you had any advice.~ + NewNPC1State3 + ~Global("Chapter","GLOBAL",2) AreaType(OUTDOOR) RandomNum(4,4)~ + ~I wondered if you had any advice.~ + NewNPC1State4 + ~Global("Chapter","GLOBAL",3) AreaType(OUTDOOR) RandomNum(4,1)~ + ~I wondered if you had any advice.~ + NewNPC1State5 + ~Global("Chapter","GLOBAL",3) AreaType(OUTDOOR) RandomNum(4,2)~ + ~I wondered if you had any advice.~ + NewNPC1State6 + ~Global("Chapter","GLOBAL",3) AreaType(OUTDOOR) RandomNum(4,3)~ + ~I wondered if you had any advice.~ + NewNPC1State7 + ~Global("Chapter","GLOBAL",3) AreaType(OUTDOOR) RandomNum(4,4)~ + ~I wondered if you had any advice.~ + NewNPC1State8 + ~Global("Chapter","GLOBAL",4) AreaType(OUTDOOR) RandomNum(4,1)~ + ~I wondered if you had any advice.~ + NewNPC1State9 + ~Global("Chapter","GLOBAL",4) AreaType(OUTDOOR) RandomNum(4,2)~ + ~I wondered if you had any advice.~ + NewNPC1State10 + ~Global("Chapter","GLOBAL",4) AreaType(OUTDOOR) RandomNum(4,3)~ + ~I wondered if you had any advice.~ + NewNPC1State11 + ~Global("Chapter","GLOBAL",4) AreaType(OUTDOOR) RandomNum(4,4)~ + ~I wondered if you had any advice.~ + NewNPC1State12 + ~Global("Chapter","GLOBAL",2) !AreaType(OUTDOOR) RandomNum(4,1)~ + ~I wondered if you had any advice.~ + NewNPC1State13 + ~Global("Chapter","GLOBAL",2) !AreaType(OUTDOOR) RandomNum(4,2)~ + ~I wondered if you had any advice.~ + NewNPC1State14 + ~Global("Chapter","GLOBAL",2) !AreaType(OUTDOOR) RandomNum(4,3)~ + ~I wondered if you had any advice.~ + NewNPC1State15 + ~Global("Chapter","GLOBAL",2) !AreaType(OUTDOOR) RandomNum(4,4)~ + ~I wondered if you had any advice.~ + NewNPC1State16 + ~Global("Chapter","GLOBAL",3) !AreaType(OUTDOOR) RandomNum(4,1)~ + ~I wondered if you had any advice.~ + NewNPC1State17 + ~Global("Chapter","GLOBAL",3) !AreaType(OUTDOOR) RandomNum(4,2)~ + ~I wondered if you had any advice.~ + NewNPC1State18 + ~Global("Chapter","GLOBAL",3) !AreaType(OUTDOOR) RandomNum(4,3)~ + ~I wondered if you had any advice.~ + NewNPC1State19 + ~Global("Chapter","GLOBAL",3) !AreaType(OUTDOOR) RandomNum(4,4)~ + ~I wondered if you had any advice.~ + NewNPC1State20 + ~Global("Chapter","GLOBAL",4) !AreaType(OUTDOOR) RandomNum(4,1)~ + ~I wondered if you had any advice.~ + NewNPC1State21 + ~Global("Chapter","GLOBAL",4) !AreaType(OUTDOOR) RandomNum(4,2)~ + ~I wondered if you had any advice.~ + NewNPC1State22 + ~Global("Chapter","GLOBAL",4) !AreaType(OUTDOOR) RandomNum(4,3)~ + ~I wondered if you had any advice.~ + NewNPC1State23 + ~Global("Chapter","GLOBAL",4) !AreaType(OUTDOOR) RandomNum(4,4)~ + ~I wondered if you had any advice.~ + NewNPC1State24 //ETC. END
In the example above, I've got one preemptive condition that will run if the NPC (or familiar) is annoyed and doesn't want to talk at the moment, followed by a PID that will run at all other times. It gets a bit long, because you're going to want to offer more than one PC response option, but it works. You could just as easily make this a CHAIN by adding an END after the SAY (and losing the SAY) and using EXTERN instead of +, but I was using cmorgan's code to save myself some typing and didn't want to have to change all of those +'s to EXTERN ~DLGfile~.
It gives you (NPC1 reply) > (1 constant PC reply) > (random NPC1 answers, several of which are condition-dependent)
"Imagination is given to man to console him for what he is not; a sense of humor, for what he is." - Oscar Wilde
berelinde's mods
TolkienAcrossTheWater website
TolkienAcrossTheWater Forum
#13
Posted 06 September 2007 - 12:22 AM
#14
Posted 06 September 2007 - 02:53 AM
"Imagination is given to man to console him for what he is not; a sense of humor, for what he is." - Oscar Wilde
berelinde's mods
TolkienAcrossTheWater website
TolkienAcrossTheWater Forum
#15
Posted 06 September 2007 - 04:02 AM
