• All, Gmail is currently rejecting messages from my host. I have a ticket in process, but it may take some time to resolve. Until further notice, do NOT use Gmail for your accounts. You will be unable to receive confirmations and two factor messages to login.

[SCRIPT] Gradient Bars (all bars)

AlexDC22

Well-known member
coding is not my forte, so if its overkill i apologize but it works with gradient colors for all players life bars individually so each
player can have its own color if you choose to, and 1 shared gradient for enemies and mp bar.
player 4 is untested but it should work , i am using 3 players and they all work accordingly so far xD
please from the pros, feedback on it would be appreciated as this took me all day smfh, am getting old lol
again everything works here on engine 4.0, and is its crappy please remove at will :)
of course youl have to adjust the numbers to fit your game and am using the same numbers for the y and x that i use in levels.txt file

I use it in update.c script as updated.c doesnt seem to work for me.
if theres a better way let me know please as it is my first time posting anything like this >_>
thank you.

Example in game look, just know that each player can have different color gradients... like p1 to p4 can be different if you chose to.
enemies only use 1 color gradient.

in levels text is where you set your bar positions and sizes, and those numbers then you use on the script for each matching setting.
the rest can be moved using the Xoffsets in the script along with gradient color choices.
EDIT: 9-3-2024
C:
// Global variables for each player's last health and corresponding enemy
int lastHpP1 = -1;
int lastHpP2 = -1;
int lastHpP3 = -1;
int lastHpP4 = -1;
int lastIhpP1 = -1;
int lastIhpP2 = -1;
int lastIhpP3 = -1;
int lastIhpP4 = -1;

// Player-specific settings
int player1Size = 58;
int player1Size1 = 58;
int player1XPos = 17;
int player1YPos = 3;
int player1XOffset = 0;
int player1MaxR = 0;
int player1MaxG = 0;
int player1MaxB = 255;
int player1MinR = 255;
int player1MinG = 0;
int player1MinB = 0;

int player2Size = 58;
int player2Size1 = 58;
int player2XPos = -35;
int player2YPos = 3;
int player2XOffset = 159;
int player2MaxR = 0;
int player2MaxG = 0;
int player2MaxB = 255;
int player2MinR = 255;
int player2MinG = 0;
int player2MinB = 0;

int player3Size = 58;
int player3Size1 = 58;
int player3XPos = 17;
int player3YPos = 3;
int player3XOffset = 214;
int player3MaxR = 0;
int player3MaxG = 0;
int player3MaxB = 255;
int player3MinR = 255;
int player3MinG = 0;
int player3MinB = 0;

int player4Size = 58;
int player4Size1 = 58;
int player4XPos = -35;
int player4YPos = 3;
int player4XOffset = 268;
int player4MaxR = 0;
int player4MaxG = 0;
int player4MaxB = 255;
int player4MinR = 255;
int player4MinG = 0;
int player4MinB = 0;

// MP Bar settings (fluorescent green to red)
int mpBarMaxR = 0;
int mpBarMaxG = 255;
int mpBarMaxB = 0;
int mpBarMinR = 255;
int mpBarMinG = 0;
int mpBarMinB = 0;
int mpBarSize = 58;
int mpBarYOffset = 6;  // Vertical offset from the HP bar
int mpBarXOffset = 0;  // Horizontal offset from the HP bar

// Enemy lifebar position offsets
int enemyLifebarXOffsetP1 = -14;
int enemyLifebarYOffsetP1 = 21;
int enemyLifebarBackgroundXOffsetP1 = -14;  // Background bar X offset
int enemyLifebarBackgroundYOffsetP1 = 21;  // Background bar Y offset

int enemyLifebarXOffsetP2 = -14;
int enemyLifebarYOffsetP2 = 21;
int enemyLifebarBackgroundXOffsetP2 = -14;  // Background bar X offset
int enemyLifebarBackgroundYOffsetP2 = 21;  // Background bar Y offset

int enemyLifebarXOffsetP3 = -14;
int enemyLifebarYOffsetP3 = 21;
int enemyLifebarBackgroundXOffsetP3 = -14;  // Background bar X offset
int enemyLifebarBackgroundYOffsetP3 = 21;  // Background bar Y offset

