Author Topic: Eavedropping and Journal Entries  (Read 303 times)

Legacy_dr. b

  • Newbie
  • *
  • Posts: 26
  • Karma: +0/-0
Eavedropping and Journal Entries
« on: August 03, 2013, 01:29:27 pm »


               Hi all,

New here. I ran into a scripting conundrum in my module that I can't seem to solve with my limited scripting experience (usually I rely on Lilac Souls' script wizard to do everything), so I thought I'd bring the issue here.

Basically, I have two NPCs that start to banter back and forth (speaking strings of text that float above their heads) when the PC enters an area (I scripted this using Gestalt's custom functions, though it is not a true cutscene--the PC can move around, leave if he wants, or, if he gets too close, get spotted by the NPCs and get attacked). This part was pretty easy, and it makes use of an ExecuteScript function in an OnEnter event.

Here's the hard part: I want to make it so that if the PC eavesdrops on the conversation long enough, an entry will be added to the player's journal. However, if the PC leaves the conversation too early and doesn't see the pertinent line of text, the entry will not be added.

I am having trouble doing this. I have it so that when the player enters the area and the cutscene fires, he also sets an integer to 1. If the player exits the area, the integer is set to 0. I then set up a conditional so that if the integer is 1 after 80 seconds have elapsed (about the time it takes for the pertinent line to be spoken), the player gets a new journal entry. However, testing the script, I notice that even if the player leaves the area and the integer is set to 0, the journal entry gets added, which I do not want.

I see why this is happening. Setting the integer to 0 does not cancel the delaycommand journal function. I'm not sure what to do. Any suggestions?

tl;dr: I'm trying to make a script that will add an entry to the player's journal if he eavesdrops on a conversation between two NPCs for long enough. I also want to make it so the entry will not be added if he leaves too soon. How do I do this?

Thanks!
               
               

               


                     Modifié par dr. b, 03 août 2013 - 12:37 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Eavedropping and Journal Entries
« Reply #1 on: August 03, 2013, 02:46:08 pm »


               Just make a custom function to delay, instead of DelayCommanding the journal function. In it, you should check the variable and return if it's zero, and if not, add the journal entry. It should return nothing in order to be DelayCommanded, so it'll be a void-type function, like so:


void CheckAddJournalEntry(object oPC) {
    if (GetLocalInt(GetArea(oPC), "NameofVar")) {//ints interpret as FALSE if zero, TRUE otherwise
        AddJournalQuestEntry(/*your paramaters here*/);
    }
}

You would then delay this instead, like so:

DelayCommand(80.0, CheckAddJournalEntry(object oPC));

Custom functions are really pretty easy once you get the hang of them. You can declare as many variables as you need in the function's parens up top (where I just put object oPC). This would allow you to make this a more general-purpose function, if you added the vars that needed to be passed into AddJournalQuestEntry, like so:


void CheckAddJournalEntry(object oPC, string sPlotID, int nState) {
    if (GetLocalInt(GetArea(oPC), "NameofVar")) {
        AddJournalQuestEntry(sPlotID, nState, oPC);
    }
}

Funky
               
               

               
            

Legacy_dr. b

  • Newbie
  • *
  • Posts: 26
  • Karma: +0/-0
Eavedropping and Journal Entries
« Reply #2 on: August 03, 2013, 10:50:16 pm »


               Very interesting! I've never done a custom function before, so this is a learning opportunity. Thanks! '<img'>
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Eavedropping and Journal Entries
« Reply #3 on: August 04, 2013, 01:49:22 am »


               I forgot to mention that the function must be above the void main where it is called. You can achieve this just by placing it above it, or by putting it in an include file, referencing the include like so:
#include "name_of_script"

You can also just put a function declaration at the top of the script, and put the rest of the function anywhere in the script you like - above or below the void main. Function declarations can be useful for adding descriptions that pop up when you double click on a function in a script - just put your comments in //commented lines above the declaration (/* */ comments won't work properly for declarations). Like so:

//Your comments here, using as many double foward-slash lines as you like, be
//it one or a dozen. Any comments written here will pop up in the Help window when you
// double click on a function in a script. You can put spaces after the // or not as you like.
// The declaration looks just like the first line of the implementation, save that it ends in a //semicolon, as a normal line of script, instead of bracketing.
void CheckAddJournalEntry(object oPC, string sPlotID, int nState);

Funky
               
               

               
            

Legacy_dr. b

  • Newbie
  • *
  • Posts: 26
  • Karma: +0/-0
Eavedropping and Journal Entries
« Reply #4 on: August 04, 2013, 03:54:09 am »


               Yep, I know! Thanks. Actually, I am curious why the GetArea command needs to be there and what it is doing there. If I have a unique variable that sets to1 when the PC enters the area and 0 when the PC exits the area (OnEnter/OnExit), isn't that enough to make the script run its check?
               
               

               


                     Modifié par dr. b, 04 août 2013 - 03:06 .
                     
                  


            

Legacy_Rolo Kipp

  • Hero Member
  • *****
  • Posts: 4349
  • Karma: +0/-0
Eavedropping and Journal Entries
« Reply #5 on: August 04, 2013, 02:08:25 pm »


               <location, location,...>

Funky is looking for a variable you set *on the area* of the chatty NPCs.
This is a good place to set it, as it would be false for all other areas (hence no journal entry if PC is in another area when the check fires).
But it *does* mean you set the var on the area when the PC enters, not on the PC.
edit: if you are setting a local int to OBJECT_SELF in the onEnter script of the area, the area *is* where the var is being stored, so it should work fine. Alway keep in mind not only what the variable is, but where it's stored and how it was set.
Edit 2: you might want to consider storing the var on the PC, simply because it is more multiplayer friendly. I.e. the eavesdropping works per PC, instead of per area. 
Likewise, you may want to script the journal entry in the Cutscene repartee of the NPCs instead of timing it. When they get to the juicy bit, set the journal entry of every PC in range ( GetObjectInShape()). That way a whole party may benefit from their nosiness :-)

