Solved Maintaining Double Lifebar

Question that is answered or resolved.

maxman

Well-known member
I'm using ondrawscript to draw the two lifebars for an enemy. I'm trying to retain the top bar as 50% health remaining while leaving the bottom bar as its max like the Punisher and some other games.

punisher-06-13-111006.png

However, when I made this based on mine, @Kratus's, and @pudu's, it seems that all lifebar units reduce at the same time instead of having one lifebar wait for another.

Full double lifebar begins.
ROD MAXED OUT! - 0189.png

Starting to reduce at the same time.
ROD MAXED OUT! - 0190.png

Half of its unit remains.
ROD MAXED OUT! - 0191.png

Here's mine for the lifebar. I have trouble maintaining the length (X size) of the lifebars.

C:
void main(){
    bossHP();

}

void bossHP(){
    void self = getlocalvar("self");
    int currentHP = getentityproperty(self, "health");
    int maxHP = getentityproperty(self, "maxhealth");
    int xPos = 50; // BASE X POSITION
    int yPos1 = 190; // FIRST BASE OF Y POSITION
    int yPos2 = 200; // SECOND BASE OF Y POSITION
    int xSize = 100; // BAR SIZE IN X AXIS
    int ySize = 8; // BAR SIZE IN Y AXIS
    int Layer = 5000;
    int darkBlue = rgbcolor(0, 0, 100);
    //int health1 = 100*currentHP/maxHP;
    //int health2 = 100*

    if(getentityvar(self, "enemigo") == NULL()){setentityvar(self, "enemigo", currentHP);}

    // ONE HALF BAR
    /*if(currentHP <= 0.5*maxHP){
        //maxHP = 0.5*maxHP;
        currentHP = (currentHP*xSize) / maxHP;
        drawbox(xPos, yPos1, currentHP, ySize, Layer, darkBlue);
        
    }

    // FULL 2 HP BARS
    if(currentHP >= xSize){
        //full_health = maxHP;
        currentHP = (currentHP * xSize) / maxHP;

        drawbox(xPos, yPos1, currentHP, ySize, Layer, darkBlue);
        drawbox(xPos, yPos2, currentHP, ySize, Layer, darkBlue);
    }*/
    

    if(currentHP > xSize){
        
        drawbox(xPos, yPos1, getentityvar(self,"enemigo"), ySize, Layer, darkBlue);
        drawbox(xPos, yPos2, getentityvar(self,"enemigo"), ySize, Layer, darkBlue);
    }if(currentHP <= xSize){
        
        drawbox(xPos, yPos1, getentityvar(self,"enemigo"), ySize, Layer, darkBlue);
        //drawbox(xPos, yPos2, getentityvar(self,"enemigo"), ySize, Layer, darkBlue);
    }

    if(currentHP < getentityvar(self, "enemigo")){ // if hp box smaller then damage box
        if(getentityvar(self,1)==NULL()){
            setentityvar(self,1,0); //set entity var 1 to zero if null this is a timer
        }
        setentityvar(self,1,getentityvar(self,1)+1); //add 1 to timer this will run every game tick
        if(getentityvar(self,1) > 3){ //if timer over 7
            setentityvar(self, "enemigo",getentityvar(self, "enemigo")-1); //reduce displayed damage by 1
            setentityvar(self,1,0); //reset timer to zero this will cause a loop untill damage is the same as hp
        }
    }

}

(What did I do wrong?)
 
I'm using ondrawscript to draw the two lifebars for an enemy. I'm trying to retain the top bar as 50% health remaining while leaving the bottom bar as its max like the Punisher and some other games.

View attachment 10862

However, when I made this based on mine, @Kratus's, and @pudu's, it seems that all lifebar units reduce at the same time instead of having one lifebar wait for another.

Full double lifebar begins.
View attachment 10859

Starting to reduce at the same time.
View attachment 10860

Half of its unit remains.
View attachment 10861

Here's mine for the lifebar. I have trouble maintaining the length (X size) of the lifebars.

C:
void main(){
    bossHP();

}

