Results 1 to 10 of 10
  1. #1
    Redeemer
    Join Date
    Apr 2005
    Location
    Chesterfield, England
    Posts
    1,143

    Default 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;

    Code:
    //<- Listen for event "RaceStart" and set bRaceBegun to True
    //================================
    function Trigger (actor Other, pawn EventInstigator)
    {
    
    local bool strEvent;
    
    strEvent = Other.GetPropertyText("Event");
    
    If (strEvent == "RaceStart")
       {
       bRaceBegun = True; //<- Let race begin
       Log("RaceBegun");
       Level.Game.Broadcast(self, "Race Begun", 'Say');
       }
    Super.Trigger(Other, EventInstigator);
    }
    Y'see, the mapping system relies on a mapper using any Trigger system of his own devising, to create any system as long as it ends with a "RaceStart" Event, so the cars know when to become responsive.

    When bRaceBegun == True, the vehicles suddenly become responsive to input, and they can all start the race.
    As you can see;

    Working code - Just here for example;
    Code:
    //============================
    //<- This sub keep cars unresponsive to input until RaceBegun = True
    
    If (bRaceBegun == False && bPerformStartCheck == True)
    {
      Self.Throttle = 0;
    }
    
    If (bRaceBegun == True && bPerformStartCheck == True)
    {
      Self.Throttle = Self.Default.Throttle;
      bPerformStartCheck = False; //<- So we don't run this check any more
    }
    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.
    Last edited by BigJim; 02-21-2007 at 01:00 PM.
    OSMT - SuperApe's 2K4 Toolset for SP and Coop mappers.
    Use Of Weapons - A Single Player campaign for 2K4, built with osmt.
    Use Of Weapons: 2 - In production.

  2. #2
    MSgt. Shooter Person
    Join Date
    Jul 2006
    Location
    Inna Jungle
    Posts
    255

    Default

    I hope my quick glance at this gives me enough info...

    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)
    Last edited by SuperApe; 02-21-2007 at 01:57 PM.

  3. #3
    Redeemer
    Join Date
    Apr 2005
    Location
    Chesterfield, England
    Posts
    1,143

    Default

    Cheers mate.

    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.


    Code:
    //<- Listen for event "RaceStart"
    //================================
    Simulated Event TriggerEvent(Name EventName, Actor Other, Pawn EventInstigator)
    {
    If (EventName == 'RaceStart')
     {
       bRaceBegun = True;
       Log("RaceBegun");
       Level.Game.Broadcast(self, "Race Begun", 'Say');
     }
    //<- End Sub
    }
    Compiles fine, but doesn't do a bean in-game.
    OSMT - SuperApe's 2K4 Toolset for SP and Coop mappers.
    Use Of Weapons - A Single Player campaign for 2K4, built with osmt.
    Use Of Weapons: 2 - In production.

  4. #4
    MSgt. Shooter Person
    Join Date
    Jul 2006
    Location
    Inna Jungle
    Posts
    255

    Default

    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:
    Code:
    function Trigger( Actor Other, Pawn EventInstigator )
    {
         GroundSpeed = 2000;
    }
    For the Trigger() function, there's rarely any need to call the parent code with the Super directive.

    Like I say, I'll look at this stuff more in depth and make some suggestions when I get a (small) free block of time.

    Hang in there.

  5. #5
    Redeemer
    Join Date
    Apr 2005
    Location
    Chesterfield, England
    Posts
    1,143

    Default

    Quote Originally Posted by SuperApe View Post
    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.

    Quote Originally Posted by SuperApe View Post
    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.

    Quote Originally Posted by SuperApe View Post
    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..;

    Quote Originally Posted by SuperApe View Post
    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:
    Code:
    function Trigger( Actor Other, Pawn EventInstigator )
    {
         GroundSpeed = 2000;
    }
    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!

    Quote Originally Posted by SuperApe View Post
    Hang in there.
    I promise
    OSMT - SuperApe's 2K4 Toolset for SP and Coop mappers.
    Use Of Weapons - A Single Player campaign for 2K4, built with osmt.
    Use Of Weapons: 2 - In production.

  6. #6
    MSgt. Shooter Person
    Join Date
    Jul 2006
    Location
    Inna Jungle
    Posts
    255

    Default

    Quote Originally Posted by BigJim View Post
    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.

    Quote Originally Posted by BigJim View Post
    ...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).

    Quote Originally Posted by BigJim View Post
    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.

  7. #7
    Redeemer
    Join Date
    Apr 2005
    Location
    Chesterfield, England
    Posts
    1,143

    Default

    Quote Originally Posted by SuperApe View Post
    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.. )

    Quote Originally Posted by SuperApe View Post
    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]


    Quote Originally Posted by SuperApe View Post
    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.

    Wish me luck.
    Last edited by BigJim; 02-21-2007 at 08:55 PM.
    OSMT - SuperApe's 2K4 Toolset for SP and Coop mappers.
    Use Of Weapons - A Single Player campaign for 2K4, built with osmt.
    Use Of Weapons: 2 - In production.

  8. #8
    Redeemer
    Join Date
    Apr 2005
    Location
    Chesterfield, England
    Posts
    1,143

    Default

    Yay cracked it.

    Finally got those wee-buggers of benders to sit still until they are triggered by an Event, called by any triggering actor or a CauseEvent commandline command.


    I had to use use as lightly different method - in fact, the one I used at first;
    By inserting the following into Tick(), to keep the Cars still until a Boolean becomes True;

    Code:
    If (bVehicleActivated == False)
    {
      Self.Throttle = 0;
    }
    Else
    I can then use the following in Trigger(), to turn on that same Boolean when triggered;

    Code:
    function Trigger(Actor Other, Pawn EventInstigator)
    {
    bVehicleActivated = True;
    log('Car Triggered');
    }
    And finally, the following, to make sure that the Car listens to the trigger call;

    Code:
    simulated function PostBeginPlay() //<- Sets up Tag for use in RaceStart
    {
    Super.PostBeginPlay();
    Self.Tag = 'RaceStart';
    Self.Wheels[0].bPoweredWheel = False;//<- For better handling
    Self.Wheels[1].bPoweredWheel = False;//<- For better handling
    Self.PassengerWeapons[0].WeaponPawnClass = None;
    Self.PassengerWeapons[1].WeaponPawnClass = None;
    }
    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!
    Last edited by BigJim; 02-22-2007 at 10:25 AM.
    OSMT - SuperApe's 2K4 Toolset for SP and Coop mappers.
    Use Of Weapons - A Single Player campaign for 2K4, built with osmt.
    Use Of Weapons: 2 - In production.

  9. #9
    MSgt. Shooter Person
    Join Date
    Jul 2006
    Location
    Inna Jungle
    Posts
    255

    Default

    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.)

  10. #10
    Redeemer
    Join Date
    Apr 2005
    Location
    Chesterfield, England
    Posts
    1,143

    Default

    Quote Originally Posted by SuperApe View Post
    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.. ).
    OSMT - SuperApe's 2K4 Toolset for SP and Coop mappers.
    Use Of Weapons - A Single Player campaign for 2K4, built with osmt.
    Use Of Weapons: 2 - In production.


 

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Copyright ©2009-2011 Epic Games, Inc. All Rights Reserved.
Digital Point modules: Sphinx-based search vBulletin skin by CompletevB.com.