Jump to content

this NPC initiated talk


Bardess

Recommended Posts

Bardess is still a starter, so here's the new problem. This Moddie-initiated talk won't fire. She turns to the PC once, but that's all. I don't know if it is because of the lack of conditions or somethig else, but

 

Z_MODDY.BCS:

IF

GlobalTimerExpired("Z_ModdyTalks","GLOBAL")

!StateCheck(Player1,STATE_SLEEPING)

InParty(Myself)

See(Player1)

CombatCounter(0)

OR(4)

Global("Z_ModdyTalk","GLOBAL",1)

Global("Z_ModdyTalk","GLOBAL",2)

Global("Z_ModdyTalk","GLOBAL",3)

Global("Z_ModdyTalk","GLOBAL",4)

THEN

RESPONSE #100

Interact(Player1)

IncrementGlobal("Z_ModdyTalk","GLOBAL",1)

SetGlobalTimer("Z_ModdyTalks","GLOBAL",5)

END

 

 

when she joins, in Z_MODDY.d I have this

 

DO ~SetGlobal("Z_ModdyJoined","GLOBAL",1) SetGlobalTimer("Z_ModdyTalks","GLOBAL",5) SetGlobal("Z_ModdyTalk","GLOBAL",1) JoinParty()~

EXIT

 

 

the dialogue that should start (in BZ_MODDY) has these conditions:

 

CHAIN IF ~InParty("Z_Moddy")

See("Player1")

!Dead("Z_Moddy")

!StateCheck("Z_Moddy",STATE_SLEEPING)

Global("Z_ModdyTalk","GLOBAL",1)

GlobalTimerExpired("Z_ModdyTalks","GLOBAL")~ THEN BZ_MODDY ModdiePC1

~masterrr? know why moddie speak?~

 

 

I missed something important?

Link to comment

Yeah, I'm afraid you've got a lot going on here that needs to be addressed. I'll do that one step at a time so it's easier to follow.

 

The easiest thing to do with this one is start at the beginning.

 

Moddie joins the party. Presumably, you're going to have some kind of joining variable, we'll call it Global("Z_ModdyJoined","GLOBAL",1), for the purpose of this exercise.

 

You're not going to want him to start his first friendship talk the minute the joining dialogue window closes, so you're going to want to set a timer.

 

First, the clean code:

 

IF
Global("Z_ModdyJoined","GLOBAL",1)
Global("Z_ModdyTalk","GLOBAL",0)
THEN
RESPONSE #100
RealSetGlobalTimer("Z_ModdyTalks","GLOBAL",1800)
SetGlobal("Z_ModdyTalk","GLOBAL",1)
END

 

Now, the commented code, so you can see what's going on, line by line.

 

IF

//Moddy is in the party
Global("Z_ModdyJoined","GLOBAL",1)

//Moddy's friendship talks haven't been started yet, nor has the timer been set
Global("Z_ModdyTalk","GLOBAL",0)
THEN
RESPONSE #100

//setting the timer for half an hour, real time
RealSetGlobalTimer("Z_ModdyTalks","GLOBAL",1800)

//incrementing the variable keeps the script from looping. This prevents a stutter. In this case, we advance the global to show that the timer is set
SetGlobal("Z_ModdyTalk","GLOBAL",1)
END

Link to comment

Next, you're going to want your trigger block. This is what will indicate that it's time for a dialogue.

 

First the tidy code:

IF
RealGlobalTimerExpired("Z_ModdyTalks","GLOBAL")
InParty(Myself)
OR(4)
Global("Z_ModdyTalk","GLOBAL",1)
Global("Z_ModdyTalk","GLOBAL",3)
Global("Z_ModdyTalk","GLOBAL",5)
Global("Z_ModdyTalk","GLOBAL",7)
THEN
RESPONSE #100
IncrementGlobal("Z_ModdyTalk","GLOBAL",1)
END

 

Now, the commented code:

IF

//Not a bad idea to keep your naming practices consistent. GlobalTimerExpired would work, but to avoid confusion, it's best to keep your real timers and your game timers labeled with something easily identifiable, like the "Real" in the trigger or action name.
RealGlobalTimerExpired("Z_ModdyTalks","GLOBAL")

//Moddy is still in the party. I'm not including a lot of state checks, etc. in the trigger block, because he won't be interrupting anything by checking to see if the timer is expired.
InParty(Myself)

//You'll notice I've made the talks trigger on odd-numbered variables. Every time I make a move, I advance the variable. So when these trigger conditions are met, the variable will advance, signalling that the variable is open, and the talk is ready to fire.
OR(4)
Global("Z_ModdyTalk","GLOBAL",1)
Global("Z_ModdyTalk","GLOBAL",3)
Global("Z_ModdyTalk","GLOBAL",5)
Global("Z_ModdyTalk","GLOBAL",7)
THEN
RESPONSE #100

