Jump to content


Photo

BG2: RandomNum conditioned


  • Please log in to reply
3 replies to this topic

#1 Bardess

Bardess

    the Eternal Noob

  • Modder
  • 483 posts

Posted 12 October 2008 - 04:54 AM

Again, I'm asking if there is a clean way to resolve this (as an alternative to my 6 blocks of code for just 3 different NPC lines).

Case#1:
I have 8 different responses for a PC-initiated flirt, but one of them will only appear if PC is a halfling. When I code that option with RandomNum(8,*) and playtest with a human, every 8th time, the option doesn't appear in the menu. I could write 2 blocks for that one flirt, one for a halfling, which would have 8 responses, and one for !halfling, with 7, but is there another way?

Case#2:
Random NPC-initiated flirts. I don't really want them to repeat, at least until the player has seen them all. But when I code them with RandomNum, it sometimes reports "no valid replies or links". I believe the code below would make it do what I wanted (or not), but it looks silly, how much of it there is.

IF ~RandomNum(3,1) GlobalLT("Z_Lovetalk","GLOBAL",10) Global("Z_FiRFlirt1","LOCALS",0)~ THEN DO ~SetGlobal("Z_FiRFlirt1","LOCALS",1)~ GOTO FlirtEarly1
IF ~RandomNum(3,2) GlobalLT("Z_Lovetalk","GLOBAL",10) Global("Z_FiRFlirt2","LOCALS",0)~ THEN DO ~SetGlobal("Z_FiRFlirt2","LOCALS",1)~ GOTO FlirtEarly2
IF ~RandomNum(3,3) GlobalLT("Z_Lovetalk","GLOBAL",10) Global("Z_FiRFlirt3","LOCALS",0)~ THEN DO ~SetGlobal("Z_FiRFlirt3","LOCALS",1)~ GOTO FlirtEarly3

IF ~RandomNum(2,1) GlobalLT("Z_Lovetalk","GLOBAL",10) Global("Z_FiRFlirt1","LOCALS",1) Global("Z_FiRFlirt2","LOCALS",0)~ THEN DO ~SetGlobal("Z_FiRFlirt2","LOCALS",1)~ GOTO FlirtEarly2
IF ~RandomNum(2,2) GlobalLT("Z_Lovetalk","GLOBAL",10) Global("Z_FiRFlirt1","LOCALS",1) Global("Z_FiRFlirt3","LOCALS",0)~ THEN DO ~SetGlobal("Z_FiRFlirt3","LOCALS",1)~ GOTO FlirtEarly3

IF ~RandomNum(2,1) GlobalLT("Z_Lovetalk","GLOBAL",10) Global("Z_FiRFlirt2","LOCALS",1) Global("Z_FiRFlirt1","LOCALS",0)~ THEN DO ~SetGlobal("Z_FiRFlirt1","LOCALS",1)~ GOTO FlirtEarly1
IF ~RandomNum(2,2) GlobalLT("Z_Lovetalk","GLOBAL",10) Global("Z_FiRFlirt2","LOCALS",1) Global("Z_FiRFlirt3","LOCALS",0)~ THEN DO ~SetGlobal("Z_FiRFlirt3","LOCALS",1)~ GOTO FlirtEarly3

IF ~RandomNum(2,1) GlobalLT("Z_Lovetalk","GLOBAL",10) Global("Z_FiRFlirt3","LOCALS",1) Global("Z_FiRFlirt1","LOCALS",0)~ THEN DO ~SetGlobal("Z_FiRFlirt1","LOCALS",1)~ GOTO FlirtEarly1
IF ~RandomNum(2,2) GlobalLT("Z_Lovetalk","GLOBAL",10) Global("Z_FiRFlirt3","LOCALS",1) Global("Z_FiRFlirt2","LOCALS",0)~ THEN DO ~SetGlobal("Z_FiRFlirt2","LOCALS",1)~ GOTO FlirtEarly2

