Trigger not working on creatures (OnEnter...)


#1

I can’t get triggers to activate when creatures enter it…but if I change the condition for PC’s and my character enters it it works. What am I doing wrong?

  void main()
    {
        // Get the creature who triggered this event.
        object oPC = GetEnteringObject();

        // Only fire for creatures.
        if (GetIsPC(oPC))
        {
        return;
        }
        else
        {
        ActionSpeakString("YAHOO");
        }
    }

I even tried this without success:

  void main()
    {
        // Get the creature who triggered this event.
        object oPC = GetEnteringObject();

        // Only fire for creatures.
        if (!GetIsPC(oPC))  
        {
        ActionSpeakString("YAHOO");
        }
    }

#2

You need to define the enterer. Otherwise, there is no one to Speak the String

void main()
{
object oEnterer = GetEnteringObject();
object oSelf = OBJECT_SELF;

and so on


#3

Try just SpeakString(). I suspect your creature has something in its action queue that is still running. You could also try ClearAllActions() before the ActionSpeakString() but that will stop the creature in its tracks.


#4

@meaglyn I tried both suggestions, the creatures didn’t even stop (in my test module they have a waypoint telling them to the go to the trigger)

      void main()
        {
            // Get the creature who triggered this event.
            object oPC = GetEnteringObject();

            // Only fire for creatures.
            if (!GetIsPC(oPC))
            {
            ClearAllActions();
            ActionSpeakString("YAHOO");
            }
        }

@DM_Wise
I figured the enterer is defined by
object oPC = GetEnteringObject();

What am I missing?


#5

You aren’t defining who is to speak the string.
According to your script, the Trigger itself is clearing all actions, and speaking the string.

Try:

AssignCommand(oPC, ClearAllActions());
AssignCommand(oPC, SpeakString(oPC, “Yahoo!”));

This is why it’s not working. Once the entering object is defined, it needs to be assigned the commands, or the script assumes it’s the firing object that should execute the commands. Also, using the Clear AllActions() command will stop the NPC from walking the waypoints. My suggestion is to just have it speak the string because speaking doesn’t sit in the action queue.


#6

D’oh. The part about it works for the PC made me gloss over that little issue. Good call Ghool.


#7

First off, thank you. Secondly, after your help I realized I wanted to get this command to work only on “certain” creatures, and I made it work by using the script below (comparing the entering object to the one I want to assign the command to). However, as soon as I add a second creature with the same tag (“Beetle”) and only of those beetles enter the trigger, it doesn’t work. Isn’t that strange?

  void main()
    {
        // Get the creature who triggered this event.
        object oPC = GetEnteringObject();
        object oBeetle = GetObjectByTag("Beetle");


        // Only fire for creatures.
        if (!GetIsPC(oPC))
        {
        if (oPC == oBeetle)
        {
       AssignCommand(oBeetle, SpeakString("Yahoo!"));
         }
    }
}

#8

That’s because GetObjectByTag only returns the first instance unless you specify the second parameter (see Lexicon). If the beetle entering is the second instance, the trigger won’t fire, as it stands.

To fire for all beetles, you need GetObjectByTag:

     void main()
        {
            // Get the creature who triggered this event.
            object oPC = GetEnteringObject();

            // Only fire for creatures.
            if (!GetIsPC(oPC))
              {
                if (GetTag(oPC) == "Beetle")
                 {
                   AssignCommand(oBeetle, SpeakString("Yahoo!"));
                 }
        }
    }

With that script, the trigger will fire every time a Beetle enters, even if one is in the trigger already, or has visited before. That may be sufficient for your purposes.


#9

Actually I don’t want it to fire for all beetles, I just want it to fire to the beetles that enter the trigger, but a quick search how do I get the tag of objects have given me what I needed to I solved the problem with GetTag :slight_smile: Thanks!

  void main()
    {
        // Get the creature who triggered this event.
        object oPC = GetEnteringObject();
        string oBeetle = GetTag(oPC);

        // Only fire for creatures.
        if (!GetIsPC(oPC))
        {
        if (oBeetle == "Beetle")
        {
       AssignCommand(oPC, SpeakString("Yahoo!"));
         }
    }
}

#10

That’s exactly the same as what Proleric posted but less efficient :slight_smile:


#11

Solemn word of advice on the side - Proleric’s making an example of two things that are actually rather important, there. Don’t skip past it too quickly; even if it seems like nitpicking, this is important stuff that’s going to bite you in the butt if you neglect it.

Warning - pedantry follows. :wink:



Prefixes in variable names are normally supposed to signify what type of variable it is, for readability and ease of understanding the code. Somebody seeing a variable called “oBeetle” would generally assume that this is an object type of variable, rather than a string. For a string variable, it should be “sBeetle”.

You’ll thank yourself for it later if you adopt a systematic naming and commenting approach, especially when your code gets longer, and when you have to revisit your code after some years, or get helpers or new team members who have to read and alter it.

In the same way, I’d suggest not declaring “oPC” if the definition is not intended to be a player character. oEnter, or even oBeetle, would be less confusing.

One more variant, for the heck of it:

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

    if (!GetIsPC(oEnter) && GetTag(oEnter) == "Beetle")
        AssignCommand(oEnter, SpeakString("Yahoo!"));
}

