Author Topic: IWD1 scripting style: interjections  (Read 6243 times)

Offline Kulyok

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 6253
  • Gender: Female
  • The perfect moment is now.
IWD1 scripting style: interjections
« on: January 15, 2008, 01:14:41 PM »
I decided to check some interjections I've written for IWD NPC, and I hit a major problem. Most of the states in IWD are states with replies:

(1)

Peasant: Well, there's been sighting of some goblins and such in the Pass, if you can believe that.
1. I see.  I wanted to ask you some other things about Easthaven. -> THINGS
2. Farewell. -> EXIT

So, I'd like to add some interjections in these, so it'd read as:

(2)

Peasant: Well, there's been sighting of some goblins and such in the Pass, if you can believe that.
NPC: Oh dear. I must interject now.
Peasant: Indeed. Tsk, tsk.
1. I see.  I wanted to ask you some other things about Easthaven. -> THINGS
2. Farewell. -> EXIT

However, when I do so, I get a very unpleasant thingy: NPC's line doesn't show, I get dialogue (1) on the screen instead of dialogue (2), but there's a "CONTINUE" button on the bottom, and if I click it, I see

NPC: Oh dear. I must interject now.
1. I see.  I wanted to ask you some other things about Easthaven. -> THINGS
2. Farewell. -> EXIT

... and I see "CONTINUE" button again on the bottom(together with the replies), and when I press it, I get

Peasant: Indeed. Tsk, tsk.
1. I see.  I wanted to ask you some other things about Easthaven. -> THINGS
2. Farewell. -> EXIT