IF ~GlobalLT("Z_Lovetalk","GLOBAL",10) Global("Z_FiRFlirt2","LOCALS",1) Global("Z_FiRFlirt3","LOCALS",1) Global("Z_FiRFlirt1","LOCALS",0)~ THEN DO ~SetGlobal("Z_FiRFlirt1","LOCALS",1)~ GOTO FlirtEarly1
IF ~GlobalLT("Z_Lovetalk","GLOBAL",10) Global("Z_FiRFlirt1","LOCALS",1) Global("Z_FiRFlirt2","LOCALS",1) Global("Z_FiRFlirt3","LOCALS",0)~ THEN DO ~SetGlobal("Z_FiRFlirt3","LOCALS",1)~ GOTO FlirtEarly3
IF ~GlobalLT("Z_Lovetalk","GLOBAL",10) Global("Z_FiRFlirt1","LOCALS",1) Global("Z_FiRFlirt3","LOCALS",1) Global("Z_FiRFlirt2","LOCALS",0)~ THEN DO ~SetGlobal("Z_FiRFlirt2","LOCALS",1)~ GOTO FlirtEarly2

IF ~RandomNum(3,1) GlobalLT("Z_Lovetalk","GLOBAL",10) Global("Z_FiRFlirt1","LOCALS",1) Global("Z_FiRFlirt2","LOCALS",1) Global("Z_FiRFlirt3","LOCALS",1)~ GOTO FlirtEarly1
IF ~RandomNum(3,2) GlobalLT("Z_Lovetalk","GLOBAL",10) Global("Z_FiRFlirt1","LOCALS",1) Global("Z_FiRFlirt2","LOCALS",1) Global("Z_FiRFlirt3","LOCALS",1)~ GOTO FlirtEarly2
IF ~RandomNum(3,3) GlobalLT("Z_Lovetalk","GLOBAL",10) Global("Z_FiRFlirt1","LOCALS",1) Global("Z_FiRFlirt2","LOCALS",1) Global("Z_FiRFlirt3","LOCALS",1)~ GOTO FlirtEarly3

