Raised This Month: $99 Target: $400
 24% 

General Numeric Base Conversion - Any base to any base


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
addons_zz
Veteran Member
Join Date: Aug 2015
Location: Dreams, zz
Old 12-27-2016 , 04:06   General Numeric Base Conversion - Any base to any base
Reply With Quote #1

General Numeric Base Conversion - Any base to any base

References:
  1. Wikipedia - Radix
  2. Wikipedia - Positional notation
  3. Wikipedia - Positional notation
  4. List of numeral systems
  5. Phanderson - Base Conversion
  6. StackExchange Computer Science - The math behind converting from any base to any base without going through base 10?

The stock:
Code:
/**  * Given a number on a certain base until 10, calculates and return the equivalent number on another  * base until 10.  *  * @param origin_number    the number to be converted.  * @param origin_base      the base where `origin_number` is on.  * @param destiny_base     the base where `origin_number` is to be converted to.  */ stock convert_numeric_base( origin_number, origin_base, destiny_base ) {     new integer;     new Array:digits;     digits  = toDigitsRepresentation( origin_number, 10 );     integer = fromDigitsRepresentation( digits, origin_base );     ArrayDestroy( digits );     digits  = toDigitsRepresentation( integer, destiny_base );     integer = fromDigitsRepresentation( digits, 10 );     ArrayDestroy( digits );     return integer; } /**  * Read an digits Dynamic Array at its given base and return an integer representation.  *  * @param digits           a Dynamic Array within the digits of inputed number on the specified base.  * @param origin_base      the base where `digits` are represented.  *  * return an integer representation inputed number on the specified base.  */ stock fromDigitsRepresentation( Array:digits, origin_base ) {     new integer;     new arraySize = ArraySize( digits );     for( new index = 0; index < arraySize; index ++ )     {         integer = integer * origin_base + ArrayGetCell( digits, index );     }     return integer; } /**  * Create an Dynamic Array within of the decimal number at its given base.  *  * @param origin_number    a decimal number to be converted.  * @param origin_base      the base where `origin_number` is to be converted to.  *  * return a Dynamic Array within the digits of inputed number on the specified base.  */ stock Array:toDigitsRepresentation( origin_number, origin_base ) {     new Array:digits = ArrayCreate();     ArrayPushCell( digits, origin_number % origin_base );     origin_number = origin_number / origin_base;     while( origin_number > 0 )     {         ArrayInsertCellBefore( digits, 0, origin_number % origin_base );         origin_number = origin_number / origin_base;     }     return digits; }