void bossHP(){
    void self = getlocalvar("self");
    int currentHP = getentityproperty(self, "health");
    int maxHP = getentityproperty(self, "maxhealth");
    int xPos = 50; // BASE X POSITION
    int yPos1 = 190; // FIRST BASE OF Y POSITION
    int yPos2 = 200; // SECOND BASE OF Y POSITION
    int xSize = 100; // BAR SIZE IN X AXIS
    int ySize = 8; // BAR SIZE IN Y AXIS
    int Layer = 5000;
    int darkBlue = rgbcolor(0, 0, 100);
    //int health1 = 100*currentHP/maxHP;
    //int health2 = 100*

    if(getentityvar(self, "enemigo") == NULL()){setentityvar(self, "enemigo", currentHP);}

    // ONE HALF BAR
    /*if(currentHP <= 0.5*maxHP){
        //maxHP = 0.5*maxHP;
        currentHP = (currentHP*xSize) / maxHP;
        drawbox(xPos, yPos1, currentHP, ySize, Layer, darkBlue);
       
    }

    // FULL 2 HP BARS
    if(currentHP >= xSize){
        //full_health = maxHP;
        currentHP = (currentHP * xSize) / maxHP;

        drawbox(xPos, yPos1, currentHP, ySize, Layer, darkBlue);
        drawbox(xPos, yPos2, currentHP, ySize, Layer, darkBlue);
    }*/
   

    if(currentHP > xSize){
       
        drawbox(xPos, yPos1, getentityvar(self,"enemigo"), ySize, Layer, darkBlue);
        drawbox(xPos, yPos2, getentityvar(self,"enemigo"), ySize, Layer, darkBlue);
    }if(currentHP <= xSize){
       
        drawbox(xPos, yPos1, getentityvar(self,"enemigo"), ySize, Layer, darkBlue);
        //drawbox(xPos, yPos2, getentityvar(self,"enemigo"), ySize, Layer, darkBlue);
    }

    if(currentHP < getentityvar(self, "enemigo")){ // if hp box smaller then damage box
        if(getentityvar(self,1)==NULL()){
            setentityvar(self,1,0); //set entity var 1 to zero if null this is a timer
        }
        setentityvar(self,1,getentityvar(self,1)+1); //add 1 to timer this will run every game tick
        if(getentityvar(self,1) > 3){ //if timer over 7
            setentityvar(self, "enemigo",getentityvar(self, "enemigo")-1); //reduce displayed damage by 1
            setentityvar(self,1,0); //reset timer to zero this will cause a loop untill damage is the same as hp
        }
    }

}

(What did I do wrong?)
@maxman Is this correct?


If yes, I made some changes in the main formula.

Code:
void bossHP(){
    void self = getlocalvar("self");
    int currentHP = getentityproperty(self, "health");
    int maxHP = getentityproperty(self, "maxhealth");
    int xPos = 50; // BASE X POSITION
    int yPos1 = 190; // FIRST BASE OF Y POSITION
    int yPos2 = 200; // SECOND BASE OF Y POSITION
    int xSize = 100; // BAR SIZE IN X AXIS
    int ySize = 8; // BAR SIZE IN Y AXIS
    int Layer = 5000;
    int darkBlue = rgbcolor(0, 0, 100);
    //int health1 = 100*currentHP/maxHP;
    //int health2 = 100*

    if(getentityvar(self, "enemigo") == NULL()){setentityvar(self, "enemigo", currentHP);}

    // ONE HALF BAR
    /*if(currentHP <= 0.5*maxHP){
        //maxHP = 0.5*maxHP;
        currentHP = (currentHP*xSize) / maxHP;
        drawbox(xPos, yPos1, currentHP, ySize, Layer, darkBlue);
        
    }

    // FULL 2 HP BARS
    if(currentHP >= xSize){
        //full_health = maxHP;
        currentHP = (currentHP * xSize) / maxHP;

        drawbox(xPos, yPos1, currentHP, ySize, Layer, darkBlue);
        drawbox(xPos, yPos2, currentHP, ySize, Layer, darkBlue);
    }*/
    
    //Main formula
    if(currentHP > maxHP/2){
        currentHP = ((currentHP-(maxHP/2))*xSize)/(maxHP/2); //split the max health in two parts and get the first part (50%-100%)
        maxHP = ((maxHP/2)*xSize)/(maxHP/2); //split the max health in two parts and get the max size
        drawbox(xPos, yPos1, maxHP, ySize, Layer, darkBlue); //top bar, always fully filled
        drawbox(xPos, yPos2, currentHP, ySize, Layer, darkBlue); //bottom bar, dynamic according to the first part amount
    }
    else
    {
        currentHP = (currentHP*xSize)/(maxHP/2); //split the max health in two parts and get the second part (0%-50%)
        drawbox(xPos, yPos1, currentHP, ySize, Layer, darkBlue); //top bar, dynamic according to the second part amount
    }

    if(currentHP < getentityvar(self, "enemigo")){ // if hp box smaller then damage box
        if(getentityvar(self,1)==NULL()){
            setentityvar(self,1,0); //set entity var 1 to zero if null this is a timer
        }
        setentityvar(self,1,getentityvar(self,1)+1); //add 1 to timer this will run every game tick
        if(getentityvar(self,1) > 3){ //if timer over 7
            setentityvar(self, "enemigo",getentityvar(self, "enemigo")-1); //reduce displayed damage by 1
            setentityvar(self,1,0); //reset timer to zero this will cause a loop untill damage is the same as hp
        }
    }
}
 
Yes! That's exactly it. But I have two problems. When I put a lifebar that gradually reduces with certain time using entityvar, the bottom bar decreases down to its max in the beginning of the level. After the enemy/boss's HP is deducted to its first half of the lifebar at the top, the top bar almost disappears, leaving only a tiny bar of his health.

C:
void main(){
    bossHP();
}

