Page 1 of 1

Function passing "Event Actor"

PostPosted: Fri Jul 31, 2009 12:09 pm
by DST
What is the proper usage of actor to be able to write such a function?

I've tried every combination of Actor *, char* , etc. etc. But i cannot seem to use Event Actor to call a custom function.

void explode(Actor *spawner, int xsize, int ysize, int iterations, int time){
}

for instance, does not work.

Re: Function passing "Event Actor"

PostPosted: Fri Jul 31, 2009 8:56 pm
by skydereign
Isn't passing "Event Actor" a const char *? You can use the actor's name, which works as such. I think that is what you were asking, I don't see other reasons to pass "Event Actor", but maybe....

Re: Function passing "Event Actor"

PostPosted: Sat Aug 01, 2009 2:52 am
by DST
If i have to use the actor's name, then the function won't be universal, which is the whole point of making it.

Re: Function passing "Event Actor"

PostPosted: Sat Aug 01, 2009 4:05 am
by skydereign
Oh, I thought you were trying to use "Event Actor" in your call. You want to give it Event Actor so any function will know to use the event actor. To do what you want, you would have to get the right Actor *, but that would eliminate the point of using Event Actor. I think it is only for built in use, so you might as well grab the right Actor *, maybe... But since the actor variables are present for the actor carrying out your custom event, then can't you use that? This is because only actors can do events, so "Event Actor" works for gE functions, and you bypass it with custom ones, right? Maybe I still don't get it...

Re: Function passing "Event Actor"

PostPosted: Sat Aug 01, 2009 3:03 pm
by pyrometal
You cannot pass "Event Actor" and such names inside your function and expect them to work without coding the behavior inside the function, though you certainly can, but there is a much easier way to accomplish the same feat with very little code!

WARNING: Your knowledge about pointers is critical here if you want to fully understand what's happening!

Put this code inside a global script:
Code: Select all
#define CNAME_THIS    ((char*)(clonename))
#define CNAME_PARENT  ((char*)(parent.clonename))
#define CNAME_CREATOR ((char*)(creator.clonename))
#define CNAME_COLLIDE ((char*)(collide.clonename))

//To modify an actors variables (x, y, velocity, etc...) do something like this!
void ActorToRelativeCenter(char*name)
{
    Actor*instance = getclone(name);
    instance->xvelocity = 0;
    instance->yvelocity = 0;
    instance->x = 0;
    instance->y = 0;
}


The dud function "ActorToRelativeCenter()" simply sets the actor coordinates and velocity to 0. This could be the game center if the actor concerned has no parent, or if it does, it will be put directly on top of the parent. This function isn't really useful, but it demonstrates some important principles.

Here, we use the "getclone();" function to retrieve an "actor pointer" to the actor whose clonename was passed to our own function and store it inside the "instance" actor pointer. We need this in order to modify the actor variables of the concerned actor. To do this, we use the pointer along with the indirect dereference operator (->) then specify the variable field we are interested in (in this case: x, y, xvel, yvel), and finally proceed on to assigning the value of zero to all of them.

This method may be used by any of your custom functions to access the actor's variables. In the case that you want to use one of GE's predefined functions like "DestroyActor()" which also requires the name of the actor to be passed to it, simply use it the following way inside your function:

Code: Select all
DestroyActor(name);  //"name" being the the variable pointing to the name of the actor


At any rate this isn't everything. As you may have guessed, statements such as "Event Actor" and "Parent Actor" are unusable. So how do we accomplish this? It's actually quite simple! You simply need to pass the "clonename" variable to the function inside an actor's scripts! Here's how to do it:

Code: Select all
ActorToRelativeCenter((char*)clonename);           //equivalent to "Event Actor"
ActorToRelativeCenter((char*)(parent.clonename));  //equivalent to "Parent Actor"
ActorToRelativeCenter((char*)(collide.clonename)); //equivalent to "Collide Actor"
ActorToRelativeCenter((char*)(creator.clonename)); //equivalent to "Creator Actor"


This works, and you can also just use the specific actor clonenames if you know them in advance , like "view" or "snake.3" etc. The arguments inside function look very messy and puzzling don't they? Personally, I wouldn't want to be typing this crap all the time I want to an especial actor... SO to simplify this nightmare we can use #define statements in our global code! They were in the top most code snippet, but her they are again!

Code: Select all
#define CNAME_THIS    ((char*)(clonename))
#define CNAME_PARENT  ((char*)(parent.clonename))
#define CNAME_CREATOR ((char*)(creator.clonename))
#define CNAME_COLLIDE ((char*)(collide.clonename))


For those whom don't know how to use the C Preprocessor directives, I suggest Google. In brief now we can use these new keywords substitute all that ugly code for us! Here's the cleaner version of the code:

Code: Select all
ActorToRelativeCenter(CNAME_THIS);    //equivalent to "Event Actor"
ActorToRelativeCenter(CNAME_PARENT);  //equivalent to "Parent Actor"
ActorToRelativeCenter(CNAME_COLLIDE); //equivalent to "Collide Actor"
ActorToRelativeCenter(CNAME_CREATOR); //equivalent to "Creator Actor"


And that is all!

To summarize, we have just created a function "ActorToRelativeCenter()" which is capable of taking the clonename of any actor including the relativistic "Event Actor", "Parent Actor", etc, and operate upon those actors the same way GE's standard functions do!

If you have any other questions about this topic, feel free to ask. Bye now!

--pyro