The Unit Tests Results:
HTML Code:
L 12/29/2016 - 16:59:05: {1.000 16292 -1944939 -1944939} I AM ENTERING ON configureTheUnitTests(0)
L 12/29/2016 - 16:59:05: {1.000 16296 -1944936    3}
L 12/29/2016 - 16:59:05: {1.000 16296 -1944919   17}
L 12/29/2016 - 16:59:05: {1.000 16296 -1944914    5}
L 12/29/2016 - 16:59:05: {1.000 16296 -1944910    4}
L 12/29/2016 - 16:59:05: {1.000 16296 -1944904    6}
L 12/29/2016 - 16:59:05: {1.000 14928 -1944899    5}         EXECUTING TEST 1 AFTER 1 SECONDS - test_convertNumericBase.aa_case1
L 12/29/2016 - 16:59:05: {1.000 15196 -1944889   10} I AM ENTERING ON convert_numeric_base(3) | number: 10 (7->10)
L 12/29/2016 - 16:59:05: {1.000 14692 -1944886    3} Array Cells: (0)     1,       (1)     0,
L 12/29/2016 - 16:59:05: {1.000 14692 -1944882    4} Array Cells: (0)     7,
L 12/29/2016 - 16:59:05: {1.000 15196 -1944878    4}     ( convert_numeric_base ) Returning integer: 7
L 12/29/2016 - 16:59:05: {1.000 14904 -1944872    6} ( displaysLastTestOk ) numberOfFailures: 0, lastFailure: 0, lastTestId: 1
L 12/29/2016 - 16:59:05: {1.000 14920 -1944868    4} OK!
L 12/29/2016 - 16:59:05: {1.000 14920 -1944863    5}
L 12/29/2016 - 16:59:05: {1.000 14920 -1944859    4}
L 12/29/2016 - 16:59:05: {1.000 14928 -1944853    6}         EXECUTING TEST 2 AFTER 1 SECONDS - test_convertNumericBase.aa_case2
L 12/29/2016 - 16:59:05: {1.000 15196 -1944849    4} I AM ENTERING ON convert_numeric_base(3) | number: 10 (6->10)
L 12/29/2016 - 16:59:05: {1.000 14692 -1944845    4} Array Cells: (0)     1,       (1)     0,
L 12/29/2016 - 16:59:05: {1.000 14692 -1944841    4} Array Cells: (0)     6,
L 12/29/2016 - 16:59:05: {1.000 15196 -1944836    5}     ( convert_numeric_base ) Returning integer: 6
L 12/29/2016 - 16:59:05: {1.000 14904 -1944832    4} ( displaysLastTestOk ) numberOfFailures: 0, lastFailure: 0, lastTestId: 2
L 12/29/2016 - 16:59:05: {1.000 14920 -1944828    4} OK!
L 12/29/2016 - 16:59:05: {1.000 14920 -1944822    6}
L 12/29/2016 - 16:59:05: {1.000 14920 -1944816    6}
L 12/29/2016 - 16:59:05: {1.000 14928 -1944812    4}         EXECUTING TEST 3 AFTER 1 SECONDS - test_convertNumericBase.aa_case3
L 12/29/2016 - 16:59:05: {1.000 15196 -1944808    4} I AM ENTERING ON convert_numeric_base(3) | number: 10 (5->10)
L 12/29/2016 - 16:59:05: {1.000 14692 -1944803    5} Array Cells: (0)     1,       (1)     0,
L 12/29/2016 - 16:59:06: {1.000 14692 -1944798    5} Array Cells: (0)     5,
L 12/29/2016 - 16:59:06: {1.000 15196 -1944794    4}     ( convert_numeric_base ) Returning integer: 5
L 12/29/2016 - 16:59:06: {1.000 14904 -1944790    4} ( displaysLastTestOk ) numberOfFailures: 0, lastFailure: 0, lastTestId: 3
L 12/29/2016 - 16:59:06: {1.000 14920 -1944784    6} OK!
L 12/29/2016 - 16:59:06: {1.000 14920 -1944779    5}
L 12/29/2016 - 16:59:06: {1.000 14920 -1944776    3}
L 12/29/2016 - 16:59:06: {1.000 14928 -1944769    7}         EXECUTING TEST 4 AFTER 2 SECONDS - test_convertNumericBase.aa_case4
L 12/29/2016 - 16:59:06: {1.000 15196 -1944765    4} I AM ENTERING ON convert_numeric_base(3) | number: 10 (8->10)
L 12/29/2016 - 16:59:06: {1.000 14692 -1944761    4} Array Cells: (0)     1,       (1)     0,
L 12/29/2016 - 16:59:06: {1.000 14692 -1944758    3} Array Cells: (0)     8,
L 12/29/2016 - 16:59:06: {1.000 15196 -1944751    7}     ( convert_numeric_base ) Returning integer: 8
L 12/29/2016 - 16:59:06: {1.000 14904 -1944748    3} ( displaysLastTestOk ) numberOfFailures: 0, lastFailure: 0, lastTestId: 4
L 12/29/2016 - 16:59:06: {1.000 14920 -1944744    4} OK!
L 12/29/2016 - 16:59:06: {1.000 14920 -1944736    8}
L 12/29/2016 - 16:59:06: {1.000 14920 -1944732    4}
L 12/29/2016 - 16:59:06: {1.000 14928 -1944730    2}         EXECUTING TEST 5 AFTER 2 SECONDS - test_convertNumericBase.aa_case5
L 12/29/2016 - 16:59:06: {1.000 15196 -1944726    4} I AM ENTERING ON convert_numeric_base(3) | number: 10 (9->10)
L 12/29/2016 - 16:59:06: {1.000 14692 -1944719    7} Array Cells: (0)     1,       (1)     0,
L 12/29/2016 - 16:59:06: {1.000 14692 -1944716    3} Array Cells: (0)     9,
L 12/29/2016 - 16:59:06: {1.000 15196 -1944712    4}     ( convert_numeric_base ) Returning integer: 9
L 12/29/2016 - 16:59:06: {1.000 14904 -1944708    4} ( displaysLastTestOk ) numberOfFailures: 0, lastFailure: 0, lastTestId: 5
L 12/29/2016 - 16:59:06: {1.000 14920 -1944702    6} OK!
L 12/29/2016 - 16:59:06: {1.000 14920 -1944698    4}
L 12/29/2016 - 16:59:06: {1.000 14920 -1944694    4}
L 12/29/2016 - 16:59:06: {1.000 14928 -1944689    5}         EXECUTING TEST 6 AFTER 2 SECONDS - test_convertNumericBase.aa_case6
L 12/29/2016 - 16:59:06: {1.000 15196 -1944684    5} I AM ENTERING ON convert_numeric_base(3) | number: 10 (10->10)
L 12/29/2016 - 16:59:06: {1.000 14692 -1944681    3} Array Cells: (0)     1,       (1)     0,
L 12/29/2016 - 16:59:06: {1.000 14692 -1944677    4} Array Cells: (0)     1,       (1)     0,
L 12/29/2016 - 16:59:06: {1.000 15196 -1944671    6}     ( convert_numeric_base ) Returning integer: 10
L 12/29/2016 - 16:59:06: {1.000 14904 -1944667    4} ( displaysLastTestOk ) numberOfFailures: 0, lastFailure: 0, lastTestId: 6
L 12/29/2016 - 16:59:06: {1.000 14920 -1944663    4} OK!
L 12/29/2016 - 16:59:06: {1.000 14920 -1944659    4}
L 12/29/2016 - 16:59:06: {1.000 14920 -1944653    6}
L 12/29/2016 - 16:59:06: {1.000 14928 -1944649    4}         EXECUTING TEST 7 AFTER 2 SECONDS - test_convertNumericBase.aa_case7
L 12/29/2016 - 16:59:06: {1.000 15196 -1944645    4} I AM ENTERING ON convert_numeric_base(3) | number: 11 (7->9)
L 12/29/2016 - 16:59:06: {1.000 14692 -1944641    4} Array Cells: (0)     1,       (1)     1,
L 12/29/2016 - 16:59:06: {1.000 14692 -1944636    5} Array Cells: (0)     8,
L 12/29/2016 - 16:59:06: {1.000 15196 -1944632    4}     ( convert_numeric_base ) Returning integer: 8
L 12/29/2016 - 16:59:06: {1.000 14904 -1944628    4} ( displaysLastTestOk ) numberOfFailures: 0, lastFailure: 0, lastTestId: 7
L 12/29/2016 - 16:59:06: {1.000 14920 -1944622    6} OK!
L 12/29/2016 - 16:59:06: {1.000 14920 -1944618    4}
L 12/29/2016 - 16:59:06: {1.000 14920 -1944614    4}
L 12/29/2016 - 16:59:06: {1.000 14928 -1944610    4}         EXECUTING TEST 8 AFTER 2 SECONDS - test_convertNumericBase.aa_case8
L 12/29/2016 - 16:59:06: {1.000 15196 -1944608    2} I AM ENTERING ON convert_numeric_base(3) | number: 2462 (7->9)
L 12/29/2016 - 16:59:06: {1.000 14668 -1944601    7} Array Cells: (0)     2,       (1)     4,       (2)     6,       (3)     2,
L 12/29/2016 - 16:59:06: {1.000 14668 -1944597    4} Array Cells: (0)     1,       (1)     2,       (2)     3,       (3)     8,
L 12/29/2016 - 16:59:06: {1.000 15196 -1944593    4}     ( convert_numeric_base ) Returning integer: 1238
L 12/29/2016 - 16:59:06: {1.000 14904 -1944586    7} ( displaysLastTestOk ) numberOfFailures: 0, lastFailure: 0, lastTestId: 8
L 12/29/2016 - 16:59:06: {1.000 14920 -1944583    3} OK!
L 12/29/2016 - 16:59:06: {1.000 14920 -1944579    4}
L 12/29/2016 - 16:59:06: {1.000 14920 -1944575    4}
L 12/29/2016 - 16:59:06: {1.000 14928 -1944569    6}         EXECUTING TEST 9 AFTER 2 SECONDS - test_convertNumericBase.aa_case9
L 12/29/2016 - 16:59:06: {1.000 15196 -1944565    4} I AM ENTERING ON convert_numeric_base(3) | number: 1238 (9->7)
L 12/29/2016 - 16:59:06: {1.000 14668 -1944561    4} Array Cells: (0)     1,       (1)     2,       (2)     3,       (3)     8,
L 12/29/2016 - 16:59:06: {1.000 14668 -1944556    5} Array Cells: (0)     2,       (1)     4,       (2)     6,       (3)     2,
L 12/29/2016 - 16:59:06: {1.000 15196 -1944551    5}     ( convert_numeric_base ) Returning integer: 2462
L 12/29/2016 - 16:59:06: {1.000 16256 -1944548    3} ( displaysLastTestOk ) numberOfFailures: 0, lastFailure: 0, lastTestId: 9
L 12/29/2016 - 16:59:06: {1.000 16272 -1944544    4} OK!
L 12/29/2016 - 16:59:06: {1.000 16272 -1944538    6}
L 12/29/2016 - 16:59:06: {1.000 16272 -1944534    4}
L 12/29/2016 - 16:59:06: {1.000 16296 -1944530    4}
L 12/29/2016 - 16:59:06: {1.000 16280 -1944526    4} I AM ENTERING ON print_all_tests_executed(0)
L 12/29/2016 - 16:59:06: {1.000 16024 -1944520    6}
L 12/29/2016 - 16:59:06: {1.000 16024 -1944517    3}
L 12/29/2016 - 16:59:06: {1.000 16024 -1944512    5}
L 12/29/2016 - 16:59:06: {1.000 16024 -1944509    3}     The following tests were executed:
L 12/29/2016 - 16:59:06: {1.000 16024 -1944503    6}
L 12/29/2016 - 16:59:06: {1.000 16008 -1944498    5}          1. test_convertNumericBase.aa_case1
L 12/29/2016 - 16:59:06: {1.000 16008 -1944494    4}          2. test_convertNumericBase.aa_case2
L 12/29/2016 - 16:59:06: {1.000 16008 -1944489    5}          3. test_convertNumericBase.aa_case3
L 12/29/2016 - 16:59:06: {1.000 16008 -1944485    4}          4. test_convertNumericBase.aa_case4
L 12/29/2016 - 16:59:06: {1.000 16008 -1944484    1}          5. test_convertNumericBase.aa_case5
L 12/29/2016 - 16:59:06: {1.000 16008 -1944476    8}          6. test_convertNumericBase.aa_case6
L 12/29/2016 - 16:59:06: {1.000 16008 -1944470    6}          7. test_convertNumericBase.aa_case7
L 12/29/2016 - 16:59:06: {1.000 16008 -1944466    4}          8. test_convertNumericBase.aa_case8
L 12/29/2016 - 16:59:06: {1.000 16008 -1944462    4}          9. test_convertNumericBase.aa_case9
L 12/29/2016 - 16:59:06: {1.000 14996 -1944458    4}
L 12/29/2016 - 16:59:06: {1.000 14988 -1944453    5}     9 tests succeed.
L 12/29/2016 - 16:59:06: {1.000 14992 -1944449    4}     0 tests failed.
L 12/29/2016 - 16:59:06: {1.000 16284 -1944445    4}
L 12/29/2016 - 16:59:06: {1.000 16272 -1944439    6}     Finished the General Numeric Base Conversion's Unit Tests execution after '2' seconds.
L 12/29/2016 - 16:59:06: {1.000 16284 -1944435    4}
L 12/29/2016 - 16:59:06: {1.000 16284 -1944431    4}