I think PCs can’t actually have tags, though, so maybe the GetIsPC() check is unnecessary. Not sure about DM-possessed creatures. :open_mouth:



Second thing Proleric pointed out there is another fundamental thing you definitely want to know about. Don’t skip past his advice carelessly. These are the foundations of the craft, and you need to understand them to build solid constructs; rushing past stuff like this will result in shoddy code in the long run, and you and your future teammembers are the people who are going to be suffering for it. I can’t emphasize this enough - do not cheerfully rush past the basics, or make a habit of disregarding any input when it’s about good form and structure. You’re going to wind up constructing a beautiful castle that you love dearly on an unstable foundation, which may easily crumble, as well as alienating the very people whose methodical mindset enables them to complement your more relaxed and creative approach as part of a team.

GetObjectByTag is a function that looks for and returns one object with a given tag. In the first variant, you were declaring oPC as the object that entered this trigger, and oBeetle as the first object in the module that has the tag “Beetle”, then checking whether oPC is oBeetle. This way around, the trigger would only ever have worked for a single beetle at a time, as there would only ever have been a single object in the module that could have passed the “oPC == oBeetle” check.

So, you really do want the trigger to work whenever any beetle enters the trigger, (note how Proleric’s example (checking for the tag of the entering object) is actually the very solution you discovered yourself; he gave you a direct shortcut there). You do not want the reaction of the beetle that enters the trigger to be assigned to all beetles, but you do want any beetle to be recognized by the trigger, qualifying for the reaction.

But: “All beetles reacting at once when a single beetle enters a trigger” isn’t actually an issue to begin with. Within the script, you have only a single object declared and defined to whom the SpeakString command would have been assigned.

    // We declare oPC as being the object that has entered the trigger in this OnEnter event script.
    object oPC = GetEnteringObject();

    // To oPC, a single object previously defined, we assign the command to speak a string.
    AssignCommand(oPC, SpeakString("Yahoo!"));

To make all beetles in the module react when a single beetle enters the trigger, you would have had to cycle through multiple objects, assigning the command to them one at a time, for instance with a while loop:

// We declare an integer i, to have an incrementable number with which to cycle through the beetles.
int i;
// We declare an object oTarget, defining it as the first object in the module that has the tag "Beetle".
object oTarget = GetObjectByTag("Beetle");
// For as long as the object oTarget is still a valid object, we repeat the actions within the while loop.
while (oTarget != OBJECT_INVALID)
    {
    // We assign the command to speak a string to the current object oTarget.
    AssignCommand(oTarget, SpeakString("Yahoo!"));

    // We change oTarget to the next object in the module that has the tag "Beetle", using our integer i incremented by 1.
    // Now, in the next round of the while loop, oTarget will be a different object.
    // First the second, then the third, then the fourth, and so on, until eventually GetObjectByTag will return OBJECT_INVALID,
    // which means that the condition of the while loop (oTarget != OBJECT_INVALID) will no longer be TRUE.
    oTarget = GetObjectByTag("Beetle", ++i);
    }

So that looks like a misunderstanding of the basics there, and one that would likely cause you some grief and confusion going forwards. I hope I’ve explained it decently and not too obnoxiously. :slight_smile:


::tips hat:: Pedantry accomplished.


#12

I would’ve replied sooner but weekends I tend to clear my mind…
I’ve already implemented your advice when it comes to prefixes… I just thought the “o” is a cute little addon I’ve seen in some script examples, I didn’t realize it has meaning; and I tend to comment usually after the script works but you’re right I haven’t been doing that much.

But yes, good advices, and thanks for laying it out. :slight_smile:

And I completely missed the fact that Proleric used GetTag like I did, I thought Proleric misunderstood me. Oopsie! But yea, the last script I did works, as well as Proleric’s script. Of course, I have other issues with the script which I’m trying to solve… but I wouldn’t like to hijack my own thread and I’ll try to figure it out myself before crying to the experts. :slight_smile:

Much obliged!

-Val

Edit: Typos all over!