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
 
It's to not make this script repetitive/redundant, but the truth is that, at first, I didn't want to add player number for this. Here's my problem. I want to find a specific player index while running a loop but without redundancy and filtering (by) player number. The ones from my first post here are, like, redundant.

Here is the one without the player number. While running a loop, I'm trying to not make it redundant as possible, but I want to add some values for specific player number. I don't know how I can change this.
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;}

            drawstring(xPos, yPos, font, life-1);

            drawstring(xPos+xAdd, yPos, font, life-1);

            drawstring(xPos+xAdd*2, yPos, font, life-1);

            drawstring(xPos+xAdd*3, yPos, font, life-1);

        }
    }
}

Like I said, it only works without filtering with player number.
 
I am with @DCurrent here - I am really trying to understand why you can't simple get the player index.
Which, btw, its faster than doing a loop like this - I am having an issue where I need to get the player index and all the NPCs positions to force them to execute a certain action, and the players always execute the animations earlier because getting a player index is faster than executing a loop.
The more entities you have on the screen, the slower it will be. Sure, nothing severe, but when you need precise sync like the example I gave you, you will notice it.
 
Back
Top Bottom