Time Limit within Looping Animation on Air

maxman

Well-known member
I see references from @Bloodbane's Avengers Template and floater script, as well as @DCurrent's paus0001 script, for a time limit on a looped animation. The entity's animation loops while it's on air. It's like Magneto's flying mode from X-Men VS Street Fighter where you can do any air attack until time expires, and he drops himself off to the ground.

With this looped animation as an example and it also has floater for floating.
Code:
anim    follow1
    loop    1
    delay    1
    offset    66 135
    bbox    44 44 30 74
    frame    data/chars/Ironman/j0.gif
    delay    8
    @cmd    keyflip 0
    @cmd    keymove 1.2 0.6
    @cmd    floater 49
    frame    data/chars/Ironman/j0.gif
    frame    data/chars/Ironman/j1.gif
    frame    data/chars/Ironman/j0.gif
    @cmd    keyflip 0
    @cmd    keymove 1.2 0.6
    frame    data/chars/Ironman/j1.gif
    frame    data/chars/Ironman/j0.gif
    @cmd    keyflip 0
    @cmd    keymove 1.2 0.6
    frame    data/chars/Ironman/j1.gif

I tried no loop on the same animation but with same frames for better movement, but every time I do one of the attacks, I used an animation script to revert back to the same animation without changing to a certain frame. What I'm trying to do is to sync within time limit to fit the rhythm of having a time limit like flying characters with air attacks like Magneto.

I want to give a time limit similar to the way paus0001 does. However, I have no clue how to emulate the way the time value for freezing works.

C:
void paus0001(int iToggle, int iTime){

    /*
    paus0001
    Damon Vaughn Caskey
    11022009
    Pause or unpause action for all entities except self.
    */

    void vSelf      = getlocalvar("self");                  //Caller   
    int  iETime     = openborvariant("elapsed_time");       //Current time.
    int  iMax       = openborvariant("ent_max");            //Entity count.
    int  iEntity;                                           //Loop counter.
    void vEntity;                                           //Target entity.

    for(iEntity=0; iEntity<iMax; iEntity++)
    {   
        vEntity = getentity(iEntity);                                       //Get target entity from current loop.       
        
        if (vEntity != vSelf)                                               //Not Self?
        {
            changeentityproperty(vEntity, "frozen", iToggle);               //Toggle frozen.
            changeentityproperty(vEntity, "freezetime", iETime + iTime);    //Toggle frozen time.
        }
    }   
}

Code:
anim follow20 #SHINKU HADOKEN
    offset 97 177
    delay 8
    bbox 78 82 44 96
    @cmd    stop
    @cmd setindexedvar "fightStarted" 1
    @cmd paus0001 1 200
    frame data/CHARS/ARyu/shnhdk01.png
    frame data/CHARS/ARyu/shnhdk02.png
    sound data/sounds/ryu/shinku.wav
    frame data/CHARS/ARyu/shnhdk03.png
    delay 70
    frame data/CHARS/ARyu/shnhdk04.png
    delay 8
    sound data/sounds/ryu/hadoken.wav
    bbox 80 86 63 92
    frame data/CHARS/ARyu/shnhdk05.png
    bbox 86 91 65 88
    @cmd spawnAndThrow "shinhado" 80 0 70 0.9 NULL() NULL()
    frame data/CHARS/ARyu/shnhdk06.png
    frame data/CHARS/ARyu/shnhdk07.png
    frame data/CHARS/ARyu/shnhdk08.png
    frame data/CHARS/ARyu/shnhdk09.png
    bbox 86 89 60 90
    frame data/CHARS/ARyu/shnhdk10.png
    bbox 86 86 56 93
    frame data/CHARS/ARyu/shnhdk11.png
    bbox 86 81 51 97
    frame data/CHARS/ARyu/shnhdk12.png
    bbox 80 79 39 99
    frame data/CHARS/ARyu/shnhdk13.png
    frame data/CHARS/ARyu/shnhdk14.png

