Jump to content

Photo

P-file Phat Phun - from traditional to CHAIN in one step.

dialog coding chain dialog states tutorial post-joined npc kicked-out dialog aran whitehand

4 replies to this topic

#1 cmorgan

cmorgan

    journeyman investigator

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

Posted 27 September 2008 - 10:16 AM

The "post joined", or "You kicked me out already" dialog, run from c-aranp.dlg, is a nice quick file to code and write. It is the easiest of all, mostly because you can pick up anyone's mod and rewrite it as you see fit. The structure is likely to be the same.

[State 0] first evaluated, takes precedence over other states. If this one is always true, the rest of the file is meaningless - nothing below this point will get evaluated.

Let's copy everyone else and put the most general "on- off" switch for Aran possible, the Alignment Test. We want to put a state in that allows Aran to take off forever if he has been kicked out of the party, and the HAPPY.2da alignment table says his alignment would be disgusted and leave. Aran will stick with the job and remain loyal to PC even in the face of heavy evil, but if PC is not loyal in return he has time to think about things and revise. He can't keep up the internal rationalizations and "I'm just doin' my job" that has allowed normal people to do horrible things; he will have been given a choice to get out of the situation. So the standard "HappinessLT" block at the top of the file, that will kick in if the .2da file says "yuck". For neutral good, from the iesdp, a reputation of 1 gives [(good) -300 | (neutral) -300 | (evil) 80], so basically, this state will fire if Aran is kicked out of the party and the party rep is 1. Perhaps I'll go back later and up that number, but right now let's play with this in place. Of course, there are mods that realign this, including BG2 Tweak Pack, but we don't mind - installing one of the "stay forevar" tweaks will work fine because those modify the HAPPTY.2da table of reactions, so the condition isn't met.

IF ~HappinessLT(Myself,-290)~ c-aranrepmismatch
	SAY ~No contracts with you. Sune's Sweet Buttocks, you are a pain in my arse.~ [C-ARAN01]
	IF ~~ THEN DO ~EscapeAreaDestroy()~ EXIT
END



OK, it this triggers, he wanders off to the nearest exit and vanishes in a puff of incandescent logic.

Speaking of logic, logic says that if an NPC is in your party, the game thinks he or she is in your party. Funny thing, though - logic also states that teachers have great influence over the future and should therefore be paid well, and that ain't true, so go figure. In the BG2 engine, you "reform" [restructure? downsize?] your party, which kicks the NPC out of your party with no dialog and *then* the NPC comes up to you and has the whole "hey, are we still hangin', or do I need to update my resume?". So the next two states deal with those possibilities - Player just reformed the party and NPC wants directions (either to be let back in, hang out somewhere, or leave FOREVAR to go post on another forum), or 2. The NPC has been hanging out somewhere and the player has wandered back to pick him/her up.

Now, there is a more "logical" in-game way of doing the kicking-out, via dialog, but it will have to wait for awhile. You can add states like this to the Player-Initiated-Dialog state, a big long single state with a zillion replies that becomes true when everything else has been ruled out and it is the only thing that can be triggered. That works from the Joined dialog file, so the player clicks on the NPC to talk, and one of the options can be "get lost, you hoser". But PIDs are way cool and crazy and need their own topic, or they start turning the party into the kind where jello shots are de rigeur and folks are swinging from the chandeliers. Besides, these things have to be added to this dialog anyways, for when folks reform their party (it still sounds so ominous, like Bolsheviks 'reforming' the Czar and his family into little teeny fragments... darn. Off-topic again. Let's move on to state 1.)

Edited by cmorgan, 18 November 2011 - 07:26 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 27 September 2008 - 10:19 AM

[State 1] If State 0 evaluates "false", then the next state gets checked. So, next up, the next most likely catch-all, the "I'm being asked to be kicked out" state. We want a couple of options for the PC here. Let's take them one at a time.
IF ~HappinessGT(Myself,-289) Global("c-arankickedout","GLOBAL",0)~ THEN BEGIN c-arankickedout
	SAY ~Hey, I'm out, if that's what you want. You want me in, out, or somewhere else?~ 
	IF ~~ THEN REPLY ~ <<TEXT >> ~ DO ~ <<ACTION>> ~ <<TRANSITION/TERMINATION>>
	IF ~~ THEN REPLY ~ <<TEXT >> ~ DO ~ <<ACTION>> ~ <<TRANSITION/TERMINATION>>
END


All of the replies are "no-condition" states, which means they can only be fired off by the engine through a direct link from another state. "no condition" is not the same as "always true"... "no condition" means "I can't see your hand up until I have answered this state, and it directs me to you". "always true" means "once I see you, you have my full and complete attention to the exclusion of everything else, even if you have already been called on".

Filling this out, we want a minimum set of options for the player.
[rejoin]
[kickout]

but I want a few more -

[rejoin]
IF ~~ THEN REPLY ~I want you to stay in the party, Aran.~ DO ~SetGlobal("c-arankickedout","GLOBAL",0) JoinParty()~ EXIT


[kickoutpermanently]
IF ~~ THEN REPLY ~I am terminating your contract permanently, Aran. The paper one. I don't mean to sound ominous or anything.~ GOTO c-aranpfired


[attackNPC]
IF ~~ THEN REPLY ~I am terminating you, Aran. Permanently. Die well.~ GOTO c-aranpterminated


Technically, these actions
DO ~ActionOverride("c-aran",SetLeavePartyDialogFile()) ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) ActionOverride("c-aran",LeaveParty())~ EXIT