int enemyLifebarXOffsetP4 = -14;
int enemyLifebarYOffsetP4 = 21;
int enemyLifebarBackgroundXOffsetP4 = -14;  // Background bar X offset
int enemyLifebarBackgroundYOffsetP4 = 21;  // Background bar Y offset

void main()
{
    if (openborvariant("in_level")) {
        drawHp();
        drawMp();
    }
}

void drawHp()
{
    int layer = 60000;

    // Draw lifebars for each player
    drawPlayerLifebar(0, player1Size, player1Size1, player1XPos, player1YPos, player1XOffset, lastHpP1, lastIhpP1, player1MaxR, player1MaxG, player1MaxB, player1MinR, player1MinG, player1MinB);
    drawPlayerLifebar(1, player2Size, player2Size1, player2XPos, player2YPos, player2XOffset, lastHpP2, lastIhpP2, player2MaxR, player2MaxG, player2MaxB, player2MinR, player2MinG, player2MinB);
    drawPlayerLifebar(2, player3Size, player3Size1, player3XPos, player3YPos, player3XOffset, lastHpP3, lastIhpP3, player3MaxR, player3MaxG, player3MaxB, player3MinR, player3MinG, player3MinB);
    drawPlayerLifebar(3, player4Size, player4Size1, player4XPos, player4YPos, player4XOffset, lastHpP4, lastIhpP4, player4MaxR, player4MaxG, player4MaxB, player4MinR, player4MinG, player4MinB);
}

void drawMp()
{
    // Draw MP bars for each player
    drawPlayerMpBar(0, player1Size, player1XPos + mpBarXOffset, player1YPos + mpBarYOffset, player1XOffset);
    drawPlayerMpBar(1, player2Size, player2XPos + mpBarXOffset, player2YPos + mpBarYOffset, player2XOffset);
    drawPlayerMpBar(2, player3Size, player3XPos + mpBarXOffset, player3YPos + mpBarYOffset, player3XOffset);
    drawPlayerMpBar(3, player4Size, player4XPos + mpBarXOffset, player4YPos + mpBarYOffset, player4XOffset);
}

void drawPlayerLifebar(int playerIndex, int size, int size1, int xPos, int yPos, int xOffset, int lastHp, int lastIhp, int maxR, int maxG, int maxB, int minR, int minG, int minB)
{
    void self = getplayerproperty(playerIndex, "entity");
    if (self) {
        int dead = getentityproperty(self, "dead");
        void type = getentityproperty(self, "type");
        void target = getentityproperty(self, "opponent");
        void iType = getentityproperty(target, "type");
        int noLife = getentityproperty(target, "nolife");
        int maxHp = getentityproperty(self, "maxhealth");
        int hp = getentityproperty(self, "health");

        if (hp > maxHp) {
            hp = maxHp;
        }

        hp = (hp * size1) / maxHp;
        if (hp > size) {
            hp = size;
        }

        // Draw full background bar
        drawbox(xPos + xOffset, yPos, size, 3, 60000, rgbcolor(0, 0, 0)); // Background color

        if (openborvariant("in_level") && type == openborconstant("TYPE_PLAYER") && dead != 1) {
            // Determine gradient color for player lifebar
            int playerColor = blendcolor(maxR, maxG, maxB, minR, minG, minB, hp, size);
            // Draw the gradient lifebar for player
            drawbox(xPos + xOffset, yPos, hp, 3, 60001, playerColor);
        }

        if (iType == openborconstant("TYPE_ENEMY") && noLife != 1) {
            int imaxHp = getentityproperty(target, "maxhealth");
            int ihp = getentityproperty(target, "health");
            ihp = (ihp * size1) / imaxHp;
            if (ihp > size) {
                ihp = size;
            }

            // Determine enemy lifebar position offsets
            int enemyXOffset = 0;
            int enemyYOffset = 0;
            int enemyBgXOffset = 0;
            int enemyBgYOffset = 0;

            switch (playerIndex) {
                case 0:
                    enemyXOffset = enemyLifebarXOffsetP1;
                    enemyYOffset = enemyLifebarYOffsetP1;
                    enemyBgXOffset = enemyLifebarBackgroundXOffsetP1;
                    enemyBgYOffset = enemyLifebarBackgroundYOffsetP1;
                    break;
                case 1:
                    enemyXOffset = enemyLifebarXOffsetP2;
                    enemyYOffset = enemyLifebarYOffsetP2;
                    enemyBgXOffset = enemyLifebarBackgroundXOffsetP2;
                    enemyBgYOffset = enemyLifebarBackgroundYOffsetP2;
                    break;
                case 2:
                    enemyXOffset = enemyLifebarXOffsetP3;
                    enemyYOffset = enemyLifebarYOffsetP3;
                    enemyBgXOffset = enemyLifebarBackgroundXOffsetP3;
                    enemyBgYOffset = enemyLifebarBackgroundYOffsetP3;
                    break;
                case 3:
                    enemyXOffset = enemyLifebarXOffsetP4;
                    enemyYOffset = enemyLifebarYOffsetP4;
                    enemyBgXOffset = enemyLifebarBackgroundXOffsetP4;
                    enemyBgYOffset = enemyLifebarBackgroundYOffsetP4;
                    break;
            }

            // Draw full background bar for enemy
            drawbox(xPos + xOffset + enemyBgXOffset, yPos + enemyBgYOffset, size, 3, 60000, rgbcolor(0, 0, 0)); // Background color

            // Determine gradient color for enemy lifebar (yellow to red)
            int enemyColor = blendcolor(255, 255, 0, 255, 0, 0, ihp, size);
            // Draw the gradient lifebar for enemy
            drawbox(xPos + xOffset + enemyXOffset, yPos + enemyYOffset, ihp, 3, 60001, enemyColor);
        }
    }
}