void bossHP(){
    void self = getlocalvar("self");
    int currentHP = getentityproperty(self, "health");
    int maxHP = getentityproperty(self, "maxhealth");
    int xPos = 50; // BASE X POSITION
    int yPos1 = 190; // FIRST BASE OF Y POSITION
    int yPos2 = 200; // SECOND BASE OF Y POSITION
    int xSize = 50; // BAR SIZE IN X AXIS
    int ySize = 10; // BAR SIZE IN Y AXIS
    int Layer = 5000;
    int Layer2 = 8000;
    int Black = rgbcolor(0, 0, 0);
    int darkBlue = rgbcolor(0, 0, 100);
    int Mount;

    drawstring(35, 147, 0, "Boss_HP:_"+currentHP);

    if(getentityvar(self, "enemigo") == NULL()){setentityvar(self, "enemigo", currentHP);}

    //Main formula
    if(currentHP > maxHP/2){
        currentHP = ((currentHP-(maxHP/2))*xSize)/(maxHP/2); //split the max health in two parts and get the first part (50%-100%)
        maxHP = ((maxHP/2)*xSize)/(maxHP/2); //split the max health in two parts and get the max size
        drawbox(xPos, yPos1, maxHP, ySize, Layer, darkBlue); //top bar, always fully filled
        drawbox(xPos, yPos2, getentityvar(self,"enemigo"), ySize, Layer, darkBlue); //bottom bar, dynamic according to the first part amount
    }
    else
    {
        currentHP = (currentHP*xSize)/(maxHP/2); //split the max health in two parts and get the second part (0%-50%)
        drawbox(xPos, yPos1, getentityvar(self,"enemigo"), ySize, Layer, darkBlue); //top bar, dynamic according to the second part amount
    }

    if(currentHP < getentityvar(self, "enemigo")){ // if hp box smaller then damage box
        if(getentityvar(self,1)==NULL()){
            setentityvar(self,1,0); //set entity var 1 to zero if null this is a timer
        }
        setentityvar(self,1,getentityvar(self,1)+1); //add 1 to timer this will run every game tick
        if(getentityvar(self,1) > 3){ //if timer over 7
            setentityvar(self, "enemigo",getentityvar(self, "enemigo")-1); //reduce displayed damage by 1
            setentityvar(self,1,0); //reset timer to zero this will cause a loop untill damage is the same as hp
        }
    }

}

 
Yes! That's exactly it. But I have two problems. When I put a lifebar that gradually reduces with certain time using entityvar, the bottom bar decreases down to its max in the beginning of the level. After the enemy/boss's HP is deducted to its first half of the lifebar at the top, the top bar almost disappears, leaving only a tiny bar of his health.
To be honest I don't understand exactly what you are trying to do.
Is there some kind of "damage over time" (dot) effect on the boss's health? Why are you reducing the boss health bar visually instead of applying a real damage?
Anyway, you need to update the "enemigo" entityvar after the HP formula.

Code:
void bossHP(){
    void self = getlocalvar("self");
    int currentHP = getentityproperty(self, "health");
    int maxHP = getentityproperty(self, "maxhealth");
    int xPos = 50; // BASE X POSITION
    int yPos1 = 190; // FIRST BASE OF Y POSITION
    int yPos2 = 200; // SECOND BASE OF Y POSITION
    int xSize = 50; // BAR SIZE IN X AXIS
    int ySize = 10; // BAR SIZE IN Y AXIS
    int Layer = 5000;
    int Layer2 = 8000;
    int Black = rgbcolor(0, 0, 0);
    int darkBlue = rgbcolor(0, 0, 100);
    int Mount;

    drawstring(35, 147, 0, "Boss_HP:_"+currentHP);


    //Main formula
    if(currentHP > maxHP/2){
        currentHP = ((currentHP-(maxHP/2))*xSize)/(maxHP/2); //split the max health in two parts and get the first part (50%-100%)
        maxHP = ((maxHP/2)*xSize)/(maxHP/2); //split the max health in two parts and get the max size
           if(getentityvar(self, "enemigo") == NULL()){setentityvar(self, "enemigo", currentHP);}
        drawbox(xPos, yPos1, maxHP, ySize, Layer, darkBlue); //top bar, always fully filled
        drawbox(xPos, yPos2, getentityvar(self,"enemigo"), ySize, Layer, darkBlue); //bottom bar, dynamic according to the first part amount
    }
    else
    {
        currentHP = (currentHP*xSize)/(maxHP/2); //split the max health in two parts and get the second part (0%-50%)
        setentityvar(self, "enemigo", currentHP);
        drawbox(xPos, yPos1, getentityvar(self,"enemigo"), ySize, Layer, darkBlue); //top bar, dynamic according to the second part amount
    }

    if(currentHP < getentityvar(self, "enemigo")){ // if hp box smaller then damage box
        if(getentityvar(self,1)==NULL()){
            setentityvar(self,1,0); //set entity var 1 to zero if null this is a timer
        }
        setentityvar(self,1,getentityvar(self,1)+1); //add 1 to timer this will run every game tick
        if(getentityvar(self,1) > 3){ //if timer over 7
            setentityvar(self, "enemigo",getentityvar(self, "enemigo")-1); //reduce displayed damage by 1
            setentityvar(self,1,0); //reset timer to zero this will cause a loop untill damage is the same as hp
        }
    }

}
 