are way overkill. If the engine is calling on the Post-Joined "P" file, the game already thinks Aran is kicked out. But it never hurts to be careful. And, of course where we do this, Aran will take off, so let's put these into a set of linked states, and toss them at the bottom of the file, out of the way:

/* goes away peacefully */
IF ~~ c-aranpfired
  SAY ~[ARAN] Thanks for nothin', <CHARNAME>. Well, I'll be off.~
  IF ~~ THEN DO ~SetGlobal("c-arankickedout","GLOBAL",1) ActionOverride("c-aran",SetLeavePartyDialogFile()) ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) ActionOverride("c-aran",LeaveParty())~ EXIT 
END

/* fights */
IF ~~ c-aranpterminated
  SAY ~[ARAN] Hey! Cyric's Buttocks, you traitorous dungheap... I'll not go wi'out a fight...~
  IF ~~ THEN DO ~SetGlobal("c-arankickedout","GLOBAL",1) ActionOverride("c-aran",SetLeavePartyDialogFile()) ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) ActionOverride("c-aran",LeaveParty()) ActionOverride("c-aran",Enemy())~ EXIT 
END


On the first, we just do the JoinPartything, and leave the global "c-arankickedout" alone. Aran rejoins, and we continue on our merry way. For all the other options, though, we need to tell the game he has been kicked out, so we have moved "c-arankickedout" to 1.

Moving on to the next possible PC reply,
[stayhere]
For the "wait here" stuff, we don't give the player an option to drop him in a ridiculous area - and let's make it a little different every time he gets dropped off. The "wait here" set of PC responses, only one of which will play each time, and will only show up as an option in an area where some wild stretch of the imagination will allow Aran to find shelter and relative safety:
IF ~RandomNum(8,1) !AreaCheck("AR0301") !AreaCheck("AR0302") !AreaCheck("AR0303") !AreaCheck("AR0304") !AreaCheck("AR0305") !AreaCheck("AR0306") !AreaCheck("AR0307") !AreaCheck("AR0509") !AreaCheck("AR0510") !AreaCheck("AR0511") !AreaCheck("AR1102") !AreaCheck("AR1107") !AreaCheck("AR0801") !AreaCheck("AR0803")~ THEN REPLY ~Aran, wait here for me, will you? I will be back.~ GOTO c-aranwaitsafe

	IF ~RandomNum(8,2) !AreaCheck("AR0301") !AreaCheck("AR0302") !AreaCheck("AR0303") !AreaCheck("AR0304") !AreaCheck("AR0305") !AreaCheck("AR0306") !AreaCheck("AR0307") !AreaCheck("AR0509") !AreaCheck("AR0510") !AreaCheck("AR0511") !AreaCheck("AR1102") !AreaCheck("AR1107") !AreaCheck("AR0801") !AreaCheck("AR0803")~ THEN REPLY ~Aran, wait here for me, will you? I will be back.~ GOTO c-aranwaitsafe2

	IF ~RandomNum(8,3) !AreaCheck("AR0301") !AreaCheck("AR0302") !AreaCheck("AR0303") !AreaCheck("AR0304") !AreaCheck("AR0305") !AreaCheck("AR0306") !AreaCheck("AR0307") !AreaCheck("AR0509") !AreaCheck("AR0510") !AreaCheck("AR0511") !AreaCheck("AR1102") !AreaCheck("AR1107") !AreaCheck("AR0801") !AreaCheck("AR0803")~ THEN REPLY ~Aran, wait here for me, will you? I will be back.~ GOTO c-aranwaitsafe3

	IF ~RandomNum(8,4) !AreaCheck("AR0301") !AreaCheck("AR0302") !AreaCheck("AR0303") !AreaCheck("AR0304") !AreaCheck("AR0305") !AreaCheck("AR0306") !AreaCheck("AR0307") !AreaCheck("AR0509") !AreaCheck("AR0510") !AreaCheck("AR0511") !AreaCheck("AR1102") !AreaCheck("AR1107") !AreaCheck("AR0801") !AreaCheck("AR0803")~ THEN REPLY ~Aran, wait here for me, will you? I will be back.~ GOTO c-aranwaitsafe4

	IF ~RandomNum(8,5) !AreaCheck("AR0301") !AreaCheck("AR0302") !AreaCheck("AR0303") !AreaCheck("AR0304") !AreaCheck("AR0305") !AreaCheck("AR0306") !AreaCheck("AR0307") !AreaCheck("AR0509") !AreaCheck("AR0510") !AreaCheck("AR0511") !AreaCheck("AR1102") !AreaCheck("AR1107") !AreaCheck("AR0801") !AreaCheck("AR0803")~ THEN REPLY ~Aran, wait here for me, will you? I will be back.~ GOTO c-aranwaitsafe5

	IF ~RandomNum(8,6) !AreaCheck("AR0301") !AreaCheck("AR0302") !AreaCheck("AR0303") !AreaCheck("AR0304") !AreaCheck("AR0305") !AreaCheck("AR0306") !AreaCheck("AR0307") !AreaCheck("AR0509") !AreaCheck("AR0510") !AreaCheck("AR0511") !AreaCheck("AR1102") !AreaCheck("AR1107") !AreaCheck("AR0801") !AreaCheck("AR0803")~ THEN REPLY ~Aran, wait here for me, will you? I will be back.~ GOTO c-aranwaitsafe6

	IF ~RandomNum(8,7) !AreaCheck("AR0301") !AreaCheck("AR0302") !AreaCheck("AR0303") !AreaCheck("AR0304") !AreaCheck("AR0305") !AreaCheck("AR0306") !AreaCheck("AR0307") !AreaCheck("AR0509") !AreaCheck("AR0510") !AreaCheck("AR0511") !AreaCheck("AR1102") !AreaCheck("AR1107") !AreaCheck("AR0801") !AreaCheck("AR0803")~ THEN REPLY ~Aran, wait here for me, will you? I will be back.~ GOTO c-aranwaitsafe7

	IF ~RandomNum(8,8) !AreaCheck("AR0301") !AreaCheck("AR0302") !AreaCheck("AR0303") !AreaCheck("AR0304") !AreaCheck("AR0305") !AreaCheck("AR0306") !AreaCheck("AR0307") !AreaCheck("AR0509") !AreaCheck("AR0510") !AreaCheck("AR0511") !AreaCheck("AR1102") !AreaCheck("AR1107") !AreaCheck("AR0801") !AreaCheck("AR0803")~ THEN REPLY ~Aran, wait here for me, will you? I will be back.~  GOTO c-aranwaitsafe8


