Solved Anim victory for 4.0

Question that is answered or resolved.

kimono

Well-known member
Hello, dear Openbor experts.
I'm currently trying to replicate the 3.0 mechanic of a victory animation triggered when all enemies in the level are defeated.

I'm currently trying to count the number of enemies present and trigger animation freespecial5 if there are none left.
I use update.c for this, with the following lines of code:
Code:
// ===== VICTORY ANIMATION (OpenBOR 4.0) =====
{
    void ent;
    void player;
    int i;
    int enemies_alive = 0;

    // Check if at least one enemy is still alive
    for(i = 0; i < openborvariant("count_entities"); i++) {
        ent = getentity(i);
        if(ent) {
            if(getentityproperty(ent, "type") == openborconstant("TYPE_ENEMY") &&
               getentityproperty(ent, "health") > 0) {
                enemies_alive = 1;
                break;
            }
        }
    }

    // All enemies are defeated → play victory animation
    if(!enemies_alive && !getglobalvar("victory_done")) {

        // Prevent the animation from triggering multiple times
        setglobalvar("victory_done", 1);

        // Play victory animation for each active player
        for(i = 0; i < openborvariant("maxplayers"); i++) {
            player = getplayerproperty(i, "entity");
            if(player &&
               getentityproperty(player, "health") > 0 &&
               getentityproperty(player, "busy") == 0)
            {
                performattack(player, openborconstant("ATK_FREESPECIAL5"));
            }
        }
    }
}

The freespecial5 animation isn't triggering at the moment.
Am I on the right track, and would you follow these steps to activate the victory animation?
 
Solution
Hello, dear Openbor experts.
I'm currently trying to replicate the 3.0 mechanic of a victory animation triggered when all enemies in the level are defeated.