To be honest I don't understand exactly what you are trying to do.
The main purpose is to emulate the way the bar (lifebar/MP) drops like you see in many games, even with the default life and MP bars that do in OpenBOR too. I wanna make it different like dropping lifebars instead of just depleting 'em instantly.

Is there some kind of "damage over time" (dot) effect on the boss's health? Why are you reducing the boss health bar visually instead of applying a real damage?
There's no DOT in it. Also, I had/have no idea how to apply the damage for the boss's health bar.

Thank you very much, Kratus! I tried many times to update that entityvar, mostly with drawbox. But I forgot how and where to apply entityvars. (It's been a while I haven't bothered using entityvars as I have little time to mod recently. But I'm trying to get back.)
 
Hi @Kratus. Even though I got it working before, the top part of the boss's lifebar starts to act like it's depleted instantly again since I modified my changes. I changed the size of the lifebar for testing. I have no idea what happened to it.

Here's my modification, along with the video:
C:
void bossHP(){
    void self = getlocalvar("self");
    int currentHP = getentityproperty(self, "health");
    int maxHP = getentityproperty(self, "maxhealth");
    int xPos = 140; // BASE X POSITION
    int yPos1 = 216; // FIRST BASE OF Y POSITION
    int yPos2 = 226; // SECOND BASE OF Y POSITION
    int xSize = 200; // BAR SIZE IN X AXIS
    int ySize = 10; // BAR SIZE IN Y AXIS
    int Layer = 8000;
    int Layer2 = 5000;
    int Black = rgbcolor(0, 0, 0);
    int darkYellow = rgbcolor(198, 198, 0);
    int darkRed = rgbcolor(128, 0, 0);

    drawstring(35, 147, 0, "Boss_HP:_"+currentHP);

    //changeentityproperty(self, "iconposition", 83, 210);


    //Main formula
    if(currentHP > maxHP/2){
        currentHP = ((currentHP-(maxHP/2))*xSize)/(maxHP/2); //split the max health in two parts and get the first part (50%-100%)
        maxHP = ((maxHP/2)*xSize)/(maxHP/2); //split the max health in two parts and get the max size
           if(getentityvar(self, "enemigo") == NULL()){setentityvar(self, "enemigo", currentHP);}
        drawbox(xPos, yPos1, maxHP, ySize, Layer, darkYellow); //top bar, always fully filled
        drawbox(xPos, yPos2, getentityvar(self,"enemigo"), ySize, Layer, darkYellow); //bottom bar, dynamic according to the first part amount
        drawbox(xPos, yPos2, xSize, ySize, Layer2, darkRed);
    }
    else
    {
        currentHP = (currentHP*xSize)/(maxHP/2); //split the max health in two parts and get the second part (0%-50%)
        setentityvar(self, "enemigo", currentHP);
        drawbox(xPos, yPos1, getentityvar(self,"enemigo"), ySize, Layer, darkYellow); //top bar, dynamic according to the second part amount
        drawbox(xPos, yPos1, xSize, ySize, Layer2, darkRed);
    }

    if(currentHP < getentityvar(self, "enemigo")){ // if hp box smaller then damage box
        if(getentityvar(self,1)==NULL()){
            setentityvar(self,1,0); //set entity var 1 to zero if null this is a timer
        }
        setentityvar(self,1,getentityvar(self,1)+1); //add 1 to timer this will run every game tick
        if(getentityvar(self,1) > 3){ //if timer over 7
            setentityvar(self, "enemigo",getentityvar(self, "enemigo")-1); //reduce displayed damage by 1
            setentityvar(self,1,0); //reset timer to zero this will cause a loop untill damage is the same as hp
        }
    }

}

 
Hi @Kratus. Even though I got it working before, the top part of the boss's lifebar starts to act like it's depleted instantly again since I modified my changes. I changed the size of the lifebar for testing. I have no idea what happened to it.

Here's my modification, along with the video:
C:
void bossHP(){
    void self = getlocalvar("self");
    int currentHP = getentityproperty(self, "health");
    int maxHP = getentityproperty(self, "maxhealth");
    int xPos = 140; // BASE X POSITION
    int yPos1 = 216; // FIRST BASE OF Y POSITION
    int yPos2 = 226; // SECOND BASE OF Y POSITION
    int xSize = 200; // BAR SIZE IN X AXIS
    int ySize = 10; // BAR SIZE IN Y AXIS
    int Layer = 8000;
    int Layer2 = 5000;
    int Black = rgbcolor(0, 0, 0);
    int darkYellow = rgbcolor(198, 198, 0);
    int darkRed = rgbcolor(128, 0, 0);

    drawstring(35, 147, 0, "Boss_HP:_"+currentHP);

    //changeentityproperty(self, "iconposition", 83, 210);


    //Main formula
    if(currentHP > maxHP/2){
        currentHP = ((currentHP-(maxHP/2))*xSize)/(maxHP/2); //split the max health in two parts and get the first part (50%-100%)
        maxHP = ((maxHP/2)*xSize)/(maxHP/2); //split the max health in two parts and get the max size
           if(getentityvar(self, "enemigo") == NULL()){setentityvar(self, "enemigo", currentHP);}
        drawbox(xPos, yPos1, maxHP, ySize, Layer, darkYellow); //top bar, always fully filled
        drawbox(xPos, yPos2, getentityvar(self,"enemigo"), ySize, Layer, darkYellow); //bottom bar, dynamic according to the first part amount
        drawbox(xPos, yPos2, xSize, ySize, Layer2, darkRed);
    }
    else
    {
        currentHP = (currentHP*xSize)/(maxHP/2); //split the max health in two parts and get the second part (0%-50%)
        setentityvar(self, "enemigo", currentHP);
        drawbox(xPos, yPos1, getentityvar(self,"enemigo"), ySize, Layer, darkYellow); //top bar, dynamic according to the second part amount
        drawbox(xPos, yPos1, xSize, ySize, Layer2, darkRed);
    }

    if(currentHP < getentityvar(self, "enemigo")){ // if hp box smaller then damage box
        if(getentityvar(self,1)==NULL()){
            setentityvar(self,1,0); //set entity var 1 to zero if null this is a timer
        }
        setentityvar(self,1,getentityvar(self,1)+1); //add 1 to timer this will run every game tick
        if(getentityvar(self,1) > 3){ //if timer over 7
            setentityvar(self, "enemigo",getentityvar(self, "enemigo")-1); //reduce displayed damage by 1
            setentityvar(self,1,0); //reset timer to zero this will cause a loop untill damage is the same as hp
        }
    }

}

@maxman Now I understand, you want a smooth movement when the life bar is updated. I did some tests and was able to replicate this behaviour for the top bar.
According to what I understand about your code, you just need to make a second variable check for the top bar, I added the "enemigo2" to do it (and it does only this task, there's no other usability for the "enemigo2" variable).

Code:
void bossHP(){
    void self = getlocalvar("self");
    int currentHP = getentityproperty(self, "health");
    int maxHP = getentityproperty(self, "maxhealth");
    int xPos = 140; // BASE X POSITION
    int yPos1 = 216; // FIRST BASE OF Y POSITION
    int yPos2 = 226; // SECOND BASE OF Y POSITION
    int xSize = 200; // BAR SIZE IN X AXIS
    int ySize = 10; // BAR SIZE IN Y AXIS
    int Layer = 8000;
    int Layer2 = 5000;
    int Black = rgbcolor(0, 0, 0);
    int darkYellow = rgbcolor(198, 198, 0);
    int darkRed = rgbcolor(128, 0, 0);

    drawstring(35, 147, 0, "Boss_HP:_"+currentHP);

    //changeentityproperty(self, "iconposition", 83, 210);


    //Main formula
    if(currentHP >= maxHP/2){
        currentHP = ((currentHP-(maxHP/2))*xSize)/(maxHP/2); //split the max health in two parts and get the first part (50%-100%)
        maxHP = ((maxHP/2)*xSize)/(maxHP/2); //split the max health in two parts and get the max size
        if(getentityvar(self, "enemigo") == NULL()){
            setentityvar(self, "enemigo", currentHP);
        }
        drawbox(xPos, yPos1, maxHP, ySize, Layer, darkYellow); //top bar, always fully filled
        drawbox(xPos, yPos2, getentityvar(self,"enemigo"), ySize, Layer, darkYellow); //bottom bar, dynamic according to the first part amount
        drawbox(xPos, yPos2, xSize, ySize, Layer2, darkRed);
    }
    else
    {
        currentHP = (currentHP*xSize)/(maxHP/2); //split the max health in two parts and get the second part (0%-50%)
        if(getentityvar(self, "enemigo2") == NULL()){
            setentityvar(self, "enemigo", currentHP);
            setentityvar(self, "enemigo2", currentHP);
        }
        drawbox(xPos, yPos1, getentityvar(self,"enemigo"), ySize, Layer, darkYellow); //top bar, dynamic according to the second part amount
        drawbox(xPos, yPos1, xSize, ySize, Layer2, darkRed);
    }

    if(currentHP < getentityvar(self, "enemigo")){ // if hp box smaller then damage box
        if(getentityvar(self,1)==NULL()){
            setentityvar(self,1,0); //set entity var 1 to zero if null this is a timer
        }
        setentityvar(self,1,getentityvar(self,1)+1); //add 1 to timer this will run every game tick
        if(getentityvar(self,1) > 3){ //if timer over 7
            setentityvar(self, "enemigo",getentityvar(self, "enemigo")-1); //reduce displayed damage by 1
            setentityvar(self,1,0); //reset timer to zero this will cause a loop untill damage is the same as hp
        }
    }

}

Is this correct?
 
@maxman Now I understand, you want a smooth movement when the life bar is updated. I did some tests and was able to replicate this behaviour for the top bar.
According to what I understand about your code, you just need to make a second variable check for the top bar, I added the "enemigo2" to do it (and it does only this task, there's no other usability for the "enemigo2" variable).

Code:
void bossHP(){
    void self = getlocalvar("self");
    int currentHP = getentityproperty(self, "health");
    int maxHP = getentityproperty(self, "maxhealth");
    int xPos = 140; // BASE X POSITION
    int yPos1 = 216; // FIRST BASE OF Y POSITION
    int yPos2 = 226; // SECOND BASE OF Y POSITION
    int xSize = 200; // BAR SIZE IN X AXIS
    int ySize = 10; // BAR SIZE IN Y AXIS
    int Layer = 8000;
    int Layer2 = 5000;
    int Black = rgbcolor(0, 0, 0);
    int darkYellow = rgbcolor(198, 198, 0);
    int darkRed = rgbcolor(128, 0, 0);

    drawstring(35, 147, 0, "Boss_HP:_"+currentHP);

    //changeentityproperty(self, "iconposition", 83, 210);


    //Main formula
    if(currentHP >= maxHP/2){
        currentHP = ((currentHP-(maxHP/2))*xSize)/(maxHP/2); //split the max health in two parts and get the first part (50%-100%)
        maxHP = ((maxHP/2)*xSize)/(maxHP/2); //split the max health in two parts and get the max size
        if(getentityvar(self, "enemigo") == NULL()){
            setentityvar(self, "enemigo", currentHP);
        }
        drawbox(xPos, yPos1, maxHP, ySize, Layer, darkYellow); //top bar, always fully filled
        drawbox(xPos, yPos2, getentityvar(self,"enemigo"), ySize, Layer, darkYellow); //bottom bar, dynamic according to the first part amount
        drawbox(xPos, yPos2, xSize, ySize, Layer2, darkRed);
    }
    else
    {
        currentHP = (currentHP*xSize)/(maxHP/2); //split the max health in two parts and get the second part (0%-50%)
        if(getentityvar(self, "enemigo2") == NULL()){
            setentityvar(self, "enemigo", currentHP);
            setentityvar(self, "enemigo2", currentHP);
        }
        drawbox(xPos, yPos1, getentityvar(self,"enemigo"), ySize, Layer, darkYellow); //top bar, dynamic according to the second part amount
        drawbox(xPos, yPos1, xSize, ySize, Layer2, darkRed);
    }

    if(currentHP < getentityvar(self, "enemigo")){ // if hp box smaller then damage box
        if(getentityvar(self,1)==NULL()){
            setentityvar(self,1,0); //set entity var 1 to zero if null this is a timer
        }
        setentityvar(self,1,getentityvar(self,1)+1); //add 1 to timer this will run every game tick
        if(getentityvar(self,1) > 3){ //if timer over 7
            setentityvar(self, "enemigo",getentityvar(self, "enemigo")-1); //reduce displayed damage by 1
            setentityvar(self,1,0); //reset timer to zero this will cause a loop untill damage is the same as hp
        }
    }

}

Is this correct?
Thank you very much, Kratus. I just changed the timer of the updated lifebar from 3 to 7 for moving slower in conjunction of both bars in regard to its (jointed) movement. For instance, when the lifebar moves down to the very end of the bottom bar, that's when it also moves down from the very beginning of the top bar according to how much damage the boss has taken. I wonder if the lifebar's movement connects between the very end of the bottom bar and the very beginning of the top bar is possible. Let's say that the boss has taken 18 damage points and the boss has a little above half (e.g., 163/300 to 145/300).

Code:
if(getentityvar(self,1) > 7){ //if timer over 7

Look at 0:27 to see what I mean.

EDIT: The lifebar should move smoothly like the one from Dungeons and Dragons: Shadow Over Mystara.
 
Last edited:
Thank you very much, Kratus. I just changed the timer of the updated lifebar from 3 to 7 for moving slower in conjunction of both bars in regard to its (jointed) movement. For instance, when the lifebar moves down to the very end of the bottom bar, that's when it also moves down from the very beginning of the top bar according to how much damage the boss has taken. I wonder if the lifebar's movement connects between the very end of the bottom bar and the very beginning of the top bar is possible. Let's say that the boss has taken 18 damage points and the boss has a little above half (e.g., 163/300 to 145/300).

Code:
if(getentityvar(self,1) > 7){ //if timer over 7

Look at 0:27 to see what I mean.

EDIT: The lifebar should move smoothly like the one from Dungeons and Dragons: Shadow Over Mystara.
@maxman In this case I think that it's better to use screens. This way, internally the life bar works as a unique bar, but visually it works as two different bars by just changing the offset of each one, avoiding any sync issue.

Here's the code, works on the ondraw event.

Code:
void bossHP(){
    void self = getlocalvar("self");
    int currentHP = getentityproperty(self, "health");
    int maxHP = getentityproperty(self, "maxhealth");
    int xPos = 1; // BASE X POSITION
    int yPos = 216; // FIRST BASE OF Y POSITION
    int xSize = 400; // BAR SIZE IN X AXIS
    int ySize = 10; // BAR SIZE IN Y AXIS
    int Layer = 1001;
    int Black = rgbcolor(0, 0, 0);
    int darkYellow = rgbcolor(198, 198, 0);
    int darkRed = rgbcolor(128, 0, 0);

    drawstring(35, 147, 0, "Boss_HP:_"+currentHP);

    if(getglobalvar("upperBar") == NULL()){
        setglobalvar("upperBar", allocscreen(xSize/2, ySize));
    }
    if(getglobalvar("bottomBar") == NULL()){
        setglobalvar("bottomBar", allocscreen(xSize/2, ySize));
    }

    clearscreen(getglobalvar("upperBar"));
    clearscreen(getglobalvar("bottomBar"));
    changedrawmethod(NULL(),"reset", 1);
    changedrawmethod(NULL(),"enabled", 1);
    changedrawmethod(NULL(),"transbg", 1);

    //Main formula
    currentHP = (currentHP*xSize)/(maxHP);
    maxHP = (maxHP*xSize)/(maxHP);
    
    if(getentityvar(self, "enemigo") == NULL()){
        setentityvar(self, "enemigo", maxHP);
    }

    drawboxtoscreen(getglobalvar("upperBar"), 0, 0, maxHP, ySize, darkRed);
    drawboxtoscreen(getglobalvar("upperBar"), 0, 0, getentityvar(self,"enemigo"), ySize, darkYellow);
    drawboxtoscreen(getglobalvar("bottomBar"), -(xSize/2), 0, maxHP, ySize, darkRed);
    drawboxtoscreen(getglobalvar("bottomBar"), -(xSize/2), 0, getentityvar(self,"enemigo"), ySize, darkYellow);

    if(currentHP < getentityvar(self, "enemigo")){ // if hp box smaller then damage box
        if(getentityvar(self,1)==NULL()){
            setentityvar(self,1,0); //set entity var 1 to zero if null this is a timer
        }
        if(getentityvar(self,1) > 3){ //if timer over 7
            setentityvar(self, "enemigo",getentityvar(self, "enemigo")-1); //reduce displayed damage by 1
            setentityvar(self,1,0); //reset timer to zero this will cause a loop untill damage is the same as hp
        }
        setentityvar(self,1,getentityvar(self,1)+1); //add 1 to timer this will run every game tick
    }

    drawscreen(getglobalvar("upperBar"), xPos, yPos, Layer);
    drawscreen(getglobalvar("bottomBar"), xPos, yPos+ySize, Layer);
}

 
PERFECT!!! I really love the look of the result now!

BTW I didn't know clearscreen exists as part of the script/code since it's never documented in the manual (or being part of source code?). But it's great to see the name there for the first time.

Thank you very much, @Kratus!!! 🫂

I'll come back and ask about the short bottom bar as its max like you see in some Capcom games later, but as for now, this is good enough.

Cheers! 🍻
 
I'm back. I have a question regarding the boss's pose as a pre-boss battle. What I want to do is to make the lifebar and its life icon to not show. Problem is the drawn sprite for the lifebar appears or doesn't appear because I declared an animation variable with != (Not) and || (Or) operations over the main one you see below. But I don't know what I'm doing. However, I have no problem with calling "iconposition" for placing it offscreen when the boss's HUD is offscreen.

C:
void main(){
    void self = getlocalvar("self");
    void ani = getentityproperty(self, "animationid");
    void mStyle = getglobalvar("musicStyle");
    void barBossG = getglobalvar("barBossG");
    void barBossR = getglobalvar("barBossR");
    void barBossB = getglobalvar("barBossB");
    int HP = getentityproperty(self, "health");
    int maxHP = getentityproperty(self, "maxhealth");
    int xSize = 544;
    int ySize = 6;
    int xPos = 113; // BASE X POSITION
    int yPos = 251;

    int Green = rgbcolor(58, 184, 27);
    int Red = rgbcolor(147, 32, 19);
    int Blue = rgbcolor(31, 86, 214);

    if(!barBossG){
        barBossG = loadsprite("data/sprites/barBossG.png");
    }

    if(!barBossB){
        barBossB = loadsprite("data/sprites/barBossB.png");
    }

    if(!barBossR){
        barBossR = loadsprite("data/sprites/barBossR.png");
    }

    if(getglobalvar("upperBar") == NULL()){
        setglobalvar("upperBar", allocscreen(xSize/2, ySize));
    }
    if(getglobalvar("bottomBar") == NULL()){
        setglobalvar("bottomBar", allocscreen(xSize/2, ySize));
    }

    clearscreen(getglobalvar("upperBar"));
    clearscreen(getglobalvar("bottomBar"));
    changedrawmethod(NULL(),"reset", 1);
    changedrawmethod(NULL(),"enabled", 1);
    changedrawmethod(NULL(),"transbg", 1);

    //Main formula
    HP = (HP*xSize)/(maxHP);
    maxHP = (maxHP*xSize)/(maxHP);
   
    if(getentityvar(self, "daBoss") == NULL()){
        setentityvar(self, "daBoss", maxHP);
    }

  if(ani == openborconstant("ANI_FOLLOW94") || ani == openborconstant("ANI_FOLLOW95") || ani == openborconstant("ANI_FOLLOW96") || ani == openborconstant("ANI_FOLLOW97") || ani == openborconstant("ANI_FOLLOW98") && ani != openborconstant("ANI_FOLLOW99")){

    if(mStyle == 0){
        drawsprite(barBossG, 87, 238, 9000);
        //drawboxtoscreen(getglobalvar("upperBar"), 0, 0, maxHP, ySize, darkRed);
        drawboxtoscreen(getglobalvar("upperBar"), 0, 0, getentityvar(self,"daBoss"), ySize, Green);
        //drawboxtoscreen(getglobalvar("bottomBar"), -(xSize/2), 0, maxHP, ySize, darkRed);
        drawboxtoscreen(getglobalvar("bottomBar"), -(xSize/2), 0, getentityvar(self,"daBoss"), ySize, Green);
    }else if(mStyle == 1){
        //drawboxtoscreen(getglobalvar("upperBar"), 0, 0, maxHP, ySize, darkRed);
        drawboxtoscreen(getglobalvar("upperBar"), 0, 0, getentityvar(self,"daBoss"), ySize, Red);
        //drawboxtoscreen(getglobalvar("bottomBar"), -(xSize/2), 0, maxHP, ySize, darkRed);
        drawboxtoscreen(getglobalvar("bottomBar"), -(xSize/2), 0, getentityvar(self,"daBoss"), ySize, Red);
        drawsprite(barBossR, 87, 238, 9000);
    }else if(mStyle == 2){
        drawsprite(barBossB, 87, 238, 9000);
        //drawboxtoscreen(getglobalvar("upperBar"), 0, 0, maxHP, ySize, darkRed);
        drawboxtoscreen(getglobalvar("upperBar"), 0, 0, getentityvar(self,"daBoss"), ySize, Blue);
        //drawboxtoscreen(getglobalvar("bottomBar"), -(xSize/2), 0, maxHP, ySize, darkRed);
        drawboxtoscreen(getglobalvar("bottomBar"), -(xSize/2), 0, getentityvar(self,"daBoss"), ySize, Blue);
    }

    if(HP < getentityvar(self, "daBoss")){ // if hp box smaller then damage box
        if(getentityvar(self,1)==NULL()){
            setentityvar(self,1,0); //set entity var 1 to zero if null this is a timer
        }
        if(getentityvar(self,1) > 2){ //if timer over 7
            setentityvar(self, "daBoss",getentityvar(self, "daBoss")-1); //reduce displayed damage by 1
            setentityvar(self,1,0); //reset timer to zero this will cause a loop untill damage is the same as hp
        }
        setentityvar(self,1,getentityvar(self,1)+1); //add 1 to timer this will run every game tick
    }

  }

    drawscreen(getglobalvar("upperBar"), xPos, yPos, 33000);
    drawscreen(getglobalvar("bottomBar"), xPos, yPos+ySize+2, 33000);

}

void oncreate(){
    void barBossG;
    void barBossR;
    void barBossB;

    if(!barBossG){
        barBossG = loadsprite("data/sprites/barBossG.png");
        setglobalvar("barBossG", barBossG);
    }

    if(!barBossB){
        barBossG = loadsprite("data/sprites/barBossB.png");
        setglobalvar("barBossB", barBossB);
    }

    if(!barBossR){
        barBossR = loadsprite("data/sprites/barBossR.png");
        setglobalvar("barBossR", barBossR);
    }

}

void ondestroy(){
    void barBossG;
    void barBossR;
    void barBossB;

    if(barBossG){
        free(barBossG);
        setglobalvar("barBossG", NULL());
    }

    if(barBossR){
        free(barBossR);
        setglobalvar("barBossR", NULL());
    }

    if(barBossB){
        free(barBossB);
        setglobalvar("barBossB", NULL());
    }

}

I tried using Not (!=) and Or (||) for declaring specific animation(s) to show its drawsprite or not when I use follow94-99. However, I'm quite lost on where to declare which animation to show and which animation not to. For instance, I want the drawsprite part not to show because that's a pre-battle intro. Moreover, the boss is using follow animatons from follow94-98, except follow99 is when the boss is ready to fight. Follow99 is when the boss's drawsprite part starts to show for battle. Plus, it's the animation that starts its boss music with script.
 
Back
Top Bottom