Jump to content

Conversation between 2 npcs problem


StealthDick

Recommended Posts

Also, how exactly do I make the debug.bat? I'm not good at making executable stuff.

 

Thanks.

Create a simple text (i.e. with Notepad; not Write) file in the game root folder (where the "FalloutNV.EXE" file is located) using the Example 'enabledebugfile.txt' file as a template:

con_SCOF "_Debug.log"  # "_" is to cause the file to sort to beginning of Windows Explorer filenames
DBMode 1 61                 # '61' is 'mod index' in decimal
DBPrintC "Starting log for mod index 61(0x3D) (<mod name>) ..."

 

Just replace the example 'mod index' number "61" (and "<mod name>") with the actual one for your mod when testing. (Everything after "#" is a comment and can be omitted, or left to remind you later.) Then in the console just give the command "bat enabledebugfile" (assuming that is your filename).

 

You need to match EXACTLY the number of "if" (or Begin) statements with the appropriate "endif" (or End) statements. The same applies to the various forms of "matching" punctuation such as "(parens)", "[brackets]", "{braces}", "quotes" (single, double, or backtick), etc. This "balancing of beginning and closing statements/punctuation" is characteristic of all programming languages; generating a syntax error when out of balance. Indenting matching statements is usually needed to ensure you didn't miss one.

 

Your two "Begin SaytoDone" to the different NPCs are both running in the same frame. They are not being "gated" by any condition. Look at the GECKWiki SayToDone example again. You want a general "Talking" variable equivalent to control whether NPC1 or NPC2 is talking. Just set "Talking" to the number of whichever is speaking at the moment, and to zero when either is done, in the script where you "SayTo <speechtopic>". (That part seems to be either in yet another script or missing completely.)

 

As I interpret it, the "SayToDone" block is for some action to take by the speaker when the dialog line has been spoken. It is not appropriate when all you want to do is say a single line and wait to deliver the next line.

 

(Per 'TIP: Assigning & Testing variables' in that same section:

Note that there are only 3 blocktypes that will continually read the code lines in successive frames:

* GameMode

* MenuMode

* ScriptEffectUpdate

 

Each having specific circumstances when they are running. All other blocks (e.g. "On<Event>") are one frame occurrence events.)

 

Suggest the following reorganization. (This is <pseudo-code> rather than <actual-code>, for the purposes of explaining the logic. Portions may need to be placed in different scripts accordingly. It has not been tested.) I add variable type prefixs to ensure I don't loose track of which type/function of variable I'm using.

 

scn aaaSSSGREETERBunkerScript
; Assuming this script is called from "aaaSSSQuest" script, no need to prefix it's variables with that Ref-ID.  It's inherited.

short bFailOnce  ; this should be defined in the "aaaSSSQuest" script.  Then it can be used in scripts called by it.
short iLastSaid  ; this should be defined in the "aaaSSSQuest" script.  Then it can be used in scripts called by it.
short bDoOnce

Begin OnHit Player
if bFailOnce == 0
   setobjectivedisplayed aaaSSSQuest 12 0
   set bFailOnce to 1
endif
END

Begin Gamemode
if aaaSSSQuest.StartTalking1 == 1
; This apparently indicates <someone(Greeter?)> is supposed to initiate conversation.
   if DoOnce == 0
   ; dialog not said previously.
      SSSBunker01REF.sayto SSSBunker12REF aaaSSSGreeterToEnforcer01 1 1
      ; start this dialog sequence only once.
      set DoOnce to 1

      ;== In dialog "aaaSSSGreeterToEnforcer01 Result Script (End)" section ===
         set iLastSaid to 1 ; dialog line number
      ;== Exit dialog "aaaSSSGreeterToEnforcer01 Result Script (End)" section ===
   elseif iLastSaid == 1
   ; NOT (DoOnce == 0)
      SSSBunker12REF.sayto SSSBunker01REF aaaSSSEnforcerToGreeter01 1 1

      ;== In dialog "aaaSSSEnforcerToGreeter01 Result Script (End)" section ===
         set iLastSaid to 2 ; dialog line number
      ;== Exit dialog "aaaSSSEnforcerToGreeter01 Result Script (End)" section ===

   elseif iLastSaid == 2
      SSSBunker12REF.sayto SSSBunker01REF aaaSSSEnforcerToGreeter02 1 1

      ;== In dialog "aaaSSSEnforcerToGreeter02 Result Script (End)" section ===
         set iLastSaid to 3 ; dialog line number
      ;== Exit dialog "aaaSSSEnforcerToGreeter02 Result Script (End)" section ===

   elseif iLastSaid == 3
      SSSBunker01REF.sayto SSSBunker12REF aaaSSSGreeterToEnforcer02 1 1

      ;== In dialog "aaaSSSGreeterToEnforcer02 Result Script (End)" section ===
         set iLastSaid to 4 ; dialog line number
      ;== Exit dialog "aaaSSSGreeterToEnforcer02 Result Script (End)" section ===

   ; Repeat for as many dialog line exchanges as needed

   Else
   ; No more dialog, so cleanup as necessary.
   ; Assuming final iLastSaid number equals "evacuate" result ...
      set aaaSSSQuest.bEvacuate to 3
   endif
endif

if aaaSSSQuest.bEvacuate == 3
   .addscriptpackage aaaSSSBunkerEvacuatePackage
   set aaaSSSQuest.bEvacuate to 4
endif
if (.getincell aaaTurnerBunkerINT != 1) && (aaaSSSQuest.bEvacuate == 4)
   disable
endif

END

No need for second NPC script.

 

-Dubious-

Link to comment
Share on other sites

Dude, I f***ing love you. You've been a huge help over the course of all the questions I've asked.

 

I'm working on another part of my quest right now, but I'll give what you said a shot when I'm done!

Thank you tons!

Edited by StealthDick
Link to comment
Share on other sites

It belatedly occurs to me that an appropriate use of the "SayToDone" block in this instance would be triggered with the line of dialog that informs the player that "Now you've done it. Begone!" or the equivalent regardless of when that occurs in the dialog sequence (possibly interrupting the normal sequence). The "action" would then be starting the combat with "Enforcer", which you would only want to trigger with that specific response (and only once), eventually leading to the "Begin OnHit Player" block possibly being triggered.

 

Let me know how it goes whenever you get back to it. I'll be here.

 

-Dubious-

Link to comment
Share on other sites

I used that script you gave me and the sameish problem still persists.

scn aaaSSSGREETERBunkerScript
; Assuming this script is called from "aaaSSSQuest" script, no need to prefix it's variables with that Ref-ID.  It's inherited.

short bDoOnce


Begin Gamemode
if aaaSSSQuest.StartTalking1 == 1
; This apparently indicates <someone(Greeter?)> is supposed to initiate conversation.
   if bDoOnce == 0
   ; dialog not said previously.
      SSSBunker01REF.sayto SSSBunker12REF aaaSSSGreeterToEnforcer01 1 1
      ; start this dialog sequence only once.
      set bDoOnce to 1

   elseif aaaSSSQuest.iLastSaid == 1
      SSSBunker12REF.sayto SSSBunker01REF aaaSSSEnforcerToGreeter01 1 1


   elseif aaaSSSQuest.iLastSaid == 2
      SSSBunker01REF.sayto SSSBunker12REF aaaSSSGreeterToEnforcer02 1 1


   elseif aaaSSSQuest.iLastSaid == 3
      SSSBunker12REF.sayto SSSBunker01REF aaaSSSEnforcerToGreeter02 1 1


   ; Repeat for as many dialog line exchanges as needed

   Else

   endif
endif

if aaaSSSQuest.bEvacuate == 3
   .addscriptpackage aaaSSSBunkerEvacuatePackage
   set aaaSSSQuest.bEvacuate to 4
endif
if (.getincell aaaTurnerBunkerINT != 1) && (aaaSSSQuest.bEvacuate == 4)
   disable
endif

END

The exchange goes exactly the wame before, where the Greeter talks to the Enforcer, the enforcer skips his line, the Greeter responds to the skipped line, and then the enforcer says his skipped line.

The way the script is set up, it SHOULD work. Idk what the problem with these NPCs is.

Link to comment
Share on other sites

Are you certain "SSSBunker12REF" is the correct Ref-ID for the Enforcer? Where you define the variable "SSSBunker12REF" (in "aaaSSSQuest" presumably) have you any check (i.e. "IsReference") to verify it is a valid assignment?

 

The variable "iLastSaid" should only be equal to "3" as a result of the "Result Script (End)" statement when line 2 of dialog is spoken. That is why that variable assignment is placed there, to ensure it is only assigned once the line has been spoken. So the Enforcer should never speak the 3rd line unless the 2nd line has been spoken. IF it is getting set elsewhere, you need to track that down.

 

You want something (such as a "debug print") in the "Else" section to confirm that you got that far, whether in order or prematurely.

 

At some point you also want to set "iLastSaid" back to zero for the next conversation you want to track. I would probably place it where you set "bEvacuate to 4" as you are certain to be done with conversation at that point.

 

Sprinkle:

PrintD "iLastSaid = [" + $(iLastSaid) + "]."

statements (or the appropriate variable equivalent) after each "If/ElseIf/Else" line in that part of the script so you get confirmation that each line's section of code is being entered. That will tell you if it's the logic or the dialog statement which is failing. You may need to place them (or similar) in the dialog "Result Script" sections as well.

 

You might want to convert my comments to your own statements of what is supposed to be happening, not just to confirm for me if my surmises are correct but also so you know what you intended if you have to come back to this code in 6 months. Be generous with comments. They save you a lot of time in the long run.

 

-Dubious-

Link to comment
Share on other sites

I just have this innate feeling that there's something wrong with the characters involved with the convo, thinking about it: I feel that it would just be better if I have the Enforcer forcegreet the PC after the Greeter begins conversating with him. I'm going to play through my entire quest on a new save and get to convo again to see if maybe my save is bugging it, if not I'm just going to take the forcegreet route. This has been an ache in my side for over a week now, and I just want to be through with it lol.

Link to comment
Share on other sites

That's fine. Make a save before you start that dialog, so you can restore before any of the conversation related variables are altered. Use the "Debug mode" bat file to get printouts when you do start the dialog sequence.

 

Also, Mktavish has found that it pays to toggle "ArchiveInvalidation" at the beginning of a reloaded "save game" session. (Not clear why, but the evidence is there.) Don't forget to exit to the desktop before reloading any save, so the game environment is fully reset. Things in memory (such as script variables) can persist if you don't.

 

-Dubious-

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...