Listen for Event broadcast by map actor?

Could anyone help me please?
I'm trying to nail down the start-line system for my Micro Machines map, whereby the cars become responsive to input only when the green light goes & the race begins.

The code to control the cars' response is handled, but I'm having problems trying to get my vehicles to listen for an Event, sent out by a Trigger actor, an AIScript>TriggerEvent action, any actor that's capable of broadcasting it's Event property, or <console type>CauseEvent command, and then setting a Boolean variable to True.

This doesn't work, but hopefully it'll give you the idea of what I mean;

It's so they can come up with weird & wacky looking start lines on their maps, with lights, movers, emitters & other bells & whistles, all hooked into ther own Tag/Events, but when the mapper sends his master "RaceStart" event, that's when the race "officially" starts.

Any help would be much appreciated, I've been through the WaitForEvent scripted actions' code, but to be perfectly hones I made neither head nor tail of it, all I need to do is hear an Event & set a boolean.
Cheers.

Any Actor "listens" to Events, as long as their Tag matches it. So if you wanted an Actor to listen for an Event (so it could be Trigger()-ed), you'll just need to make sure it's Tag is set properly. If the Actor isn't placeable (accessable in the editor) then you'll need to have this set as a default property.

BTW, when an Actor is triggered via Event that matches it's Tag, the Trigger() function is executed. No further check within Trigger() is needed.

But, I'm wondering if perhaps this could be done a slightly different way, with just a little more coding involved. Another actor (placeable Info class) could be sitting in your map, listen for the Event, and perform a number of different things, like set your cars up, say "Go!", etc. This would be a fairly simple custom actor built just for this map.

(Again, when I get my next break, I'll go through this and your beta map thread in depth to see if I can help further)

Right now, I'm trying to attack it from 2 directions, first, by using the Handler mut, to loop through all the instances of MicroBender and manipulate them, and secondly, as you can see here, by inserting the code directly into MicroBender, thereby cutting out all the looping through instances of MicroBender.

This is because my mut wasn't working, so I want to test out the code in a single Microbender, before transferring it over to the Mut, where it will (eventually) control all instances in the map.

(*just incase you were wondering why I was using both the vehicle and the mut to do essentially the same thing)

I've spent the day trying to nail down listening for events, I eventually want this code to run in the Mut, so I'd rather avoid using a system whereby the cars respond if they are directly "triggered" (ie; their .Tag property is called), but instead to make them listen out for all external Events and discern them, like the WaitForEvent action does.

Okay, still don't have enough time yet, but you're posting fast and furious, so I'll try to keep up.

TriggerEvent() is not the same as Trigger(). These two functions are like a transmitter and reciever. (sort of)

TriggerEvent() is a function that makes your actor do what the ACTION_TriggerEvent step in an AIScript does. It calls out an EventName to any actor in the level that has a matching Tag. Trigger() on the other hand, is the function that is run on an actor who has been "triggered". IOW, I have a refrigerator door Mover that fires an Event called, "foo", when it opens. I have a TriggerLight that has it's Tag set to, "foo". When the frig door opens, the Event "foo" is called out by use of a TriggerEvent() function on the Mover, then the TriggerLight is singled out (because of it's Tag "foo") and executes it's Trigger() function, causing the light to turn on. Does that make sense?

Stuff that should go in an actor's Trigger() function would be the code you want to execute when an Event matching the actor's Tag is called out in-game. If you want your actor to set GroundSpeed to 2000 on trigger, simply put:

Okay, still don't have enough time yet, but you're posting fast and furious, so I'll try to keep up.

Sorry dude, I'll slow down if you want. If you're at work & only get a few breaks, please, don't waste 'em on coding.

Originally Posted by SuperApe

TriggerEvent() is not the same as Trigger(). These two functions are like a transmitter and reciever. (sort of)

Ah, I see. I knew I was taking a punt on which one it was.

Originally Posted by SuperApe