<...elocution>
               
               

               


                     Modifié par Rolo Kipp, 04 août 2013 - 01:20 .
                     
                  


            

Legacy_dr. b

  • Newbie
  • *
  • Posts: 26
  • Karma: +0/-0
Eavedropping and Journal Entries
« Reply #6 on: August 09, 2013, 12:17:47 am »


               Hi again!

Thanks so much for your helpful commentary on how to make this script work. I've been doing some coding, but I'm having a bit of trouble: the script wizard is not recognizing the custom function that I have made. I am not sure why; it could just be a simple grammatical error or typo that I can't find. I *did* make sure to add the #include line where necessary. I can show you the three scripts that I have working in conjunction with each other. Script #3 is not compling. On the DelayCommand line, I'm getting an "UNKNOWN STATE IN COMPILER" error. Any observations would be very helpful. Thanks!

First script:
“onen_cs_deserteast” (this goes in OnEnter; it executes both the cutscene script [not included here, since it is not relevant] and the custom function)

void main()
{
   object oPC = GetEnteringObject();

   if (!GetIsPC(oPC))
       { return; }

   if (GetLocalInt(oPC,"iCutsceneViewed") > 0)
       { return; }

   SetLocalInt(oPC,"iCutsceneViewed",1);

   SetLocalObject(GetModule(),"goldvein",oPC);
   ExecuteScript("cs_deserteast",GetArea(oPC));
   ExecuteScript("fx_deserteast",GetArea(oPC));
}

Second script:
“cf_checkadd” (this script contains the custom function)

void CheckAddJournalEntry(object oPC, string sPlotID, int nState) {
    if (GetLocalInt(GetArea(oPC), "edrop")==1) {
        AddJournalQuestEntry("find_smug", 1, oPC,TRUE,FALSE);
    }
}

Third script:
“fx_deserteast” (this script executes the custom function)

#include "cf_checkadd"

void main()
{
   DelayCommand(80.0,CheckAddJournalEntry(object oPC));
}
               
               

               


                     Modifié par dr. b, 08 août 2013 - 11:21 .
                     
                  


            

Legacy_Squatting Monk

  • Hero Member
  • *****
  • Posts: 776
  • Karma: +0/-0
Eavedropping and Journal Entries
« Reply #7 on: August 09, 2013, 12:47:44 am »


               The problem is on that line. You need to remove the object keyword so it read like this:


    DelayCommand(80.0,CheckAddJournalEntry(oPC));

This still won't compile, though. You also need to define oPC in that script:


    object oPC = GetEnteringObject();
    DelayCommand(80.0,CheckAddJournalEntry(oPC));

Finally, CheckAddJournalEntry() is requiring two more parameters. I don't know what values you're wanting there, and your custom function doesn't seem to use them anyway. You may just want to remove them.
               
               

               


                     Modifié par Squatting Monk, 08 août 2013 - 11:49 .
                     
                  


            

Legacy_dr. b

  • Newbie
  • *
  • Posts: 26
  • Karma: +0/-0
Eavedropping and Journal Entries
« Reply #8 on: August 09, 2013, 05:16:56 am »


               Thank you. I fixed the third script and now it compiles. It did require an extra parameter, which I set as the journal entry from script 2 (I wasn't quite sure how to remove the parameter requirement, as you suggested). It now looks like this:

#include "cf_checkadd"

void main()
{
DelayCommand(80.0,CheckAddJournalEntry(oPC, "find_smug", 1));
}

However, although the script compiles, upon testing the module, no journal entry gets added, so somethingh still isn't working. Note that I added a line of code to script #1 telling it to set the integer edrop to 1.
               
               

               


                     Modifié par dr. b, 09 août 2013 - 04:23 .
                     
                  


            

Legacy_dr. b

  • Newbie
  • *
  • Posts: 26
  • Karma: +0/-0
Eavedropping and Journal Entries
« Reply #9 on: August 09, 2013, 02:26:56 pm »


               Never mind, found the problem and fixed it. Thanks, everyone!