void drawPlayerMpBar(int playerIndex, int size, int xPos, int yPos, int xOffset)
{
    void self = getplayerproperty(playerIndex, "entity");
    if (self) {
        int maxMp = getentityproperty(self, "maxmp");
        int mp = getentityproperty(self, "mp");

        if (mp > maxMp) {
            mp = maxMp;
        }

        mp = (mp * size) / maxMp;
        if (mp > size) {
            mp = size;
        }

        // Draw full background bar
        drawbox(xPos + xOffset, yPos, size, 3, 60000, rgbcolor(0, 0, 0)); // Background color

        if (openborvariant("in_level") && getentityproperty(self, "dead") != 1) {
            // Determine gradient color for player MP bar
            int mpColor = blendcolor(mpBarMaxR, mpBarMaxG, mpBarMaxB, mpBarMinR, mpBarMinG, mpBarMinB, mp, size);
            // Draw the gradient MP bar for player
            drawbox(xPos + xOffset, yPos, mp, 3, 60001, mpColor);
        }
    }
}

// Function to blend two colors based on health percentage
int blendcolor(int maxR, int maxG, int maxB, int minR, int minG, int minB, int current, int max)
{
    int percent = (current * 100) / max;
    int r = (maxR * percent + minR * (100 - percent)) / 100;
    int g = (maxG * percent + minG * (100 - percent)) / 100;
    int b = (maxB * percent + minB * (100 - percent)) / 100;

    // Ensure values are properly initialized and within range
    r = (r >= 0 && r <= 255) ? r : 0;
    g = (g >= 0 && g <= 255) ? g : 0;
    b = (b >= 0 && b <= 255) ? b : 0;

    return rgbcolor(r, g, b);
}
 
Last edited:
coding is not my forte, so if its overkill i apologize but it works with gradient colors for all players life bars individually so each
player can have its own color if you choose to, and 1 shared gradient for enemies and mp bar.
player 4 is untested but it should work , i am using 3 players and they all work accordingly so far xD
please from the pros, feedback on it would be appreciated as this took me all day smfh, am getting old lol
again everything works here on engine 4.0, and is its crappy please remove at will :)
of course youl have to adjust the numbers to fit your game and am using the same numbers for the y and x that i use in levels.txt file