The Unit Tests Source Code:
Spoiler
Attached Files
File Type: sma Get Plugin or Get Source (full_unit_tests.sma - 384 views - 21.0 KB)
__________________
Plugin: Sublime Text Studio , Galileo
Multi-Mod: Manager / Plugin / Server

Help the AlliedModders' website stay online!

Last edited by addons_zz; 12-29-2016 at 21:13. Reason: Updated the Unit Tests code
addons_zz is offline
shehzad1234
Senior Member
Join Date: Jan 2016
Old 12-27-2016 , 11:16   Re: General Numeric Base Conversion - Any base to any base
Reply With Quote #2

__________________
Contact : Facebook
All Join -=}BBI{=- Hns Server :- 103.50.161.8:10001
shehzad1234 is offline
Craxor
Veteran Member
Join Date: Jan 2016
Location: ro
Old 12-29-2016 , 11:51   Re: General Numeric Base Conversion - Any base to any base
Reply With Quote #3

i understand nothing, explain please
__________________
Project: Counter-Strike Dragon Ball Mod (csdb) [done: 0%]
Craxor is offline
Send a message via ICQ to Craxor
HamletEagle
AMX Mod X Plugin Approver
Join Date: Sep 2013
Location: Romania
Old 12-29-2016 , 12:03   Re: General Numeric Base Conversion - Any base to any base
Reply With Quote #4

It's just a way to convert from a base to another base(for example, from 10 to 2)
__________________
HamletEagle is offline
addons_zz
Veteran Member
Join Date: Aug 2015
Location: Dreams, zz
Old 12-29-2016 , 16:27   Re: General Numeric Base Conversion - Any base to any base
Reply With Quote #5

Quote:
Originally Posted by [email protected] View Post
Where can I use them?
Let us suppose you are building a map list menu by demand, i.e.,
  1. If there are 50000 maps on you server, you do not create a `new menu style` looping throw all the maps and build a monster menu.
  2. Also, as the menu is as big as 50000 maps, anyone will never be able to go from the first page, to the last map page hitting the more button, as it is too big.

The solution is to allow the user open an alphabetically sorted maps menu on any page it want to, accessing only enough maps from the general array map for that page.
And for that you cannot fully use the `new style menu` because for that menu, you need to provide all its entries while building it, and here it is not the case.

The solution based `new menu style` disabling the paging and using the info[] to pass the map index, not need this.
I am presenting is just for fun, as using the `new menu style` disabling the paging and using the info[] to pass the maps index is better.
This solution is using numeric base conversion applies only for the old style menu construction using a global array to store the pages where each server player is currently on.
  1. For that you will need to calculate how many pages there are on the menu, to show it on you menu header:
    Code:
    /**  * Calculate which is the number of the last menu page.  *  * @param totalMenuItems     how many items there are on the menu  * @param menuItemPerPage    how much items there are on each menu's page  */ #define GET_LAST_PAGE_NUMBER(%1,%2) \         ( ( ( %1 + 1 ) / %2 ) \     + ( ( ( ( %1 + 1 ) % %2 ) > 0 ) ? 1 : 0 ) ); #define MAX_MENU_ITEMS_PER_PAGE 7 ... new lastPageNumber = GET_LAST_PAGE_NUMBER( mapsCount, MAX_MENU_ITEMS_PER_PAGE ) ...


  2. You will need to know on what page to display the menu when the menu is open, and as we allow the user to open it on any page, we need to intercept it and to set the current page accordingly.
    Code:
    new g_mapMenuPages[ MAX_PLAYERS + 1 ]; new const MAP_MENU_COMMAND[] = "coolmenu"; /**  * Generic say handler to determine if we need to act on what was said.  */ public cmd_say( player_id ) {     new thirdWord[ 2 ];     static sentence  [ 70 ];     static firstWord [ 32 ];     static secondWord[ 32 ];     sentence  [ 0 ] = '^0';     firstWord [ 0 ] = '^0';     secondWord[ 0 ] = '^0';     read_args( sentence, charsmax( sentence ) );     remove_quotes( sentence );     parse( sentence  ,            firstWord , charsmax( firstWord  ),            secondWord, charsmax( secondWord ),            thirdWord , charsmax( thirdWord  ) );     // if the chat line has more than 2 words, we're not interested at all     if( thirdWord[ 0 ] == '^0' )     {         new userFlags = get_user_flags( player_id );         // if the chat line contains 1 word, it could be a map or a one-word command as "say coolmenu50"         if( secondWord[ 0 ] == '^0' )         {             if( userFlags & ADMIN_MAP                 && containi( firstWord, MAP_MENU_COMMAND ) > -1 )             {                 // Calculate how much pages there are available.                 new mapsCount      = ArraySize( g_loadedMapsArray );                 new lastPageNumber = GET_LAST_PAGE_NUMBER( mapsCount, MAX_MENU_ITEMS_PER_PAGE )                 setCorrectMenuPage( player_id, firstWord, g_mapMenuPages, lastPageNumber );                 mapMenuBuilder( player_id );                 return PLUGIN_HANDLED;             }         }         else if( userFlags & ADMIN_MAP                  && equali( firstWord, MAP_MENU_COMMAND ) )         {             // Calculate how much pages there are available.             new mapsCount      = ArraySize( g_loadedMapsArray );             new lastPageNumber = GET_LAST_PAGE_NUMBER( mapsCount, MAX_MENU_ITEMS_PER_PAGE )             setCorrectMenuPage( player_id, secondWord, g_mapMenuPages, lastPageNumber );             mapMenuBuilder( player_id );             return PLUGIN_HANDLED;         }     }     return PLUGIN_CONTINUE; } /**  * Remove all the text from the string, except the first digits chain, to allow to open the menu  * as `say coomenuPageNumber`. For example: `say coomenu50`.  */ stock setCorrectMenuPage( player_id, pageString[], menuPages[], pagesCount ) {     if( strlen( pageString ) > 1 )     {         new searchIndex;         new resultIndex;         while( pageString[ searchIndex ]                && !isdigit( pageString[ searchIndex ] ) )         {             pageString[ 0 ]           = pageString[ searchIndex ];             pageString[ searchIndex ] = '^0';             searchIndex++;         }         // When the page number start with a digit, we would erase all the string if not doing this.         if( searchIndex == 0 )         {             searchIndex = 1;         }         while( isdigit( pageString[ searchIndex ] ) )         {             pageString[ resultIndex ] = pageString[ searchIndex ];             pageString[ searchIndex ] = '^0';             searchIndex++;             resultIndex++;         }     }     if( isdigit( pageString[ 0 ] ) )     {         // The pages index, start on 0         new targetPage = str_to_num( pageString );         if( pagesCount > targetPage )         {             menuPages[ player_id ] = targetPage - 1;         }         else         {             menuPages[ player_id ] = pagesCount - 1;         }     } }


  3. Now you build the menu:
    Code:
    /**  * Common strings sizes used around the plugin.  */ #define MAX_LONG_STRING     256 #define MAX_SHORT_STRING    64 #define MAX_BIG_BOSS_STRING 512 #define MAX_MAPNAME_LENGHT  64 new Array:g_loadedMapsArray; new g_menuName[] = "MAPS MENU" public plugin_init() {     register_plugin( "Maps Menu", "1.0", "Addons zz" )     register_menucmd( register_menuid( g_menuName ), 1023, "player_choice" )     // Fill the array `g_loadedMapsArray` with all the 50000 maps sorted alphabetically     ...     register_clcmd( "say", "cmd_say", -1 );     register_clcmd( "say_team", "cmd_say", -1 ); } /**  * Gather all maps that match the current page on `g_mapMenuPages`, for the `player_id`.  */ stock mapMenuBuilder( player_id ) {     new mapIndex;     new mapsCount;     new itemsCount;     new menuKeys;     new writePosition;     new mapName  [ MAX_MAPNAME_LENGHT ];     new menu_body[ MAX_BIG_BOSS_STRING ];     mapsCount = ArraySize( g_loadedMapsArray );     // Calculate how much pages there are available.     new currentPageNumber = g_mapMenuPages[ player_id ];     new lastPageNumber    = GET_LAST_PAGE_NUMBER( mapsCount, MAX_MENU_ITEMS_PER_PAGE )     // To create the menu     writePosition = formatex( menu_body, charsmax( menu_body ), "%s  %d /%d^n^n", "Map List", currentPageNumber + 1, lastPageNumber );     // Get the initial page maps index     mapIndex = currentPageNumber * MAX_MENU_ITEMS_PER_PAGE;     for( ; mapIndex < mapsCount && itemsCount < MAX_MENU_ITEMS_PER_PAGE; mapIndex++ )     {         ArrayGetString( g_loadedMapsArray, mapIndex, mapName, charsmax( mapName ) );                 // create valid keys ( 1 to 7 )         menuKeys |= ( 1 << itemsCount )         itemsCount++;                 writePosition = formatex( menu_body[ writePosition ], charsmax( menu_body ) - writePosition,                 "%d. %s %s^n", itemsCount, mapName, disabledReason );     }     // calculates the the final page buttons     if( currentPageNumber )     {         if( lastPageNumber == currentPageNumber + 1 )         {             menuKeys |= MENU_KEY_0 | MENU_KEY_8;             writePosition += formatex( menu_body[ writePosition ], sizeof( menu_body ) - writePosition, "^n8. Back.^n0. Exit" )         }         else         {             menuKeys |= MENU_KEY_0 | MENU_KEY_8 | MENU_KEY_9;             writePosition += formatex( menu_body[ writePosition ], sizeof( menu_body ) - writePosition, "^n8. Back.^n9. More...^n0. Exit" )         }     }     else     {         menuKeys |= MENU_KEY_0 | MENU_KEY_9;         writePosition += formatex( menu_body[ writePosition ], sizeof( menu_body ) - writePosition, "^n9. More.^n0. Exit" )        }     show_menu( player_id, menuKeys, menu_body, 0, g_menuName ) }


  4. Now we use the numeric base conversion from the base 7 `a.k.a., MAX_MENU_ITEMS_PER_PAGE` to the base 10. This is because the menu options are written in the septal base, however the map indexes on the array `g_loadedMapsArray` are in decimal.
    Code:
    public player_choice( player_id, item ) {     /*      * You press the key 0, you gets 9 here. ...      * So here, i made the switch back.      */     switch( item )     {         case 9: item = 0         case 0: item = 1         case 1: item = 2         case 2: item = 3         case 3: item = 4         case 4: item = 5         case 5: item = 6         case 6: item = 7         case 7: item = 8         case 8: item = 9     }     switch( item )     {         case 1..7:         {             new mapName[ MAX_MAPNAME_LENGHT ];             // Here we need to convert a number on base 7 on a number on base 10 to find the correct map array index.             new pageSeptalNumber = convert_numeric_base( g_mapMenuPages[ player_id ], 10, MAX_MENU_ITEMS_PER_PAGE );             item = convert_numeric_base( pageSeptalNumber * 10, MAX_MENU_ITEMS_PER_PAGE, 10 ) + item - 1;             ArrayGetString( g_loadedMapsArray, item, mapName, charsmax( mapName ) );             server_print( "Selected map: %s, mapIndex: %d", mapName, item );         }         case 8:         {             // Here we to perform the back button             g_mapMenuPages[ player_id ] ? g_mapMenuPages[ player_id ]-- : 0;         }         case 9:         {             // Here we to perform the more button             g_mapMenuPages[ player_id ]++;         }         default:         {             // Do nothing, i.e., exit the menu             return;         }     }     // Here we show the menu again.     mapMenuBuilder( player_id ); }

On the above code we need to keep the global variable `g_mapMenuPages`, and doing so, we are also able to remember the last position the user was when the re-opens the menu later, which is very nice.

With this menu you may:
  1. Close it whatever you want to and re-open on the same page you left before.
  2. Open whatever page you want to.
  3. Save big server performance, as you only calculate on the pages you will use, not all the 50000 maps entries at once.

References:
  1. New AMXX Menu System
__________________
Plugin: Sublime Text Studio , Galileo
Multi-Mod: Manager / Plugin / Server

Help the AlliedModders' website stay online!

Last edited by addons_zz; 12-29-2016 at 21:13. Reason: fix keys registrering
addons_zz is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 00:51.


Powered by vBulletin®
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Theme made by Freecode