I have a TriggerLight that has it's Tag set to, "foo". When the frig door opens, the Event "foo" is called out by use of a TriggerEvent() function on the Mover, then the TriggerLight is singled out (because of it's Tag "foo") and executes it's Trigger() function, causing the light to turn on. Does that make sense?

Yes. If I can use your example further - I'd like my cars (and eventually I'll transplant this code into the mut) to listen out for *all* events called, and single out a hardcoded one.
Since while your TriggerLight has a Tag, my Cars & Mut don't, or at least, not one I want to use for this purpose.

The problem as I see it is that I don't want to use the Cars' or Mut's Tag property, so the code has to listen out for all events, and compare them against the string "RaceStart", in order to determine the correct Event has been called.

In other words, I kinda need the code that runs every time an Actor is correctly called by an Event, the code that "hears" the Event, and matches it with a particular Actor's Tag.

But then I read on..;

Originally Posted by SuperApe

Stuff that should go in an actor's Trigger() function would be the code you want to execute when an Event matching the actor's Tag is called out in-game. If you want your actor to set GroundSpeed to 2000 on trigger, simply put:

For the Trigger() function, there's rarely any need to call the parent code with the Super directive.

..And I begin to think about it, in a different way..

Why not just "Trigger" my cars to become active by calling their Tag with a triggerable actor?
I mean, if I were mapping, and not coding, it's the first thing I'd think of.

"If you want to make an Actor do something, Trigger it" - Is a pretty good ground rule for OSM and mapping in general, right?
So, let's consider it for a moment.
Supposing we set our Benders to have a GroundSpeed of 0 by default, and then use the above Trigger() function to "Activate" them upon the race start.

It would mean setting a Default .Tag, which is doable, since some OSM actors have custom default .Tags.

In fact, the more I think about it the more I like it, it's far more intuitive than my idea, and it'll make much more sense to future mappers. - Thanks Glenn!

Sorry dude, I'll slow down if you want. If you're at work & only get a few breaks, please, don't waste 'em on coding.

It's not quite that. I'm playing Mr. Mom and get only the time it takes for my sweetie to nap. No idea when that will happen, no idea how long that can be. It's maddening to try and do the basics: eat, sleep, etc. This is actually part of the "fun" in my day that keeps me sane, boyo.

Originally Posted by BigJim

...I'd like my cars (and eventually I'll transplant this code into the mut) to listen out for *all* events called, and single out a hardcoded one...The problem as I see it is that I don't want to use the Cars' or Mut's Tag property, so the code has to listen out for all events, and compare them against the string "RaceStart", in order to determine the correct Event has been called...In other words, I kinda need the code that runs every time an Actor is correctly called by an Event, the code that "hears" the Event, and matches it with a particular Actor's Tag.

That's just not how Events work. If I may take the idea and reframe it: you'd like to wait for a condition, then have "stuff happen" on your cars (or your Mutator, then on your cars).

Originally Posted by BigJim

Why not just "Trigger" my cars to become active by calling their Tag with a (triggering) actor?

Now you've got the idea. Please note that you will "call their Tag" (with an Event) by a triggering actor, not a triggerable actor. By coding your cars with a Trigger() function, you make them "triggerable", but the actor that fires the Event is a "triggering" actor. (ie., your AIScript you already have in place using an ACTION_TriggerEvent step)

If given the chance to go through the map and parse out your wish list, I would've steered you to this, just a little later than you came to it. It's good to see you thinking through this, but I'm finding that if you go a little too fast, you can miss some of the basic concepts in play. (Event-Tag relationship, for example)

This is a good solution you came up with that isn't too hard (complicated) to implement. Simpler is better for purposes of development. Less chance of wild bug hunts. There are plenty of ways to skin this cat, so if you run into trouble, we can implement the other idea I had: a custom Info actor to handle race start.

It's not quite that.
///
This is actually part of the "fun" in my day that keeps me sane, boyo.

Hoho, bad luck that man! (or good luck, depending.. )

Originally Posted by SuperApe