- which is not what I want at all. :(

I mean, I_C_T(or INTERJECT and COPY_TRANS at the end - same thing) used to work perfectly in BG2. In IWD, though, I really have no idea what's happening(and how to make it work). Help?

Offline jcompton

  • Niche Exploiter
  • Administrator
  • Planewalker
  • *****
  • Posts: 7246
Re: IWD1 scripting style: interjections
« Reply #1 on: January 15, 2008, 02:29:11 PM »
The first thing to do is to examine the resulting dialogues in NI/InfExp/WeiDU decompile and see if you're getting what you expect and the engine is just interpreting your triggers and externs "wrong" somehow, or if I_C_T is behaving differently for IWD than it does for BG2, at which point you ask the bigg to look at differences between IWD and BG2 DLG structure.
Cespenar says, "Kelsey and friends be at the Pocket Plane? Ohhh yesssss!" http://www.pocketplane.net

Offline Kulyok

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 6253
  • Gender: Female
  • The perfect moment is now.
Re: IWD1 scripting style: interjections
« Reply #2 on: January 15, 2008, 02:37:16 PM »
I have already, and, yes, in IE everything looks as it should. (And, yes, I dearly hope the bigg takes a look at this topic.)

Offline jcompton

  • Niche Exploiter
  • Administrator
  • Planewalker
  • *****
  • Posts: 7246
Re: IWD1 scripting style: interjections
« Reply #3 on: January 15, 2008, 02:45:39 PM »
All the same, I suggest you do this:

Write a simple interject which creates this problem in IWD

Compile it to IWD and to BG2 (changing the DLG name only, as needed)

Decompile the relevant DLGs from the two games and look very carefully at the generated code for the before-during-after states (may as well post them all here.)
Cespenar says, "Kelsey and friends be at the Pocket Plane? Ohhh yesssss!" http://www.pocketplane.net

Offline Kulyok

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 6253
  • Gender: Female
  • The perfect moment is now.
Re: IWD1 scripting style: interjections
« Reply #4 on: January 15, 2008, 02:56:37 PM »
IWD

I_C_T DTOWNGEN 33 O#KarinDTOWNGEN33
== O#KARIN IF ~InParty("O#Karin") Range("O#Karin",60)~ THEN ~When you do, it may be too late.~
== DTOWNGEN IF ~InParty("O#Karin") Range("O#Karin",60)~ THEN ~Don't tell me you believed it, too.  Orcs in Easthaven!  Ha!~
END

DTOWNGEN:

IF ~~ THEN BEGIN 33 // from: 0.1
  SAY #7473 /* ~Well, there's been sighting of some goblins and such in the Pass, if you can believe that.  They usually hole up in the Spine of the World and kill each other.  Some fool claimed he even saw some orcs outside of town, but I'll wait until he sobers up before giving *that* tale any weight. ~ */
  IF ~~ THEN REPLY #7449 /* ~I see.  I wanted to ask you some other things about Easthaven.~ */ GOTO 0
  IF ~~ THEN REPLY #376 /* ~I must take my leave.  Farewell.~ */ EXIT
  IF ~Global("O#KarinDTOWNGEN33","GLOBAL",0)
InParty("O#Karin")
Range("O#Karin",60)
~ THEN DO ~SetGlobal("O#KarinDTOWNGEN33","GLOBAL",1)~ EXTERN ~O#KARIN~ 192
END

O#KARIN:

IF ~~ THEN BEGIN 192 // from:
  SAY #35061 /* ~When you do, it may be too late.~ */
  IF ~~ THEN REPLY #7449 /* ~I see.  I wanted to ask you some other things about Easthaven.~ */ EXTERN ~DTOWNGEN~ 0
  IF ~~ THEN REPLY #376 /* ~I must take my leave.  Farewell.~ */ EXIT
  IF ~InParty("O#Karin")
Range("O#Karin",60)
~ THEN EXTERN ~DTOWNGEN~ 65
END

DTOWNGEN:

IF ~~ THEN BEGIN 65 // from:
  SAY #35627 /* ~Don't tell me you believed it, too.  Orcs in Easthaven!  Ha!~ */
  IF ~~ THEN REPLY #7449 /* ~I see.  I wanted to ask you some other things about Easthaven.~ */ GOTO 0
  IF ~~ THEN REPLY #376 /* ~I must take my leave.  Farewell.~ */ EXIT
END

BG2

I_C_T GORAPR 0 O#XanApprentice2
== O#XAN25J IF ~InParty("O#Xan") InMyArea("O#Xan") !StateCheck("O#Xan",CD_STATE_NOTVALID) GlobalGT("Chapter","GLOBAL",7)~ THEN ~We are not your torturers, boy. Lie still, and - ~
== O#XAN25J IF ~InParty("O#Xan") InMyArea("O#Xan") !StateCheck("O#Xan",CD_STATE_NOTVALID) GlobalGT("Chapter","GLOBAL",7)~ THEN ~No. Too late...~
== GORAPR IF ~InParty("O#Xan") InMyArea("O#Xan") !StateCheck("O#Xan",CD_STATE_NOTVALID) GlobalGT("Chapter","GLOBAL",7)~ THEN ~Yes, I am dying... and I want to die in peace. Please...~
END

GORAPR:

IF ~True()
~ THEN BEGIN 0 // from: 1.1
  SAY #62880 /* ~No... no more.  Have mercy.  I will never tell you.  Please... just let me die.~ */
  IF ~~ THEN REPLY #62881 /* ~I am not here to hurt you.  I'm here to help.~ */ GOTO 1
  IF ~~ THEN REPLY #62882 /* ~Never tell me what?  What are you talking about?~ */ GOTO 1
  IF ~~ THEN REPLY #62884 /* ~I want answers - NOW!  ~ */ GOTO 1
  IF ~Global("O#XanApprentice2","GLOBAL",0)
InParty("O#Xan")
InMyArea("O#Xan")
!StateCheck("O#Xan",CD_STATE_NOTVALID)
GlobalGT("Chapter","GLOBAL",7)
~ THEN DO ~SetGlobal("O#XanApprentice2","GLOBAL",1)~ EXTERN ~O#XAN25J~ 37
  IF ~Global("O#XanApprentice2","GLOBAL",0)
InParty("O#Xan")
InMyArea("O#Xan")
!StateCheck("O#Xan",CD_STATE_NOTVALID)
GlobalLT("Chapter","GLOBAL",8)
~ THEN DO ~SetGlobal("O#XanApprentice2","GLOBAL",1)~ EXTERN ~O#XANJ~ 2903
END

O#XAN25J:

IF ~~ THEN BEGIN 37 // from:
  SAY #91318 /* ~We are not your torturers, boy. Lie still, and - ~ */
  IF ~~ THEN REPLY #62881 /* ~I am not here to hurt you.  I'm here to help.~ */ EXTERN ~GORAPR~ 1
  IF ~~ THEN REPLY #62882 /* ~Never tell me what?  What are you talking about?~ */ EXTERN ~GORAPR~ 1
  IF ~~ THEN REPLY #62884 /* ~I want answers - NOW!  ~ */ EXTERN ~GORAPR~ 1
  IF ~InParty("O#Xan")
InMyArea("O#Xan")
!StateCheck("O#Xan",CD_STATE_NOTVALID)
GlobalGT("Chapter","GLOBAL",7)
~ THEN EXTERN ~GORAPR~ 18
  IF ~InParty("O#Xan")
InMyArea("O#Xan")
!StateCheck("O#Xan",CD_STATE_NOTVALID)
GlobalGT("Chapter","GLOBAL",7)
~ THEN GOTO 38
END

IF ~~ THEN BEGIN 38 // from: 37.4
  SAY #91319 /* ~No. Too late...~ */
  IF ~~ THEN REPLY #62881 /* ~I am not here to hurt you.  I'm here to help.~ */ EXTERN ~GORAPR~ 1
  IF ~~ THEN REPLY #62882 /* ~Never tell me what?  What are you talking about?~ */ EXTERN ~GORAPR~ 1
  IF ~~ THEN REPLY #62884 /* ~I want answers - NOW!  ~ */ EXTERN ~GORAPR~ 1
  IF ~InParty("O#Xan")
InMyArea("O#Xan")
!StateCheck("O#Xan",CD_STATE_NOTVALID)
GlobalGT("Chapter","GLOBAL",7)
~ THEN EXTERN ~GORAPR~ 18
END

GORAPR:


IF ~~ THEN BEGIN 18 // from:
  SAY #91320 /* ~Yes, I am dying... and I want to die in peace. Please...~ */
  IF ~~ THEN REPLY #62881 /* ~I am not here to hurt you.  I'm here to help.~ */ GOTO 1
  IF ~~ THEN REPLY #62882 /* ~Never tell me what?  What are you talking about?~ */ GOTO 1
  IF ~~ THEN REPLY #62884 /* ~I want answers - NOW!  ~ */ GOTO 1
END

IF ~~ THEN BEGIN 19 // from:
  SAY #91320 /* ~Yes, I am dying... and I want to die in peace. Please...~ */
  IF ~~ THEN REPLY #62881 /* ~I am not here to hurt you.  I'm here to help.~ */ GOTO 1
  IF ~~ THEN REPLY #62882 /* ~Never tell me what?  What are you talking about?~ */ GOTO 1
  IF ~~ THEN REPLY #62884 /* ~I want answers - NOW!  ~ */ GOTO 1
END

Offline Kulyok

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 6253
  • Gender: Female
  • The perfect moment is now.
Re: IWD1 scripting style: interjections
« Reply #5 on: January 15, 2008, 02:58:05 PM »
The one in BG2 works as it should, the one in IWD doesn't.

Offline Kulyok

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 6253
  • Gender: Female
  • The perfect moment is now.
Re: IWD1 scripting style: interjections
« Reply #6 on: January 15, 2008, 03:14:09 PM »
(I decided to try EXTEND_TOP+COPY_TRANS instead, and, predictably, the end result was the same. Weidu still evaluates from bottom to top):


EXTEND_TOP DTOWNGEN 33
IF ~InParty("O#Karin") Range("O#Karin",60) Global("O#KarinDTOWNGEN33","GLOBAL",0)~ EXTERN O#KARIN O#Ktempcheck
END

CHAIN O#KARIN O#Ktempcheck
~When you do, it may be too late.~
DO ~SetGlobal("O#KarinDTOWNGEN33","GLOBAL",1)~
// == DTOWNGEN ~Don't tell me you believed it, too.  Orcs in Easthaven!  Ha!~
END
COPY_TRANS DTOWNGEN 33

Offline jcompton

  • Niche Exploiter
  • Administrator
  • Planewalker
  • *****
  • Posts: 7246
Re: IWD1 scripting style: interjections
« Reply #7 on: January 15, 2008, 03:17:16 PM »
Weidu still evaluates from bottom to top

It's not WeiDU that evaluates from bottom to top, it's the game engine.

Anyway, I unfortunately suspect that you have run into a limitation of IWD for this type of dialogue construction, but hopefully someone else will chance by and point out some mysterious workaround for IWD DLG.
Cespenar says, "Kelsey and friends be at the Pocket Plane? Ohhh yesssss!" http://www.pocketplane.net

Offline berelinde

  • Planewalker
  • *****
  • Posts: 1188
  • Gender: Female
    • Gavin, cleric of Lathander, for Tutu
Re: IWD1 scripting style: interjections
« Reply #8 on: January 15, 2008, 06:19:59 PM »
Domi ran into the same problem with IWD2. I_C_T didn't work. I think she got around it by using a combination of A_T_Ts and EXTEND_BOTTOMs, with a few INTERJECTs thrown in. Honestly, though, she really did have to do some pretty clunky work-arounds for it.

Offline Kulyok

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 6253
  • Gender: Female
  • The perfect moment is now.
Re: IWD1 scripting style: interjections
« Reply #9 on: January 16, 2008, 01:18:11 AM »
That's what I've been thinking about, as well.  Maybe there is a workaround, though.

Offline CamDawg

  • Infidel
  • Planewalker
  • *****
  • Posts: 859
  • Dreaming of a red Xmas
    • The Gibberlings Three
Re: IWD1 scripting style: interjections
« Reply #10 on: January 16, 2008, 05:42:06 AM »
Domi ran into the same problem with IWD2. I_C_T didn't work. I think she got around it by using a combination of A_T_Ts and EXTEND_BOTTOMs, with a few INTERJECTs thrown in. Honestly, though, she really did have to do some pretty clunky work-arounds for it.
Back in my day, we didn't have no fancypants I_C_T. We used E_B and C_T and we liked it.  </grumpy old man>
The Gibberlings Three - Home of IE Mods

The BG2 Fixpack - All the fixes of Baldurdash, plus a few hundred more. Now available, with more fixes being added in every release.

Offline CoM_Solaufein

  • CoM Founder
  • Planewalker
  • *****
  • Posts: 184
  • Gender: Male
  • War is Peace, Freedom is Slavery, Ignorance is Strength
    • Chosen of Mystra
Re: IWD1 scripting style: interjections
« Reply #11 on: January 16, 2008, 07:20:02 AM »
Back in my day we just over write the damn thing and call it good.

Offline Kulyok

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 6253
  • Gender: Female
  • The perfect moment is now.
Re: IWD1 scripting style: interjections
« Reply #12 on: January 16, 2008, 10:46:07 AM »
Okay, ADD_TRANS_TRIGGER may work, thought I. But then, since an interjection can only trigger if InParty(NPC) and Range(NPC,60)  (InMyArea doesn't work in IWD, either), I have to write an ADD_TRANS TRIGGER with
OR(2) !InParty(NPC) !Range(NPC,60)

Now guess what?

Icewind Dale doesn't have the OR() command. Ever. And two A_T_T in a row won't work, either, since I'll need to have OR() in the character's replies. *And* I need to set a variable and use it in A_T_T, as well. In short, it won't work. :(

Offline jcompton

  • Niche Exploiter
  • Administrator
  • Planewalker
  • *****
  • Posts: 7246
Re: IWD1 scripting style: interjections
« Reply #13 on: January 16, 2008, 11:58:27 AM »
Then just have people interject even if they're not in the party. It's not the end of the world.
Cespenar says, "Kelsey and friends be at the Pocket Plane? Ohhh yesssss!" http://www.pocketplane.net

Offline Kulyok

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 6253
  • Gender: Female
  • The perfect moment is now.
Re: IWD1 scripting style: interjections
« Reply #14 on: January 16, 2008, 12:07:52 PM »
That won't work, I'm afraid:

- even InParty aside, I need at least a Range check(if Karin is supposed to interject in the Temple, but he is, in fact, outside, the game will crash), and a Global varaible check(otherwise these replies will never become available). So I need at least this structure:

Peasant: Well, there's been sighting of some goblins and such in the Pass, if you can believe that.
(EITHER Karin's not here, OR his interjection has already happened) 1. I see.  I wanted to ask you some other things about Easthaven. -> THINGS
(EITHER Karin's not here, OR his interjection has already happened) 2. Farewell. -> EXIT
(Karin's here, AND his interjection hasn't happened) -> KARIN INTERJECTS

- but IWD doesn't have OR(). End of story. :(

I might just leave these interjections as they are now: a curious player will press Continue below, and others will just play as if the interjection wasn't there. Besides, it's the only way to show it right now.

Offline jcompton

  • Niche Exploiter
  • Administrator
  • Planewalker
  • *****
  • Posts: 7246
Re: IWD1 scripting style: interjections
« Reply #15 on: January 16, 2008, 12:42:02 PM »
My head may be cloudy right now, but... If you're careful about what you're doing, I dno't see why you need to check for "this interjection has already happened."

COPY_TRANS occurs before all other .D actions, including EXTEND_BOTTOM. So as long as you don't set yourself up in a loop some other way, you can use the old-style E_B/C_T construction, with Range, and not have to worry about getting stuck in one DLG.
Cespenar says, "Kelsey and friends be at the Pocket Plane? Ohhh yesssss!" http://www.pocketplane.net

Offline Kulyok

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 6253
  • Gender: Female
  • The perfect moment is now.
Re: IWD1 scripting style: interjections
« Reply #16 on: January 16, 2008, 12:56:17 PM »
Quote
My head may be cloudy right now, but... If you're careful about what you're doing, I dno't see why you need to check for "this interjection has already happened."

I have to check for "this interjection has already happened" to enable the replies again.

- to have an interjection into a state which has replies, I have to disable these replies via A_T_T.
- if I only check for NPC's presence and nothing else, I get A_T_T DTOWNGEN 33 ~!See("O#Karin")~ to all replies. Thus, if Karin *is* in the party(and his interjection shows), DTOWNGEN's replies will never be active, and we're stuck.

Offline jcompton

  • Niche Exploiter
  • Administrator
  • Planewalker
  • *****
  • Posts: 7246
Re: IWD1 scripting style: interjections
« Reply #17 on: January 16, 2008, 01:07:05 PM »
I have to check for "this interjection has already happened" to enable the replies again.

Ah, I see, you're talking about the EXTEND_TOP world.

Yeah, I think your solution is simply to tell players "look carefully and hit Continue whenever possible."
Cespenar says, "Kelsey and friends be at the Pocket Plane? Ohhh yesssss!" http://www.pocketplane.net

Offline Mike1072

  • Planewalker
  • *****
  • Posts: 298
  • Gender: Male
Re: IWD1 scripting style: interjections
« Reply #18 on: January 16, 2008, 02:22:50 PM »
Quote
My head may be cloudy right now, but... If you're careful about what you're doing, I dno't see why you need to check for "this interjection has already happened."

I have to check for "this interjection has already happened" to enable the replies again.

- to have an interjection into a state which has replies, I have to disable these replies via A_T_T.
- if I only check for NPC's presence and nothing else, I get A_T_T DTOWNGEN 33 ~!See("O#Karin")~ to all replies. Thus, if Karin *is* in the party(and his interjection shows), DTOWNGEN's replies will never be active, and we're stuck.
Is it possible to make a copy of the original lines and add different triggers to each?

!IsHere -> Copy of Line 1
!IsHere -> Copy of Line 2
IsHere AND HasHappened -> Line 1
IsHere AND HasHappened -> Line 2
IsHere AND NotHappened -> Interject

Offline Kulyok

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 6253
  • Gender: Female
  • The perfect moment is now.
Re: IWD1 scripting style: interjections
« Reply #19 on: January 16, 2008, 02:29:31 PM »
Quote
Is it possible to make a copy of the original lines and add different triggers to each?

I thought about that, but I don't think so: only by creating your own dialog.tlk, most likely.

Offline Mike1072

  • Planewalker
  • *****
  • Posts: 298
  • Gender: Male
Re: IWD1 scripting style: interjections
« Reply #20 on: January 16, 2008, 11:28:13 PM »
I really meant transitions instead of lines, but I'm way over my head here.  Hope you get it figured out!

Offline Kulyok

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 6253
  • Gender: Female
  • The perfect moment is now.
Re: IWD1 scripting style: interjections
« Reply #21 on: January 17, 2008, 01:22:35 AM »
Thanks. :) Can you imagine I've been lying awake for hours yesterday trying to figure it out? (Veeeery romantic, sure enough. )

I guess in the end, I have two solutions: leave it as it is and tell the users to watch out for continue buttons, or, indeed, A_T_T something on the existing replies, so they're available only if an NPC isn't available for the interjections, and try to add the same replies _after_ NPC interjects - which will present compatibility issues with other dialogue-changing mods for sure.  Not that there're many, though. I'll see if I can work it out as painlessly as possible.

Offline Kulyok

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 6253
  • Gender: Female
  • The perfect moment is now.
Re: IWD1 scripting style: interjections
« Reply #22 on: January 17, 2008, 07:40:31 AM »
Okay, I'm more or less prepared to do a huuge recoding, but before I do, I think I'll use my last resort and post a link in Weidu forum. :)

Offline Kulyok

  • Global Moderator
  • Planewalker
  • *****
  • Posts: 6253
  • Gender: Female
  • The perfect moment is now.
Re: IWD1 scripting style: interjections
« Reply #23 on: January 18, 2008, 04:16:13 AM »
For those curious, a working solution (one of) was found here, thanks to the_bigg.

 

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Name: Email:
Verification:
Type the letters shown in the picture
Listen to the letters / Request another image
Type the letters shown in the picture:
What color is grass?:
What is the seventh word in this sentence?:
What is five minus two (use the full word)?: