AMXX-BG.INFO menuapi.inc Raw include

menuapi.inc

Original include source with line numbers.

Back Download .inc
1 #if defined __MENU_API_VERSION__
2 #endinput
3 #endif
4
5 #define __MENU_API_VERSION__ 1.0.1
6
7 static const __msgShowMenu = 96;
8 static const __successSetName = 123321;
9
10 #define ITEM_EXIT 10
11 #define ITEM_NEXT 9
12 #define ITEM_BACK 8
13
14 #define __MENU_ITEMS_PER_PAGE 7
15 #define __MENU_ITEMS_PER_PAGEWC 9 //without controls
16
17 #define get_arg_string(%0,%1,%2) \
18 for (new i = 0; i <= %2; i++) \
19 if ((%1[i] = getarg(%0, i)) == EOS) break
20
21 #define arg_is_valid(%0) (%0[0] != __msgShowMenu && %0[1] != __successSetName)
22
23 enum MenuProps (+=1) {
24 MENU_PROP_NUMFMT,
25 MENU_PROP_NUMFMT_DISABLE,
26 MENU_PROP_NOACCESS_FMT,
27 MENU_PROP_EXIT,
28 MENU_PROP_DISPLAY_PAGES,
29 MENU_PROP_BACKNAME,
30 MENU_PROP_NEXTNAME,
31 MENU_PROP_EXITNAME,
32 MENU_PROP_COPYRIGHT
33 };
34
35 enum any: __menuStruct {
36 menuID,
37 menuHandler,
38 menuItems,
39 menuExit,
40 menuDisplayPages,
41
42 menuTitle[196],
43 menuNumFmt[12],
44 menuNumFmtDisable[12],
45 menuNoAccessFmt[64],
46 menuBackName[64],
47 menuNextName[64],
48 menuExitName[64],
49 menuCopyright[64]
50 };
51
52 enum any: __menuItemStruct {
53 itemID,
54 itemArrayID,
55 itemAlias,
56 itemAccess,
57 itemCallback,
58 itemName[128],
59 itemTempName[128]
60 };
61
62 enum any: __playerDataStruct {
63 playerCurrentMenu,
64 playerMenuCurrentPage,
65 playerCurrentRealKey[__MENU_ITEMS_PER_PAGEWC]
66 };
67
68 static Array: __menusList;
69 static __fmtTemp[128];
70 static __playerData[33][__playerDataStruct];
71 static __maxPlayers;
72
73 stock MenuCreate(handler[], title[], any:...) {
74 if (!__menusList) {
75 __menusList = ArrayCreate(__menuStruct);
76 register_clcmd("menuselect", "__MenuSelectItem");
77 register_message(__msgShowMenu, "__MessageShowMenuHandle");
78
79 __maxPlayers = get_maxplayers();
80 }
81
82 if (get_func_id(handler, -1/*this*/) == INVALID_HANDLE) {
83 return INVALID_HANDLE;
84 }
85
86 new sMenuTemp[__menuStruct];
87
88 sMenuTemp[menuID] = ArraySize(__menusList);
89 if ((sMenuTemp[menuHandler] = CreateOneForward(get_plugin(-1/*this*/), handler, FP_CELL, FP_CELL, FP_CELL)) == INVALID_HANDLE) {
90 return INVALID_HANDLE;
91 }
92
93 new szTitle[196]; vformat(szTitle, charsmax(szTitle), title, 3);
94
95 if (szTitle[0] == EOS) {
96 return INVALID_HANDLE;
97 }
98
99 copy(sMenuTemp[menuTitle], charsmax(szTitle), szTitle);
100 copy(sMenuTemp[menuNumFmt], charsmax(sMenuTemp[menuNumFmt]), "\r%i.");
101 copy(sMenuTemp[menuNumFmtDisable], charsmax(sMenuTemp[menuNumFmtDisable]), "\d%i.");
102 copy(sMenuTemp[menuNoAccessFmt], charsmax(sMenuTemp[menuNoAccessFmt]), "\d%s \r*");
103
104 sMenuTemp[menuItems] = _:ArrayCreate(__menuItemStruct);
105
106 sMenuTemp[menuExit] = true;
107 sMenuTemp[menuDisplayPages] = true;
108 copy(sMenuTemp[menuExitName], charsmax(sMenuTemp[menuExitName]), "Exit");
109 copy(sMenuTemp[menuBackName], charsmax(sMenuTemp[menuBackName]), "Back");
110 copy(sMenuTemp[menuNextName], charsmax(sMenuTemp[menuNextName]), "Next");
111
112 ArrayPushArray(__menusList, sMenuTemp);
113 return sMenuTemp[menuID];
114 }
115
116 stock MenuAddItem(const menuid, const alias, const name[], const access = INVALID_HANDLE, const callback[32] = "") {
117 new sMenuTemp[__menuStruct];
118 if (!__GetMenuData(menuid, sMenuTemp)) {
119 return INVALID_HANDLE;
120 }
121
122 new sItemTemp[__menuItemStruct];
123 sItemTemp[itemID] = ArraySize(Array: sMenuTemp[menuItems]);
124 sItemTemp[itemArrayID] = sMenuTemp[menuItems];
125 sItemTemp[itemAlias] = alias;
126 sItemTemp[itemAccess] = access;
127 sItemTemp[itemCallback] = INVALID_HANDLE;
128 if (get_func_id(callback, -1/*this*/) != INVALID_HANDLE &&
129 (sItemTemp[itemCallback] = CreateOneForward(get_plugin(-1/*this*/), callback, FP_CELL, FP_CELL, FP_CELL)) == INVALID_HANDLE) {
130 return INVALID_HANDLE;
131 }
132 copy(sItemTemp[itemName], charsmax(sItemTemp[itemName]), name);
133
134 ArrayPushArray(Array: sMenuTemp[menuItems], sItemTemp);
135 return sItemTemp[itemID];
136 }
137
138 stock MenuAddItemF(const menuid, const alias, const nameid, const access = INVALID_HANDLE, const callback[32] = "") {
139 if (nameid != __successSetName) {
140 return INVALID_HANDLE;
141 }
142
143 new iValue = MenuAddItem(menuid, alias, __fmtTemp, access, callback);
144 __fmtTemp[0] = EOS;
145
146 return iValue;
147 }
148
149 stock ItemFormat(const buffer[], any:...) {
150 vformat(__fmtTemp, charsmax(__fmtTemp), buffer, 2);
151
152 if (__fmtTemp[0] == EOS) {
153 return INVALID_HANDLE;
154 }
155
156 return __successSetName;
157 }
158
159 stock bool: MenuDisplay(const player, const menu) {
160 new sMenuTemp[__menuStruct];
161 if (!__GetMenuData(menu, sMenuTemp)) {
162 return false;
163 }
164
165 if (!is_user_connected(player)) {
166 return false;
167 }
168
169 new iPage = __playerData[player][playerMenuCurrentPage];
170 if (iPage < 0) {
171 return false;
172 }
173
174 new szBuffer[512], iLen, bitsKeys = MENU_KEY_0, iRetValue, iStart, iEnd,
175 iTotalPages, iTemp, iItems = ArraySize(Array: sMenuTemp[menuItems]),
176 iItemsPerPage = iItems > __MENU_ITEMS_PER_PAGEWC ? __MENU_ITEMS_PER_PAGE : __MENU_ITEMS_PER_PAGEWC;
177
178 if ((iStart = iPage * iItemsPerPage) >= iItems) {
179 iStart = iPage = __playerData[player][playerMenuCurrentPage] = 0;
180 }
181
182 if ((iEnd = iStart + iItemsPerPage) > iItems) {
183 iEnd = iItems;
184 }
185
186 iTotalPages = iItems / iItemsPerPage + (iItems % iItemsPerPage ? 1: 0);
187
188 if (iTotalPages > 1 && sMenuTemp[menuDisplayPages]) {
189 iLen = formatex(szBuffer, charsmax(szBuffer), "\w%s \w\R(%i/%i )\w^n^n", sMenuTemp[menuTitle], iPage+1, iTotalPages);
190 }
191 else {
192 iLen = formatex(szBuffer, charsmax(szBuffer), "\w%s^n^n", sMenuTemp[menuTitle]);
193 }
194
195 new sItemTemp[__menuItemStruct], iFmtType, szTempFormat[128];
196
197 while (iStart < iEnd) {
198 __GetItemData(menu, iStart, sItemTemp);
199 iStart++;
200
201 iRetValue = ITEM_ENABLED;
202 sItemTemp[itemTempName][0] = EOS;
203
204 if (sItemTemp[itemCallback] != INVALID_HANDLE) {
205 ExecuteForward(sItemTemp[itemCallback], iRetValue, player, menu, iStart-1);
206 __GetItemData(menu, iStart-1, sItemTemp);
207 }
208
209 if (sItemTemp[itemAccess] != INVALID_HANDLE && ~get_user_flags(player) & sItemTemp[itemAccess]) {
210 iRetValue = ITEM_DISABLED;
211 copy(szTempFormat, charsmax(szTempFormat), sItemTemp[itemName]);
212 __RemoveColorSymbols(szTempFormat, charsmax(szTempFormat));
213 formatex(sItemTemp[itemTempName], charsmax(sItemTemp[itemTempName]), sMenuTemp[menuNoAccessFmt], szTempFormat);
214 }
215
216 iFmtType = iRetValue == ITEM_DISABLED ? menuNumFmtDisable : menuNumFmt;
217 iRetValue == ITEM_DISABLED ? (bitsKeys &= ~(1 << iTemp)) : (bitsKeys |= (1 << iTemp));
218 iLen += formatex(szBuffer[iLen], charsmax(szBuffer) - iLen, sMenuTemp[iFmtType], ++iTemp);
219 iFmtType = sItemTemp[itemTempName][0] == EOS ? itemName : itemTempName;
220 iLen += formatex(szBuffer[iLen], charsmax(szBuffer) - iLen,
221 "\w %s^n%s", sItemTemp[iFmtType], iStart == iEnd ? "^n" : ""
222 );
223 __playerData[player][playerCurrentRealKey][iTemp] = iStart - 1;
224 }
225
226 if (iItems > iItemsPerPage) {
227 iFmtType = iPage ? menuNumFmt : menuNumFmtDisable;
228 iPage ? (bitsKeys |= MENU_KEY_8) : (bitsKeys &= ~MENU_KEY_8);
229 iLen += formatex(szBuffer[iLen], charsmax(szBuffer) - iLen, sMenuTemp[iFmtType], ITEM_BACK);
230 iLen += formatex(szBuffer[iLen], charsmax(szBuffer) - iLen, "%s %s^n", iPage ? "\w" : "\d", sMenuTemp[menuBackName]);
231 iFmtType = iEnd < iItems ? menuNumFmt : menuNumFmtDisable;
232 iEnd < iItems ? (bitsKeys |= MENU_KEY_9) : (bitsKeys &= ~MENU_KEY_9);
233 iLen += formatex(szBuffer[iLen], charsmax(szBuffer) - iLen, sMenuTemp[iFmtType], ITEM_NEXT);
234 iLen += formatex(szBuffer[iLen], charsmax(szBuffer) - iLen, "%s %s^n", iEnd < iItems ? "\w" : "\d", sMenuTemp[menuNextName]);
235 }
236
237 if (bool:(sMenuTemp[menuExit])) {
238 iLen += formatex(szBuffer[iLen], charsmax(szBuffer) - iLen, sMenuTemp[menuNumFmt], 0);
239 iLen += formatex(szBuffer[iLen], charsmax(szBuffer) - iLen, "\w %s", sMenuTemp[menuExitName]);
240 }
241 else {
242 bitsKeys &= ~MENU_KEY_0;
243 }
244
245 if (sMenuTemp[menuCopyright][0] != EOS) {
246 iLen += formatex(szBuffer[iLen], charsmax(szBuffer) - iLen, "%s^n%s", bool:(sMenuTemp[menuExit]) ? "^n" : "", sMenuTemp[menuCopyright]);
247 }
248
249 __playerData[player][playerCurrentMenu] = menu;
250 show_menu(player, bitsKeys, szBuffer);
251 return true;
252 }
253
254 stock MenuClose(const player) {
255 show_menu(player, 0, "^n", 1);
256 }
257
258 stock GetPlayerMenu(const player) {
259 return __playerData[player][playerCurrentMenu];
260 }
261
262 stock GetPlayerMenuPage(const player) {
263 new iPage = __playerData[player][playerMenuCurrentPage]
264 return iPage != INVALID_HANDLE ? ++iPage : INVALID_HANDLE;
265 }
266
267 stock bool: MenuDestroy(const menu) {
268 new sMenuTemp[__menuStruct];
269 if (!__GetMenuData(menu, sMenuTemp)) {
270 return false;
271 }
272
273 for (new i = 1; i <= __maxPlayers; i++) {
274 __playerData[i][playerCurrentMenu] = INVALID_HANDLE;
275 __playerData[i][playerMenuCurrentPage] = 0;
276 }
277
278 ArrayDeleteItem(__menusList, menu);
279 ArrayDestroy(Array: sMenuTemp[menuItems]);
280 return true;
281 }
282
283 stock bool: MenuItemGetInfo(const menuid, const item, name[], const len, bool: removecolor = false, &alias = 0, &access = 0, &callback = 0) {
284 new sItemTemp[__menuItemStruct];
285 if (!__GetItemData(menuid, item, sItemTemp)) {
286 return false;
287 }
288
289 copy(name, len, sItemTemp[itemName]);
290 if (removecolor) {
291 __RemoveColorSymbols(name, len);
292 }
293 alias = sItemTemp[itemAlias];
294 access = sItemTemp[itemAccess];
295 callback = sItemTemp[itemCallback];
296 return true;
297 }
298
299 stock bool: MenuSetProp(const menuid, const MenuProps: prop, any:...) {
300 new sMenuTemp[__menuStruct];
301 if (!__GetMenuData(menuid, sMenuTemp)) {
302 return false;
303 }
304
305 new szBuffer[64];
306
307 if (numargs() < 2) {
308 return false;
309 }
310
311 switch (prop) {
312 case MENU_PROP_NUMFMT: {
313 get_arg_string(2, szBuffer, charsmax(szBuffer));
314 copy(sMenuTemp[menuNumFmt], charsmax(sMenuTemp[menuNumFmt]), szBuffer);
315
316 if (numargs() > 3) {
317 get_arg_string(3, szBuffer, charsmax(szBuffer));
318 if (arg_is_valid(szBuffer)) {
319 copy(sMenuTemp[menuNumFmtDisable], charsmax(sMenuTemp[menuNumFmtDisable]), szBuffer);
320 }
321 }
322 }
323
324 case MENU_PROP_NUMFMT_DISABLE: {
325 get_arg_string(2, szBuffer, charsmax(szBuffer));
326 copy(sMenuTemp[menuNumFmtDisable], charsmax(sMenuTemp[menuNumFmtDisable]), szBuffer);
327 }
328
329 case MENU_PROP_NOACCESS_FMT: {
330 get_arg_string(2, szBuffer, charsmax(szBuffer));
331 copy(sMenuTemp[menuNoAccessFmt], charsmax(sMenuTemp[menuNoAccessFmt]), szBuffer);
332 }
333
334 case MENU_PROP_EXIT: {
335 sMenuTemp[menuExit] = getarg(2);
336 }
337
338 case MENU_PROP_DISPLAY_PAGES: {
339 sMenuTemp[menuDisplayPages] = bool: getarg(2);
340 }
341
342 case MENU_PROP_BACKNAME: {
343 get_arg_string(2, szBuffer, charsmax(szBuffer));
344 copy(sMenuTemp[menuBackName], charsmax(sMenuTemp[menuBackName]), szBuffer);
345
346 if (numargs() > 2) {
347 get_arg_string(3, szBuffer, charsmax(szBuffer));
348 if (arg_is_valid(szBuffer)) {
349 copy(sMenuTemp[menuNextName], charsmax(sMenuTemp[menuNextName]), szBuffer);
350
351 if (numargs() > 3) {
352 get_arg_string(4, szBuffer, charsmax(szBuffer));
353 copy(sMenuTemp[menuExitName], charsmax(sMenuTemp[menuExitName]), szBuffer);
354 }
355 }
356 }
357 }
358
359 case MENU_PROP_NEXTNAME: {
360 get_arg_string(2, szBuffer, charsmax(szBuffer));
361 copy(sMenuTemp[menuNextName], charsmax(sMenuTemp[menuNextName]), szBuffer);
362 }
363
364 case MENU_PROP_EXITNAME: {
365 get_arg_string(2, szBuffer, charsmax(szBuffer));
366 copy(sMenuTemp[menuExitName], charsmax(sMenuTemp[menuExitName]), szBuffer);
367 }
368
369 case MENU_PROP_COPYRIGHT: {
370 get_arg_string(2, szBuffer, charsmax(szBuffer));
371 copy(sMenuTemp[menuCopyright], charsmax(sMenuTemp[menuCopyright]), szBuffer);
372 }
373
374 default: return false;
375 }
376
377 ArraySetArray(__menusList, menuid, sMenuTemp);
378
379 return true;
380 }
381
382 stock MenuSetItemName(const menu, const item, buffer[], any:...) {
383 new sItemTemp[__menuItemStruct];
384 if (!__GetItemData(menu, item, sItemTemp)) {
385 return;
386 }
387
388 new szName[128];
389 vformat(szName, charsmax(szName), buffer, 4);
390 copy(sItemTemp[itemName], charsmax(sItemTemp[itemName]), szName);
391 ArraySetArray(Array: sItemTemp[itemArrayID], item, sItemTemp);
392 }
393
394 static stock __GetMenuData(const menu, buffer[__menuStruct]) {
395 if (menu < 0 || menu >= ArraySize(__menusList)) {
396 return false;
397 }
398
399 ArrayGetArray(__menusList, menu, buffer);
400 return true;
401 }
402
403 static stock __GetItemData(const menu, const item, buffer[__menuItemStruct]) {
404 new sMenuTemp[__menuStruct];
405 if (!__GetMenuData(menu, sMenuTemp)) {
406 return false;
407 }
408
409 if (item < 0 || item >= ArraySize(Array: sMenuTemp[menuItems])) {
410 return false;
411 }
412
413 ArrayGetArray(Array: sMenuTemp[menuItems], item, buffer);
414
415 new sItemTemp[__menuItemStruct];
416 ArrayGetArray(Array: sMenuTemp[menuItems], item, sItemTemp);
417
418 return true;
419 }
420
421 public __MenuSelectItem(const player) {
422 new sMenuTemp[__menuStruct];
423 if (!__GetMenuData(__playerData[player][playerCurrentMenu], sMenuTemp)) {
424 return;
425 }
426
427 new iDummy, iMenu = sMenuTemp[menuID];
428 new szArg[11]; read_argv(1, szArg, charsmax(szArg));
429 new iKey = str_to_num(szArg), bool: bPagination = bool:(ArraySize(Array: sMenuTemp[menuItems]) -1 > __MENU_ITEMS_PER_PAGEWC);
430
431 switch (iKey) {
432 case ITEM_EXIT: {
433 __playerData[player][playerCurrentMenu] = INVALID_HANDLE;
434 __playerData[player][playerMenuCurrentPage] = 0;
435 }
436
437 case ITEM_BACK: {
438 if (bPagination) {
439 --__playerData[player][playerMenuCurrentPage];
440 MenuDisplay(player, iMenu);
441 }
442 else {
443 __playerData[player][playerCurrentMenu] = INVALID_HANDLE;
444 __playerData[player][playerMenuCurrentPage] = 0;
445 ExecuteForward(sMenuTemp[menuHandler], iDummy, player, iMenu, __playerData[player][playerCurrentRealKey][iKey]);
446 }
447 }
448
449 case ITEM_NEXT: {
450 if (bPagination) {
451 ++__playerData[player][playerMenuCurrentPage];
452 MenuDisplay(player, iMenu);
453 }
454 else {
455 __playerData[player][playerCurrentMenu] = INVALID_HANDLE;
456 __playerData[player][playerMenuCurrentPage] = 0;
457 ExecuteForward(sMenuTemp[menuHandler], iDummy, player, iMenu, __playerData[player][playerCurrentRealKey][iKey]);
458 }
459 }
460
461 default: {
462 __playerData[player][playerCurrentMenu] = INVALID_HANDLE;
463 __playerData[player][playerMenuCurrentPage] = 0;
464 ExecuteForward(sMenuTemp[menuHandler], iDummy, player, iMenu, __playerData[player][playerCurrentRealKey][iKey]);
465 }
466 }
467 }
468
469 public __MessageShowMenuHandle(const msgid, const msgdest, const player) {
470 __playerData[player][playerCurrentMenu] = INVALID_HANDLE;
471 __playerData[player][playerMenuCurrentPage] = 0;
472 }
473
474 static stock __RemoveColorSymbols(buffer[], const len) {
475 replace_all(buffer, len, "\w", "");
476 replace_all(buffer, len, "\y", "");
477 replace_all(buffer, len, "\r", "");
478 replace_all(buffer, len, "\d", "");
479 }