Damaged state for entities and damaged pain animation

Mr.Q!

Well-known member
I have this pillar entity that after receiving damage it turns into a damaged version of itself, it changes from its normal idle animation into a desired follow animation after some % of damage. Thing is, despite working well, whenever I hit it, it changes into his "no damaged" pain animation, and it looks wrong of course, because it has already received some damage.

Is there any way in this .txt to tell the engine to use a desired anim follow instead the normal anim pain? Like, if it's using its anim follow2, it should use anim follow7 as anim pain, etc.

You can take a look at the attached image for reference.


Code:
anim spawn
     loop      0
     delay     1
     offset    40 144
     bbox      0
platform 13 149 -10 -10 64 64 10 150
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif
sound    data/sounds/fallbr3.wav
@cmd landFrame
@cmd spawn001 "gslam1" "gslam1" 0 0 0 0 0
@cmd spawn001 "fslam1" "fslam1" 0 0 0 0 0
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif


anim idle
@script
 void self = getlocalvar("self");
 int hp = getentityproperty(self, "health");
 int maxhp = getentityproperty(self, "maxhealth");
 if(hp <= 0.7*maxhp){
  changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW1"));
 }
@end_script
     loop      0
     delay     1
     offset    40 144
     bbox      15 23 50 123
platform 13 149 -10 -10 64 64 10 150
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif

anim follow1
@script
 void self = getlocalvar("self");
 int hp = getentityproperty(self, "health");
 int maxhp = getentityproperty(self, "maxhealth");
 if(hp <= 0.4*maxhp){
  changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW2"));
 }
@end_script
     loop      0
     delay     1
     offset    40 144
     bbox      15 23 50 123
platform 13 149 -10 -10 64 64 10 150
     frame     Data/bgs/bonus/ffury2/ff2pilar2.gif
     frame     Data/bgs/bonus/ffury2/ff2pilar2.gif

anim follow2
@script
 void self = getlocalvar("self");
 int hp = getentityproperty(self, "health");
 int maxhp = getentityproperty(self, "maxhealth");
 if(hp <= 0.2*maxhp){
  changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW3"));
 }
@end_script
     loop      0
     delay     1
     offset    40 144
     bbox      15 23 50 123
platform 13 149 -10 -10 64 64 10 150
     frame     Data/bgs/bonus/ffury2/ff2pilar3.gif
     frame     Data/bgs/bonus/ffury2/ff2pilar3.gif

anim follow3
     loop      0
     delay     1
     offset    40 144
     bbox      15 23 50 123
platform 13 149 -10 -10 64 64 10 150
     frame     Data/bgs/bonus/ffury2/ff2pilar4.gif
     frame     Data/bgs/bonus/ffury2/ff2pilar4.gif

anim pain
     loop      0
     delay     2
     offset    39 144
     bbox      15 23 50 123
platform 13 149 -10 -10 64 64 10 150
sound    data/sounds/debris1.wav
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif
     offset    40 144
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif
     offset    39 144
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif
     offset    40 141
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif
 

Attachments

  • Untitled-1.png
    Untitled-1.png
    37.6 KB · Views: 3
Last edited:
I have this pillar entity that after receiving damage it turns into a damaged version of itself, it changes from its normal idle animation into a desired follow animation after some % of damage. Thing is, despite working well, whenever I hit it, it changes into his "no damaged" pain animation, and it looks wrong of course, because it has already received some damage.

Is there any way in this .txt to tell the engine to use a desired anim follow instead the normal anim pain? Like, if it's using its anim follow2, it should use anim follow7 as anim pain, etc.

You can take a look at the attached image for reference.


Code:
anim spawn
     loop      0
     delay     1
     offset    40 144
     bbox      0
platform 13 149 -10 -10 64 64 10 150
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif
sound    data/sounds/fallbr3.wav
@cmd landFrame
@cmd spawn001 "gslam1" "gslam1" 0 0 0 0 0
@cmd spawn001 "fslam1" "fslam1" 0 0 0 0 0
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif


anim idle
@script
 void self = getlocalvar("self");
 int hp = getentityproperty(self, "health");
 int maxhp = getentityproperty(self, "maxhealth");
 if(hp <= 0.7*maxhp){
  changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW1"));
 }
@end_script
     loop      0
     delay     1
     offset    40 144
     bbox      15 23 50 123
platform 13 149 -10 -10 64 64 10 150
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif

anim follow1
@script
 void self = getlocalvar("self");
 int hp = getentityproperty(self, "health");
 int maxhp = getentityproperty(self, "maxhealth");
 if(hp <= 0.4*maxhp){
  changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW2"));
 }
@end_script
     loop      0
     delay     1
     offset    40 144
     bbox      15 23 50 123
platform 13 149 -10 -10 64 64 10 150
     frame     Data/bgs/bonus/ffury2/ff2pilar2.gif
     frame     Data/bgs/bonus/ffury2/ff2pilar2.gif

anim follow2
@script
 void self = getlocalvar("self");
 int hp = getentityproperty(self, "health");
 int maxhp = getentityproperty(self, "maxhealth");
 if(hp <= 0.2*maxhp){
  changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW3"));
 }
@end_script
     loop      0
     delay     1
     offset    40 144
     bbox      15 23 50 123
platform 13 149 -10 -10 64 64 10 150
     frame     Data/bgs/bonus/ffury2/ff2pilar3.gif
     frame     Data/bgs/bonus/ffury2/ff2pilar3.gif

anim follow3
     loop      0
     delay     1
     offset    40 144
     bbox      15 23 50 123
platform 13 149 -10 -10 64 64 10 150
     frame     Data/bgs/bonus/ffury2/ff2pilar4.gif
     frame     Data/bgs/bonus/ffury2/ff2pilar4.gif

anim pain
     loop      0
     delay     2
     offset    39 144
     bbox      15 23 50 123
platform 13 149 -10 -10 64 64 10 150
sound    data/sounds/debris1.wav
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif
     offset    40 144
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif
     offset    39 144
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif
     offset    40 141
     frame     Data/bgs/bonus/ffury2/ff2pilar1.gif


There's a couple of techniques you could use.

Just for simplicity, I would simply reverse it. Instead of scripting the damaged animation on hit, make the damaged version the default state, and script the undamaged animation on spawn. Then all you have to do is let it go back to normal once hit. That way you're not fighting anything once it starts taking damage.

DC
 
Hmm can you provide an example? Because the thing I would want is to trigger a different animation instead of the normal pain animation, it should reflect the current damage that it has taken.

For example, if it's 100% healt, it should display its normal anim pain, but if it's at 70%health and changes into anim follow1, it should display for example, anim follow10 of it takes damage...Most sure thing I am not understanding your answer :dunce:
 
Hmm can you provide an example? Because the thing I would want is to trigger a different animation instead of the normal pain animation, it should reflect the current damage that it has taken.

For example, if it's 100% healt, it should display its normal anim pain, but if it's at 70%health and changes into anim follow1, it should display for example, anim follow10 of it takes damage...Most sure thing I am not understanding your answer :dunce:

That's a bit different. I thought you wanted normal -> damaged -> Destroyed. If you want different levels of damage it's just a little more complex. Certainly doable, but I'm turning in for the night. I'll try to write a in depth if no one beats me to it tomorrow.

DC
 
There's a couple of techniques you could use.

Just for simplicity, I would simply reverse it. Instead of scripting the damaged animation on hit, make the damaged version the default state, and script the undamaged animation on spawn. Then all you have to do is let it go back to normal once hit. That way you're not fighting anything once it starts taking damage.

DC
From looking at his code, he uses offsets in certain frames from anim pain he has for shaking. What he wants is that every time a hero attacks the pillar, it shakes and then goes back to its very state depending on the damaged condition.