Let's say, for example, I have Iron Man floating with his looping animation. I can move using keymove and keyflip, and floater makes him remain on air. However, I need something that gives time value like paus0001 for remaining on air without floating forever. It's kinda like @cmd norun 1 which is at the last frame of anim run when it loops. You keep running until it stops. I'd like to do air attacks before time expires. I don't wanna keep doing air attacks forever while the animation is looping after being reverted. How can I get that to do air attacks within a certain time limit while the floating animation loops?
 
floater function is the one holding Ironman in his floating state. So if you want to give timed floating state, you could code timed floater function which only apply floating when timer hasn't run out.
This function would require recording start of the timer and resetting the timer on landing. For the timer, it depends on how floating is triggered. In Ironman's case, it is when jump key is pressed while jumping.
 
This function would require recording start of the timer and resetting the timer on landing. For the timer, it depends on how floating is triggered.
How can I identify recording time starter and resetting the timer?

OK. Here's the concept on what I'm trying to make with the flying animation within the time limit.
time limit within floating animations.png

I tried using entityvar many times for this, but I don't know what I'm doing with this. I'm sure I got 'em wrong here.

C:
void floatTimer(int Time, void Ani)
{// Floats in Time centiseconds
    void self = getlocalvar("self");
    int eTime = openborvariant("elapsed_time");
    int vari = getentityvar(self, "vari");

    if(vari <= Time){
    //    setentityvar(self, "vari", Time);
        changeentityproperty(self, "tosstime", eTime + 2*Time);
    //    performattack(self, Ani);
    }

    changeentityproperty(self, "tosstime", eTime + 2*Time);
    //performattack(self, Ani);

  
    if(vari > Time){
        //changeentityproperty(self, "tosstime", eTime + 2*Time);
        //setentityvar(self, "vari", NULL());
        performattack(self, Ani);
    }
  
}

C:
void floatTimer(int Time, void Ani)
{// Floats in Time centiseconds
    void self = getlocalvar("self");
    int eTime = openborvariant("elapsed_time");
    int vari = getentityvar(self, "vari");

    if(vari == NULL()){
        setentityvar(self, "vari", 0);
    //    changeentityproperty(self, "tosstime", eTime + 2*Time);
        performattack(self, Ani);
    }

    //changeentityproperty(self, "tosstime", eTime + 2*Time);
    //performattack(self, Ani);

  
    if(vari == 1){
        changeentityproperty(self, "tosstime", eTime + 2*Time);
        setentityvar(self, "vari", NULL());
        //performattack(self, Ani);
    }
  
}

Attack from flying animation:
Code:
anim follow4 #attack from flying animation
    delay 4
    offset 5 99
    frame data/chars/hero03/flatk00.png
    frame data/chars/hero03/flatk01.png
    frame data/chars/hero03/flatk02.png
    @cmd anichange "ANI_FOLLOW1"
    frame data/chars/hero03/flatk02.png

Flying animation:
Code:
anim    follow1
    loop    1
    delay    1
    offset    66 135
    bbox    44 44 30 74
    frame    data/chars/Ironman/j0.gif
    delay    8
    @cmd    keyflip 0
    @cmd    keymove 1.2 0.6
    @cmd    floatTimer 49 openborconstant("ANI_WALKOFF")
    frame    data/chars/Ironman/j0.gif
    frame    data/chars/Ironman/j1.gif
    frame    data/chars/Ironman/j0.gif
    @cmd    keyflip 0
    @cmd    keymove 1.2 0.6
    frame    data/chars/Ironman/j1.gif
    frame    data/chars/Ironman/j0.gif
    @cmd    keyflip 0
    @cmd    keymove 1.2 0.6
    frame    data/chars/Ironman/j1.gif

Yes, I use attack button during flying animation with keyscript.