That's just not how Events work. If I may take the idea and reframe it: you'd like to wait for a condition, then have "stuff happen" on your cars (or your Mutator, then on your cars).

Ah, gotcha.
I was under the impression that when a game-Event fired, *every single* actor capable of hearing an event would hear it, each would compare it's string against their own Tag property, and then the one (or several) who had a match would proceed to "do something".

The way you describe it, it's like the Event fires off, and knows intuitively which Tag actor to zoom straight in on, the way I had thought of it, some code must run, somewhere, that runs through a list of *all* Tags, and matches it with the relevant Tag before communicating to the matching actor. [/Jim fears the leet-ninja code]

Originally Posted by SuperApe

Now you've got the idea. Please note that you will "call their Tag" (with an Event) by a triggering actor, not a triggerable actor. By coding your cars with a Trigger() function, you make them "triggerable", but the actor that fires the Event is a "triggering" actor. (ie., your AIScript you already have in place using an ACTION_TriggerEvent step)

Thanks. As soon as I posted that I tottered off & tried some tests doing just as you describe;

* The .Tag of MicroBender set to "RaceStart".
* A ScriptedTrigger calling TriggerEvent="RaceStart" after 10 secs
* A screen message confirming when the trigger ran it's script

Ok, so then I used the exact Trigger() function you posted, with a series of commands that re-set various properties (only one at a time), the aim being to enable the vehicle to move when Trigger() was called.

First step is to set a DefaultProperty so that the vehicle cannot move until that same property is re-set in Trigger(). So far, so simple you'd think.

I tried GroundSpeed, IdleRPM, PHYS_Karma (ouch), GearRatios, all of which seemed to have either no effect when set to 0 (or equivalent), or completely borked the vehicle's handling, rather than totally preventing it's moving.

I saved, closed the Ed & re-opened it to check again, and lo - the property changes I made had been re-set to default.
Just like how the PassengerWeaponPawns keep re-appearing every time I edit the map, & need to be deleted each time.

I'll go back, and edit PostBeginPlay() to set all the properties, including the ones that need to be 0.
I bet they're defaulting to the superclass' values if they don't like what I've set them..
Ah, I hope that's another little mystery solved.

I'm also not *entirely* sure Trigger() is actually being called, I added a change to the HeadLightProjectorScale in one of the earlier tests, and when the car's Tag was called, the headlights didn't change.
Might be nothing, but I'll add some log calls to the function just to make sure it's actually calling.

I'm sure you can see what it all does, again, faster than I could type it.

The strange thing y'see, is that that many of the Car (I've got to get used to calling them "Cars", and not "Vehicles") properties didn't work for my purposes - ie, I'd try to set them to 0, to effectively hobble the car, but come runtime, they'd still drive around while 'supposedly' driving around on 0-Groundspeed, or 0-PoweredWheels or 0-RPM, even though I knew they shouldn't be able to.

I rather think that many of these vehicle properties must be being re-set by the engine at runtime, leaving them impossible to sink my hooks into.

Anywhoo, I cracked this about 10hours ago but couldn't get back onto the internet;
I wanted to post quickly so you didn't spend oodles of time on the problem, to find some clean, efficient, and elegant yet ultimately redundant method to do the same thing.

Thanks for the help mate, right, that's one problem down, only several more to go!

While I'm glad you got something to work, I can guarantee there's a more efficient way. (If it works, it's not a big deal. But if any coders look and find you're using Tick(), they'll scoff.)

Heh heh, yup, I was dubious about using that function, because it runs constantly and there's tons of other, moe essential things going on in there - my hope is that since there's not much happening at that time during the game (pre-race) that it won't hurt too much.

Agreed tho' - there's bound to be loads of more neat & efficient ways to do it, though I admit I didn't want you to have spent ages working on one, knowing you've only got limited time, when a cheap & cheerful way would do.

TBH my problem tends to be that I'm used to being able to run any code whenever I want, and also to access any property or method of anything at any time, whereas with UScript, I find that I've got to "play along" much more, and that often means figuring out the rules (or failing to.. ).