//Since this is the trigger block, I advance the variable to show that the trigger conditions have been met. This opens the variable (even number) and allows the action block to happen.
IncrementGlobal("Z_ModdyTalk","GLOBAL",1)
END

Link to comment

Your trigger conditions are met, and it's time for Moddy to talk.

 

As always, first, the clean code:

IF
OR(4)
Global("Z_ModdyTalk","GLOBAL",2)
Global("Z_ModdyTalk","GLOBAL",4)
Global("Z_ModdyTalk","GLOBAL",6)
Global("Z_ModdyTalk","GLOBAL",8)
CombatCounter(0)
!See([ENEMY])
InParty(Myself)
InMyArea(Player1)
!StateCheck(Player1,CD_STATE_NOTVALID)
!StateCheck(Myself,CD_STATE_NOTVALID)
THEN
RESPONSE #100
Interact(Player1)
END

 

And the commented code:

IF

//We advanced the variable to an even number during the trigger block, so we're going to look for the even numbered variable for the action block.
OR(4)
Global("Z_ModdyTalk","GLOBAL",2)
Global("Z_ModdyTalk","GLOBAL",4)
Global("Z_ModdyTalk","GLOBAL",6)
Global("Z_ModdyTalk","GLOBAL",8)

//Combat checks are great, but you don't want Moddy to start talking when the enemy is in sight, but not actually engaged, so the !See([ENEMY]) is necessary, too
CombatCounter(0)
!See([ENEMY])

//Moddy is in the party
InParty(Myself)

//Moddy has not been sent to wait in an abandoned building, or anything, and he can see the PC
See(Player1)

//the custom state CD_STATE_NOTVALID is a very handy state, as it covers all instances where an actor might not be able to engage in dialogue, like when he's dead, silenced, stunned, or any of a number of other condtions. It's easy to add via the tp2 code, and I'll give you that after this example.
!StateCheck(Player1,CD_STATE_NOTVALID)
!StateCheck(Myself,CD_STATE_NOTVALID)
THEN
RESPONSE #100

//start talking to player 1.
Interact(Player1)
END

 

 

tp2 code patching for the CD_STATE_NOTVALID state:

/* STATE.IDS patching - adds custom IsValidForPartyDialogue state - courtesy of CamDawg */
APPEND ~STATE.IDS~ ~0x80101FEF CD_STATE_NOTVALID~
		 UNLESS ~CD_STATE_NOTVALID~

Link to comment

Now, for the dialogue. You *really* only want one trigger condition for scripted dialogue. Having multiple ones gets messy, and cause all kinds of undesired behavior if the triggers don't match your script, like CTD.

 

CHAIN 
IF ~Global("Z_ModdyTalk","GLOBAL",2)~ THEN BZ_MODDY ModdiePC1
~masterrr? know why moddie speak?~
DO ~SetGlobal("Z_ModdyTalk","GLOBAL",3) RealSetGlobalTimer("Z_ModdyTalks","GLOBAL",1800)~

 

You may notice that I am advancing the variable again. I do this so that this dialogue remains available until the talk actually fires. This prevents talks from being dropped because the player issued a movement command when the NPC was about to start talking. I'm also setting the timer here, for the same reason.

 

Now, the trigger block will check the variable and cue the next talk, the action block will start the dialogue, and the dialogue itself will close the variable, make it available to be picked up the next time the trigger block runs, and no looping, no stutter, no dropped talks.

Link to comment

Yes! Thank you, bere, I never understood the odd- and even number thing before. Nor why a script must have three blocks for this kind of banters to be initiated. :)

 

Does a One-Day NPC need a thank you list in the ReadMe? :)

Link to comment
Yes! Thank you, bere, I never understood the odd- and even number thing before. Nor why a script must have three blocks for this kind of banters to be initiated. :)

You can get by with two script blocks, by combining the trigger block and the action block, and if you want, I can show you how.

 

But I warn you that combining the trigger and action blocks introduces the risk of dropped talks. As you are using the banter file for the friendship talks instead of the joined dialogue file for them, one dropped talk will mean that the whole dialogue sequence stops right there. You really are better off using a multi-step approach.

 

Does a One-Day NPC need a thank you list in the ReadMe? :)

You are not obligated to thank anyone, unless they specifically ask for credit, although some people appreciate it.

 

From my end, all I am doing is repeating what I have learned from other modders, especially Kulyok and Jastey, so any thanks related to talk scripting would go to them, not me :)

 

Edit: can't spell.

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...