Am I missing a better way?
(Because it has always annoyed me when the same flirt repeats twice+. If there isn't a nice way to avoid it, I could code them in a certain order, but would that be ok?)

"Farewell, Charname, and may Irenicus get you!"

Mazzy to Edwin:
"When science finally locates the center of the planes, I'm sure you'll be taken aback to find that you're not it."

- Author of lil one-day Moddie fox. -


#2 GeN1e

GeN1e

    A very GAR character

  • Modder
  • 1604 posts

Posted 12 October 2008 - 06:49 AM

Random NPC-initiated flirts. I don't really want them to repeat, at least until the player has seen them all.


First, the dialog
IF ~
Global("flirt","locals",1)
Global("choose_flirt","locals",2) //if we're not using a timer (see at the end of script), otherwise the matching value should be 4
~ THEN DO ~
SetGlobal("choose_flirt","locals",0)
IncrementGlobal("flirts_fired_in_total","locals",1)
SetGlobal("flirt_1_fired","locals",1)
//SetGlobal("flirt","locals",0) //if you feel uncomfortable without a strict control over variables, then include this line; the system will work fine without it, so it's not necessary (it's not used as a condition in the script, and it will be reset by randomizator, so the previous value won't haunt you) 
~ GOTO Flirt_1_node

IF ~
Global("flirt","locals",2)
Global("choose_flirt","locals",2) //if we're not using a timer, you know the rest
~ THEN DO ~
SetGlobal("choose_flirt","locals",0)
IncrementGlobal("flirts_fired_in_total","locals",1)
SetGlobal("flirt_2_fired","locals",2)
//SetGlobal("flirt","locals",0) //if you feel uncomfortable...
~ GOTO Flirt_2_node

IF ~
Global("flirt","locals",3)
Global("choose_flirt","locals",2)
~ THEN DO ~
SetGlobal("choose_flirt","locals",0)
IncrementGlobal("flirts_fired_in_total","locals",1)
SetGlobal("flirt_3_fired","locals",3)
//SetGlobal("flirt","locals",0)
~ GOTO Flirt_3_node

...

IF ~
Global("flirt","locals",20)
Global("choose_flirt","locals",2)
~ THEN DO ~
SetGlobal("choose_flirt","locals",0)
IncrementGlobal("flirts_fired_in_total","locals",1)
SetGlobal("flirt_20_fired","locals",20)
//SetGlobal("flirt","locals",0)
~ GOTO Flirt_20_node

As you can see, the trick here is to SetGlobal("flirt_%number%_fired","locals",%number%), the value that responds to variable's name.
IncrementGlobal("flirts_fired_in_total","locals",1) can eventually bring the value well over 1000, but even if it will I doubt it can cause troubles
Now, the script assigned to NPC

//randomly selecting a flirt
IF
Global("choose_flirt","locals",0)
THEN
RESPONSE #100
SetGlobal("flirt","locals",1)
SetGlobal("choose_flirt","locals",1)
RESPONSE #100
SetGlobal("flirt","locals",2)
SetGlobal("choose_flirt","locals",1)
RESPONSE #100
SetGlobal("flirt","locals",3)
SetGlobal("choose_flirt","locals",1)
...
RESPONSE #100
SetGlobal("flirt","locals",20)
SetGlobal("choose_flirt","locals",1)
END

//check for the flirt been already triggered
IF //if it was triggered
GlobalLT("flirts_fired_in_total","locals",20) //if there are not triggered yet flirts remaining
Global("choose_flirt","locals",1)
OR(20)
LocalsEqual("flirt","flirt_1_fired")
LocalsEqual("flirt","flirt_2_fired")
LocalsEqual("flirt","flirt_3_fired")
...
LocalsEqual("flirt","flirt_20_fired")
THEN
RESPONSE #100
SetGlobal("choose_flirt","locals",0) //go back to random selecting, repeating the circle until we're lucky
END

IF //if it wasn't
GlobalLT("flirts_fired_in_total","locals",20)
Global("choose_flirt","locals",1)
!LocalsEqual("flirt","flirt_1_fired") //yes, no OR() here
!LocalsEqual("flirt","flirt_2_fired")
!LocalsEqual("flirt","flirt_3_fired")
...
!LocalsEqual("flirt","flirt_20_fired")
THEN
RESPONSE #100
SetGlobal("choose_flirt","locals",2) //it's okay to proceed now
END

//if we have already seen every flirttalk, then there is no need to check, we simply approve the choice of selector
IF
GlobalGT("flirts_fired_in_total","locals",19)
Global("choose_flirt","locals",1)
THEN
RESPONSE #100
SetGlobal("choose_flirt","locals",2)
END

//setting a timer, if we need it
IF
Global("choose_flirt","locals",2)
THEN
RESPONSE #100
SetGlobalTimer("flirt_timer","locals",600)
SetGlobal("choose_flirt","locals",3)
END

IF
GlobalTimerExpired("flirt_timer","locals")
Global("choose_flirt","locals",3)
THEN
RESPONSE #100
SetGlobal("choose_flirt","locals",4)
END


EDIT

Fixing typos in dialog:
1) GO TO to GOTO
2) IncrementGlobal("flirt_fired_in_total","locals",1) to IncrementGlobal("flirts_fired_in_total","locals",1)

Standartizing the code

Edited by GeN1e, 12 October 2008 - 07:56 AM.

Retired from modding.


#3 GeN1e

GeN1e

    A very GAR character

  • Modder
  • 1604 posts

Posted 12 October 2008 - 08:19 AM

I could write 2 blocks for that one flirt, one for a halfling, which would have 8 responses, and one for !halfling, with 7

Do you mean the:

~RandomNum(8,1)~
~RandomNum(8,2)~
~RandomNum(8,3)~
~RandomNum(8,4)~
~RandomNum(8,5)~
~RandomNum(8,6)~
~RandomNum(8,7)~
~RandomNum(8,8)
Race(Player1,HUMAN)~
~RandomNum(8,8)
Race(Player1,HALFING)~

It's far easier to fork dialog branches near the top, rather than the base. I can think of no better way than this, so that's what I'd do (and did for Aurora).

I hope it will help.

Retired from modding.


#4 Bardess

Bardess

    the Eternal Noob

  • Modder
  • 483 posts

Posted 12 October 2008 - 08:49 AM

Looks like everything's workin now. Thank you! ^o^

I've just tested the NPC-initiated flirts, and they're looking right. Though it took me a while to figure the system by which that script works. :blush:
And the PC menu compiled correctly, so I guess that's that. Yay. ^_^

"Farewell, Charname, and may Irenicus get you!"

Mazzy to Edwin:
"When science finally locates the center of the planes, I'm sure you'll be taken aback to find that you're not it."

- Author of lil one-day Moddie fox. -