am setting it in player text file like this: ondrawscript data/scripts/gradient_bars.c
if theres a better way let me know please as it is my first time posting anything like this >_>
thank you.

C:
// Global variables for each player's last health and corresponding enemy
int lastHpP1 = -1;
int lastHpP2 = -1;
int lastHpP3 = -1;
int lastHpP4 = -1;
int lastIhpP1 = -1;
int lastIhpP2 = -1;
int lastIhpP3 = -1;
int lastIhpP4 = -1;

// Player-specific settings
int player1Size = 58;
int player1Size1 = 58;
int player1XPos = 17;
int player1YPos = 3;
int player1XOffset = 0;
int player1MaxR = 0;
int player1MaxG = 0;
int player1MaxB = 255;
int player1MinR = 255;
int player1MinG = 0;
int player1MinB = 0;

int player2Size = 58;
int player2Size1 = 58;
int player2XPos = -35;
int player2YPos = 3;
int player2XOffset = 159;
int player2MaxR = 0;
int player2MaxG = 0;
int player2MaxB = 255;
int player2MinR = 255;
int player2MinG = 0;
int player2MinB = 0;

int player3Size = 58;
int player3Size1 = 58;
int player3XPos = 17;
int player3YPos = 3;
int player3XOffset = 214;
int player3MaxR = 0;
int player3MaxG = 0;
int player3MaxB = 255;
int player3MinR = 255;
int player3MinG = 0;
int player3MinB = 0;

int player4Size = 58;
int player4Size1 = 58;
int player4XPos = -35;
int player4YPos = 3;
int player4XOffset = 268;
int player4MaxR = 0;
int player4MaxG = 0;
int player4MaxB = 255;
int player4MinR = 255;
int player4MinG = 0;
int player4MinB = 0;

// MP Bar settings (fluorescent green to red)
int mpBarMaxR = 0;
int mpBarMaxG = 255;
int mpBarMaxB = 0;
int mpBarMinR = 255;
int mpBarMinG = 0;
int mpBarMinB = 0;
int mpBarSize = 58;
int mpBarYOffset = 6;  // Vertical offset from the HP bar
int mpBarXOffset = 0;  // Horizontal offset from the HP bar

// Enemy lifebar position offsets
int enemyLifebarXOffsetP1 = -14;
int enemyLifebarYOffsetP1 = 21;
int enemyLifebarBackgroundXOffsetP1 = -14;  // Background bar X offset
int enemyLifebarBackgroundYOffsetP1 = 21;  // Background bar Y offset

int enemyLifebarXOffsetP2 = -14;
int enemyLifebarYOffsetP2 = 21;
int enemyLifebarBackgroundXOffsetP2 = -14;  // Background bar X offset
int enemyLifebarBackgroundYOffsetP2 = 21;  // Background bar Y offset

int enemyLifebarXOffsetP3 = -14;
int enemyLifebarYOffsetP3 = 21;
int enemyLifebarBackgroundXOffsetP3 = -14;  // Background bar X offset
int enemyLifebarBackgroundYOffsetP3 = 21;  // Background bar Y offset

int enemyLifebarXOffsetP4 = -14;
int enemyLifebarYOffsetP4 = 21;
int enemyLifebarBackgroundXOffsetP4 = -14;  // Background bar X offset
int enemyLifebarBackgroundYOffsetP4 = 21;  // Background bar Y offset

void main()
{
    drawHp();
    drawMp();
}

void drawHp()
{
    int layer = 60000;

    // Draw lifebars for each player
    drawPlayerLifebar(0, player1Size, player1Size1, player1XPos, player1YPos, player1XOffset, lastHpP1, lastIhpP1, player1MaxR, player1MaxG, player1MaxB, player1MinR, player1MinG, player1MinB);
    drawPlayerLifebar(1, player2Size, player2Size1, player2XPos, player2YPos, player2XOffset, lastHpP2, lastIhpP2, player2MaxR, player2MaxG, player2MaxB, player2MinR, player2MinG, player2MinB);
    drawPlayerLifebar(2, player3Size, player3Size1, player3XPos, player3YPos, player3XOffset, lastHpP3, lastIhpP3, player3MaxR, player3MaxG, player3MaxB, player3MinR, player3MinG, player3MinB);
    drawPlayerLifebar(3, player4Size, player4Size1, player4XPos, player4YPos, player4XOffset, lastHpP4, lastIhpP4, player4MaxR, player4MaxG, player4MaxB, player4MinR, player4MinG, player4MinB);
}

