stats command error...
#1

hello,

i'm experiencing an error on my command called stats, tried a few ways, but still couldn't overcome that error. so here's my command:

Code:
CMD:stats(playerid, params[])
{
    if(PlayerInfo[playerid][LoggedIn] == true)
	{
    	new string[256], id, tname[MAX_PLAYER_NAME];
   	 	new admin, kills, deaths, registered[6], score, money, admrank[32];
   	 	if(sscanf(params, "u", id)) return SendClientMessage(playerid, COLOR_RED, "Syntax: /stats <playerid>");
     	if(id == INVALID_PLAYER_ID) {
			GetPlayerName(id, tname, sizeof(tname));
    		admin = PlayerInfo[playerid][AdminLevel];
			kills = PlayerInfo[playerid][Kills];
			deaths = PlayerInfo[playerid][Deaths];
			score = PlayerInfo[playerid][Score];
			money = GetPlayerMoney(playerid);
   			if(PlayerInfo[id][LoggedIn] == false)
  			{
				switch(PlayerInfo[id][LoggedIn])
				{
					case 0: registered = "No";
				}
			}
			else
   			{
				switch(PlayerInfo[id][LoggedIn])
 				{
 					case 1: registered = "Yes";
   				}
   			}
   			if(IsPlayerAdmin(id))
			{
				format(string,sizeof(string), "{00FF00}Name:{FFFFFF} %s\n{00FF00}Registered:{FFFFFF} %s\n{00FF00}Admin Level:{FF0000} RCON Admin\n{00FF00}Kills:{FFFFFF} %d\n{00FF00}Deaths:{FFFFFF} %d\n{00FF00}Score:{FFFFFF} %d\n{00FF00}Money:{FFFFFF} %d",tname, registered, kills, deaths, score, money);
  				ShowPlayerDialog(playerid, DIALOG_STATS, DIALOG_STYLE_MSGBOX, "{FFFFFF}Player's Statistics:", string, "Okay", "");
			}
   			else if(PlayerInfo[id][AdminLevel] > 0)
			{
				switch(PlayerInfo[id][AdminLevel])
 				{
					case 1: admrank = "{FFFF00}(Moderator)";
	        		case 2: admrank = "{008000}(Administrator)";
       				case 3: admrank = "{3366FF}(Manager)";
		 		}
		 	}
    		format(string,sizeof(string), "{00FF00}Name:{FFFFFF} %s\n{00FF00}Registered:{FFFFFF} %s\n{00FF00}Admin Level:{FFFFFF} %d %s\n{00FF00}Kills:{FFFFFF} %d\n{00FF00}Deaths:{FFFFFF} %d\n{00FF00}Score:{FFFFFF} %d\n{00FF00}Money:{FFFFFF} %d",tname, registered, admin, admrank, kills, deaths, score, money);
   			ShowPlayerDialog(playerid, DIALOG_STATS, DIALOG_STYLE_MSGBOX, "{FFFFFF}Player's Statistics:", string, "Okay", "");
		}
		else
		{
			format(string, sizeof(string), "{00FF00}Name:{FFFFFF} %s\n{00FF00}Registered:{FFFFFF} %s\n{00FF00}Kills:{FFFFFF} %d\n{00FF00}Deaths:{FFFFFF} %d\n{00FF00}Score:{FFFFFF} %d\n{00FF00}Money:{FFFFFF} %d", tname, registered, kills, deaths, score, money);
        	ShowPlayerDialog(playerid, DIALOG_STATS, DIALOG_STYLE_MSGBOX, "{FFFFFF}Player's Statistics:", string, "Okay", "");
			return 1;
		} else return SendClientMessage(playerid, COLOR_RED, "ERROR: Player is not connected");
	} else return SendClientMessage(playerid, COLOR_RED, "ERROR: Account must be registered in order to use commands.");
}
the error's this:

Code:
C:\Users\Heheboii\Desktop\samp037_svr_R2-1-1_win32 (1)\gamemodes\fps.pwn(1013) : error 029: invalid expression, assumed zero
C:\Users\Heheboii\Desktop\samp037_svr_R2-1-1_win32 (1)\gamemodes\fps.pwn(1013) : warning 215: expression has no effect
C:\Users\Heheboii\Desktop\samp037_svr_R2-1-1_win32 (1)\gamemodes\fps.pwn(1013) : error 001: expected token: ";", but found "return"
Pawn compiler 3.2.3664	 	 	Copyright © 1997-2006, ITB CompuPhase


2 Errors.
that might be easy for some of you around here, but for me it isn't, since i'm a newbie in scripting, and yes i'm still watching tutorials

i'm thankful for any responses given
Reply
#2

The errors and warning are given because you have `else` twice. Take a look at the example below:
pawn Code:
new some_value;

if (some_value == 1)
{
    // code..
}
else
{
    // code..
}
else return 1; // <-- this line causes the errors and warning
More about the command now. You use:
pawn Code:
if(id == INVALID_PLAYER_ID) {
    // code..
}
You should check if `id` is NOT equal to INVALID_PLAYER_ID. You use `playerid` in some arrays instead of `id`.