and now the states that finish off this batch of possibilities:
IF ~~ c-aranwaitsafe
  SAY ~[ARAN] Bring me back somethin' nice, will you?~
  IF ~~ THEN DO ~SetGlobal("c-arankickedout","GLOBAL",1) ActionOverride("c-aran",SetLeavePartyDialogFile()) ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) ActionOverride("c-aran",LeaveParty())~ EXIT
END

IF ~~ c-aranwaitsafe2
  SAY ~[ARAN] Selune's Misty Eyes. I hope there isn't much dangerous around here. It could harm a lad, you know.~
  IF ~~ THEN DO ~SetGlobal("c-arankickedout","GLOBAL",1) ActionOverride("c-aran",SetLeavePartyDialogFile()) ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) ActionOverride("c-aran",LeaveParty())~ EXIT
END

IF ~~ c-aranwaitsafe3
  SAY ~[ARAN] I'll just be thinkin' about that last inn. Or any inn.~
  IF ~~ THEN DO ~SetGlobal("c-arankickedout","GLOBAL",1) ActionOverride("c-aran",SetLeavePartyDialogFile()) ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) ActionOverride("c-aran",LeaveParty())~ EXIT
END

IF ~~ c-aranwaitsafe4
  SAY ~[ARAN] Just don't be gone too long, eh?~
  IF ~~ THEN DO ~SetGlobal("c-arankickedout","GLOBAL",1) ActionOverride("c-aran",SetLeavePartyDialogFile()) ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) ActionOverride("c-aran",LeaveParty())~ EXIT
END

IF ~~ c-aranwaitsafe5
  SAY ~[ARAN] I'll scout around a bit, and settle somewhere around here 'til you get back.~ 
  IF ~~ THEN DO ~SetGlobal("c-arankickedout","GLOBAL",1) ActionOverride("c-aran",SetLeavePartyDialogFile()) ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) ActionOverride("c-aran",LeaveParty())~ EXIT
END

IF ~~ c-aranwaitsafe6
  SAY ~[ARAN] Chauntea's Basket, I could grow moss waitin'. So don't be long, eh?~
  IF ~~ THEN DO ~SetGlobal("c-arankickedout","GLOBAL",1) ActionOverride("c-aran",SetLeavePartyDialogFile()) ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) ActionOverride("c-aran",LeaveParty())~ EXIT
END

IF ~~ c-aranwaitsafe7
  SAY ~[ARAN] There's got to be somethin' I can ferment around here. I'm runnin' short o' ale.~
  IF ~~ THEN DO ~SetGlobal("c-arankickedout","GLOBAL",1) ActionOverride("c-aran",SetLeavePartyDialogFile()) ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) ActionOverride("c-aran",LeaveParty())~ EXIT
END

IF ~~ c-aranwaitsafe8
  SAY ~[ARAN] Tymorra's Luck - I'd be a mite happier if I was along wi' ye. But you call th' shots, so here I stay.~
  IF ~~ THEN DO ~SetGlobal("c-arankickedout","GLOBAL",1) ActionOverride("c-aran",SetLeavePartyDialogFile()) ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) ActionOverride("c-aran",LeaveParty())~ EXIT
END

These could all be small CHAINs of several NPCs having a response, but i want to save more of that for other files. If every time a player clicks everyone comments, we end up with overkill.

so the next PC option,

[gotoaninn]
IF ~~ THEN REPLY ~Aran, go on and make your way alone. I will join you when I am able.~ GOTO c-aransenttoaninn

gets filled out with its own set of directly called states:

/*  Head for the Hills */
IF ~~ c-aransenttoaninn
	SAY ~Well, I can try. Where do you want me to go?~
	IF ~~ THEN REPLY ~Head for the Brynlaw docks.~ GOTO c-aranpdocks
	IF ~~ THEN REPLY ~Meet me in the Market District in Athalka.~ GOTO c-aranpmarket
	IF ~~ THEN REPLY ~Meet me outside of the D'Arnise Keep.~ GOTO c-aranpkeep
	IF ~~ THEN REPLY ~Meet me in Trademeet.~ GOTO c-aranptrademeet
	IF ~~ THEN REPLY ~Meet me outside of the Windspeare Hills.~ GOTO c-aranpwindspear
END

IF ~~ c-aranpdocks
	SAY ~Aye, then. I'll take up fishin'.~ 
	IF ~~ THEN DO ~SetGlobal("c-arankickedout","GLOBAL",1) ActionOverride("c-aran",SetLeavePartyDialogFile()) ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) ActionOverride("c-aran",LeaveParty()) ActionOverride("c-aran",EscapeAreaMove( <<DOCKS>> ))~ EXIT