void drawMp()
{
    // Draw MP bars for each player
    drawPlayerMpBar(0, player1Size, player1XPos + mpBarXOffset, player1YPos + mpBarYOffset, player1XOffset);
    drawPlayerMpBar(1, player2Size, player2XPos + mpBarXOffset, player2YPos + mpBarYOffset, player2XOffset);
    drawPlayerMpBar(2, player3Size, player3XPos + mpBarXOffset, player3YPos + mpBarYOffset, player3XOffset);
    drawPlayerMpBar(3, player4Size, player4XPos + mpBarXOffset, player4YPos + mpBarYOffset, player4XOffset);
}

void drawPlayerLifebar(int playerIndex, int size, int size1, int xPos, int yPos, int xOffset, int lastHp, int lastIhp, int maxR, int maxG, int maxB, int minR, int minG, int minB)
{
    void self = getplayerproperty(playerIndex, "entity");
    if (self) {
        int dead = getentityproperty(self, "dead");
        void type = getentityproperty(self, "type");
        void target = getentityproperty(self, "opponent");
        void iType = getentityproperty(target, "type");
        int noLife = getentityproperty(target, "nolife");
        int maxHp = getentityproperty(self, "maxhealth");
        int hp = getentityproperty(self, "health");

        if (hp > maxHp) {
            hp = maxHp;
        }

        hp = (hp * size1) / maxHp;
        if (hp > size) {
            hp = size;
        }

        // Draw full background bar
        drawbox(xPos + xOffset, yPos, size, 3, 60000, rgbcolor(0, 0, 0)); // Background color

        if (openborvariant("in_level") && type == openborconstant("TYPE_PLAYER") && dead != 1) {
            // Determine gradient color for player lifebar
            int playerColor = blendcolor(maxR, maxG, maxB, minR, minG, minB, hp, size);
            // Draw the gradient lifebar for player
            drawbox(xPos + xOffset, yPos, hp, 3, 60001, playerColor);
        }

        if (iType == openborconstant("TYPE_ENEMY") && noLife != 1) {
            int imaxHp = getentityproperty(target, "maxhealth");
            int ihp = getentityproperty(target, "health");
            ihp = (ihp * size1) / imaxHp;
            if (ihp > size) {
                ihp = size;
            }

            // Determine enemy lifebar position offsets
            int enemyXOffset = 0;
            int enemyYOffset = 0;
            int enemyBgXOffset = 0;
            int enemyBgYOffset = 0;

            switch (playerIndex) {
                case 0:
                    enemyXOffset = enemyLifebarXOffsetP1;
                    enemyYOffset = enemyLifebarYOffsetP1;
                    enemyBgXOffset = enemyLifebarBackgroundXOffsetP1;
                    enemyBgYOffset = enemyLifebarBackgroundYOffsetP1;
                    break;
                case 1:
                    enemyXOffset = enemyLifebarXOffsetP2;
                    enemyYOffset = enemyLifebarYOffsetP2;
                    enemyBgXOffset = enemyLifebarBackgroundXOffsetP2;
                    enemyBgYOffset = enemyLifebarBackgroundYOffsetP2;
                    break;
                case 2:
                    enemyXOffset = enemyLifebarXOffsetP3;
                    enemyYOffset = enemyLifebarYOffsetP3;
                    enemyBgXOffset = enemyLifebarBackgroundXOffsetP3;
                    enemyBgYOffset = enemyLifebarBackgroundYOffsetP3;
                    break;
                case 3:
                    enemyXOffset = enemyLifebarXOffsetP4;
                    enemyYOffset = enemyLifebarYOffsetP4;
                    enemyBgXOffset = enemyLifebarBackgroundXOffsetP4;
                    enemyBgYOffset = enemyLifebarBackgroundYOffsetP4;
                    break;
            }

            // Draw full background bar for enemy
            drawbox(xPos + xOffset + enemyBgXOffset, yPos + enemyBgYOffset, size, 3, 60000, rgbcolor(0, 0, 0)); // Background color

            // Determine gradient color for enemy lifebar (yellow to red)
            int enemyColor = blendcolor(255, 255, 0, 255, 0, 0, ihp, size);
            // Draw the gradient lifebar for enemy
            drawbox(xPos + xOffset + enemyXOffset, yPos + enemyYOffset, ihp, 3, 60001, enemyColor);
        }
    }
}