I'm currently trying to count the number of enemies present and trigger animation freespecial5 if there are none left.
I use update.c for this, with the following lines of code:
Code:
// ===== VICTORY ANIMATION (OpenBOR 4.0) =====
{
    void ent;
    void player;
    int i;
    int enemies_alive = 0;

    // Check if at least one enemy is still alive
    for(i = 0; i < openborvariant("count_entities"); i++) {
        ent = getentity(i);
        if(ent) {
            if(getentityproperty(ent, "type") == openborconstant("TYPE_ENEMY") &&
               getentityproperty(ent...
Hello, dear Openbor experts.
I'm currently trying to replicate the 3.0 mechanic of a victory animation triggered when all enemies in the level are defeated.

I'm currently trying to count the number of enemies present and trigger animation freespecial5 if there are none left.
I use update.c for this, with the following lines of code:
Code:
// ===== VICTORY ANIMATION (OpenBOR 4.0) =====
{
    void ent;
    void player;
    int i;
    int enemies_alive = 0;

    // Check if at least one enemy is still alive
    for(i = 0; i < openborvariant("count_entities"); i++) {
        ent = getentity(i);
        if(ent) {
            if(getentityproperty(ent, "type") == openborconstant("TYPE_ENEMY") &&
               getentityproperty(ent, "health") > 0) {
                enemies_alive = 1;
                break;
            }
        }
    }

    // All enemies are defeated → play victory animation
    if(!enemies_alive && !getglobalvar("victory_done")) {

        // Prevent the animation from triggering multiple times
        setglobalvar("victory_done", 1);

        // Play victory animation for each active player
        for(i = 0; i < openborvariant("maxplayers"); i++) {
            player = getplayerproperty(i, "entity");
            if(player &&
               getentityproperty(player, "health") > 0 &&
               getentityproperty(player, "busy") == 0)
            {
                performattack(player, openborconstant("ATK_FREESPECIAL5"));
            }
        }
    }
}

The freespecial5 animation isn't triggering at the moment.
Am I on the right track, and would you follow these steps to activate the victory animation?
I still need to improve some things but was able to simulate the native engine victory feature.
I will post as soon as I finish it.

 
Solution
Awesome Kratus, you're a savior!
It's great to at least get back the original features of version 3.0 by migrating to Openbor version 4.0.

4 players are planned for later versions and I don't know if it's possible to include an option so that NPCs can also trigger this victory animation.
 
Problem solved by @Kratus (thank you very much!) through a build revision and the following settings:
Endlevel.txt :
Code:
# endlevel

name    endlevel
type    endlevel
grabdistance 100
shadow    0

anim spawn
@script
{
    setglobalvar("enemies_alive", 0);
    setglobalvar("victory_entity", getlocalvar("self"));
}
@end_script
    loop    0
    delay    12
    offset    0 0
    bbox    -32 -32 32 32
    frame    data/chars/misc/empty.gif

anim idle
    loop    1
    delay    12
    offset    0 0
    bbox    -32 -32 32 32
    frame    data/chars/misc/empty.gif

Two victory animations :
Code:
anim victory
    offset    60 98
    delay   16
    frame   data/chars/ax/m0.png
    frame    data/chars/ax/m1.png
    delay   40
    frame    data/chars/ax/m2.png
    delay   100
    frame    data/chars/ax/m2.png

anim follow11 ## FAKE VICTORY ANIMATION
    offset    60 98
    delay   16
    frame   data/chars/ax/m0.png
    frame    data/chars/ax/m1.png
    delay   40
    frame    data/chars/ax/m2.png
    delay   -1000
    frame    data/chars/ax/m2.png

updated.c :
Code:
// ===== VICTORY ANIMATION (OpenBOR 4.0) =====
void victory()
{
    void ent;
    void player;
    int i;

    // All enemies are defeated → play victory animation
    if(getglobalvar("enemies_alive") == 0){
        
        // Play victory animation for each active player
        for(i = 0; i < openborvariant("maxplayers"); i++){
            player = getplayerproperty(i, "entity");
            int pIndex = getentityproperty(player, "playerindex");
            int delay = 250;
            void allowedAnims = getentityproperty(player, "animationID") == openborconstant("ANI_IDLE") ||
                                getentityproperty(player, "animationID") == openborconstant("ANI_SLEEP") ||
                                getentityproperty(player, "animationID") == openborconstant("ANI_WALK") ||
                                getentityproperty(player, "animationID") == openborconstant("ANI_RUN");
            if(player &&
               getentityproperty(player, "health") > 0 &&
               allowedAnims &&
               getglobalvar("victory_done_"+pIndex) == NULL())
            {
                changeentityproperty(player, "velocity", 0, 0, 0);
                performattack(player, openborconstant("ANI_FOLLOW11"));

                 // Prevent the animation from triggering multiple times
                setglobalvar("victory_done_"+pIndex, 1);

                if(getglobalvar("victory_total") == NULL()){
                    setglobalvar("victory_total", 1);
                }
                else
                {
                    setglobalvar("victory_total", getglobalvar("victory_total")+1);
                }
            }
            
            if(openborvariant("count_players") == getglobalvar("victory_total"))
            {
                if(getglobalvar("victory_finish") == NULL()){
                    changeentityproperty(getglobalvar("victory_entity"), "lifespancountdown", delay);
                    setglobalvar("victory_finish", 1);
                }
            }
        }
    }

    //DEBUG INFO ONLY, COMMENT OR ERASE IF YOU WANT
    //drawstring(50, 50, 0, "count enemies "+openborvariant("count_enemies"));
    //drawstring(50, 60, 0, "alive enemies "+getglobalvar("enemies_alive"));
    //drawstring(50, 70, 0, "victory p1 "+getglobalvar("victory_done_0"));
    //drawstring(50, 80, 0, "victory p2 "+getglobalvar("victory_done_1"));
    //drawstring(50, 90, 0, "victory p3 "+getglobalvar("victory_done_2"));
    //drawstring(50, 100, 0, "victory total "+getglobalvar("victory_total"));
    //drawstring(50, 110, 0, "count players "+openborvariant("count_players"));
    //drawstring(50, 120, 0, "victory finish "+getglobalvar("victory_finish"));
}
 
Back
Top Bottom