END

IF ~~ c-aranpmarket
	SAY ~Aye, then. There's bugger all to do around here anyways. I'll go check on th' shops an' resupply.~ 
	IF ~~ THEN DO ~SetGlobal("c-arankickedout","GLOBAL",1) ActionOverride("c-aran",SetLeavePartyDialogFile()) ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) ActionOverride("c-aran",LeaveParty()) ActionOverride("c-aran",EscapeAreaMove( <<MARKET>> ))~ EXIT
END

IF ~~ c-aranpkeep
	SAY ~Aye, then. I'll wait around th' Keep an stay hidden, like.~ 
	IF ~~ THEN DO ~SetGlobal("c-arankickedout","GLOBAL",1) ActionOverride("c-aran",SetLeavePartyDialogFile()) ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) ActionOverride("c-aran",LeaveParty()) ActionOverride("c-aran",EscapeAreaMove( <<KEEP>> ))~ EXIT
END

IF ~~ c-aranptrademeet
	SAY ~Aye, then. Trademeet it is.~ 
	IF ~~ THEN DO ~SetGlobal("c-arankickedout","GLOBAL",1) ActionOverride("c-aran",SetLeavePartyDialogFile()) ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) ActionOverride("c-aran",LeaveParty()) ActionOverride("c-aran",EscapeAreaMove( <<TRADEMEET>> ))~ EXIT
END

IF ~~ c-aranpwindspear
	SAY ~Aye, then. Might be somethin' interestin' to do around that little village, there, I guess.~ 
	IF ~~ THEN DO ~SetGlobal("c-arankickedout","GLOBAL",1) ActionOverride("c-aran",SetLeavePartyDialogFile()) ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) ActionOverride("c-aran",LeaveParty()) ActionOverride("c-aran",EscapeAreaMove( <<WINDSPEAR>> ))~ EXIT
END


I am lazy, plus working on this in bits and pieces of spare time over days (and weeks, actually), so I am not going to fill in the specific data for the EscapeAreaMove right now. I'll come back and replace <<WINDSPEAR>>, <<DOCKS>>, etc. when I have a wekend to fire up NI or DLTCEP and get specifics of where I want Aran to show up.
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 27 September 2008 - 10:26 AM

ok, the last conditioned state in the file - the "I've been kicked out and am being asked to rejoin" one.

For this one, we want to add some other NPC talks. So let's use CHAIN.

[State 2]
/* extend this with NPC reactions, CHAIN */
CHAIN IF ~HappinessGT(Myself,-289) Global("c-arankickedout","GLOBAL",1)~ THEN ~C-ARANP~ c-aranrejoins
~I was wonderin' when you would show up. I have been checkin' out the area, but I was startin' to worry.~
== ~MINSCJ~ IF ~InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC]  XXXX SPOKEN XXXX ( XXXX ACTION XXXX ) ~ //options:  DO ~ XXXX SET XXXX ~ <<TERMINATION_PLACEHOLDER>>
END
++ ~Sure. Join up.~ DO ~SetGlobal("c-arankickedout","GLOBAL",0) SetGlobal("c-aranjoined","GLOBAL",1) JoinParty()~ EXIT
++ ~Just checking on how you are doing. Wait here.~ EXIT


which resolves to

/* extend this with NPC reactions, CHAIN */
CHAIN IF ~HappinessGT(Myself,-289) Global("c-arankickedout","GLOBAL",1)~ THEN ~C-ARANP~ c-aranrejoins
~I was wonderin' when you would show up. I have been checkin' out the area, but I was startin' to worry.~
== ~MINSCJ~ IF ~InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC]  Ah, Aran! We shall fight together again!~ //options:  DO ~ XXXX SET XXXX ~ <<TERMINATION_PLACEHOLDER>>
END
++ ~Sure. Join up.~ DO ~SetGlobal("c-arankickedout","GLOBAL",0) SetGlobal("c-aranjoined","GLOBAL",1) JoinParty()~ EXIT
++ ~Just checking on how you are doing. Wait here.~ EXIT


but then every time the dialog runs, Minsc will say the same thing. So let's play with it again -

/* extend this with NPC reactions, CHAIN */
CHAIN IF ~HappinessGT(Myself,-289) Global("c-arankickedout","GLOBAL",1)~ THEN ~C-ARANP~ c-aranrejoins
~I was wonderin' when you would show up. I have been checkin' out the area, but I was startin' to worry.~
== ~MINSCJ~ IF ~Global("c-kickedminsc","GLOBAL",0) InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC]  Ah, Aran! We shall fight together again!~  DO ~SetGlobal("c-kickedminsc","GLOBAL",1)~
END
++ ~Sure. Join up.~ DO ~SetGlobal("c-arankickedout","GLOBAL",0) SetGlobal("c-aranjoined","GLOBAL",1) JoinParty()~ EXIT
++ ~Just checking on how you are doing. Wait here.~ EXIT