I tried to re-write the command
pawn Code:
CMD:stats(playerid, params[])
{
    if (PlayerInfo[playerid][LoggedIn] == false) return SendClientMessage(playerid, COLOR_RED, "ERROR: Account must be registered in order to use commands.");
    if (sscanf(params, "u", id)) return SendClientMessage(playerid, COLOR_RED, "Syntax: /stats <playerid>");

    new id;
    if (id == INVALID_PLAYER_ID) return SendClientMessage(playerid, COLOR_RED, "ERROR: Player is not connected");

    new string[266], tname[MAX_PLAYER_NAME], registered[4], admrank[57], // increase 266 if text is cut
        admin = PlayerInfo[id][AdminLevel],
        kills = PlayerInfo[id][Kills],
        deaths = PlayerInfo[id][Deaths],
        score = PlayerInfo[id][Score],
        money = GetPlayerMoney(id);

    GetPlayerName(id, tname, sizeof(tname));
    registered = (PlayerInfo[id][LoggedIn] == false) ? ("No") : ("Yes");

    static const ranks_with_color[][] = {"", "{FFFF00}(Moderator)", "{008000}(Administrator)", "{3366FF}(Manager)"};
 
    if (IsPlayerAdmin(id))
    {
        admrank = "{00FF00}Admin Level:{FF0000} RCON Admin\n";
    }
    else if (1 <= PlayerInfo[id][AdminLevel] <= 3)
    {
        format(admrank, sizeof(admrank), "{00FF00}Admin Level:{FFFFFF} %d %s\n", PlayerInfo[id][AdminLevel], ranks_with_color[PlayerInfo[id][AdminLevel]]);
    }

    format(string, sizeof(string), "{00FF00}Name:{FFFFFF} %s\n{00FF00}Registered:{FFFFFF} %s\n%s{00FF00}Kills:{FFFFFF} %d\n{00FF00}Deaths:{FFFFFF} %d\n{00FF00}Score:{FFFFFF} %d\n{00FF00}Money:{FFFFFF} %d", tname, registered, admrank, kills, deaths, score, money);
    ShowPlayerDialog(playerid, DIALOG_STATS, DIALOG_STYLE_MSGBOX, "{FFFFFF}Player's Statistics:", string, "Okay", "");
    return 1;
}
Reply
#3

Quote:
Originally Posted by Calisthenics
View Post
The errors and warning are given because you have `else` twice. Take a look at the example below:
pawn Code:
new some_value;

if (some_value == 1)
{
    // code..
}
else
{
    // code..
}
else return 1; // <-- this line causes the errors and warning
More about the command now. You use:
pawn Code:
if(id == INVALID_PLAYER_ID) {
    // code..
}
You should check if `id` is NOT equal to INVALID_PLAYER_ID. You use `playerid` in some arrays instead of `id`.

I tried to re-write the command
pawn Code:
CMD:stats(playerid, params[])
{
    if (PlayerInfo[playerid][LoggedIn] == false) return SendClientMessage(playerid, COLOR_RED, "ERROR: Account must be registered in order to use commands.");
    if (sscanf(params, "u", id)) return SendClientMessage(playerid, COLOR_RED, "Syntax: /stats <playerid>");

    new id;
    if (id == INVALID_PLAYER_ID) return SendClientMessage(playerid, COLOR_RED, "ERROR: Player is not connected");

    new string[266], tname[MAX_PLAYER_NAME], registered[4], admrank[57], // increase 266 if text is cut
        admin = PlayerInfo[id][AdminLevel],
        kills = PlayerInfo[id][Kills],
        deaths = PlayerInfo[id][Deaths],
        score = PlayerInfo[id][Score],
        money = GetPlayerMoney(id);

    GetPlayerName(id, tname, sizeof(tname));
    registered = (PlayerInfo[id][LoggedIn] == false) ? ("No") : ("Yes");

    static const ranks_with_color[][] = {"", "{FFFF00}(Moderator)", "{008000}(Administrator)", "{3366FF}(Manager)"};
 
    if (IsPlayerAdmin(id))
    {
        admrank = "{00FF00}Admin Level:{FF0000} RCON Admin\n";
    }
    else if (1 <= PlayerInfo[id][AdminLevel] <= 3)
    {
        format(admrank, sizeof(admrank), "{00FF00}Admin Level:{FFFFFF} %d %s\n", PlayerInfo[id][AdminLevel], ranks_with_color[PlayerInfo[id][AdminLevel]]);
    }

    format(string, sizeof(string), "{00FF00}Name:{FFFFFF} %s\n{00FF00}Registered:{FFFFFF} %s\n%s{00FF00}Kills:{FFFFFF} %d\n{00FF00}Deaths:{FFFFFF} %d\n{00FF00}Score:{FFFFFF} %d\n{00FF00}Money:{FFFFFF} %d", tname, registered, admrank, kills, deaths, score, money);
    ShowPlayerDialog(playerid, DIALOG_STATS, DIALOG_STYLE_MSGBOX, "{FFFFFF}Player's Statistics:", string, "Okay", "");
    return 1;
}
alright so the command worked as expected to do, but it's just a little bit hard for a scripter like me to understand what you coded, for example static const ranks thing, those (no) (yes), it's the first time i've seen those but it works, if you could simplify the code like it's on mine, it would be appreciated (if you want to)

