Frame 0 bug workarounds ?

ABK

Well-known member
Player picks up weapon - item entity for the weapon disappears once GET anim is played and all is good - now im binding that picked up weapon to the player , the issue is - i cant do it from frame 0 cause it most of the time is not appearing, its the nasty frame 0 "bug" .

Some people know it, some say it does not exist and its not a bug( cause of how animationscripts are updated just once per frame but somehow first frame is not properly updated on init ), id say it is very very true issue even if its supposed to be like this and i had to give up a lot of mechanics in games because of it.
So what are Your workarounds for this? I tried very long delays on frame 0 , very short delays on frame 0 - nothing, sometimes binded entity is just not spawned, it must be on frame 1.

Because of this - i have a blink, where picked up weapon disappears, and if its big enough , it is pretty noticeable.

How to solve this ? By turning animationscripts to inline ?

So absolute fastest way to spawn it is with if ( har == NULL() ) but it still does the blink, even if delay is 1


Another way that would save me - having DEATH animation in item entity, so after i pickup item - its DEATH animation is played while player plays his GET animation. But is that even doable ? No info on how to trigger DEATH with item objects on pickup. Sure- i can spawn a clone, but no, i dont want to cause i plan to do a lot more weapons like this and it will be ton of clones of clones just for displaying one frame for milisecond.

Code:
anim    get
    loop    0
    offset    92 309
    bbox none
                @script
                void self = getlocalvar("self");
                 void har;
             if ( frame == 1  ){
                clearspawnentry();
    setspawnentry("name", "drumbind");
    har = spawn();
    setentityvar(self, 0, har); // Store 'har' in an entityvar of 'self'
   bindentity(har, self, 30, 0, 0, -1, 6,1);
        }
 
  
                     if ( frame == 3 ){
    bindentity(har, self, 0, 0, 20, -1, 6,1 );
        }
                     if ( frame == 4 ){
    bindentity(har, self, -10, 0, 80, -1, 6,1 );
        }
                     if ( frame == 5 ){
    bindentity(har, self, -20, 0, 200,-1,  6,1 );
        }
                     if ( frame == 6 ){
    bindentity(har, self, -35, 0, 280,-1, 6,-1 );
        }
    @end_script
    delay 2
alphamask data/chars/heman/get_001-mask.png
frame    data/chars/heman/get_001.png
delay  7
alphamask data/chars/heman/get_002-mask.png
frame    data/chars/heman/get_002.png
alphamask data/chars/heman/get_003-mask.png
frame    data/chars/heman/get_003.png
alphamask data/chars/heman/get_004-mask.png
frame    data/chars/heman/get_004.png
alphamask data/chars/heman/get_005-mask.png
frame    data/chars/heman/get_005.png
alphamask data/chars/heman/get_006-mask.png
frame    data/chars/heman/get_006.png
alphamask data/chars/heman/get_007-mask.png
frame    data/chars/heman/get_007.png
 
Last edited:
Two points here:

Some people know it, some say it does not exist and its not a bug( cause of how animationscripts are updated just once per frame but somehow first frame is not properly updated on init ), id say it is very very true issue even if its supposed to be like this and i had to give up a lot of mechanics in games because of it.
Yep, its not a bug. I used to call it bug but, in fact, it isnt. As you said, the update will occur on the next tick.

"But some things doesn't work on the first tick, so how it cannot be a bug?"
The answer is: the user did it wrong, not the engine. In your case, you are relying in animationscript for that, which takes action just after the engine update.
This is one of the cases where you need to use updatescript, because it will fire while the updating is happening.

Another way that would save me - having DEATH animation in item entity, so after i pickup item - its DEATH animation is played while player plays his GET animation. But is that even doable ? No info on how to trigger DEATH with item objects on pickup. Sure- i can spawn a clone, but no, i dont want to cause i plan to do a lot more weapons like this and it will be ton of clones of clones just for displaying one frame for milisecond.

If I am not mistaken, Items doesn't have DEATH animation. But you can do it by script.

About the clones, there is a trick for that - I always forgot the make a tutorial about it, so I will make a topic and link it back here later.
 
yeah i know about didhitscript in items, but i dont want separate entity just for spawning it for 1 frame, looks like i will have to...
and i think i will just bind entity with didhitscript ... this should solve it.

Ok im trying to acquire player that is picking up the item, im getting vt empty, so what happened ? opp is not acwquired anymore since item is dead so there is no opp ? so how to acquire it properly so it persists ?


Code:
didhitscript @script
void main() {
    void self = getlocalvar("self");
   void opp = getentityproperty(self, "opponent");
    void har;
    clearspawnentry();
    setspawnentry("name", "drumbind");
    har = spawn();
   settextobj(1, 220 , 220 , 0, -1, opp , openborvariant("elapsed_time")+170);
    bindentity(har, opp, 30, 0, 0, -1, 6,1);
}
@end_script
 
Last edited:
Ok im trying to acquire player that is picking up the item, im getting vt empty, so what happened ? opp is not acwquired anymore since item is dead so there is no opp ? so how to acquire it properly so it persists ?
Because "didhitscripts" happens AFTER the hit had confirmed, so the item is already dead. Try using "ondoattack" instead.
 
ok...
is it

ondoattackscript @script
or
ondoattack @script

or i simply cant have it near header ?
Dont wanna separate c files , wanna self contained entities.
ondoattack does not show any debug info so i asume its not even triggering
 
ok this does not work too, still looking for solution to acquire attacker as item, maybe item is totally different case and there is no "opponent" at all caues item is picked up and not attacked

Code:
Ondeathscript @script
void main() {
    void self = getlocalvar("self");
   void opp = getentityproperty(self, "opponent");
    void har;
    clearspawnentry();
    setspawnentry("name", "drumbind");
    har = spawn();
   settextobj(1, 220 , 220 , 0, -1, opp , openborvariant("elapsed_time")+170); 
    bindentity(har, opp, 30, 0, 0, -1, 6,1);
}
@end_script
 
worst case id hjave to seek for nearest player which is not ideal at all since 2 can be close to this weapon but maybe detecting anim ID as GET can pinpoint it precisely
also its not player type anymore ? since weapon models are not player but "none"
 
@bWWd,

Why not use didhitscript on the item? It fires on item pickup exactly for this kind of thing. The "hit" entity is the one that picked item up.

This guarantees the right entity is targeted and that any animation or effects you want are timed correctly.

Items don't have a death routine, but nothing stops you from manually running a death or follow animation to get the look you want.

DC
 
Player picks up weapon - item entity for the weapon disappears once GET anim is played and all is good - now im binding that picked up weapon to the player , the issue is - i cant do it from frame 0 cause it most of the time is not appearing, its the nasty frame 0 "bug" .
Especifically about this part, like Ilu said it's not a bug mainly because you are in the middle of an entire model change process. So, it's comprehensive that some tasks are skipped at frame 0.

However, a simple workaround that works for me is by simply jumping the first frame, applying a delay value of 1 and then proceeding normally from the second frame onwards.

C:
anim get
    loop    0
    delay    1
    offset    130 163
    frame    data/chars/heroes/zan/get00.png
        delay    16
    @cmd bindPos "Zan_Orb1" -18 1 1
    frame    data/chars/heroes/zan/get00.png

 
ondoattackscript @script
or
ondoattack @script
So far I know this does not exist through inline scripts in the engine, ondoattack/didhit must have separated .c files to trigger these events.
Using the DC didhit tip as an example, you must call the "damagetaker" in order to get the damaged entity (in this case is the "food" that is damaging player and not the opposite").

Here's the food didhitscript:
C:
void main()
{//Alternative method to play "get food" sample
    void self    = getlocalvar("self");
    void player    = getlocalvar("damagetaker");
    void name    = getentityproperty(player, "defaultname");
    int health    = getentityproperty(self, "health");

    sound("data/sounds/sor3_food.wav");
    itemText(name+"_+"+health); //SHOW THE PLAYER WHO PICKED UP THE FOOD
}

C:
name            Chicken
type            item
health            100
nolife            1
facing             1
gfxshadow        1 1
didhitscript    data/scripts/didhit/food.c

 
Neat, now im in the process of having item entity that is changing to pickable when player is close on top of it and to hittable obstacle when player is punch-reach distance, this way i can have barrel drums that i can hit or pickup.So far it works ok. I will probably use didhit with damagetaker to acquire pickedup item name and bind the right ones automatically.
Im creating universal picking up mechanics so i can have whatever item/obstacle/enemy entity i want and its bind to player, can be hit and can be picked up depending on how far player is from it

To think that all of this could be avoided if we had death for items that simply plays some effect of being taken...
 
To think that all of this could be avoided if we had death for items that simply plays some effect of being taken...
According to my tests, indeed picked up items didn't die, they are only hidden. So this idea would not work even if type items had an ondeath scripts.
But the didhit does the same job, acting in the exact moment when items are picked up.

Another idea would be creating a copy of the item entity but as an obstacle type and then binding each other. This way both will work at the same time with their own properties, then you can use all the available script events to change one when another is affected.

EDIT: Sorry, I said about items not dying and staying hidden, but it's for weapon item entities. For foods they are removed after a certain time but it seems that this is a direct removal like the killentity does, not triggering any death routine.
 
Last edited:
Back
Top Bottom