Aller au contenu

Photo

Speak Trigger - please trigger again


  • Veuillez vous connecter pour répondre
10 réponses à ce sujet

#1
Friar

Friar
  • Members
  • 293 messages

I sort of remember having this conversation before or reading about it when it was not easy for me to articulate what the problem was.

 

I have placed a lot of speak triggers in my module. Some times they lead to a critical conversation.

Many times the triggers are used for one-liners either by the PC or NPCs.

 

Fortunately, the triggers do not play the conversation each time the PC steps on it. That would be annoying.

However, in some cases this would be useful for me if they played everytime the PC enters the trigger.

 

For instance, PC is greeted by an NPC when they enter a shop with a one liner. "Welcome."

Or an area they aren't supposed to be in. "If you go any further we will attack."

 

In the conversation I have the node: "Show Once?"

set to "always"

 

I began investigating the trigger properties.

I notice it has variables

Do these have anything to do with ensuring the trigger always fires?



#2
andysks

andysks
  • Members
  • 1 652 messages

Try to make your own script for firing conversation. It will save you the headache and bugs that the gtr_speak_node will cause. I tried, and tried... until I gave up on the matter. I know use this:

 

///////////////////////////////////////////////
/*
Andy 19.05.2014
roe_trigger_ipspeaker
Creates an ipspeaker as we enter the trigger
Variables: Speaker Tag = String for the NPC who will initiate the dialogue
           Convo       = String for the name of the convo
           Delay       = Duh?
           DestroySelf = Int. TRUE for destroying the trigger after it fires
           Condition   = Int. By default is 0. If left like that the trigger will fire.
                         If we set the int to 1, and on the trigger's tag it won't until
                         we set it to 0 again.
*/           
//////////////////////////////////////////////
//TODO?
//Journal Entries conditionals?
//Maybe in the future. For now it's working fine.
/////////////////////////////////////////////

#include "ginc_ipspeaker"

////////////////////////////////////////
//Function Definition
///////////////////////////////////////

void SpawnSpeaker()
{
    object oPC = GetFirstPC();
    object oEntering = GetEnteringObject();
    
    if (!GetIsPC(oEntering))
    return;
    
///////////////////////////////////////
//Variables Definitions    
//////////////////////////////////////

    string sSpeakerTag = GetLocalString(OBJECT_SELF, "SpeakerTag");
    string sConvo      = GetLocalString(OBJECT_SELF, "Convo");
    location lLocation = GetLocation(oPC);
    float fDelay       = GetLocalFloat(OBJECT_SELF, "Delay");
    int iDestroySelf   = GetLocalInt (OBJECT_SELF, "DestroySelf");
    int iCondition     = GetLocalInt (OBJECT_SELF, "Condition");
    
    

    
    CreateIPSpeaker(sSpeakerTag,sConvo,lLocation,fDelay);
    

}

//////////////////////////////////////
//Main Code
/////////////////////////////////////

void main()
{
    int iCondition     = GetLocalInt (OBJECT_SELF, "Condition");
    
    if(iCondition == 1)
    return;
    
    else if(iCondition == 0)
    
    SpawnSpeaker();
    
    int iDestroySelf = GetLocalInt(OBJECT_SELF, "DestroySelf");
    if( iDestroySelf == 1)
    {
        DelayCommand(3.0,DestroyObject(OBJECT_SELF));
    }

}  

 

Not finished yet, but it does all a speak trigger does and better :). In my opinion at least. Maybe it is a messy script, for I suck at scripting... but it does its work fine :).



#3
Guest_Iveforgotmypassword_*

Guest_Iveforgotmypassword_*
  • Guests
Here's a trick.. Give the speak trigger a tag then set the speak trigger variables to run -1,talk now 1, cutscene bars 1 ( if you want them ) and multi use 1, fill these numbers in by changing the numbers in the vakue int line. Also fill in the conversation name and npc tag but write this where it says value string not in the value int line.

Now when you want this to fire at a certain time spawn in the creature with the same npc tag as you put in the trigger's npc tag section, it wont fire until they arrive but you can jump up and down on it as many times as you want beforehand and it will still be active.

On one of the last nodes of the trigger's conversation destroy the trigger and you'll never hear that conversation again or make the npc leave the area. If the npc that's talking is a permanent feature spawn in a rat and name the trigger's npc tag line with the rats tag ( I've used invisible tiny kobolds before ).

#4
Friar

Friar
  • Members
  • 293 messages

I tried clarifying what I am talking about by editing my original post.

 

I also used the script writer to do this since it worked elsewhere for something I was trying to do.

//Put this script OnEnter
void main()
{

object oPC = GetEnteringObject();

if (!GetIsPC(oPC)) return;

if (GetTag(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC)) != "disguise1")
   return;

AssignCommand(GetObjectByTag("NPC3"), ActionSpeakString("Hello guy wearing disguise1"));

if (GetTag(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC)) != "disguise2")
   return;

AssignCommand(GetObjectByTag("NPC3"), ActionSpeakString("Hello guy wearing disguise2"));

if (GetTag(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC)) != "disguise3")
   return;

AssignCommand(GetObjectByTag("NPC3"), ActionSpeakString("Hello guy wearing disguise3"));
}

The first line plays out fine if the PC is wearing disguise1. However I can't seem to find what command I need to check for all the disguises and then I want to add a greeting if the guy isn't wearing any disguises at all... a standard greeting.



#5
kevL

kevL
  • Members
  • 4 070 messages

you need to set up a default:


string sSpeakString = "hello guy-i-don't-know-is-wearing-a-disguise";

int bIsDisguised = FALSE;
string sDisguise = GetTag(GetItemInSlot(INVENTORY_SLOT_CHEST), oPC);
if (GetStringLeft(sDisguise, 8) == "disguise")
    bIsDisguised = TRUE;

if (bIsDisguised)
{
    int iDisguiseType = StringToInt(GetStringRight(sDisguise, 1)); // only does 0..9 disguise types
    switch (iDisguiseType)
    {
        case 0: sSpeakString = "hello guy in Disguise 0";
        break;

        case 1: sSpeakString = "hello guy in Disguise 1";
        break;

        // etc.

        default: sSpeakString = "error";
        break;
    }
}

AssignCommand(GetObjectByTag("NPC3"), ActionSpeakString(sSpeakString));


see what i did thar?

#6
Friar

Friar
  • Members
  • 293 messages

I'm not sure how to get that script to work.

It says Invalid Declaration type on this part

if (GetStringLeft(sDisguise, 8) == "disguise")
    bIsDisguised = TRUE;

Also I'm a little confused

 

Does that script assume there is one disguise but in different conditions? Or do I somehow write the variables into the trigger and then get them to match the item tags?

 

Darn

I should have just taken this topic to the script section.



#7
kevL

kevL
  • Members
  • 4 070 messages

my mistake ( darn parentheses )
 

// 'fr_disguise_talk'

//Put this script OnEnter
void main()
{
    object oPC = GetEnteringObject();
    
    string sSpeakString = "hello guy-who-isn't-wearing-a-disguise";
    
    int bIsDisguised = FALSE;
    string sDisguise = GetTag(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC));
    if (GetStringLeft(sDisguise, 8) == "disguise")
        bIsDisguised = TRUE;
    
    if (bIsDisguised)
    {
        int iDisguiseType = StringToInt(GetStringRight(sDisguise, 1)); // only does 0..9 disguise types
        switch (iDisguiseType)
        {
            case 0: sSpeakString = "hello guy in Disguise 0";
            break;
    
            case 1: sSpeakString = "hello guy in Disguise 1";
            break;
    
            // etc.
    
            default: sSpeakString = "error";
            break;
        }
    }
    
    AssignCommand(GetObjectByTag("NPC3"), ActionSpeakString(sSpeakString));
}


This assumes all disguises (and only disguises) are worn in the slot chest and have a tag that starts w/ the letters "disguise"

It first assigns a default string so speak, then it searches for a "disguise" in the chest slot of the PC. If one is found, it then gets the number at the end of that chest-item's tag (0 through 9) and decides what the NPC should say instead of the default.

Finally, having determined the speakstring like that, it Assigns the command to the NPC to actually talk,


ps. a fair bit of scripting goes down in Toolset, kinda hard to separate them ...



#8
Friar

Friar
  • Members
  • 293 messages

Ah! That makes sense.

 

And so if I wanted to name the tag disguise_soldier

I could change change the

case 0: sSpeakString = "hello guy in Disguise 0";
            break;

to something like this?

case soldier: sSpeakString = "hello soldier";
            break;

Or maybe I would make the tag: disguisesoldier



#9
kevL

kevL
  • Members
  • 4 070 messages

the problem there is that a switch/case statement will only take an integer value

 

you could replace it with if/else statements, along the lines of

 

if (GetStringRight(sDisguise, 4) == "sold")

do soldier stuff ... etc.

 

and limit the identifying letters to 4 characters at the end, to get a consistency for those string values. I rather suggest simply writing some documentation at the top of the script, stating

 

disguise0 - soldier

disguise1 - blacksmith

disguise2 - etc.

 

and keeping the switch/case as is (but if you want to tinker that's what its here for)



#10
Friar

Friar
  • Members
  • 293 messages

Well I'm keeping it simple with

disguise0

disguise1

disguise2

 

The only thing is that this script isn't firing off.

Even the "error" default debug option isn't showing up.

Any idea what I ought to check?

 

 

 

....

Nevermind

I had the NPC improperly tagged.

 

 

....

Thanks again KevL!



#11
kevL

kevL
  • Members
  • 4 070 messages

np Friar