QueueGameScriptFunction

Started by duckwizard, Wed 09/03/2011 23:15:36

Previous topic - Next topic

duckwizard

Not sure if this belongs in the Module forums instead, but it is pretty Technical :)

I was kind of bummed on the way character events are only handled in the global script - it seemed like it would be far more useful if they could be handled in the room script instead (so characters can do different things in different rooms without having a giant mess of if/else in their single event handler).

So I wrote a simple plugin that lets you dispatch an unhandled event to the room script from unhandled_event().  When there is an unhandled event, it will figure out the character (or object) name and the action that wasn't handled, and then it will try to call the corresponding function in the room script.

Example: You have a character called cChrisJones.  When you're in room 1 and you look at him, he should say "You're in room 1!" and when you're in room 2 he should say "Toto, I've a feeling we're not in room 1 anymore!":

Code: ags

//room1.asc
function cChrisJones_Look()
{
        cChrisJones.Say("You're in room 1!");
}

//room2.asc
function cChrisJones_Look()
{
        cChrisJones.Say("Toto, I've a feeling we're not in room 1 anymore!");
}


I compiled my plugin and it works great out-of-the-box.  Except for one thing.  If I had a room with cChrisJones in it, and I didn't supply a cChrisJones_Look() function in that room script, it crashes because I'm trying to call a function that doesn't exist.

So my question is: is there any way to check if the function exists before I call it with QueueGameScriptFunction?

Thanks!

Edited: forgot to close my code block

Khris

Quote from: duckwizard on Wed 09/03/2011 23:15:36
Not sure if this belongs in the Module forums instead, but it is pretty Technical :)
You can't start a thread there anyway, the mods move the thread if it contains the publication of a new template/module so this thread doesn't really qualify yet anyway.


To be honest I don't get why you're going through all that trouble. Are you really going to have multiple characters who all give a different response in each room? Unhandled events usually produce a generic response anyway. And even if you did, using a few if-elses won't cause that much mess.

As far as I can see you're moving the event handler code around while jumping through hoops and end up with something far from being more organized.

duckwizard

I guess it is a lot of trouble.  But if I have a sidekick character in my game for example, who is there with me in all 244 rooms, and he has to say interesting things about each room, then yeah - his Talk() function in the global script is going to be pretty gnarly.  And I just think that stuff specific to a room belongs in the room script - it's just what makes sense to me as a programmer.

Ideally I would check for the room's cChrisJones_Talk function, and if it doesn't exist I would check for the cChrisJones_Talk function in the global script.  Thus it really wouldn't be that much trouble to get what I think is more organized and readable game code (the unique code in my plugin comprises about 30 lines).

But, if there's really no way to "look before you leap" when it comes to GameScriptFunction, then I guess I'll have to give up.

Wyz

#3
I've (mis)used the QueueGameScriptFunction function to create an event system for some of my plug-ins and even when the function was not defined it never made my game crash. Could you give an example about how you call the function?

edit:
Quote
It would be nice to have entity scripts, though, so the global script isn't cluttered with junk. Imagine having a script for each character, inventory item and GUI. Even if it's just a dummy that gets appended to the global script.

You should totally post about that in the wishlist topic  :)
Life is like an adventure without the pixel hunts.

Scavenger

If you aren't using speech, I guess you could use a Text Property instead. So when you click on your sidekick, he says:
Code: ags

function cChrisJones_Look()
{
        String gollygee = Room.GetTextProperty("Sidekick's Description");
        if (gollygeebatman) cChrisJones.Say ("%s", gollygee);
        else cChrisJones.Say ("Holy undefined room, Batman!");

}


Alternatively, you could use a Dialog. Just make a dialog option for each room, and turn off every other option, and when you click on your sidekick, you can have a short conversation. Just remember on loading each room to turn off every dialog option and turn on the relevant one.

You're thinking too complex. AGS has it's own foibles, but you can work with it without too much trouble.

It would be nice to have entity scripts, though, so the global script isn't cluttered with junk. Imagine having a script for each character, inventory item and GUI. Even if it's just a dummy that gets appended to the global script.

duckwizard

Quote from: Wyz on Thu 10/03/2011 00:12:36
I've (mis)used the QueueGameScriptFunction function to create an event system for some of my plug-ins and even when the function was not defined it never made my game crash. Could you give an example about how you call the function?

It doesn't seem like there are many other ways to call the function:

Code: ags

engine->QueueGameScriptFunction(funcName, 0, 0);


where funcName contains the name of the function I wanted to call in the room script.  If the function exists, it gets called.  If not, I get a crash: "Error: prepare_script: error -18 (no such function in script) trying to run cMerlin_Talk (Room 9)"

Wyz

#6
I seem to be unable to reproduce that error. I've tried for both global and room scope; when I call for a non-existing function simply nothing happens. I've tested this with AGS 3.1.2, what version did you use?
Life is like an adventure without the pixel hunts.

duckwizard

I am using v3.1.2 SP1 (Build 3.1.2.82).  Just downloaded it a few days ago.  Windows 7, 64-bit, if that matters (which I don't think it does, since it seems like an error that was designed to be thrown in this situation.  Unfortunately.)

SMF spam blocked by CleanTalk