void drawPlayerMpBar(int playerIndex, int size, int xPos, int yPos, int xOffset)
{
    void self = getplayerproperty(playerIndex, "entity");
    if (self) {
        int maxMp = getentityproperty(self, "maxmp");
        int mp = getentityproperty(self, "mp");

        if (mp > maxMp) {
            mp = maxMp;
        }

        mp = (mp * size) / maxMp;
        if (mp > size) {
            mp = size;
        }

        // Draw full background bar
        drawbox(xPos + xOffset, yPos, size, 3, 60000, rgbcolor(0, 0, 0)); // Background color

        if (openborvariant("in_level") && getentityproperty(self, "dead") != 1) {
            // Determine gradient color for player MP bar
            int mpColor = blendcolor(mpBarMaxR, mpBarMaxG, mpBarMaxB, mpBarMinR, mpBarMinG, mpBarMinB, mp, size);
            // Draw the gradient MP bar for player
            drawbox(xPos + xOffset, yPos, mp, 3, 60001, mpColor);
        }
    }
}

// Function to blend two colors based on health percentage
int blendcolor(int maxR, int maxG, int maxB, int minR, int minG, int minB, int current, int max)
{
    int percent = (current * 100) / max;
    int r = (maxR * percent + minR * (100 - percent)) / 100;
    int g = (maxG * percent + minG * (100 - percent)) / 100;
    int b = (maxB * percent + minB * (100 - percent)) / 100;

    // Ensure values are properly initialized and within range
    r = (r >= 0 && r <= 255) ? r : 0;
    g = (g >= 0 && g <= 255) ? g : 0;
    b = (b >= 0 && b <= 255) ? b : 0;

    return rgbcolor(r, g, b);
}
Looks good :) I only suggest adding some visual examples for people to understand how the effect works when active.
 
OG Post updated...not sure if thats what your asking for? sorry not to good at explaining stuff lol
Yes friend, it's exactly that. It's a cool script, congratulations!

found out this script works better in update.c than ondrawscript.
Exactly, for progress bars I recommend updated.c due to the consistency and accuracy. But I recommend putting only important functions on it to not overload the event.

Another thing I recommend is to use the updated.c instead of the update.c unless you need to interrupt key presses before the engine processes it. It's because the updated.c runs at the end of an engine cycle, meaning that the engine already did everything it needs and your script can run with no worries.

For a few small scripts it will not show differences in practice, but if you have many things running at the same time it may present performance issues. I tested it in my first SOR2X versions, where I was using too many scripts in the update.c and the performance dropped severely mainly during special effects, like shadow trails.

1724789210419.png
 
Yes friend, it's exactly that. It's a cool script, congratulations!


Exactly, for progress bars I recommend updated.c due to the consistency and accuracy. But I recommend putting only important functions on it to not overload the event.

Another thing I recommend is to use the updated.c instead of the update.c unless you need to interrupt key presses before the engine processes it. It's because the updated.c runs at the end of an engine cycle, meaning that the engine already did everything it needs and your script can run with no worries.

For a few small scripts it will not show differences in practice, but if you have many things running at the same time it may present performance issues. I tested it in my first SOR2X versions, where I was using too many scripts in the update.c and the performance dropped severely mainly during special effects, like shadow trails.

View attachment 9003
sweet thanks for the info and updated 1st post to reflect that.

EDIT: now i remember why i didnt use updated... doesnt seem to work. sorry thats the extent of my knowledge lol
 
oops fixed the code so it wont show up in mainmenu after you quit the game... it should only show in game now... apologies
 
Back
Top Bottom