Appropriating Script for Player Index

maxman

Well-known member
I have a question regarding the way to use for scripting for player index. This one, for example, is that I want to give player index the way @Kratus does in his projects.

I usually made it like this.
C:
void main(){
    LastoNumber();
}

void LastoNumber()
{

    if(openborvariant("in_level"))
    {
        int P1 = getplayerproperty(0, "entity");
        int P2 = getplayerproperty(1, "entity");
        int P3 = getplayerproperty(2, "entity");
        int P4 = getplayerproperty(3, "entity");
        int P1Life = getplayerproperty(0, "lives");
        int P2Life = getplayerproperty(1, "lives");
        int P3Life = getplayerproperty(2, "lives");
        int P4Life = getplayerproperty(3, "lives");
        int font = 3; //Standard Life Font
        void mStyle = getglobalvar("musicStyle");

        if(mStyle == 0){font = 4;} // Green font
        if(mStyle == 1){font = 6;} // Red font
        if(mStyle == 2){font = 5;} // Blue font
        

        if(P1)
        {
            drawstring(111, 9, font, P1Life-1);
        }

        if(P2)
        {
            drawstring(231, 9, font, P2Life-1);
        }

        if(P3)
        {
            drawstring(351, 9, font, P3Life-1);
        }

        if(P4)
        {
            drawstring(471, 9, font, P4Life-1);
        }

    }
}

What I want is different from what I usually do. It's something that goes like this for having the player part as part of the function here.

C:
void main(){
    lastNumber2(0); // player 1
    lastNumber2(1); // player 2
    lastNumber2(2); // player 3
    lastNumber2(3); // player 4
}

void lastNumber2(int player){
    if(openborvariant("in_level")){
        int ent = getplayerproperty(player, "ent");

        if(ent != NULL()){ // Does this playable entity exist?

            int Life = getplayerproperty(player, "lives");
            int font = 3; //Standard Life Font
            void mStyle = getglobalvar("musicStyle");

            if(mStyle == 0){font = 4;} // Green font
            if(mStyle == 1){font = 6;} // Red font
            if(mStyle == 2){font = 5;} // Blue font

            int xPos = 111;
            int yPos = 9;
            int xAdd = 120;
            int align;

            if(player == 0){
                drawstring(xPos, yPos, font, Life-1);
            }
            if(player == 1){
                drawstring(xPos+xAdd, yPos, font, Life-1);
            }
            if(player == 2){
                drawstring(xPos+xAdd*2, yPos, font, Life-1);
            }
            if(player == 3){
                drawstring(xPos+xAdd*3, yPos, font, Life-1);
            }

        }
    }
}

This leads me to my question on the player variable/function I use as a new script. Its result is correct as what I previously made. But is giving the player variable/function with its index like this correct ((player == 0))? I don't know if it's correct to use this kind since I want the text to be aligned accordingly to each/specific player index based on where it should be located.

ROD MAXED OUT! - 0247.png
 
I have a question regarding the way to use for scripting for player index. This one, for example, is that I want to give player index the way @Kratus does in his projects.

I usually made it like this.
C:
void main(){
    LastoNumber();
}

void LastoNumber()
{

    if(openborvariant("in_level"))
    {
        int P1 = getplayerproperty(0, "entity");
        int P2 = getplayerproperty(1, "entity");
        int P3 = getplayerproperty(2, "entity");
        int P4 = getplayerproperty(3, "entity");
        int P1Life = getplayerproperty(0, "lives");
        int P2Life = getplayerproperty(1, "lives");
        int P3Life = getplayerproperty(2, "lives");
        int P4Life = getplayerproperty(3, "lives");
        int font = 3; //Standard Life Font
        void mStyle = getglobalvar("musicStyle");

        if(mStyle == 0){font = 4;} // Green font
        if(mStyle == 1){font = 6;} // Red font
        if(mStyle == 2){font = 5;} // Blue font
       

        if(P1)
        {
            drawstring(111, 9, font, P1Life-1);
        }

        if(P2)
        {
            drawstring(231, 9, font, P2Life-1);
        }

        if(P3)
        {
            drawstring(351, 9, font, P3Life-1);
        }

        if(P4)
        {
            drawstring(471, 9, font, P4Life-1);
        }

    }
}

What I want is different from what I usually do. It's something that goes like this for having the player part as part of the function here.

C:
void main(){
    lastNumber2(0); // player 1
    lastNumber2(1); // player 2
    lastNumber2(2); // player 3
    lastNumber2(3); // player 4
}

void lastNumber2(int player){
    if(openborvariant("in_level")){
        int ent = getplayerproperty(player, "ent");

        if(ent != NULL()){ // Does this playable entity exist?

            int Life = getplayerproperty(player, "lives");
            int font = 3; //Standard Life Font
            void mStyle = getglobalvar("musicStyle");

            if(mStyle == 0){font = 4;} // Green font
            if(mStyle == 1){font = 6;} // Red font
            if(mStyle == 2){font = 5;} // Blue font

            int xPos = 111;
            int yPos = 9;
            int xAdd = 120;
            int align;

            if(player == 0){
                drawstring(xPos, yPos, font, Life-1);
            }
            if(player == 1){
                drawstring(xPos+xAdd, yPos, font, Life-1);
            }
            if(player == 2){
                drawstring(xPos+xAdd*2, yPos, font, Life-1);
            }
            if(player == 3){
                drawstring(xPos+xAdd*3, yPos, font, Life-1);
            }

        }
    }
}

