Added basic class API: ZR_IsValidClassIndex, ZR_GetActiveClass, ZR_SelectClientClass, ZR_GetClassByName, ZR_GetClassDisplayName
This commit is contained in:
		| @@ -33,3 +33,4 @@ | |||||||
|  |  | ||||||
| #include <zr/infect.zr> | #include <zr/infect.zr> | ||||||
| #include <zr/respawn.zr> | #include <zr/respawn.zr> | ||||||
|  | #include <zr/class.zr> | ||||||
|   | |||||||
							
								
								
									
										109
									
								
								src/include/zr/class.zr.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								src/include/zr/class.zr.inc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | |||||||
|  | /* | ||||||
|  |  * ============================================================================ | ||||||
|  |  * | ||||||
|  |  *  Zombie:Reloaded | ||||||
|  |  * | ||||||
|  |  *  File:          class.zr.inc | ||||||
|  |  *  Type:          Include | ||||||
|  |  *  Description:   Player class API. | ||||||
|  |  * | ||||||
|  |  *  Copyright (C) 2009-2012  Greyscale, Richard Helgeby | ||||||
|  |  * | ||||||
|  |  *  This program is free software: you can redistribute it and/or modify | ||||||
|  |  *  it under the terms of the GNU General Public License as published by | ||||||
|  |  *  the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  *  (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  *  This program is distributed in the hope that it will be useful, | ||||||
|  |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  *  GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  *  You should have received a copy of the GNU General Public License | ||||||
|  |  *  along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ============================================================================ | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @section Internal class cache types. Specifies which class data to access. | ||||||
|  |  */ | ||||||
|  | #define ZR_CLASS_CACHE_ORIGINAL 0   /** Original class data loaded from file. */ | ||||||
|  | #define ZR_CLASS_CACHE_MODIFIED 1   /** Default cache. Class data modified by eventual multipliers, map configs, commands, etc. */ | ||||||
|  | #define ZR_CLASS_CACHE_PLAYER   2   /** Current player class attributes. The class index parameter is used as client index when reading from this cache. */ | ||||||
|  | /** | ||||||
|  |  * @endsection | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Results when selecting a class for a player. | ||||||
|  |  */ | ||||||
|  | enum ClassSelectResult | ||||||
|  | { | ||||||
|  |     ClassSelected_NoChange,     /** No class change was necessary (class already selected). */ | ||||||
|  |     ClassSelected_Instant,      /** Class was instantly changed. */ | ||||||
|  |     ClassSelected_NextSpawn     /** Class will be used next spawn. */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Returns whether a class index is valid or not. | ||||||
|  |  * | ||||||
|  |  * @param classIndex    Class index to validate. | ||||||
|  |  * | ||||||
|  |  * @return              True if valid, false otherwise. | ||||||
|  |  */ | ||||||
|  | native bool:ZR_IsValidClassIndex(classIndex); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Gets the currently active class index that the player is using. | ||||||
|  |  * | ||||||
|  |  * @param client    The client index. | ||||||
|  |  * | ||||||
|  |  * @return          The active class index. | ||||||
|  |  */ | ||||||
|  | native bool:ZR_GetActiveClass(client); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Selects a class for a player. | ||||||
|  |  * | ||||||
|  |  * Human class attribute may be instantly applied if player is alive, human and | ||||||
|  |  * instant class change is enabled. Otherwise only the selected index will be | ||||||
|  |  * updated for next spawn. | ||||||
|  |  * | ||||||
|  |  * Class selection will be saved in client cookies if enabled. | ||||||
|  |  * | ||||||
|  |  * @param client            Client index. | ||||||
|  |  * @param classIndex        Class index. | ||||||
|  |  * @param applyIfPossible   Optional. Apply class attributes if conditions allow | ||||||
|  |  *                          it. Default is true. | ||||||
|  |  * @param saveIfEnabled     Optional. Save class selection in client cookies if | ||||||
|  |  *                          enabled. Default is true. | ||||||
|  |  * | ||||||
|  |  * @return                  Class selection result. See enum ClassSelectResult. | ||||||
|  |  */ | ||||||
|  | native ClassSelectResult:ZR_SelectClientClass(client, classIndex, bool:applyIfPossible = true, bool:saveIfEnabled = true); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Gets the class index of the class with the specified name. | ||||||
|  |  * | ||||||
|  |  * Note: This search is linear and probably won't perform well in large loops. | ||||||
|  |  * | ||||||
|  |  * @param className     Class name to search for. | ||||||
|  |  * @param cacheType     Optional. Specifies which class cache to read from, | ||||||
|  |  *                      except player cache. | ||||||
|  |  * | ||||||
|  |  * @return              Class index, or -1 if none found. | ||||||
|  |  */ | ||||||
|  | native ZR_GetClassByName(const String:className[], cacheType = ZR_CLASS_CACHE_MODIFIED); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Gets the class name displayed in the class menu. | ||||||
|  |  * | ||||||
|  |  * @param index         Index of the class in a class cache or a client index, | ||||||
|  |  *                      depending on the cache type specified. | ||||||
|  |  * @param buffer        The destination string buffer. | ||||||
|  |  * @param maxlen        The length of the destination string buffer. | ||||||
|  |  * @param cacheType     Optional. Specifies which class cache to read from. | ||||||
|  |  * @return              Number of cells written. -1 on error. | ||||||
|  |  */ | ||||||
|  | native ZR_GetClassDisplayName(index, String:buffer[], maxlen, cacheType = ZR_CLASS_CACHE_MODIFIED); | ||||||
							
								
								
									
										177
									
								
								src/testsuite/zr/classapitest.sp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								src/testsuite/zr/classapitest.sp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,177 @@ | |||||||
|  | /* | ||||||
|  |  * ============================================================================ | ||||||
|  |  * | ||||||
|  |  *  Zombie:Reloaded | ||||||
|  |  * | ||||||
|  |  *  File:          classapitest.sp | ||||||
|  |  *  Type:          Test plugin | ||||||
|  |  *  Description:   Tests the class API. | ||||||
|  |  * | ||||||
|  |  *  Copyright (C) 2009-2012  Greyscale, Richard Helgeby | ||||||
|  |  * | ||||||
|  |  *  This program is free software: you can redistribute it and/or modify | ||||||
|  |  *  it under the terms of the GNU General Public License as published by | ||||||
|  |  *  the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  *  (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  *  This program is distributed in the hope that it will be useful, | ||||||
|  |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  *  GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  *  You should have received a copy of the GNU General Public License | ||||||
|  |  *  along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ============================================================================ | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #pragma semicolon 1 | ||||||
|  | #include <sourcemod> | ||||||
|  | #include <zombiereloaded> | ||||||
|  |  | ||||||
|  | public Plugin:myinfo = | ||||||
|  | { | ||||||
|  |     name = "Zombie:Reloaded Class API Test", | ||||||
|  |     author = "Greyscale | Richard Helgeby", | ||||||
|  |     description = "Tests the class API for ZR", | ||||||
|  |     version = "1.0.0", | ||||||
|  |     url = "http://code.google.com/p/zombiereloaded/" | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | public OnPluginStart() | ||||||
|  | { | ||||||
|  |     LoadTranslations("common.phrases"); | ||||||
|  |      | ||||||
|  |     RegConsoleCmd("zrtest_is_valid_class_index", IsValidClassCommand, "Returns whether the specified class index is valid or not. Usage: zrtest_is_valid_class_index <class index>"); | ||||||
|  |     RegConsoleCmd("zrtest_get_active_class", GetActiveClassCommand, "Gets the current class the specified player is using. Usage: zrtest_get_active_class <target>"); | ||||||
|  |     RegConsoleCmd("zrtest_select_class", SelectClassCommand, "Selects a class for a player. Usage: zrtest_select_class <target> <class index>"); | ||||||
|  |     RegConsoleCmd("zrtest_get_class_by_name", GetClassCommand, "Gets class index by class name. Usage: zrtest_get_class_by_name <class name>"); | ||||||
|  |     RegConsoleCmd("zrtest_get_class_display_name", GetNameCommand, "Gets class display name. Usage: zrtest_get_class_display_name <class index>"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | public Action:IsValidClassCommand(client, argc) | ||||||
|  | { | ||||||
|  |     new classIndex = -1; | ||||||
|  |     new String:valueString[64]; | ||||||
|  |      | ||||||
|  |     if (argc >= 1) | ||||||
|  |     { | ||||||
|  |         GetCmdArg(1, valueString, sizeof(valueString)); | ||||||
|  |         classIndex = StringToInt(valueString); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         ReplyToCommand(client, "Returns whether the specified class index is valid or not. Usage: zrtest_is_valid_class_index <class index>"); | ||||||
|  |         return Plugin_Handled; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ReplyToCommand(client, "Class %d is valid: %d", classIndex, ZR_IsValidClassIndex(classIndex)); | ||||||
|  |      | ||||||
|  |     return Plugin_Handled; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | public Action:GetActiveClassCommand(client, argc) | ||||||
|  | { | ||||||
|  |     new target = -1; | ||||||
|  |     new String:valueString[64]; | ||||||
|  |      | ||||||
|  |     if (argc >= 1) | ||||||
|  |     { | ||||||
|  |         GetCmdArg(1, valueString, sizeof(valueString)); | ||||||
|  |         target = FindTarget(client, valueString); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         ReplyToCommand(client, "Gets the current class the specified player is using. Usage: zrtest_get_active_class <target>"); | ||||||
|  |         return Plugin_Handled; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ReplyToCommand(client, "Active class of client %d: %d", target, ZR_GetActiveClass(target)); | ||||||
|  |      | ||||||
|  |     return Plugin_Handled; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | public Action:SelectClassCommand(client, argc) | ||||||
|  | { | ||||||
|  |     new target = -1; | ||||||
|  |     new classIndex = -1; | ||||||
|  |     new bool:applyIfPossible = true; | ||||||
|  |     new bool:saveIfEnabled = true; | ||||||
|  |      | ||||||
|  |     new String:valueString[64]; | ||||||
|  |      | ||||||
|  |     if (argc >= 1) | ||||||
|  |     { | ||||||
|  |         GetCmdArg(1, valueString, sizeof(valueString)); | ||||||
|  |         target = FindTarget(client, valueString); | ||||||
|  |          | ||||||
|  |         GetCmdArg(2, valueString, sizeof(valueString)); | ||||||
|  |         classIndex = StringToInt(valueString); | ||||||
|  |          | ||||||
|  |         if (argc >= 4) | ||||||
|  |         { | ||||||
|  |             GetCmdArg(3, valueString, sizeof(valueString)); | ||||||
|  |             applyIfPossible = bool:StringToInt(valueString); | ||||||
|  |              | ||||||
|  |             GetCmdArg(4, valueString, sizeof(valueString)); | ||||||
|  |             saveIfEnabled = bool:StringToInt(valueString); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         ReplyToCommand(client, "Selects a class for a player. Usage: zrtest_select_class <target> <class index> [<apply if possible> <save if enabled>]"); | ||||||
|  |         return Plugin_Handled; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ReplyToCommand(client, "Selected class %d for client %d. Result: %d", classIndex, target, ZR_SelectClientClass(target, classIndex, applyIfPossible, saveIfEnabled)); | ||||||
|  |      | ||||||
|  |     return Plugin_Handled; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | public Action:GetClassCommand(client, argc) | ||||||
|  | { | ||||||
|  |     new String:className[64]; | ||||||
|  |      | ||||||
|  |     if (argc >= 1) | ||||||
|  |     { | ||||||
|  |         GetCmdArg(1, className, sizeof(className)); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         ReplyToCommand(client, "Gets class index by class name. Usage: zrtest_get_class_by_name <class name>"); | ||||||
|  |         return Plugin_Handled; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ReplyToCommand(client, "Class index of \"%s\": %d", className, ZR_GetClassByName(className)); | ||||||
|  |      | ||||||
|  |     return Plugin_Handled; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | public Action:GetNameCommand(client, argc) | ||||||
|  | { | ||||||
|  |     new classIndex = -1; | ||||||
|  |     new String:valueString[64]; | ||||||
|  |     new String:displayName[64]; | ||||||
|  |      | ||||||
|  |     if (argc >= 1) | ||||||
|  |     { | ||||||
|  |         GetCmdArg(1, valueString, sizeof(valueString)); | ||||||
|  |         classIndex = StringToInt(valueString); | ||||||
|  |          | ||||||
|  |         if (!ZR_IsValidClassIndex(classIndex)) | ||||||
|  |         { | ||||||
|  |             ReplyToCommand(client, "Invalid class index: %d", classIndex); | ||||||
|  |             return Plugin_Handled; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         ReplyToCommand(client, "Gets class display name. Usage: zrtest_get_class_display_name <class index>"); | ||||||
|  |         return Plugin_Handled; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     ZR_GetClassDisplayName(classIndex, displayName, sizeof(displayName)); | ||||||
|  |     ReplyToCommand(client, "Display name of class %d: \"%s\"", classIndex, displayName); | ||||||
|  |      | ||||||
|  |     return Plugin_Handled; | ||||||
|  | } | ||||||
| @@ -43,6 +43,7 @@ | |||||||
|  |  | ||||||
| #include "zr/api/infect.api" | #include "zr/api/infect.api" | ||||||
| #include "zr/api/respawn.api" | #include "zr/api/respawn.api" | ||||||
|  | #include "zr/api/class.api" | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Initializes all main natives and forwards. |  * Initializes all main natives and forwards. | ||||||
| @@ -52,6 +53,7 @@ APIInit() | |||||||
|     // Forward event to sub-modules. |     // Forward event to sub-modules. | ||||||
|     APIInfectInit(); |     APIInfectInit(); | ||||||
|     APIRespawnInit(); |     APIRespawnInit(); | ||||||
|  |     APIClassInit(); | ||||||
| } | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -68,12 +70,14 @@ stock APIValidateClientIndex(client, EligibleCondition:alive = Condition_Either) | |||||||
|     if (client < 1 || client > MaxClients) |     if (client < 1 || client > MaxClients) | ||||||
|     { |     { | ||||||
|         ThrowNativeError(SP_ERROR_NATIVE, "Invalid client index. (%d)", client); |         ThrowNativeError(SP_ERROR_NATIVE, "Invalid client index. (%d)", client); | ||||||
|  |         return; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     // Verify that the client is connected. |     // Verify that the client is connected. | ||||||
|     if (!IsClientConnected(client)) |     if (!IsClientConnected(client)) | ||||||
|     { |     { | ||||||
|         ThrowNativeError(SP_ERROR_NATIVE, "Client %d is not connected.", client); |         ThrowNativeError(SP_ERROR_NATIVE, "Client %d is not connected.", client); | ||||||
|  |         return; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     // Check if the player must be dead or alive. |     // Check if the player must be dead or alive. | ||||||
|   | |||||||
							
								
								
									
										167
									
								
								src/zr/api/class.api.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								src/zr/api/class.api.inc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,167 @@ | |||||||
|  | /* | ||||||
|  |  * ============================================================================ | ||||||
|  |  * | ||||||
|  |  *  Zombie:Reloaded | ||||||
|  |  * | ||||||
|  |  *  File:          class.api.inc | ||||||
|  |  *  Type:          Core | ||||||
|  |  *  Description:   Native handlers for the ZR API. (Class module) | ||||||
|  |  * | ||||||
|  |  *  Copyright (C) 2009-2012  Greyscale, Richard Helgeby | ||||||
|  |  * | ||||||
|  |  *  This program is free software: you can redistribute it and/or modify | ||||||
|  |  *  it under the terms of the GNU General Public License as published by | ||||||
|  |  *  the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  *  (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  *  This program is distributed in the hope that it will be useful, | ||||||
|  |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  *  GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  *  You should have received a copy of the GNU General Public License | ||||||
|  |  *  along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  * ============================================================================ | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Initializes all natives and forwards related to infection. | ||||||
|  |  */ | ||||||
|  | APIClassInit() | ||||||
|  | { | ||||||
|  |     // Class module natives/forwards (class.zr.inc) | ||||||
|  |      | ||||||
|  |     // Natives | ||||||
|  |     CreateNative("ZR_IsValidClassIndex", APIIsValidClassIndex); | ||||||
|  |     CreateNative("ZR_GetActiveClass", APIGetActiveClass); | ||||||
|  |     CreateNative("ZR_SelectClientClass", APISelectClientClass); | ||||||
|  |     CreateNative("ZR_GetClassByName", APIGetClassByName); | ||||||
|  |     CreateNative("ZR_GetClassDisplayName", APIGetClassDisplayName); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Native call function (ZR_IsValidClassIndex) | ||||||
|  |  * | ||||||
|  |  * bool:ZR_IsValidClassIndex(classIndex); | ||||||
|  |  */ | ||||||
|  | public APIIsValidClassIndex(Handle:plugin, numParams) | ||||||
|  | { | ||||||
|  |     new classIndex = GetNativeCell(1); | ||||||
|  |      | ||||||
|  |     return ClassValidateIndex(classIndex); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Native call function (ZR_GetActiveClass) | ||||||
|  |  * | ||||||
|  |  * native bool:ZR_GetActiveClass(client); | ||||||
|  |  */ | ||||||
|  | public APIGetActiveClass(Handle:plugin, numParams) | ||||||
|  | { | ||||||
|  |     new client = GetNativeCell(1); | ||||||
|  |      | ||||||
|  |     // Validate the client index. Player must be alive. | ||||||
|  |     APIValidateClientIndex(client, Condition_True); | ||||||
|  |      | ||||||
|  |     return ClassGetActiveIndex(client); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Native call function (ZR_SelectClientClass) | ||||||
|  |  * | ||||||
|  |  * native ClassSelectResult:ZR_SelectClientClass(client, classIndex, bool:applyIfPossible = true, bool:saveIfEnabled = true) | ||||||
|  |  */ | ||||||
|  | public APISelectClientClass(Handle:plugin, numParams) | ||||||
|  | { | ||||||
|  |     new client = GetNativeCell(1); | ||||||
|  |     new classIndex = GetNativeCell(2); | ||||||
|  |     new bool:applyIfPossible = bool:GetNativeCell(3); | ||||||
|  |     new bool:saveIfEnabled = bool:GetNativeCell(4); | ||||||
|  |      | ||||||
|  |     // Validate the client index. | ||||||
|  |     APIValidateClientIndex(client, Condition_Either); | ||||||
|  |      | ||||||
|  |     // Validate class index. | ||||||
|  |     if (!ClassValidateIndex(classIndex)) | ||||||
|  |     { | ||||||
|  |         ThrowNativeError(SP_ERROR_NATIVE, "Invalid class index. (%d)", classIndex); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     return _:ClassSelectClientClass(client, classIndex, applyIfPossible, saveIfEnabled); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Native call function (ZR_GetClassByName) | ||||||
|  |  * | ||||||
|  |  * native ZR_GetClassByName(const String:className[], cacheType = ZR_CLASS_CACHE_MODIFIED); | ||||||
|  |  */ | ||||||
|  | public APIGetClassByName(Handle:plugin, numParams) | ||||||
|  | { | ||||||
|  |     decl String:className[64]; | ||||||
|  |     className[0] = 0; | ||||||
|  |      | ||||||
|  |     // Get class name. | ||||||
|  |     if (GetNativeString(1, className, sizeof(className)) != SP_ERROR_NONE) | ||||||
|  |     { | ||||||
|  |         ThrowNativeError(SP_ERROR_NATIVE, "Unexpected error when reading className parameter. Possibly corrupt or missing data."); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     new cacheType = GetNativeCell(2); | ||||||
|  |     if (cacheType == ZR_CLASS_CACHE_PLAYER) | ||||||
|  |     { | ||||||
|  |         ThrowNativeError(SP_ERROR_NATIVE, "Invalid cache type. Player cache is not allowed in this function."); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     return ClassGetIndex(className, cacheType); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Native call function (ZR_GetClassDisplayName) | ||||||
|  |  * | ||||||
|  |  * native ZR_GetClassDisplayName(classIndex, String:buffer[], maxlen, cacheType = ZR_CLASS_CACHE_MODIFIED); | ||||||
|  |  */ | ||||||
|  | public APIGetClassDisplayName(Handle:plugin, numParams) | ||||||
|  | { | ||||||
|  |     new index = GetNativeCell(1); | ||||||
|  |     new maxlen = GetNativeCell(3); | ||||||
|  |     new cacheType = GetNativeCell(4); | ||||||
|  |      | ||||||
|  |     if (maxlen <= 0) | ||||||
|  |     { | ||||||
|  |         // No buffer size. | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // Validate index. | ||||||
|  |     if (cacheType == ZR_CLASS_CACHE_PLAYER) | ||||||
|  |     { | ||||||
|  |         // Client index. | ||||||
|  |         APIValidateClientIndex(index, Condition_Either); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         // Class index. | ||||||
|  |         if (!ClassValidateIndex(index)) | ||||||
|  |         { | ||||||
|  |             ThrowNativeError(SP_ERROR_NATIVE, "Invalid class index. (%d)", index); | ||||||
|  |             return 0; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     decl String:displayName[maxlen]; | ||||||
|  |      | ||||||
|  |     new bytes = ClassGetName(index, displayName, maxlen, cacheType); | ||||||
|  |     if (bytes <= 0) | ||||||
|  |     { | ||||||
|  |         // The class doesn't have a name for some reason. Make sure the buffer is empty. | ||||||
|  |         displayName[0] = 0; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     SetNativeString(2, displayName, maxlen); | ||||||
|  |      | ||||||
|  |     return bytes; | ||||||
|  | } | ||||||
| @@ -235,7 +235,7 @@ stock ClassGetGroup(index, String:buffer[], maxlen, cachetype = ZR_CLASS_CACHE_P | |||||||
| } | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Gets the class name to be displayed in the class menu. |  * Gets the class name displayed in the class menu. | ||||||
|  * |  * | ||||||
|  * @param index     Index of the class in a class cache or a client index, |  * @param index     Index of the class in a class cache or a client index, | ||||||
|  *                  depending on the cache type specified. |  *                  depending on the cache type specified. | ||||||
|   | |||||||
| @@ -340,77 +340,22 @@ ClassMenuSelect(client, teamid) | |||||||
|  */ |  */ | ||||||
| public ClassMenuSelectHandle(Handle:menu, MenuAction:action, client, slot) | public ClassMenuSelectHandle(Handle:menu, MenuAction:action, client, slot) | ||||||
| { | { | ||||||
|     decl String:classname[MENU_LINE_REG_LENGTH]; |     decl String:className[MENU_LINE_REG_LENGTH]; | ||||||
|     new classindex; |     new classIndex; | ||||||
|     new teamid; |  | ||||||
|     new bool:autoclose = GetConVarBool(g_hCvarsList[CVAR_CLASSES_MENU_AUTOCLOSE]); |     new bool:autoclose = GetConVarBool(g_hCvarsList[CVAR_CLASSES_MENU_AUTOCLOSE]); | ||||||
|     new bool:iszombie = InfectIsClientInfected(client); |  | ||||||
|      |      | ||||||
|     switch (action) |     switch (action) | ||||||
|     { |     { | ||||||
|         case MenuAction_Select: |         case MenuAction_Select: | ||||||
|         { |         { | ||||||
|             // Get class name from the information string. |             // Get class name from the information string. | ||||||
|             GetMenuItem(menu, slot, classname, sizeof(classname)); |             GetMenuItem(menu, slot, className, sizeof(className)); | ||||||
|              |              | ||||||
|             // Solve class index from the name. |             // Solve class index from the name. | ||||||
|             classindex = ClassGetIndex(classname); |             classIndex = ClassGetIndex(className); | ||||||
|              |              | ||||||
|             // Solve teamid from the class index. |             // Select (and eventually apply) class. | ||||||
|             teamid = ClassGetTeamID(classindex, ZR_CLASS_CACHE_MODIFIED); |             ClassSelectClientClass(client, classIndex); | ||||||
|              |  | ||||||
|             // Allow instant class change if enabled and both class and player is human. |  | ||||||
|             if (ClassAllowInstantChange[client] && !iszombie && teamid == ZR_CLASS_TEAM_HUMANS) |  | ||||||
|             { |  | ||||||
|                 // Directly change the selected class index. |  | ||||||
|                 ClassSelected[client][teamid] = classindex; |  | ||||||
|                  |  | ||||||
|                 // Update cache and apply attributes. |  | ||||||
|                 ClassReloadPlayerCache(client, classindex); |  | ||||||
|                 ClassApplyAttributes(client); |  | ||||||
|             } |  | ||||||
|             else |  | ||||||
|             { |  | ||||||
|                 // Check if the player is alive. |  | ||||||
|                 if (IsPlayerAlive(client)) |  | ||||||
|                 { |  | ||||||
|                     // Set next spawn index if the player is changing the class on |  | ||||||
|                     // his active team. |  | ||||||
|                     if ((iszombie && teamid == ZR_CLASS_TEAM_ZOMBIES) || |  | ||||||
|                         (!iszombie && teamid == ZR_CLASS_TEAM_HUMANS) || |  | ||||||
|                         (ClassPlayerInAdminMode[client] && teamid == ZR_CLASS_TEAM_ADMINS)) |  | ||||||
|                     { |  | ||||||
|                         // Check if player selected the same class that he already is. |  | ||||||
|                         if (ClassSelected[client][teamid] == classindex) |  | ||||||
|                         { |  | ||||||
|                             // Player is already the specified class. Disable |  | ||||||
|                             // next class for the specified team. |  | ||||||
|                             ClassSelectedNext[client][teamid] = -1; |  | ||||||
|                         } |  | ||||||
|                         else |  | ||||||
|                         { |  | ||||||
|                             // Set class to be used on next spawn. |  | ||||||
|                             ClassSelectedNext[client][teamid] = classindex; |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                     else |  | ||||||
|                     { |  | ||||||
|                         // Directly change the selected class index. |  | ||||||
|                         ClassSelected[client][teamid] = classindex; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 else |  | ||||||
|                 { |  | ||||||
|                     // Player isn't alive. The class can be directly changed. |  | ||||||
|                     ClassSelected[client][teamid] = classindex; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|              |  | ||||||
|             // Save selected class index in cookie if enabled. |  | ||||||
|             if (GetConVarBool(g_hCvarsList[CVAR_CLASSES_SAVE])) |  | ||||||
|             { |  | ||||||
|                 CookiesSetInt(client, g_hClassCookieClassSelected[teamid], classindex + 1); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|         case MenuAction_Cancel: |         case MenuAction_Cancel: | ||||||
|         { |         { | ||||||
|   | |||||||
| @@ -587,12 +587,12 @@ stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes]) | |||||||
| /** | /** | ||||||
|  * Checks if the specified class index is a valid index. |  * Checks if the specified class index is a valid index. | ||||||
|  * |  * | ||||||
|  * @param classindex    The class index to validate. |  * @param classIndex    The class index to validate. | ||||||
|  * @return              True if the class exist, false otherwise. |  * @return              True if the class exist, false otherwise. | ||||||
|  */ |  */ | ||||||
| stock bool:ClassValidateIndex(classindex) | stock bool:ClassValidateIndex(classIndex) | ||||||
| { | { | ||||||
|     if (classindex >= 0 && classindex < ClassCount) |     if (classIndex >= 0 && classIndex < ClassCount) | ||||||
|     { |     { | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
| @@ -660,10 +660,10 @@ stock ClassGetIndex(const String:name[], cachetype = ZR_CLASS_CACHE_MODIFIED) | |||||||
| { | { | ||||||
|     decl String:current_name[64]; |     decl String:current_name[64]; | ||||||
|  |  | ||||||
|     // Check if there are no classes. |     // Check if there are no classes, or reading from player cache. | ||||||
|     if (ClassCount == 0) |     if (ClassCount == 0 || cachetype == ZR_CLASS_CACHE_PLAYER) | ||||||
|     { |     { | ||||||
|         return false; |         return -1; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     // Loop through all classes. |     // Loop through all classes. | ||||||
|   | |||||||
| @@ -377,6 +377,16 @@ enum ClassSpeedMethods | |||||||
|     ClassSpeed_Prop,            /** Modifies players' max speed property(m_flMaxspeed). */ |     ClassSpeed_Prop,            /** Modifies players' max speed property(m_flMaxspeed). */ | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Results when selecting a class for a player. | ||||||
|  |  */ | ||||||
|  | enum ClassSelectResult | ||||||
|  | { | ||||||
|  |     ClassSelected_NoChange,     /** No class change was necessary (class already selected). */ | ||||||
|  |     ClassSelected_Instant,      /** Class was instantly changed. */ | ||||||
|  |     ClassSelected_NextSpawn     /** Class will be used next spawn. */ | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Empty filter structure. |  * Empty filter structure. | ||||||
|  */ |  */ | ||||||
| @@ -1196,6 +1206,86 @@ ClassClientSetDefaultIndexes(client = -1) | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Selects a class for a player. | ||||||
|  |  * | ||||||
|  |  * Human class attribute may be instantly applied if player is alive, human and | ||||||
|  |  * instant class change is enabled. Otherwise only the selected index will be | ||||||
|  |  * updated for next spawn. | ||||||
|  |  * | ||||||
|  |  * Class selection will be saved in client cookies if enabled. | ||||||
|  |  * | ||||||
|  |  * @param client            Client index. | ||||||
|  |  * @param classIndex        Class index. | ||||||
|  |  * @param applyIfPossible   Optional. Apply class attributes if conditions allow | ||||||
|  |  *                          it. Default is true. | ||||||
|  |  * @param saveIfEnabled     Optional. Save class selection in client cookies if | ||||||
|  |  *                          enabled. Default is true. | ||||||
|  |  * | ||||||
|  |  * @return                  Class selection result. See enum ClassSelectResult. | ||||||
|  |  */ | ||||||
|  | ClassSelectResult:ClassSelectClientClass(client, classIndex, bool:applyIfPossible = true, bool:saveIfEnabled = true) | ||||||
|  | { | ||||||
|  |     new bool:iszombie = InfectIsClientInfected(client); | ||||||
|  |     new teamid = ClassGetTeamID(classIndex, ZR_CLASS_CACHE_MODIFIED); | ||||||
|  |     new ClassSelectResult:selectResult = ClassSelected_NoChange; | ||||||
|  |      | ||||||
|  |     // Allow instant class change if enabled and both class and player is human. | ||||||
|  |     if (applyIfPossible && | ||||||
|  |         ClassAllowInstantChange[client] && | ||||||
|  |         !iszombie && teamid == ZR_CLASS_TEAM_HUMANS) | ||||||
|  |     { | ||||||
|  |         // Update selected class index. | ||||||
|  |         ClassSelected[client][teamid] = classIndex; | ||||||
|  |          | ||||||
|  |         // Update cache and apply attributes. | ||||||
|  |         ClassReloadPlayerCache(client, classIndex); | ||||||
|  |         ClassApplyAttributes(client); | ||||||
|  |          | ||||||
|  |         selectResult = ClassSelected_Instant; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         // Set next spawn index if the player is changing the class on | ||||||
|  |         // his active team. | ||||||
|  |         if (IsPlayerAlive(client) && | ||||||
|  |             (iszombie && teamid == ZR_CLASS_TEAM_ZOMBIES) || | ||||||
|  |             (!iszombie && teamid == ZR_CLASS_TEAM_HUMANS) || | ||||||
|  |             (ClassPlayerInAdminMode[client] && teamid == ZR_CLASS_TEAM_ADMINS)) | ||||||
|  |         { | ||||||
|  |             // Check if selecting the same class that the player already is. | ||||||
|  |             if (ClassSelected[client][teamid] == classIndex) | ||||||
|  |             { | ||||||
|  |                 // Player is already the specified class. No need to change | ||||||
|  |                 // class next spawn. | ||||||
|  |                 ClassSelectedNext[client][teamid] = -1; | ||||||
|  |                 selectResult = ClassSelected_NoChange; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 // Set class to be used on next spawn. | ||||||
|  |                 ClassSelectedNext[client][teamid] = classIndex; | ||||||
|  |                 selectResult = ClassSelected_NextSpawn; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             // Directly change the selected class index. | ||||||
|  |             ClassSelected[client][teamid] = classIndex; | ||||||
|  |             selectResult = ClassSelected_NextSpawn; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // Save selected class index in cookie if enabled. | ||||||
|  |     // Note: Saved indexes are increased by one. | ||||||
|  |     if (saveIfEnabled && GetConVarBool(g_hCvarsList[CVAR_CLASSES_SAVE])) | ||||||
|  |     { | ||||||
|  |         CookiesSetInt(client, g_hClassCookieClassSelected[teamid], classIndex + 1); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     return selectResult; | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Dump class data into a string. String buffer length should be at about 2048 |  * Dump class data into a string. String buffer length should be at about 2048 | ||||||
|  * cells. |  * cells. | ||||||
|   | |||||||
| @@ -68,6 +68,7 @@ enum Game | |||||||
|  * Current game. |  * Current game. | ||||||
|  */ |  */ | ||||||
| new Game:g_game = Game_Unknown; | new Game:g_game = Game_Unknown; | ||||||
|  | #pragma unused g_game | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Updates g_game. Will log a warning if a unsupported game is detected. |  * Updates g_game. Will log a warning if a unsupported game is detected. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user