EDIT:
I recently found out that when I was testing both ondoattack and onpain scripts for duck pain animations, it doesn't work for newer builds anymore. Let alone the old ones.

ondoattack.c:
C:
void main(){
    DuckPain();
    //DoubleHit();
    attackOpponentToScreen();
}

void DuckPain(){
    
    void vEnt = getlocalvar("self"); //Calling entity
    
    if(getlocalvar("which") == 0){ // Defending
        void vAniID = getentityproperty(vEnt, "animationid"); // Calling animation ID
        int lastHitY = openborvariant("lasthity"); // Confirming or getting hit last from bottom as top (like from character's feet to head)
        
        if(vAniID == openborconstant("ANI_DUCK")){ // Is the player ducking?
            if(lastHitY >= 0){ // Detecting on the player for getting attacked last in Y
                setentityvar(vEnt, "DuckForcePain", 5); // Check the onpain script part for "DuckForcePain" that exists there and is set as entityvar. The value is a frame number for certain anim pain
            }
        }
    }
}

painscript.c:
C:
void main(){
    forcePain();
}

void forcePain(){
    void vEnt = getlocalvar("self");
    int forcePain = getentityvar(vEnt, "forcePain");
    
    int DuckForcePain = getentityvar(vEnt, "DuckForcePain");
    int damage = getentityvar(vEnt, "damage");
    void vAniID = getentityproperty(vEnt, "animationid");
    void vTarget = getentityproperty(vEnt, "opponent");
    int hResolution = openborvariant("hResolution");
    int xPos = openborvariant("xpos");
    int x = getentityproperty(vEnt, "x");
    int Tx = getentityproperty(vTarget, "x");
    int dir = getentityproperty(vEnt, "direction");
    int Tdir = getentityproperty(vTarget, "direction");
    
    if(forcePain != NULL()){
        setentityvar(vEnt, "forcePain", NULL());
        changeentityproperty(vEnt, "animation", openborconstant("ANI_pain" + forcePain));
        if( x >= xPos+hResolution-10){
            changeentityproperty(vTarget, "velocity", -1.5, 0, 0);
        }else if(x <= xPos+10){
            changeentityproperty(vTarget, "velocity", 1.5, 0, 0);
        }
    }
    
    if(damage != NULL()){
        setentityvar(vEnt, "damage", NULL());
        changeentityproperty(vEnt, "attacking", openborconstant("ATK_NORMAL" + damage));
    }
    
    
    if(vAniID = openborconstant("ANI_DUCK")){
        if(DuckForcePain != NULL()){
            setentityvar(vEnt, "DuckForcePain", NULL()); //For anim pain
            updateframe(vEnt, DuckForcePain); // Change frame under the same pain animation
            if( x >= xPos+hResolution-1){
                changeentityproperty(vTarget, "velocity", -1.5, 0, 0);
            }else if(x <= xPos+1){
                changeentityproperty(vTarget, "velocity", 1.5, 0, 0);
            }
        }
    }
    
    
}

Code:
onpainscript data/scripts/painscript.c
ondoattackscript data/scripts/ondoattack.c

I like having two ways in one pain animations so I wouldn't waste a number of pain animations in the code. I don't like making one side per pain animation like crouch pain per animation and/or stand pain per pain animation.

Code:
anim pain #Face 1-2-1
    offset 97 177
    delay 4
    #IDLE PAIN
    bbox 71 81 37 96
    @cmd    velo001 -2 0 0
    frame data/CHARS/ARyu/gethit00.png
    delay 7
    frame data/CHARS/ARyu/gethit01.png
    delay 5
    frame data/CHARS/ARyu/gethit01.png
    frame data/CHARS/ARyu/gethit00.png
    @cmd beidle
    frame data/CHARS/ARyu/gethit00.png
    #DUCK PAIN
    bbox 75 112 42 68
    @cmd    velo001 -2 0 0
    frame data/CHARS/ARyu/duckhit1.png
    frame data/CHARS/ARyu/duckhit2.png
    frame data/CHARS/ARyu/duckhit2.png
    frame data/CHARS/ARyu/duckhit1.png
    @cmd    keyint2 "ANI_DUCK" 2 "D" 0
    @cmd    keyint2 "ANI_FOLLOW6" 0 "D" 1
    #@cmd    keyint openborconstant("ANI_DUCK") 2 "D" 0 0
    #@cmd    keyint openborconstant("ANI_FOLLOW6") 0 "D" 1 0
    frame data/CHARS/ARyu/duckhit1.png
 
