Hi I just created a menu with all the players connected and the points each one has got. I created some code so when you have the menu opened, it updates the points each player has, but when more than 1 player opens the menu, it doesn't work for every one.
PHP Code:
new g_Points[33];
new name[33][32];
new g_maxplayers;
new menu;
new i;
new flag = 0;
What is that?! Please look at a tutorial which shows how to make a menu, because your code doesn't make any sense at all. First of all you're creating the menu with a global variable, so every player will recreate it when opened.
Of course you should be able to learn without being talked down to. I see what you wanted to create with the code. And you're not so far away from it being complete.
The thing with updating player menus is that they can change at any time. And you don't want to press the wrong player by mistake.
I would use an old menu in this case. Otherwise you can't update it without setting the page to the first again.
The whole point of the new menu style is that you create it once and get a feedback when completed. That's not what you are after. You're trying to create a more dynamic menu.
You need to consider players leaving, and others taking their place with a new UID.
A perfect menu would take all of these things into account.
I made an example that you can test alone. It will simulate players and them leaving.
I made comments throughout so you'd be able to understand what's going on.
When you're done testing, replace all the functions that end with _debug with the original ones.
Unfortunately these things might appear complicated to a beginner so I don't think I would've been able to nudge you in the right direction. That's why I created the whole thing instead.
If you have questions, please ask.
main plugin
Code:
#include <amxmodx>#include <debug> // For testing solo. Remove when done testing.#define PLAYERS_PER_PAGE 7 // Set this to a number between 1 and 7.new gPoints[33];
new gPlayers[33][32];
new gPlayerUserID[33][33];
new gPlayersnum[33];
new gMenuPage[33];
public plugin_init(){register_plugin("Test Plugin 1", "1.0", "[ --{-@ ]");
register_menucmd(register_menuid("RandomMenu"), 1023, "MenuHandler"); // Old menu style, has to be registredfor(new i ; i < sizeof gPoints ; i++ )// Random for testing solo. Remove when done testing.
gPoints[i] = random(100);
register_clcmd("say /menu", "Command");
InitDebug(); // For testing solo. Remove when done testing.}public Command(id){
get_players_debug(gPlayers[id], gPlayersnum[id]); // Get the players currently playing
gMenuPage[id] = 0; // Reset the page. The menu might have been used before.// Remove self?for(new i ; i < gPlayersnum[id] ; i++ ){if( gPlayers[id][i] == id ){
gPlayers[id][i] = gPlayers[id][gPlayersnum[id] - 1];
gPlayersnum[id]--;
break;
}}// Clear the array.arrayset(gPlayerUserID[id], 0, sizeof gPlayerUserID[]);
// Get everyones UIDfor(new i ; i < gPlayersnum[id] ; i++ )
gPlayerUserID[id][gPlayers[id][i]] = get_user_userid_debug(gPlayers[id][i]);
ShowMenu(id); // Show itset_task(0.3, "ShowMenu", id, _, _, "b"); // And keep showing it}public ShowMenu(id){static MenuBody[1024];
static CurPlayerName[32];
new MenuKeys = MENU_KEY_0; // Exit keynew len = formatex(MenuBody, charsmax(MenuBody), "\yThe title goes here^nSelect a player:^n^n"); // Start formatting the body of the menu.new ClampedLoop = clamp(gPlayersnum[id] - PLAYERS_PER_PAGE * gMenuPage[id], 1, PLAYERS_PER_PAGE); // You want to display all of the people that are in the array from of the page you are on and forward.// However, you also need to clamp it so it doesn't go above the number of entries you can show.for(new i ; i < ClampedLoop ; i++ ){new CurPlayer = gPlayers[id][PLAYERS_PER_PAGE * gMenuPage[id] + i]; // This will retrieve the id of the "next" player in the array.if( is_user_connected_debug(CurPlayer) && gPlayerUserID[id][CurPlayer] == get_user_userid_debug(CurPlayer)){// Check if the player is still connected and that it is the same player.
get_user_name_debug(CurPlayer, CurPlayerName, charsmax(CurPlayerName)); // If the player is, get the name.
len += formatex(MenuBody[len], charsmax(MenuBody) - len, "\y%d\w. %s\R\r%d^n", i + 1, CurPlayerName, gPoints[CurPlayer]); // Add the player to the menu.
MenuKeys |= (1 << i ); // Add the key to the bitsum to enable the key.}else
len += formatex(MenuBody[len], charsmax(MenuBody) - len, "\d%d. *LEFT*^n", i + 1); // Add a placeholder to avoid shifting the menu order.}if( gMenuPage[id] > 0){// Check if the page is not the first one.
len += formatex(MenuBody[len], charsmax(MenuBody) - len, "^n\y8\w. Back^n"); // If it isn't, display "Back" as enabled
MenuKeys |= MENU_KEY_8; // And enable it.}else
len += formatex(MenuBody[len], charsmax(MenuBody) - len, "^n\d8. Back^n"); // If it is the first page, display as disabled.if(( gMenuPage[id] + 1) * PLAYERS_PER_PAGE < gPlayersnum[id]){// Check if the page is the last one.
len += formatex(MenuBody[len], charsmax(MenuBody) - len, "\y9\w. Next^n");
MenuKeys |= MENU_KEY_9;
}else
len += formatex(MenuBody[len], charsmax(MenuBody) - len, "\d9. Next^n");
formatex(MenuBody[len], charsmax(MenuBody) - len, "\y0\w. Exit"); // Add the exit keyshow_menu(id, MenuKeys, MenuBody, 1, "RandomMenu"); // And show it for 1 second.}public MenuHandler(id, key){switch(key){case7 : // Back
gMenuPage[id]--;
case8 : // Next
gMenuPage[id]++;
case9 : // Exitremove_task(id);
}
player_disconnect_debug(random_num(2, 32)); // Just for testing solo. Remove when done testing.if( key >= 7)// Back, next or exitreturn;
remove_task(id); // Close the menunew SelectedPlayer = gPlayers[id][gMenuPage[id] * PLAYERS_PER_PAGE + key]; // Here is your resulting player.// After this point, debug stuff.new name[32];
get_user_name_debug(id, name, charsmax(name));
new name2[32];
get_user_name_debug(SelectedPlayer, name2, charsmax(name2));
server_print("%s (%d) pressed key %d on page %d and therefor selected %s (%d)", name, id, key, gMenuPage[id], name2, SelectedPlayer);
}
Dear sir, I have a question. Maybe a bit off-topic.. makes me curious on this
PHP Code:
register_menucmd(register_menuid("RandomMenu"), 1023, "MenuHandler"); // Old menu style, has to be registred
is it ( 2^10 ) - 1 and why? Same goes to something like
PHP Code:
g_iArray[33]
why does the array need to store '33' index for client if there is only max of 32 clients in a server? or is it ( 0-32 ) which '0' is also included as starting index? I am sorry for asking this but sometimes this simple question might help others which encounter the same question as mine. Thank you, sir. Again, my apology for the off-topic question...
__________________
Quote:
Originally Posted by addons_zz
Also, just to not read `the article`, read all you find. Read and read, for ever and ever. Never stop reading.
Why? Because there is not one single universal truth which holds the meaning for everything.
It's 1023 in this case because that's how menu works. You provide a bitsum for keys that you want to be available in your menu (0-9). Take a look here: http://amxmodx.org/api/amxconst#menu-keys
So, if you want your menu to have only keys 1 and 3, you would pass (MENU_KEY_1 | MENU_KEY_3) to register_menucmd(). 1023 is the sum of all 10, meaning all keys are available.
In "client" arrays you want 33 because in a 33 long array indices go from 0 to 32, and players use indices 1 to 32. You could set length to 32 but then you would have to substract 1 from client index every time you want to access that array, or otherwise you would go out of bounds. 4 bytes of memory spent is nothing compared to that useless calculation. This question has also been answered multiple times on this forum.
As for other arrays, unless it's a limit in the game (like name's max length which is 32), it's just that people like working with such numbers.