This leads me to my question on the player variable/function I use as a new script. Its result is correct as what I previously made. But is giving the player variable/function with its index like this correct ((player == 0))? I don't know if it's correct to use this kind since I want the text to be aligned accordingly to each/specific player index based on where it should be located.

View attachment 11542
I use both ways, depending on the situation. Usually for global events I prefer to code the script for a single player and declare it multiple times for all players instead of repeating every single line for each player.

I try to code things in the most reusable way possible.

1759176647299.png
 
@Kratus, you could optimize that function quite a bit using a loop. That would also make it auto adapt if you ever change player settings:

C-like:
void drawheal(){
    
    int paused = openborvariant("pause");
    int in_options = openborvariant("in_options");
   
    // Exit if paused or in options screen.
    if(paused || in_options){
        return;
    }
   
    if(getglobalvar("specialMoves") == "sor4_recovery"){

        int max_players = openborvariant("maxplayers");
        void player_ent = NULL();

        int i = 0;
        for(i = 0; i < max_players; i++){
            player_ent = getplayerproperty(i, "entity");
            healfunction(player_ent, i);              
        }

        // Heal partner.
        void parter = getglobalvar("currentPartner");
        healfunction(partner, 1);
    }      
}

I would also suggest you swapping getglobalvar("specialMoves") == "sor4_recovery" for a bitfield: I can show you how. String comparisons are a massive bottleneck. Never, EVER use strings for logical values unless you don't have any other choice.

DC
 
@Kratus, you could optimize that function quite a bit using a loop. That would also make it auto adapt if you ever change player settings:
The loop is a cool idea, thanks man. I will consider changing it in the SORX in future updates.

I would also suggest you swapping getglobalvar("specialMoves") == "sor4_recovery" for a bitfield: I can show you how. String comparisons are a massive bottleneck. Never, EVER use strings for logical values unless you don't have any other choice.
Yeah, the first versions of my systems worked with comparison of integers and then translated to text only when drawing the menu.
However, for some specific things, strings ended up becoming easier for me to update and debug the code.
I even tried to use constants like in the engine source, but for some reason they consume a lot more memory in the game than globalvars.
But thanks for the tip :)
 
I even tried to use constants like in the engine source, but for some reason they consume a lot more memory in the game than globalvars.
But thanks for the tip

I'd like to have a look at that some time. Constants are constants - they don't use memory at all. If they do, we may have a bug to ferret out. Even then, performance wise you'd be better off removing logical strings. It's difficult to overstate just how piggish strings are on a CPU compared to other types.

DC
 
That loop part seems to be a smart idea. What I'm trying to avoid is code redundancy, especially X position.

I just made my attempt for avoiding code redundancy. However, I don't see any players' life numbers displaying in game at all. It only works without declaring a check (e.g., player_ent == 0).

C:
void lastNumber3(){
    if(openborvariant("in_level")){
        int max_players = openborvariant("count_players");
        void player_ent = NULL();

        int i = 0;
        for(i = 0; i< max_players; i++){
            player_ent = getplayerproperty(i, "entity");
            int life = getplayerproperty(i, "lives");
            int xPos = 111;
            int yPos = 9;
            int xAdd = 120;
            int font = 3;
            void mStyle = getglobalvar("musicStyle");

            if(mStyle == 0){font = 4;}
            if(mStyle == 1){font = 6;}
            if(mStyle == 2){font = 5;}

            if(player_ent == 0){
                drawstring(xPos, yPos, font, life-1);
            }
            if(player_ent == 1){
                drawstring(xPos+xAdd, yPos, font, life-1);
            }
            if(player_ent == 2){
                drawstring(xPos+xAdd*2, yPos, font, life-1);
            }
            if(player_ent == 3){
                drawstring(xPos+xAdd*3, yPos, font, life-1);
            }
        }
    }
}

I do want to xAdd variable multiplied with how many players exist based on the player's X position (by displaying each player's respective life value), but at the same time, I'm trying to avoid redundancy. Is there a way to circumvent this or should I go back to square one?
 
That loop part seems to be a smart idea. What I'm trying to avoid is code redundancy, especially X position.

I just made my attempt for avoiding code redundancy. However, I don't see any players' life numbers displaying in game at all. It only works without declaring a check (e.g., player_ent == 0).

C:
void lastNumber3(){
    if(openborvariant("in_level")){
        int max_players = openborvariant("count_players");
        void player_ent = NULL();

        int i = 0;
        for(i = 0; i< max_players; i++){
            player_ent = getplayerproperty(i, "entity");
            int life = getplayerproperty(i, "lives");
            int xPos = 111;
            int yPos = 9;
            int xAdd = 120;
            int font = 3;
            void mStyle = getglobalvar("musicStyle");

            if(mStyle == 0){font = 4;}
            if(mStyle == 1){font = 6;}
            if(mStyle == 2){font = 5;}

            if(player_ent == 0){
                drawstring(xPos, yPos, font, life-1);
            }
            if(player_ent == 1){
                drawstring(xPos+xAdd, yPos, font, life-1);
            }
            if(player_ent == 2){
                drawstring(xPos+xAdd*2, yPos, font, life-1);
            }
            if(player_ent == 3){
                drawstring(xPos+xAdd*3, yPos, font, life-1);
            }
        }
    }
}

I do want to xAdd variable multiplied with how many players exist based on the player's X position (by displaying each player's respective life value), but at the same time, I'm trying to avoid redundancy. Is there a way to circumvent this or should I go back to square one?

Why on earth are you running a loop and then filtering by the player number? That completely defeats the purpose.

DC
 
Back
Top Bottom