Last edited:
If I understand your problem correctly, your entity has four damage states and four sprites that play depending on that state.

However, when it takes damage, the engine always executes the PAIN animation, and what you want is for PAIN to play with "ff2pilar2.gif" or "ff2pilar3.gif" or "ff2pilar4.gif" instead of "ff2pilar1.gif," depending on the damage level.

The engine will always execute PAIN, so one way to solve this is to place a script at frame 0 of PAIN that jumps to a different animation depending on the entity's remaining health.

If I'm not mistaken, something like this should work for you.

C:
anim pain
    @script
    if (frame==0) {
        void self = getlocalvar("self");
        int hp = getentityproperty(self, "health");
        int maxhp = getentityproperty(self, "maxhealth");
        if(hp <= 0.2*maxhp){
            executeanimation(self, openborconstant("ANI_FREESPECIAL6"),0);
        } else if (hp <= 0.4*maxhp) {
            executeanimation(self, openborconstant("ANI_FREESPECIAL5"),0);
        } else if (hp <= 0.7*maxhp) {
            executeanimation(self, openborconstant("ANI_FREESPECIAL4"),0);
        }
    }
    @end_script
    loop      0
    delay     2
    offset    39 144
    bbox      15 23 50 123
    platform 13 149 -10 -10 64 64 10 150
    sound    data/sounds/debris1.wav
    frame     Data/bgs/bonus/ffury2/ff2pilar1.gif
    offset    40 144
    frame     Data/bgs/bonus/ffury2/ff2pilar1.gif
    offset    39 144
    frame     Data/bgs/bonus/ffury2/ff2pilar1.gif
    offset    40 141
    frame     Data/bgs/bonus/ffury2/ff2pilar1.gif

anim freespecial4
    loop      0
    delay     2
    offset    39 144
    bbox      15 23 50 123
    platform 13 149 -10 -10 64 64 10 150
    sound    data/sounds/debris1.wav
    frame     Data/bgs/bonus/ffury2/ff2pilar2.gif
    offset    40 144
    frame     Data/bgs/bonus/ffury2/ff2pilar2.gif
    offset    39 144
    frame     Data/bgs/bonus/ffury2/ff2pilar2.gif
    offset    40 141
    frame     Data/bgs/bonus/ffury2/ff2pilar2.gif

anim freespecial5
    loop      0
    delay     2
    offset    39 144
    bbox      15 23 50 123
    platform 13 149 -10 -10 64 64 10 150
    sound    data/sounds/debris1.wav
    frame     Data/bgs/bonus/ffury2/ff2pilar3.gif
    offset    40 144
    frame     Data/bgs/bonus/ffury2/ff2pilar3.gif
    offset    39 144
    frame     Data/bgs/bonus/ffury2/ff2pilar3.gif
    offset    40 141
    frame     Data/bgs/bonus/ffury2/ff2pilar3.gif

anim freespecial6
    loop      0
    delay     2
    offset    39 144
    bbox      15 23 50 123
    platform 13 149 -10 -10 64 64 10 150
    sound    data/sounds/debris1.wav
    frame     Data/bgs/bonus/ffury2/ff2pilar4.gif
    offset    40 144
    frame     Data/bgs/bonus/ffury2/ff2pilar4.gif
    offset    39 144
    frame     Data/bgs/bonus/ffury2/ff2pilar4.gif
    offset    40 141
    frame     Data/bgs/bonus/ffury2/ff2pilar4.gif
 
Back
Top Bottom