We have a model entity with a bright red light at it's very centre. For improving the light effect, we've attached a flare sprite to that model:
action red_model
{
ent_create ("light.pcx", my.x, flare_light); // attach light sprite
patrol(); // perform move behavior
}
action flare_light
{
my.bright = ON; // make light more brilliant
my.facing = ON; // always face the camera
while (1)
{
vec_set(my.x,you.x); // place the sprite at the xyz position of the entity who created it
wait(1);
}
}
We expected that the light sprite is fixed to the center of the model, and moves together with it. However it always seems to lag behind by one frame. And even worse, the model now moves at only half the speed as before! What's happening?
The second problem is easy to fix: We've forgotten to make the light passable. So the model permanently collides with it's own light, which halves its speed. Entities attached to other ones must get the passable flag:
action flare_light
{
my.passable = on;
... // etc.
But what produces the strange time lag? If two entities influence
each other, it's important to keep in mind the order of their two
simultaneously running actions. They won't run really at the same time. In the
example, during one frame the function scheduler runs first the flare_light
action, and then the red_model's patrol action. Functions that are started
first will run first. So the flare_light is always placed to the position the
red_model had in the frame before. The solution is simple: By changing the
order of the actions ...
action red_model
{
patrol(); // perform move behavior first
ent_create ("light.pcx", my.x, flare_light); // attach light sprite and start it's action after that
}
...the light stays perfectly at the entities' center. We could
alternatively use PROC_LATE for changing the order of actions.
For the same reason, a function moving a shadow sprite must
always be called after the movement function of the entity.