Author Topic: Two simple scripts, fuckload of problems.  (Read 9646 times)

Offline Soul Sojourner

  • Resident Awesome
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2748
  • Nothing is true; everything is permitted.
    • View Profile
    • Email
Two simple scripts, fuckload of problems.
« on: January 10, 2009, 07:36:33 PM »
Why, by all that is so fucking bloody unholy... are these two... simple... little... miniature... tiny... scripts... GIVING ME A FUCKING HEADACHE!?

Seriously... I know there's some simple shit I've been missing this entire time that for some blasted reason I can't seem to grasp that will solve my problems with these two scripts... but for every thing I try I've so far fucked up pretty bad. lol.

Okay, what I wanted to do was make two separate things happen. Really simple things, actually (or so I thought... lol).

The first thing. I have a gate at the entrance to an area, there is nowhere to go but through this gate but the gate is locked and needs a key. I have a guard at the gate which I want to distribute a key to every player who asks for it. In the conversation, I have the player ask the guard if they may enter... this is where I want the script to come into play. What I want, is for the guard to tell the player they already have a key and not give them another one IF (fucking if) they already have one. So I want the script to detect if the player has the key, IF they have the key, I want the guard to tell them they already have one and not to give them another one. IF they don't have one, I want the guard to tell them something else (basically the guard saying something like "Sure here's the key."), and give them the key. My problem is, is that I can't figure out how to get one line or the other of text to appear in the conversation depending on whether or not they have the key. I tried using "Text appears when" and If then statements... but I keep fucking up somewhere.

Now, the other script... which is more of a bitch... I have an area where 'servants' are walking through the halls and doing their own thing (using the follow waypoint on the default heartbeat script), and what I want is for those servants to say something in text while they are walking (as talking above their head), but also saying something using an actual sound file at the same time. What they say in the sound file matches perfectly to what they will say in text. My problem is... I can't get the sound thing to work at all! I've gotten them walking around and talking in text... I've tried using the delay command and loops on their heartbeat and spawn scripts... but nothing's worked so far. At first I tried using the PlaySound function... What I want is for them to continually say stuff in text and aloud forever, but only like every 30 seconds or so. Problem is... the PlaySound function only seems to work when a characters action queue is clear... and since I have them constantly walking from waypoint to waypoint... their action queue is never clear... also PlaySound isn't even an action! It plays instantly! For some reason though it doesn't work unless the queue is clear so... I tried using SoundObjectPlay... but... that means I have to use a sound object... I tried things with that but it also ended in failure.

I've probably made a hundred scripts for both situations to no avail. Seems like a simple thing to do yet it is eluding me so... Blindly frustrating it is.

Offline 420

  • Hero Member
  • *****
  • Posts: 4087
    • View Profile
    • Email
Re: Two simple scripts, fuckload of problems.
« Reply #1 on: January 11, 2009, 01:36:43 AM »
The first thing. I have a gate at the entrance to an area, there is nowhere to go but through this gate but the gate is locked and needs a key. I have a guard at the gate which I want to distribute a key to every player who asks for it. In the conversation, I have the player ask the guard if they may enter... this is where I want the script to come into play. What I want, is for the guard to tell the player they already have a key and not give them another one IF (fucking if) they already have one. So I want the script to detect if the player has the key, IF they have the key, I want the guard to tell them they already have one and not to give them another one. IF they don't have one, I want the guard to tell them something else (basically the guard saying something like "Sure here's the key."), and give them the key. My problem is, is that I can't figure out how to get one line or the other of text to appear in the conversation depending on whether or not they have the key. I tried using "Text appears when" and If then statements... but I keep fucking up somewhere.
Put this in the "Text appears when" of the dialog that option that states that the PC already has a key. This should be above the alternate dialog option that gives the key. (Replace "ItemTag" with the tag of the item.)
Code: [Select]
int StartingConditional()
{
if(GetItemPossessedBy(GetPCSpeaker(), "ItemTag") == OBJECT_INVALID)
    {
    return FALSE;
    }
return TRUE;
}



Now, the other script... which is more of a bitch... I have an area where 'servants' are walking through the halls and doing their own thing (using the follow waypoint on the default heartbeat script), and what I want is for those servants to say something in text while they are walking (as talking above their head), but also saying something using an actual sound file at the same time. What they say in the sound file matches perfectly to what they will say in text. My problem is... I can't get the sound thing to work at all! I've gotten them walking around and talking in text... I've tried using the delay command and loops on their heartbeat and spawn scripts... but nothing's worked so far. At first I tried using the PlaySound function... What I want is for them to continually say stuff in text and aloud forever, but only like every 30 seconds or so. Problem is... the PlaySound function only seems to work when a characters action queue is clear... and since I have them constantly walking from waypoint to waypoint... their action queue is never clear... also PlaySound isn't even an action! It plays instantly! For some reason though it doesn't work unless the queue is clear so... I tried using SoundObjectPlay... but... that means I have to use a sound object... I tried things with that but it also ended in failure.
Try using the PlayVoiceChat function in combination with the VOICE_CHAT_ constants.

-420
« Last Edit: January 11, 2009, 01:45:35 AM by 420 »