Keyscript:
C:
void main(){
    void self = getlocalvar("self");
    int index = getentityproperty(self, "playerindex");
    void ani = getentityproperty(self, "animationid");
    int attack = playerkeys(index, 1, "attack");
    int attack2 = playerkeys(index, 1, "attack2");
    int attack3 = playerkeys(index, 1, "attack3");
    int attack4 = playerkeys(index, 1, "attack4");
    int jump = playerkeys(index, 1, "jump");
    int special = playerkeys(index, 1, "special");

    if(jump){ // Press jump?
        if(ani == openborconstant("ANI_FOLLOW1")){ // Is the character floating
            performattack(self, openborconstant("ANI_WALKOFF")); // Do something like drop off
        }
    }

    if(ani == openborconstant("ANI_FOLLOW1")){ // Is the character floating
        if(attack){ // Press attack?
            performattack(self, openborconstant("ANI_FOLLOW3"));
        }else if(attack2){ // Press attack2?
            performattack(self, openborconstant("ANI_FOLLOW11"));
        }else if(attack4){ // Press attack4?
            performattack(self, openborconstant("ANI_FOLLOWL29"));
        }else if(special){ // Press attack3?
            performattack(self, openborconstant("ANI_FOLLOW5"));
        }
    }
}
 
Last edited:
I've reviewed flying mode scripts and recalled that I've set floating time twice, once in keyscript and the other in the floating animation.
For my suggestion above, you don't need to record start of the timer and instead just set total floating time in keyscript, and without declaring floater in the animation.
It should be like this in keyscript (originally ironkey.c):
C:
    if(iJump){
      if(vAniID == openborconstant("ANI_JUMP")){
        changeentityproperty(vSelf, "animation", openborconstant("ANI_FOLLOW1"),2);
        changeentityproperty(vSelf, "tosstime", eTime + 5*200); // 5 seconds.
        changeentityproperty(vSelf, "velocity", 0, 0, 0);
      } else if(vAniID == openborconstant("ANI_FOLLOW1")){
        changeentityproperty(vSelf, "animation", openborconstant("ANI_JUMP"),2);
        changeentityproperty(vSelf, "tosstime", eTime);
        updateframe(vSelf, 3);
      }
    }

The above tosstime setting to 5 seconds.
Without floater function, the floating will not be reapplied IOW after 5 seconds, character will fall.

After floating time is up, character falls without changing animation. The latter would require different script.
[The next day]
If you want changing animation after certain time period, you can use this function:
C:
void TimeAni(int Time, void Ani)
{// Changes to other animation after certain defined time has elapsed
// Time : Time in seconds.
// Ani : Animation to change to
    void self = getlocalvar("self");
    int TPhase = getentityvar(self, "Phase");
    int eTime = openborvariant("elapsed_time");
    int Cd = openborconstant(Ani);

    if(TPhase==NULL()){
      setentityvar(self, "Phase", eTime);
    }

    if(eTime - TPhase >= Time*200){
      setentityvar(self, "Phase", NULL());
      performattack(self, Cd);
    }
}

Usage example:
Code:
anim    freespecial5
    loop    1 5 12
    delay    5
    offset    97 190
        sound   data/chars/ryu/tatsu.wav
    frame    data/chars/ryu/sp01.gif
    frame    data/chars/ryu/sp02.gif
    frame    data/chars/ryu/sp03.gif
    seta    15
    frame    data/chars/ryu/sp04.gif
        delay   3
    frame    data/chars/ryu/sp05.gif
    frame    data/chars/ryu/sp06.gif
        attack    88 68 82 95 21 1
    dropv    2 4 0
    frame    data/chars/ryu/sp07.gif
    frame    data/chars/ryu/sp08.gif
        attack    19 72 84 94 21 1
    dropv    2 4 0
    frame    data/chars/ryu/sp09.gif
    frame    data/chars/ryu/sp10.gif # 10
    frame    data/chars/ryu/sp11.gif #
    @cmd    TimeAni 5 "ANI_FOLLOW5"
    frame    data/chars/ryu/sp05.gif
    frame    data/chars/ryu/sp06.gif
        attack    88 68 82 95 21 1
    dropv    2 4 0
    frame    data/chars/ryu/sp07.gif
    frame    data/chars/ryu/sp08.gif
        attack    19 72 84 94 21 1
    dropv    2 4 0
    frame    data/chars/ryu/sp09.gif
    frame    data/chars/ryu/sp10.gif
    frame    data/chars/ryu/sp11.gif #

Here, Ryu will perform spinning kick for at least 5 seconds before TimeAni function changes his animation to FOLLOW5.

You can use this function for your purpose but don't forget to disable floating state after changing animation.
 
Last edited:
Back
Top Bottom