p.s: there's a warning which i consider as an error since most warnings i've experienced turned out to be errors in my coding so here it is:

Code:
C:\Users\Heheboii\Desktop\samp037_svr_R2-1-1_win32 (1)\gamemodes\fps.pwn(971) : warning 204: symbol is assigned a value that is never used: "admin"
Pawn compiler 3.2.3664	 	 	Copyright © 1997-2006, ITB CompuPhase


1 Warning.
Reply
#4

As the warning states, the variable 'admin' is just never used. You could replace all of the 'PlayerInfo[id][AdminLevel]' with 'admin' or just remove the line ' admin = PlayerInfo[id][AdminLevel], '

As for the 'static const', it's the same as creating a variable with the different strings attached, except friendlier to resources because they're static (never changing)
Reply
#5

Yes, sure. I can explain what they do and what can be replaced with.

(no) (yes) method is called Ternary Operator. It is basically an if-else which instead of `if ` and `else`, it uses ? and :
pawn Code:
if (a == 1)
{
    b = 2;
}
else
{
    b = 3;
}

// if (expression) { variable = value1; } else { variable = value2; }
is the same as:
pawn Code:
b = (a == 1) ? 2 : 3;

// variable = (expression) ? value1 : value2;
pawn Code:
if (a == 1)
{
    b = "yes";
}
else
{
    b = "no";
}
is the same as:
pawn Code:
b = (a == 1) ? ("yes") : ("no");
Literal strings are wrapped with () due to a compiler bug (which has been fixed on the community compiler).
So the code:
pawn Code:
registered = (PlayerInfo[id][LoggedIn] == false) ? ("No") : ("Yes");
can be replaced with:
pawn Code:
if (PlayerInfo[id][LoggedIn] == false)
{
    registered = "No";
}
else
{
    registered = "Yes";
}
static const is an array that will be created only the first time (static local is called).
pawn Code:
if (a == 1)
{
    b = "moderator";
}
else if (a == 2)
{
    b = "administrator";
}
else if (a == 3)
{
    b = "manager";
}
is the same as:
pawn Code:
switch (a)
{
    case 1: b = "moderator";
    case 2: b = "administrator";
    case 3: b = "manager";
}
is the same as:
pawn Code:
static const ranks[][] = {"", "moderator", "administrator", "manager"};
// a 2-dimension array. First dimension has size of 4 (4 ranks) and second dimension is the size of the strings
// ranks[0] is empty
// ranks[1] is "moderator"
// ranks[2] is "administrator"
// ranks[3] is "manager"

strcat(b, ranks[a]);
// strcat joins the text.
// b is empty so we copy the rank from the array.
// the index is the admin level. If level is 2, ranks[2] gives "administrator"
So the code:
pawn Code:
static const ranks_with_color[][] = {"", "{FFFF00}(Moderator)", "{008000}(Administrator)", "{3366FF}(Manager)"};
 
if (IsPlayerAdmin(id))
{
    admrank = "{00FF00}Admin Level:{FF0000} RCON Admin\n";
}
else if (1 <= PlayerInfo[id][AdminLevel] <= 3)
{
    format(admrank, sizeof(admrank), "{00FF00}Admin Level:{FFFFFF} %d %s\n", PlayerInfo[id][AdminLevel], ranks_with_color[PlayerInfo[id][AdminLevel]]);
}
can be replaced with:
pawn Code:
if (IsPlayerAdmin(id))
{
    admrank = "{00FF00}Admin Level:{FF0000} RCON Admin\n";
}

switch (admin) // now `admin` variable is used and the warning will go away
{
    case 1: admrank = "{00FF00}Admin Level:{FFFFFF} 1 {FFFF00}(Moderator)\n";
    case 2: admrank = "{00FF00}Admin Level:{FFFFFF} 2 {008000}(Administrator)\n";
    case 3: admrank = "{00FF00}Admin Level:{FFFFFF} 3 {3366FF}(Manager)\n";
}
If you notice, `admrank` stores a text if the player is RCON admin or an admin in general. Otherwise it will be empty and using it in `format` will not insert anything.
pawn Code:
format(string, sizeof (string), "Name: %s\n%sScore: %d", name, admrank, score);
It will either insert a whole new line or nothing.
Reply
#6

umm i think it will take a while for me to completely understand how this thing works and how to even use the way you coded it, but yeah, the command worked, the code looks fine even tho it's a little bit hard once again to understand.
Reply


Forum Jump:


Users browsing this thread: