View previous topic :: View next topic |
Author |
Message |
Willem
Joined: 23 Jan 2008 Posts: 73
|
Posted: Thu Feb 14, 2008 3:52 pm Post subject: Calling function on a specific entity |
|
|
So I'm hacking around with some stuff and have a question. I know QuakeC isn't object oriented so you can't call methods within entities but at the same ... man, that would be handy.
I find myself setting up stuff like changing an entities think function to point to a function where I can do something to the entity and then it changes it back to it's regular think. This works but it feels ... hacky and smells bad.
Is there a more elegant way to call functions on an entity that you've just spawned (for example) than this, or is this the only way and I'm wasting time benig annoying about it?
For example, say I have an entity that spawns a monster_army. I then want to call a function on that entity. This is how I currently do it:
myentity = spawn();
myentity.think = monster_army_myinitfunction;
myentity.nextthink = time + 0.01;
And then monster_army_myinitfunction will get called next frame. Which works. But it smells bad. Is there a better way? _________________ www.wantonhubris.com |
|
Back to top |
|
 |
Wazat
Joined: 15 Oct 2004 Posts: 732 Location: Middle 'o the desert, USA
|
Posted: Thu Feb 14, 2008 5:19 pm Post subject: |
|
|
Well, there's:
myentity = spawn();
// call init function with self pointing to the new entity
oldself = self;
self = myentity;
monster_army_myinitfunction();
self = oldself; // get self back to what it used to be
That's the standard way of doing it in QC. I hope it helps. _________________ When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work. |
|
Back to top |
|
 |
FrikaC Site Admin

Joined: 08 Oct 2004 Posts: 947
|
Posted: Thu Feb 14, 2008 5:24 pm Post subject: |
|
|
The more common way to do it is:
Code: |
local entity oself;
...
oself = self;
self = spawn();
monster_army_myinitfunction();
self = oself;
|
This has the advantage that it's done immediately, not when the engine gets around to calling thinks on your new entity, so if there's any setup you're reliant upon it will be done right away.
Prydon Gate encapsulated this behavior in a function because I found myself doing it a lot. This requires fteqcc/frikqcc to be properly parsed however.
Code: |
void(entity e, void() func) call =
{
local entity oself;
oself = self;
self = e;
func();
self = oself;
};
|
With this function, you can then simplify the above code to:
Code: |
call (spawn(), monster_army_myinitfunction);
|
Additional versions of call can be created taking more parameters for the function & offering back return values. It's not totally ideal, but it really helps clean up code on occasion. [/code] |
|
Back to top |
|
 |
Willem
Joined: 23 Jan 2008 Posts: 73
|
Posted: Thu Feb 14, 2008 5:55 pm Post subject: |
|
|
Thanks guys! It never occured to me that "self" would be writable. Nice! _________________ www.wantonhubris.com |
|
Back to top |
|
 |
Urre

Joined: 05 Nov 2004 Posts: 1073 Location: Sweden
|
Posted: Fri Feb 15, 2008 8:51 am Post subject: |
|
|
One should also note that as long as you're using NetQuake (that is, not QuakeWorld) you can do
Code: | myentity.nextthink = time; |
which makes it call the think function the very next server frame, no matter the framerate, whereas time + 0.01 wouldn't be called the next frame if the fps is above 100, which isn't that uncommon in a singleplayer game for example. This is especially useful when you want to do funky things like physics in QC, which require execution every frame, and advanced AI like bots often use this as well. _________________ Look out for Twigboy |
|
Back to top |
|
 |
|