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.
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.
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.
::tips hat:: Pedantry accomplished.