Veteran Member
Join Date: Feb 2011
Location: Stockholm, Sweden
|
01-04-2017
, 16:45
Re: The menu doesn't update for every player
|
#4
|
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 registred
for ( 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 UID
for ( new i ; i < gPlayersnum[id] ; i++ )
gPlayerUserID[id][gPlayers[id][i]] = get_user_userid_debug(gPlayers[id][i]);
ShowMenu(id); // Show it
set_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 key
new 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 key
show_menu(id, MenuKeys, MenuBody, 1, "RandomMenu"); // And show it for 1 second.
}
public MenuHandler(id, key) {
switch(key) {
case 7 : // Back
gMenuPage[id]--;
case 8 : // Next
gMenuPage[id]++;
case 9 : // Exit
remove_task(id);
}
player_disconnect_debug(random_num(2, 32)); // Just for testing solo. Remove when done testing.
if ( key >= 7 ) // Back, next or exit
return;
remove_task(id); // Close the menu
new 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);
}
debug.inc
Code:
#if defined _debug_included
#endinput
#endif
#define _debug_included
new gIsConnected[33];
new gUserID[33];
InitDebug() {
for ( new i = 17 ; i ; ) {
new randPlayer = random_num(2, sizeof gIsConnected - 1);
if ( ! gIsConnected[randPlayer] ) {
gIsConnected[randPlayer] = 1;
i--;
}
}
for ( new i ; i < sizeof gUserID ; i++ )
gUserID[i] = random_num(10000, 99999);
}
new NameArray[33][32] = {
"",
"Patrick Bateman",
"Lester Burnham",
"Robert Langdon",
"Freddy Krueger",
"Jason Voorhes",
"Friedrich Weimer",
"Wade Wilson",
"Vassili Zaitsev",
"Tyler Durden",
"Vincent Freeman",
"Will Salas",
"Slevin Kelevra",
"Lisbeth Salander",
"Simon Silver",
"Harry Goldfarb",
"John Kramer",
"Tony Montana",
"Nancy Callahan",
"Kylo Ren",
"Travis Bickle",
"Brian O'Conner",
"Skeeter Phelan",
"Katniss Everdeen",
"Bella Swan",
"Keyser Soze",
"Jack Dawson",
"Paul Avery",
"Tre Styles",
"Barry B. Benson",
"Bruce Wayne",
"Jack Sparrow",
"Ron Burgundy"
};
stock is_user_connected_debug(id) {
if ( is_user_connected(id) )
return 1;
return gIsConnected[id];
}
stock get_user_name_debug(id, name[], len) {
if ( is_user_connected(id) ) {
get_user_name(id, name, len);
return;
}
copy(name, len, NameArray[id]);
}
stock get_user_userid_debug(id) {
if ( is_user_connected(id) )
return get_user_userid(id);
return gUserID[id];
}
stock get_players_debug(players[32], &num, const flags[]="", const team[]="") {
get_players(players, num, flags, team);
for ( new i = 0 ; i < 33 && num < 32 ; i++ ) {
if ( gIsConnected[i] ) {
players[num++] = i;
}
}
}
stock player_connect_debug(id) {
gIsConnected[id] = 1;
gUserID[id] = random_num(10000, 99999);
}
stock player_disconnect_debug(id) {
gIsConnected[id] = 0;
}
__________________
Last edited by Black Rose; 01-04-2017 at 16:56.
|
|