Now it will only play once. Heck, let's give Minsc some more lines to say -
/* Rejoining */
CHAIN IF ~HappinessGT(Myself,-289) Global("c-arankickedout","GLOBAL",1)~ THEN ~C-ARANP~ c-aranrejoins
~I was wonderin' when you would show up. I have been checkin' out the area, but I was startin' to worry.~
== ~MINSCJ~ IF ~Global("c-kickedminsc","GLOBAL",0) InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC]  Ah, Aran! We shall fight together again!~  DO ~SetGlobal("c-kickedminsc","GLOBAL",1)~
== ~MINSCJ~ IF ~Global("c-kickedminsc","GLOBAL",1) InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC]  Boo has missed you, Aran! Why do you go off alone so much?~  DO ~SetGlobal("c-kickedminsc","GLOBAL",2)~
== ~MINSCJ~ IF ~Global("c-kickedminsc","GLOBAL",2) InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC]  <CHARNAME>, must we keep leaving Aran behind and then picking him up again? Boo's whiskers are turning grey with the confusion.~  DO ~SetGlobal("c-kickedminsc","GLOBAL",3)~
END
++ ~Sure. Join up.~ DO ~SetGlobal("c-arankickedout","GLOBAL",0) SetGlobal("c-aranjoined","GLOBAL",1) JoinParty()~ EXIT
++ ~Just checking on how you are doing. Wait here.~ EXIT



What if aran was in a relationship with PC?
/* Rejoining */
CHAIN IF ~HappinessGT(Myself,-289) Global("c-arankickedout","GLOBAL",1)~ THEN ~C-ARANP~ c-aranrejoins
~I was wonderin' when you would show up. I have been checkin' out the area, but I was startin' to worry.~
== ~C-ARANP~ IF ~GlobalGT("c-aranromance","GLOBAL",1) Global("c-aranromancedone","GLOBAL",0)~ THEN ~[ARAN] Missed me, did you, <CHARNAME>? I did certainly miss you.~
== ~MINSCJ~ IF ~Global("c-kickedminsc","GLOBAL",0) InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC]  Ah, Aran! We shall fight together again!~  DO ~SetGlobal("c-kickedminsc","GLOBAL",1)~
== ~MINSCJ~ IF ~Global("c-kickedminsc","GLOBAL",1) InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC]  Boo has missed you, Aran! Why do you go off alone so much?~  DO ~SetGlobal("c-kickedminsc","GLOBAL",2)~
== ~MINSCJ~ IF ~Global("c-kickedminsc","GLOBAL",2) InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC]  <CHARNAME>, must we keep leaving Aran behind and then picking him up again? Boo's whiskers are turning grey with the confusion.~  DO ~SetGlobal("c-kickedminsc","GLOBAL",3)~
END
++ ~Sure. Join up.~ DO ~SetGlobal("c-arankickedout","GLOBAL",0) SetGlobal("c-aranjoined","GLOBAL",1) JoinParty()~ EXIT
++ ~Just checking on how you are doing. Wait here.~ EXIT


Hey, wait a sec. Let's add some different lines for Aran, too, and some different sets of NPCs to comment on them. Fun with CHAIN.
/* extend this with NPC reactions, CHAIN */
CHAIN IF ~HappinessGT(Myself,-289) Global("c-arankickedout","GLOBAL",1)~ THEN ~C-ARANP~ c-aranrejoins
~I was wonderin' when you would show up. I have been checkin' out the area, but I was startin' to worry.~
== ~C-ARANP~ IF ~GlobalGT("c-aranromance","GLOBAL",1) Global("c-aranromancedone","GLOBAL",0)~ THEN ~[ARAN] Missed me, did you, <CHARNAME>? I did certainly miss you.~
== ~MINSCJ~ IF ~Global("c-kickedminsc","GLOBAL",0) InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC]  Ah, welome! We shall fight evil together!~  DO ~SetGlobal("c-kickedminsc","GLOBAL",1)~
== ~MINSCJ~ IF ~Global("c-kickedminsc","GLOBAL",1) InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC]  Boo has missed you, Aran! Why do you go off alone so much?~  DO ~SetGlobal("c-kickedminsc","GLOBAL",2)~
== ~MINSCJ~ IF ~Global("c-kickedminsc","GLOBAL",2) InParty("Minsc") InMyArea("Minsc") !StateCheck("Minsc",CD_STATE_NOTVALID)~ THEN ~[MINSC]  <CHARNAME>, must we keep leaving Aran behind and then picking him up again? Boo's whiskers are turning grey with the confusion.~  DO ~SetGlobal("c-kickedminsc","GLOBAL",3)~
END
IF ~RandomNum(4,1)~ THEN EXTERN ~C-ARANP~ c-aranrejoinone
IF ~RandomNum(4,2)~ THEN EXTERN ~C-ARANP~ c-aranrejointwo
IF ~RandomNum(4,3)~ THEN EXTERN ~C-ARANP~ c-aranrejointhree
IF ~RandomNum(4,4)~ THEN EXTERN ~C-ARANP~ c-aranrejoinfour

CHAIN ~C-ARANP~ c-aranrejoinone
~Bloody great t' see some o' you survived wi' out me. Got a spot open?~
== ~EDWINJ~ IF ~InParty("Edwin") InMyArea("Edwin") !StateCheck("Edwin",CD_STATE_NOTVALID)~ THEN ~[EDWIN]  Wonder of wonders. The simian survived separation from its protectors.~
== ~ANOMENJ~ IF ~InParty("Anomen") InMyArea("Anomen") !StateCheck("Anomen",CD_STATE_NOTVALID)~ THEN ~[ANOMEN] You are quite overconfident in your assesment of your usefulness, are you not?~ 
== ~HAERDAJ~ IF ~InParty("HaerDalis") InMyArea("HaerDalis") !StateCheck("HaerDalis",CD_STATE_NOTVALID)~ THEN ~[HAERDALIS] An eagle returned to the fold!~ 
== ~IMOEN2J~ IF ~InParty("Imoen2") InMyArea("Imoen2") !StateCheck("Imoen2",CD_STATE_NOTVALID)~ THEN ~[IMOEN] Heya. I'll let <CHARNAME> fill you in on what's happened so far.~
END
++ ~Sure. Join up.~ DO ~SetGlobal("c-arankickedout","GLOBAL",0) SetGlobal("c-aranjoined","GLOBAL",1) JoinParty()~ EXIT
++ ~Just checking on how you are doing. Wait here.~ EXIT