Offline Soul Sojourner

  • Resident Awesome
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2748
  • Nothing is true; everything is permitted.
    • View Profile
    • Email
Re: Two simple scripts, fuckload of problems.
« Reply #2 on: January 11, 2009, 08:26:18 PM »
Put this in the "Text appears when" of the dialog that option that states that the PC already has a key. This should be above the alternate dialog option that gives the key. (Replace "ItemTag" with the tag of the item.)
Code: [Select]
int StartingConditional()
{
if(GetItemPossessedBy(GetPCSpeaker(), "ItemTag") == OBJECT_INVALID)
    {
    return FALSE;
    }
return TRUE;
}


Try using the PlayVoiceChat function in combination with the VOICE_CHAT_ constants.

-420
That worked flawlessly. My problem there was I wasn't using int StartingConditional. When I did use that, it always popped up the other option and gave them another key (most likely because it was above the dialogue text with the script on it, I think.)

This second script is the bugger though, I don't think voicechat will work though. The actual thing I want the servants to say out loud is a sound file (one of grovels from the second expansion), and the constants use their actual voicechat stuff rather than playing sound files. I thought PlaySound would be the best option, but like I said... they're always walking so it wouldn't work. Unless I actually just fucked it up and their walking wasn't the reason for it not working.

Offline 420

  • Hero Member
  • *****
  • Posts: 4087
    • View Profile
    • Email
Re: Two simple scripts, fuckload of problems.
« Reply #3 on: January 11, 2009, 09:14:26 PM »

This second script is the bugger though, I don't think voicechat will work though. The actual thing I want the servants to say out loud is a sound file (one of grovels from the second expansion), and the constants use their actual voicechat stuff rather than playing sound files. I thought PlaySound would be the best option, but like I said... they're always walking so it wouldn't work. Unless I actually just fucked it up and their walking wasn't the reason for it not working.
Ah, the problem is that you have to manually type out the text that you want them to say.

For Smith Hold I use something like this on heartbeat:
Code: [Select]
ActionSpeakString("It's break time now, yes? Yes? Maybe? No, back to work.");
PlaySound("vs_nx2goblm_59");

-420

Offline Soul Sojourner

  • Resident Awesome
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2748
  • Nothing is true; everything is permitted.
    • View Profile
    • Email
Re: Two simple scripts, fuckload of problems.
« Reply #4 on: January 12, 2009, 02:15:59 AM »
Ah, the problem is that you have to manually type out the text that you want them to say.

For Smith Hold I use something like this on heartbeat:
Code: [Select]
ActionSpeakString("It's break time now, yes? Yes? Maybe? No, back to work.");
PlaySound("vs_nx2goblm_59");

-420
I've been able to get them to show text above their heads, my problem is that the PlaySound function isn't working. It's probably better if I show you what I have right now. This was the last script I wrote for them and what I currently have for their heartbeat script.

Code: [Select]
void main()
{
    object oNPC = OBJECT_SELF;
    float fWait = 30.0f;
    float fWaitLonger = 60.0f;
    string sSpeakOne = "It not that dirty here, no no no, but boss says clean, so we clean, clean, clean.";
    string sSpeakTwo = "It's breaktime now yes, yes, maybe? Nooo, baack to work.";
    int nTalkVolume = TALKVOLUME_TALK;
    string sSayAloud = "vs_nx2goblm_55";
    string sSayAloud2 = "vs_nx2goblm_59";

    DelayCommand(fWait, SpeakString(sSpeakOne, nTalkVolume));
    PlaySound(sSayAloud);

    DelayCommand(fWaitLonger, SpeakString(sSpeakTwo, nTalkVolume));
    PlaySound(sSayAloud2);
}

However, PlaySound doesn't actually work... the DelayCommand is there to space things apart although that isn't working either (my guess has been because it's onheartbeat) so every few seconds they say more text above their head (instead of 30 seconds or so), and I'm trying to play two different sounds at two different times, but also have them have the correct sound play with the corresponding text talk.
« Last Edit: January 12, 2009, 02:21:36 AM by Soul Sojourner »

Offline 420

  • Hero Member
  • *****
  • Posts: 4087
    • View Profile
    • Email
Re: Two simple scripts, fuckload of problems.
« Reply #5 on: January 12, 2009, 05:12:48 PM »
Try delaying both the text and the sound.
Code: [Select]
void main()
{
    object oNPC = OBJECT_SELF;
    float fWait = 30.0f;
    float fWaitLonger = 60.0f;
    string sSpeakOne = "It not that dirty here, no no no, but boss says clean, so we clean, clean, clean.";
    string sSpeakTwo = "It's breaktime now yes, yes, maybe? Nooo, baack to work.";
    int nTalkVolume = TALKVOLUME_TALK;
    string sSayAloud = "vs_nx2goblm_55";
    string sSayAloud2 = "vs_nx2goblm_59";

    DelayCommand(fWait, SpeakString(sSpeakOne, nTalkVolume));
    DelayCommand(fWait, PlaySound(sSayAloud));

    DelayCommand(fWaitLonger, SpeakString(sSpeakTwo, nTalkVolume));
    DelayCommand(fWaitLonger, PlaySound(sSayAloud2));
}
However, I use a random roll to make NPC's say things so I don't have to worry about DelayCommand. So, for example, I roll a 1d6 on heartbeat and if it rolls a 1 or 2 the NPC speaks the text/sound. That means every 6 seconds (1 round) there is a 1/3 chance the NPC will speak it's line.

-420
« Last Edit: January 12, 2009, 05:16:04 PM by 420 »

Offline Soul Sojourner

  • Resident Awesome
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2748
  • Nothing is true; everything is permitted.
    • View Profile
    • Email
Re: Two simple scripts, fuckload of problems.
« Reply #6 on: January 12, 2009, 10:30:15 PM »
I like the way you think, that's a very good idea. I may very well use that method instead of DelayCommand myself, since DelayCommand won't actually wait the full time it's supposed to. However, I have to get the script to where it's at least working first. I just tried it out with the delay on PlaySound (like you have in the code box), but it failed. I haven't been able to get PlaySound to work at all. It simply doesn't play for whatever reason.

This is what I got from NWN Lexicon:

"Known Bugs
This might not be an actual bug, but though PlaySound isn't an action (you don't get the little yellow square on the screen), if you assign a PlaySound to someone, it will wait for their current action queue to finish before playing."