CHAIN ~C-ARANP~ c-aranrejointwo
~I was gettin' tired o' cookin' for one, all by myself. Can I join up again?~
== ~JAHEIRAJ~ IF ~InParty("Jaheira") InMyArea("Jaheira") !StateCheck("Jaheira",CD_STATE_NOTVALID)~ THEN ~[JAHEIRA] Then you will be glad to cook tonight. I have several ingredients that will be most interesting to add.~
== ~JANJ~ IF ~InParty("Jan") InMyArea("Jan") !StateCheck("Jan",CD_STATE_NOTVALID)~ THEN ~[JAN]  Have you any new turnip recipies? I am always trying new things with turnips. Why, just the other day I tried ground ankheg chitin as a spice, and it was perfect - it did not overpower the turnip taste at all. It even cleaned my teeth while I ate.~ 
== ~YOSHJ~ IF ~InParty("Yoshimo") InMyArea("Yoshimo") !StateCheck("Yoshimo",CD_STATE_NOTVALID)~ THEN ~[YOSHIMO] Indeed. Cooking alone is as lonely as eating alone.~
END
++ ~Sure. Join up.~ DO ~SetGlobal("c-arankickedout","GLOBAL",0) SetGlobal("c-aranjoined","GLOBAL",1) JoinParty()~ EXIT
++ ~Just checking on how you are doing. Wait here.~ EXIT

CHAIN ~C-ARANP~ c-aranrejointhree
~No real fightin' around here so far. Perhaps they are waitin' for you to show up, <CHARNAME>. You want me back in?~
== ~KELDORJ~ IF ~InParty("Keldorn") InMyArea("Keldorn") !StateCheck("Keldorn",CD_STATE_NOTVALID)~ THEN ~[KELDORN] That would seem to be the case so far this adventure.~ 
== ~KORGANJ~ IF ~InParty("Korgan") InMyArea("Korgan") !StateCheck("Korgan",CD_STATE_NOTVALID)~ THEN ~[KORGAN] They just wanna try me on fer size.~ 
== ~VALYGARJ~ IF ~InParty("Valygar") InMyArea("Valygar") !StateCheck("Valygar",CD_STATE_NOTVALID)~ THEN ~[VALYGAR] It would seem that fighting follows us everywhere.~
END
++ ~Sure. Join up.~ DO ~SetGlobal("c-arankickedout","GLOBAL",0) SetGlobal("c-aranjoined","GLOBAL",1) JoinParty()~ EXIT
++ ~Just checking on how you are doing. Wait here.~ EXIT

CHAIN ~C-ARANP~ c-aranrejoinfour
~Ilmater's Bloody Wrists, but it was boorin' around here. You thinkin' about usin' my skills again?~
== ~MAZZYJ~ IF ~InParty("Mazzy") InMyArea("Mazzy") !StateCheck("Mazzy",CD_STATE_NOTVALID)~ THEN ~[MAZZY] Unfortunately, where we have been has not been precisely 'boring'.~
== ~NALIAJ~ IF ~InParty("Nalia") InMyArea("Nalia") !StateCheck("Nalia",CD_STATE_NOTVALID)~ THEN ~[NALIA] I do need someone to take care of some of the cleaning and cooking.~
== ~VICONIJ~ IF ~InParty("Viconia") InMyArea("Viconia") !StateCheck("Viconia",CD_STATE_NOTVALID)~ THEN ~[VICONIA] Let me kill this surfacer slug, <CHARNAME>. His odor offends me.~ 
== ~AERIEJ~ IF ~InParty("Aerie") InMyArea("Aerie") !StateCheck("Aerie",CD_STATE_NOTVALID)~ THEN ~[AERIE] Hello, Aran... er.. could you please put me down?~
== ~C-ARANP~ IF ~InParty("Aerie") InMyArea("Aerie") !StateCheck("Aerie",CD_STATE_NOTVALID)~ THEN ~[ARAN] Why, sure enough. Sorry, got a bit carried away, there.~
END
++ ~Sure. Join up.~ DO ~SetGlobal("c-arankickedout","GLOBAL",0) SetGlobal("c-aranjoined","GLOBAL",1) JoinParty()~ EXIT
++ ~Just checking on how you are doing. Wait here.~ EXIT


Under this construct, a different set of NPCs get a chance to respond if they are in the party. We can keep this up indefinitely, but already we have gone from a simple single-condition state to about the most intricate and elaborate CHAIN overkill in one file. Things to go back and add in later:

  • checks for logic - like what happens if Minsc has not been in the party with Aran before? Some rewriting, or soem adtitonal conditions needed.
  • Romance/noromance options on all three states. The single line is a little subtle for the game, I think. Plus, nothing references romance status/nonstatus in states 0 and 1.
  • Waste-not-want-not... we need to add more than "join - stay here" to the CHAIN stuff. Like the termination option for evil players. That is pretty much just copy/paste from the other state, linking into the same end-state.
  • clean-up of placeholders for EscapeAreaMove()
  • combining all this into a single file without all the talk, so we can play with the concept of WEIGHT and how things get added between CHAIN and APPEND.

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 24 November 2008 - 10:14 AM

The ToB portion is relatively simple, too.

Using berelinde's Homeward Bound for mod NPCs gives players the roleplaying chance to send Aran back to the Real World™ in Amn, using the Fate Spirit. There are few mods that play with leaving an NPC anywhere else, as relatively fre access to the PocketPlane makes it convenient to move the whole party, but let's play with letting Aran stick around one of the two inns when possible, or be left in places, or be sent back alone to the PocketPlane - it is tough to know exactly what options will support players roleplaying the best, as everyone will do this differently. But this should cover most of the potential options. The only other thing to be concerned about with C-ARN25P is the recognition of romance. We won't break Aran and PC up if they are in a romance. If PC decides to take an extended business trip without him, Aran isn't going to flip out. We can control reactions to having an affair by adding to the Jfile and /or epilogues.

/* BEGIN C-ARN25P is covered in intital dialog compilation. */

/* Sending the NPC home from the Pocket Plane, and bringing them back */
/* courtesy of berelinde, using Homeward Bound code */

EXTEND_BOTTOM FATESP 6
+ ~InParty("c-aran") InMyArea("c-aran") !StateCheck("c-aran",CD_STATE_NOTVALID)~ + ~Send Aran Whitehand home to Amn.~ DO ~SetGlobal("c-aransenthome","GLOBAL",1) 
	ActionOverride("c-aran",SetGlobal("KickedOut","LOCALS",1)) 
	ActionOverride("c-aran",SetLeavePartyDialogFile()) 
	ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) 
	ActionOverride("c-aran",LeaveParty())
	ActionOverride("c-aran",GivePartyAllEquipment())
	ActionOverride("c-aran",MakeGlobal())
	Wait(1)
	CreateVisualEffectObject("SPDIMNDR","c-aran")
	Wait(4)
	MoveGlobal("AR0607","c-aran",[272.294])~ EXIT
+ ~Global("c-aransenthome","GLOBAL",1)~ + ~Bring Aran Whitehand back from Amn.~ DO ~CreateVisualEffect("SPPORTAL",[1999.1228]) 
	Wait(2)
	MoveGlobal("AR4500","c-aran",[1999.1228])
	Wait(1)~ + 8
END

APPEND ~C-ARN25P~

/* AR4500 = pocketplane || AR5003 = Saradush Inn || AR5501 = Amkethran Inn */

/* Adding a special dialogue to the 25P for NPCs sent home from the Pocket Plane */
IF ~Global("c-aransenthome","GLOBAL",1) Global("KickedOut","LOCALS",1)~ THEN BEGIN c-rejoinfromamn
  SAY ~[ARAN] Aye then, <CHARNAME>. What's th' word? You need me?~
  ++ ~[PC] Yes, come with me, Aran.~ DO ~SetGlobal("c-aransenthome","GLOBAL",0) SetGlobal("KickedOut","LOCALS",0) JoinParty()~ EXIT
  + ~RandNum(3,1)~ + ~[PC] Actually, wait here awhile longer, Aran. I need you close by.~ DO ~SetGlobal("c-aransenthome","GLOBAL",0)~ + c-aranwaitherepp1
  + ~RandNum(3,2)~ + ~[PC] Actually, wait here awhile longer, Aran. I need you close by.~ DO ~SetGlobal("c-aransenthome","GLOBAL",0)~ + c-aranwaitherepp2
  + ~RandNum(3,3)~ + ~[PC] Actually, wait here awhile longer, Aran. I need you close by.~ DO ~SetGlobal("c-aransenthome","GLOBAL",0)~ + c-aranwaitherepp3
END

/* Pocketplane Rejoin */
IF ~Global("KickedOut","LOCALS",1) AreaCheck("AR4500")~ THEN BEGIN c-aranbootedout
  SAY ~Aye, I am listenin'. Do you want me along? There's naught to do here worth doin'.~
  ++ ~Come on, Aran. We are off to have yet another battle.~ DO ~JoinParty()~ EXIT
  ++ ~Not right now, thanks.~ + c-aranwaitspp
END

/* Saradush or Amkethran Rejoin */
IF ~Global("KickedOut","LOCALS",1) OR(2) AreaCheck("AR5003") AreaCheck("AR5501")~ THEN BEGIN c-aranrejoin
  SAY ~I can keep myself a mite busy by drinkin', here, but I'd rather be fightin' alongside you. Take me along?~ 
  ++ ~Of course. Join up, so we can go save the world.~ DO ~SetGlobal("KickedOut","LOCALS",0) JoinParty()~ EXIT
  ++ ~Not right now. I might be back later, though.~ + c-aranrejoin1
  ++ ~[PC] I am sending you back to the Pocket Plane, Aran. I need you there right now.~ DO ~ActionOverride("c-aran",SetGlobal("KickedOut","LOCALS",1)) 
  ActionOverride("c-aran",SetLeavePartyDialogFile()) 
  ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) 
  ActionOverride("c-aran",LeaveParty())
  ActionOverride("c-aran",GivePartyAllEquipment())
  ActionOverride("c-aran",MakeGlobal())
  Wait(1)
  CreateVisualEffectObject("SPDIMNDR","c-aran")
  Wait(4)
  MoveGlobal("AR4500","c-aran",[1999.1228])~ EXIT
END