That's why I thought that their walking from waypoint to waypoint may have been the cause for it to not play.

However, I just read this as well...

"Remarks
PlaySound returns immediately, it does not wait for the sound to finish playing. If you want to play a sound using a trigger, then look at the SoundObjectPlay function, as PlaySound requires an object to work."

Agh...

Offline Soul Sojourner

  • Resident Awesome
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2748
  • Nothing is true; everything is permitted.
    • View Profile
    • Email
Re: Two simple scripts, fuckload of problems.
« Reply #7 on: January 12, 2009, 11:53:27 PM »
Fuck yeah! I finally fucking got it.

The only other function that looked like it could do what I needed it to do was PlaySoundByStrRef, but the problem was that I needed the specific string reference for each individual sound. I couldn't seem to get PlaySound to work in any way no matter what I tried, and wanted the NPC's to walk at the same time, so I went through the work of finding the string references. (man it took some digging, the easy method of finding it kept returning errors, so I had to manually find it.) Once I used that. Eureka. =D

Code: [Select]
void main()
{
    object oNPC = OBJECT_SELF;
    float fWait = 30.0f;
    float fWaitLonger = 60.0f;
    string sSpeakOne = "It not that dirty here, no no no, but boss says clean, so we clean, clean, clean.";
    string sSpeakTwo = "It's breaktime now yes, yes, maybe? Nooo, baack to work.";
    int nTalkVolume = TALKVOLUME_TALK;
    int nStrRef = 84033;
    int nStrRef2 = 84037;
    int nRunAsAction = FALSE;

    DelayCommand(fWait, SpeakString(sSpeakOne, nTalkVolume));
    DelayCommand(fWait, PlaySoundByStrRef(nStrRef, nRunAsAction));

    DelayCommand(fWaitLonger, SpeakString(sSpeakTwo, nTalkVolume));
    DelayCommand(fWaitLonger, PlaySoundByStrRef(nStrRef2, nRunAsAction));
}

Now, I gotta lose the DelayCommand function, because now the constant babbling from the servants is annoying. lol.

I'll try some things. Thanks for all of your assistance, 420, it's appreciated.

Offline Soul Sojourner

  • Resident Awesome
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2748
  • Nothing is true; everything is permitted.
    • View Profile
    • Email
Re: Two simple scripts, fuckload of problems.
« Reply #8 on: January 13, 2009, 12:43:44 AM »
Finally, here's the finished product.

Code: [Select]
void main()
{
    object oNPC = OBJECT_SELF;
    string sSpeakOne = "It not that dirty here, no, no, no. But boss says clean, so we clean, clean, clean.";
    string sSpeakTwo = "It's breaktime now yes? Yes? Maybe? No, back to work.";
    int nTalkVolume = TALKVOLUME_TALK;
    int nStrRef = 84033;
    int nStrRef2 = 84037;
    int nRunAsAction = FALSE;
    int nNumDice = 1;
    int nDiceRoll1 = 2;
    int nDiceRoll2 = 11;

    if(d12(nNumDice) <= nDiceRoll1)
        {
        SpeakString(sSpeakOne, nTalkVolume);
        PlaySoundByStrRef(nStrRef, nRunAsAction);
        }
    else if(d12(nNumDice) >= nDiceRoll2)
        {
        SpeakString(sSpeakTwo, nTalkVolume);
        PlaySoundByStrRef(nStrRef2, nRunAsAction);
        }
}
It works flawlessly now. Thanks for the tip about the dice roll, 420, I love it! There are multiple servants that walk around in a single area, they all follow the same waypoints but are in different locations... so I needed it to be a lot less than 1/3 of the time. lol.

Anyone who wants to use it or modify it and use it or whatever, go ahead. Though I doubt anyone here would need it! =P

I'm sure I'll be at my wits end with more scripts soon enough... lol.