/* Any Other Area Rejoin */
IF ~Global("KickedOut","LOCALS",1) !AreaCheck("AR5003") !AreaCheck("AR5501") !AreaCheck("AR4500")~ THEN BEGIN c-aranrejoin
  SAY ~Right, then. There you are. There's naught for me to do here, an' I'd rather be fightin' alongside you. Take me along?~ 
  ++ ~Of course. Join up, so we can go save the world.~ DO ~SetGlobal("KickedOut","LOCALS",0) JoinParty()~ EXIT
  ++ ~Not right now. I might be back later, though. Stay right here and wait for me.~ + c-aranrejoin2
  + <<POSSIBLE_TO_LEAVE>> + ~Why don't you find a good inn and wait for us there? Perhaps in Saradush?~ + c-aranwaitsaradush
  + <<IMPOSSIBLE_TO_LEAVE>> + ~Why don't you find a good inn and wait for us there? Perhaps in Saradush?~ + c-araninnimpossible
  + <<POSSIBLE_TO_LEAVE>> + ~Why don't you find a good inn and wait for us there? I hear there is a good inn somewhere around Amkethran...~ + c-aranwaitsamkethran
  + <<IMPOSSIBLE_TO_LEAVE>> + ~Why don't you find a good inn and wait for us there? I hear there is a good inn somewhere around Amkethran...~ + c-araninnimpossible
  ++ ~[PC] I am sending you back to the Pocket Plane, Aran. I need you there right now.~ DO ~ActionOverride("c-aran",SetGlobal("KickedOut","LOCALS",1)) 
  ActionOverride("c-aran",SetLeavePartyDialogFile()) 
  ActionOverride("c-aran",ChangeAIScript("",DEFAULT)) 
  ActionOverride("c-aran",LeaveParty())
  ActionOverride("c-aran",GivePartyAllEquipment())
  ActionOverride("c-aran",MakeGlobal())
  Wait(1)
  CreateVisualEffectObject("SPDIMNDR","c-aran")
  Wait(4)
  MoveGlobal("AR4500","c-aran",[1999.1228])~ EXIT
END

IF ~~ c-aranwaitspp
  SAY ~Bane's Bones, I'd much rather fight a bit than sit around with a stick up my arse. But you call th' shots, <CHARNAME>. I'll be here when you need me.~
  IF ~~ THEN EXIT
END

IF ~~  c-aranwaitsaradush
  SAY ~Fine. I'll be waitin' at the pub in Saradush, when you need me.~
  IF ~~ THEN DO ~SetGlobal("KickedOut","LOCALS",1) EscapeAreaMove("AR5003",####,####,#)~ EXIT
END

IF ~~  c-aranwaitsamkethran
  SAY ~Fine. I'll be waitin' at the pub in Amkethran, when you need me.~
  IF ~~ THEN DO ~SetGlobal("KickedOut","LOCALS",1) EscapeAreaMove("AR5501",####,####,#)~ EXIT
END

IF ~~ THEN BEGIN c-aranrejoin1
  SAY ~Right, then. I'll just wait. The barmaid looks pretty fetchin' anyways.~
  IF ~~ THEN EXIT
END

IF ~~ THEN BEGIN c-aranrejoin2
  SAY ~Right, then. I'll just wait. Didn't want to go on no Shar-kissed adventure, nohow. I'll go take a blighted nap an' be done wi' it.~
  IF ~~ THEN EXIT
END

IF ~~ c-aranwaitherepp1
  SAY [ARAN] Aye, I'll wait. Tyr's Eye, I left th' blighted rolls o' silk behind. I had in mind to live like a king this time. Guess th' old bedroll will just have to do.~
  IF ~~ THEN EXIT
END

IF ~~ c-aranwaitherepp2
  SAY [ARAN] Aye, I'll wait. Mask's Left hand, I left th' blighted cookin' spices behind. Oh well - there'll be some opportunity to restock sometime, I suppose.~
  IF ~~ THEN EXIT
END

IF ~~ c-aranwaitherepp3
  SAY [ARAN] Aye, I'll wait. By the way, I'm feelin' a bit nekkid, an' all, on account o' bein' swooped up here wi' naught for gear. Lend a lad a sword, please, eh?~
  IF ~~ THEN EXIT
END

/* Impossible to go to an inn from here */
IF ~~ c-araninnimpossible
  SAY [ARAN] Aye, that would be a nice trick, now wouldn't it. I'd oblige, if I could, but you know right well I can't leave here alone. Enough wi' th' jokes, eh?~
  IF ~~ THEN EXIT
END

END // of append to c-arn25p


If anyone has good landing coordinates for PocketPlane and the two inns that would be nice, as I am working without a net most days (building this stuff without an install present, filling in open time here and there with no access to working files).

Notes: It would probably be smart to put a "Not In Watcher's Keep" check on the send-to-an-inn possibilities, or other places that are inaccessible. Unfortunately, I am not familiar enough with ToB to have all them off the top of my head.
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 08 October 2011 - 08:20 AM

Reworked and revamped joining/leaving dialogs to deal with journal entries and make things more tightly tailored to the game. Way overkill, seeing as most folks just join or leave, but it was fun to see if I could get more areas put into the journal and try for a different join/leave conversation each time (8 general ones progressively, plus randomness built into the mix, plus being able to send him on to other places, etc.)

latest code here: https://github.com/c...4f0e3d2b2cadedd
I love deadlines. I love the whooshing noise they make as they go by. - Douglas Adams



Reply to this topic



  



Also tagged with one or more of these keywords: dialog coding, chain, dialog states, tutorial, post-joined, npc, kicked-out dialog, aran whitehand

1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users