- This plugin allows you to zombie classes with different speed, health & gravity.
|Note:
- Say /zm to open zombie classes menu.
- Open your zombie_escape.txt & add at the end of it:
Code: Select all
MENU_ZCLASS = \rChoose Zombie Class \d| NO_ZCLASSES = !tThere aren't classes available!y. ZOMBIE_SELECT = Your next zombie class is going to be ZOMBIE_HEALTH = Health ZOMBIE_SPEED = Speed ZOMBIE_GRAVITY = Gravity
|Guide:
- This plugin doesn't support different models for each class like ZP so if you want models use Special Models.
|Code:
- ze_zombie_class.sma
- #include <zombie_escape>
- #include <ze_zombie_class_const>
- new const ZE_ZOMBIECLASSES_FILE[] = "ze_zombieclasses.ini"
- #define ZOMBIES_DEFAULT_NAME "Zombie"
- #define ZOMBIES_DEFAULT_DESCRIPTION "Classic"
- #define ZOMBIES_DEFAULT_HEALTH 1800
- #define ZOMBIES_DEFAULT_SPEED 315
- #define ZOMBIES_DEFAULT_GRAVITY 800
- const OFFSET_CSMENUCODE = 205
- // For class list menu handlers
- #define MENU_PAGE_CLASS g_menu_data[id]
- new g_menu_data[33]
- enum _:TOTAL_FORWARDS
- {
- FW_SELECT_CLASS_PRE = 0,
- FW_SELECT_CLASS_POST
- }
- new g_iForwards[TOTAL_FORWARDS], g_iForwardResult
- new Array:g_szZombieClassRealName,
- Array:g_szZombieClassName,
- Array:g_szZombieClassDesc,
- Array:g_iZombieClassHealth,
- Array:g_iZombieClassSpeed,
- Array:g_flZombieClassGravity
- new g_iZombieClass[33], g_iNextZombieClass[33], g_szAdditionalMenuText[32], g_iZombieClassNumber
- public plugin_natives()
- {
- register_native("ze_get_current_zombie_class", "native_ze_get_current_zombie_class", 1)
- register_native("ze_get_next_zombie_class", "native_ze_get_next_zombie_class", 1)
- register_native("ze_set_next_zombie_class", "native_ze_set_next_zombie_class", 1)
- register_native("ze_get_zombie_class_health", "native_ze_get_zombie_class_health", 1)
- register_native("ze_register_zombie_class", "native_ze_register_zombie_class")
- register_native("ze_get_zombie_class_id", "native_ze_get_zombie_class_id", 1)
- register_native("ze_get_zombie_class_name", "native_ze_get_zombie_class_name")
- register_native("ze_get_zombie_class_desc", "native_ze_get_zombie_class_desc")
- register_native("ze_get_zombie_class_number", "native_ze_get_zombie_class_number", 1)
- register_native("ze_open_zombie_classes_menu", "native_ze_open_zombie_classes_menu", 1)
- register_native("ze_add_zombie_class_menu_text", "native_ze_add_zombie_class_menu_text", 1)
- g_szZombieClassRealName = ArrayCreate(32, 1)
- g_szZombieClassName = ArrayCreate(32, 1)
- g_szZombieClassDesc = ArrayCreate(32, 1)
- g_iZombieClassHealth = ArrayCreate(1, 1)
- g_iZombieClassSpeed = ArrayCreate(1, 1)
- g_flZombieClassGravity = ArrayCreate(1, 1)
- }
- public plugin_init()
- {
- register_plugin("[ZE] Addons: Zombie Classes", "1.0", "Jack GamePlay")
- register_clcmd("say /zm", "Show_Zombie_Classes_Menu")
- g_iForwards[FW_SELECT_CLASS_PRE] = CreateMultiForward("ze_select_zombie_class_pre", ET_CONTINUE, FP_CELL, FP_CELL)
- g_iForwards[FW_SELECT_CLASS_POST] = CreateMultiForward("ze_select_zombie_class_post", ET_CONTINUE, FP_CELL, FP_CELL)
- }
- public plugin_cfg()
- {
- if (g_iZombieClassNumber < 1)
- {
- ArrayPushString(g_szZombieClassRealName, ZOMBIES_DEFAULT_NAME)
- ArrayPushString(g_szZombieClassName, ZOMBIES_DEFAULT_NAME)
- ArrayPushString(g_szZombieClassDesc, ZOMBIES_DEFAULT_DESCRIPTION)
- ArrayPushCell(g_iZombieClassHealth, ZOMBIES_DEFAULT_HEALTH)
- ArrayPushCell(g_iZombieClassSpeed, ZOMBIES_DEFAULT_SPEED)
- ArrayPushCell(g_flZombieClassGravity, ZOMBIES_DEFAULT_GRAVITY)
- g_iZombieClassNumber++
- }
- }
- public client_putinserver(id)
- {
- g_iZombieClass[id] = ZE_WRONG_ZOMBIE_CLASS
- g_iNextZombieClass[id] = ZE_WRONG_ZOMBIE_CLASS
- }
- public client_disconnected(id)
- {
- MENU_PAGE_CLASS = 0
- }
- public Show_Zombie_Classes_Menu(id)
- {
- static szMenu[128], szClassName[32], szClassDesc[32]
- new iMenuID, iItemData[2], iIndex
- formatex(szMenu, charsmax(szMenu), "%L", LANG_PLAYER, "MENU_ZCLASS")
- iMenuID = menu_create(szMenu, "ZombieClassesMenuHandler")
- for (iIndex = 0; iIndex < g_iZombieClassNumber; iIndex++)
- {
- // Additional text to display
- g_szAdditionalMenuText[0] = 0
- // Execute class select attempt forward
- ExecuteForward(g_iForwards[FW_SELECT_CLASS_PRE], g_iForwardResult, id, iIndex)
- // Show class to player?
- if (g_iForwardResult >= ZE_CLASS_DONT_SHOW)
- continue
- ArrayGetString(g_szZombieClassName, iIndex, szClassName, charsmax(szClassName))
- ArrayGetString(g_szZombieClassDesc, iIndex, szClassDesc, charsmax(szClassDesc))
- // Class available to player?
- if (g_iForwardResult >= ZE_CLASS_UNAVAILABLE)
- formatex(szMenu, charsmax(szMenu), "\d%s | %s | %s", szClassName, szClassDesc, g_szAdditionalMenuText)
- // Class is current class?
- else if (iIndex == g_iNextZombieClass[id])
- formatex(szMenu, charsmax(szMenu), "\w%s \d| \y%s \d[\yCurrent\d] \r%s", szClassName, szClassDesc, g_szAdditionalMenuText)
- else
- formatex(szMenu, charsmax(szMenu), "\y%s \d| \w%s \r%s", szClassName, szClassDesc, g_szAdditionalMenuText)
- iItemData[0] = iIndex
- iItemData[1] = 0
- menu_additem(iMenuID, szMenu, iItemData)
- }
- // No classes to display?
- if (menu_items(iMenuID) <= 0)
- {
- ze_colored_print(id, "%L", LANG_PLAYER, "NO_ZCLASSES")
- menu_destroy(iMenuID)
- return
- }
- // Back - Next - Exit
- formatex(szMenu, charsmax(szMenu), "%L", LANG_PLAYER, "BACK")
- menu_setprop(iMenuID, MPROP_BACKNAME, szMenu)
- formatex(szMenu, charsmax(szMenu), "%L", LANG_PLAYER, "NEXT")
- menu_setprop(iMenuID, MPROP_NEXTNAME, szMenu)
- formatex(szMenu, charsmax(szMenu), "%L", LANG_PLAYER, "EXIT")
- menu_setprop(iMenuID, MPROP_EXITNAME, szMenu)
- MENU_PAGE_CLASS = min(MENU_PAGE_CLASS, menu_pages(iMenuID) - 1)
- set_pdata_int(id, OFFSET_CSMENUCODE, 0)
- menu_display(id, iMenuID, MENU_PAGE_CLASS)
- }
- public ZombieClassesMenuHandler(id, iMenuID, iItemID)
- {
- // Menu was closed
- if (iItemID == MENU_EXIT)
- {
- MENU_PAGE_CLASS = 0
- menu_destroy(iMenuID)
- return PLUGIN_HANDLED
- }
- // Remember class menu page
- MENU_PAGE_CLASS = iItemID / 7
- // Retrieve class index
- new iItemData[2], iDummy, iIndex
- menu_item_getinfo(iMenuID, iItemID, iDummy, iItemData, charsmax(iItemData), _, _, iDummy)
- iIndex = iItemData[0]
- // Execute class select attempt forward
- ExecuteForward(g_iForwards[FW_SELECT_CLASS_PRE], g_iForwardResult, id, iIndex)
- // Class available to player?
- if (g_iForwardResult >= ZE_CLASS_UNAVAILABLE)
- {
- menu_destroy(iMenuID)
- return PLUGIN_HANDLED
- }
- // Make selected class next class for player
- g_iNextZombieClass[id] = iIndex
- new szClassName[32]
- ArrayGetString(g_szZombieClassName, g_iNextZombieClass[id], szClassName, charsmax(szClassName))
- ze_colored_print(id, "!t%L!y: !g%s", LANG_PLAYER, "ZOMBIE_SELECT", szClassName)
- ze_colored_print(id, "!t%L!y: !g%i !y- !t%L!y: !g%i !y- !t%L!y: !g%i", LANG_PLAYER, "ZOMBIE_HEALTH", ArrayGetCell(g_iZombieClassHealth, g_iNextZombieClass[id]), LANG_PLAYER, "ZOMBIE_SPEED", ArrayGetCell(g_iZombieClassSpeed, g_iNextZombieClass[id]), LANG_PLAYER, "ZOMBIE_GRAVITY", ArrayGetCell(g_flZombieClassGravity, g_iNextZombieClass[id]))
- // Execute class select post forward
- ExecuteForward(g_iForwards[FW_SELECT_CLASS_POST], g_iForwardResult, id, iIndex)
- menu_destroy(iMenuID)
- return PLUGIN_HANDLED
- }
- public ze_user_infected(id)
- {
- // Show zombie class menu if they haven't chosen any (e.g. just connected)
- if (g_iNextZombieClass[id] == ZE_WRONG_ZOMBIE_CLASS)
- {
- if (g_iZombieClassNumber > 1)
- Show_Zombie_Classes_Menu(id)
- else // If only one class is registered, choose it automatically
- g_iNextZombieClass[id] = 0
- }
- // Bots pick class automatically
- if (is_user_bot(id))
- {
- // Try choosing class
- new iIndex, iStart_Index = random_num(0, g_iZombieClassNumber - 1)
- for (iIndex = iStart_Index + 1; /* no condition */; iIndex++)
- {
- // Start over when we reach the end
- if (iIndex >= g_iZombieClassNumber)
- iIndex = 0
- // Execute class select attempt forward
- ExecuteForward(g_iForwards[FW_SELECT_CLASS_PRE], g_iForwardResult, id, iIndex)
- // Class available to player?
- if (g_iForwardResult < ZE_CLASS_UNAVAILABLE)
- {
- g_iNextZombieClass[id] = iIndex
- break
- }
- // Loop completed, no class could be chosen
- if (iIndex == iStart_Index)
- break
- }
- }
- // Set selected zombie class. If none selected yet, use the first one
- g_iZombieClass[id] = g_iNextZombieClass[id]
- if (g_iZombieClass[id] == ZE_WRONG_ZOMBIE_CLASS)
- g_iZombieClass[id] = 0
- // Apply zombie attributes
- set_entvar(id, var_health, float(ArrayGetCell(g_iZombieClassHealth, g_iZombieClass[id])))
- set_entvar(id, var_gravity, float(ArrayGetCell(g_flZombieClassGravity, g_iZombieClass[id])) / 800)
- ze_set_zombie_speed(id, ArrayGetCell(g_iZombieClassSpeed, g_iZombieClass[id]))
- }
- public native_ze_get_current_zombie_class(id)
- {
- if (!is_user_connected(id))
- {
- log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player (%d)", id)
- return ZE_WRONG_ZOMBIE_CLASS
- }
- return g_iZombieClass[id]
- }
- public native_ze_get_next_zombie_class(id)
- {
- if (!is_user_connected(id))
- {
- log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player (%d)", id)
- return ZE_WRONG_ZOMBIE_CLASS
- }
- return g_iNextZombieClass[id]
- }
- public native_ze_set_next_zombie_class(id, iClassID)
- {
- if (!is_user_connected(id))
- {
- log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player (%d)", id)
- return false
- }
- if (0 > iClassID >= g_iZombieClassNumber)
- {
- log_error(AMX_ERR_NATIVE, "[ZE] Invalid zombie class id (%d)", iClassID)
- return false
- }
- g_iNextZombieClass[id] = iClassID
- return true
- }
- public native_ze_get_zombie_class_health(id, iClassID)
- {
- if (!is_user_connected(id))
- {
- log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player (%d)", id)
- return -1
- }
- if (0 > iClassID >= g_iZombieClassNumber)
- {
- log_error(AMX_ERR_NATIVE, "[ZE] Invalid zombie class id (%d)", iClassID)
- return -1
- }
- return ArrayGetCell(g_iZombieClassHealth, iClassID)
- }
- public native_ze_register_zombie_class(plugin_id, num_params)
- {
- new szName[32]
- get_string(1, szName, charsmax(szName))
- if (strlen(szName) < 1)
- {
- log_error(AMX_ERR_NATIVE, "[ZE] Can't register zombie class with an empty name")
- return ZE_WRONG_ZOMBIE_CLASS
- }
- new iIndex, szZombieClassName[32]
- for (iIndex = 0; iIndex < g_iZombieClassNumber; iIndex++)
- {
- ArrayGetString(g_szZombieClassRealName, iIndex, szZombieClassName, charsmax(szZombieClassName))
- if (equali(szName, szZombieClassName))
- {
- log_error(AMX_ERR_NATIVE, "[ZE] Zombie class already registered (%s)", szName)
- return ZE_WRONG_ZOMBIE_CLASS
- }
- }
- new szDesc[32]
- get_string(2, szDesc, charsmax(szDesc))
- new iHealth = get_param(3)
- new iSpeed = get_param(4)
- new flGravity = get_param(5)
- // Load settings from zombie classes file
- new szRealName[32]
- copy(szRealName, charsmax(szRealName), szName)
- ArrayPushString(g_szZombieClassRealName, szRealName)
- // Name
- if (!amx_load_setting_string(ZE_ZOMBIECLASSES_FILE, szRealName, "NAME", szName, charsmax(szName)))
- amx_save_setting_string(ZE_ZOMBIECLASSES_FILE, szRealName, "NAME", szName)
- ArrayPushString(g_szZombieClassName, szName)
- // Description
- if (!amx_load_setting_string(ZE_ZOMBIECLASSES_FILE, szRealName, "INFO", szDesc, charsmax(szDesc)))
- amx_save_setting_string(ZE_ZOMBIECLASSES_FILE, szRealName, "INFO", szDesc)
- ArrayPushString(g_szZombieClassDesc, szDesc)
- // Health
- if (!amx_load_setting_int(ZE_ZOMBIECLASSES_FILE, szRealName, "HEALTH", iHealth))
- amx_save_setting_int(ZE_ZOMBIECLASSES_FILE, szRealName, "HEALTH", iHealth)
- ArrayPushCell(g_iZombieClassHealth, iHealth)
- // Speed
- if (!amx_load_setting_int(ZE_ZOMBIECLASSES_FILE, szRealName, "SPEED", iSpeed))
- amx_save_setting_int(ZE_ZOMBIECLASSES_FILE, szRealName, "SPEED", iSpeed)
- ArrayPushCell(g_iZombieClassSpeed, iSpeed)
- // Gravity
- if (!amx_load_setting_int(ZE_ZOMBIECLASSES_FILE, szRealName, "GRAVITY", flGravity))
- amx_load_setting_int(ZE_ZOMBIECLASSES_FILE, szRealName, "GRAVITY", flGravity)
- ArrayPushCell(g_flZombieClassGravity, flGravity)
- g_iZombieClassNumber++
- return g_iZombieClassNumber - 1
- }
- public native_ze_get_zombie_class_id(const szName[])
- {
- new iIndex, szZombieClassName[32]
- for (iIndex = 0; iIndex < g_iZombieClassNumber; iIndex++)
- {
- ArrayGetString(g_szZombieClassRealName, iIndex, szZombieClassName, charsmax(szZombieClassName))
- if (equali(szName, szZombieClassName))
- return iIndex
- }
- return ZE_WRONG_ZOMBIE_CLASS
- }
- public native_ze_get_zombie_class_name(plugin_id, num_params)
- {
- new iClassID = get_param(1)
- if (0 > iClassID >= g_iZombieClassNumber)
- {
- log_error(AMX_ERR_NATIVE, "[ZE] Invalid zombie class id (%d)", iClassID)
- return false
- }
- new szName[32]
- ArrayGetString(g_szZombieClassName, iClassID, szName, charsmax(szName))
- new iLen = get_param(3)
- set_string(2, szName, iLen)
- return true
- }
- public native_ze_get_zombie_class_desc(plugin_id, num_params)
- {
- new iClassID = get_param(1)
- if (0 > iClassID >= g_iZombieClassNumber)
- {
- log_error(AMX_ERR_NATIVE, "[ZE] Invalid zombie class id (%d)", iClassID)
- return false
- }
- new szDesc[32]
- ArrayGetString(g_szZombieClassDesc, iClassID, szDesc, charsmax(szDesc))
- new iLen = get_param(3)
- set_string(2, szDesc, iLen)
- return true
- }
- public native_ze_get_zombie_class_number()
- {
- return g_iZombieClassNumber
- }
- public native_ze_open_zombie_classes_menu(id)
- {
- if (!is_user_connected(id))
- {
- log_error(AMX_ERR_NATIVE, "[ZE] Invalid Player (%d)", id)
- return false
- }
- Show_Zombie_Classes_Menu(id)
- return true
- }
- public native_ze_add_zombie_class_menu_text(const text[])
- {
- format(g_szAdditionalMenuText, charsmax(g_szAdditionalMenuText), "%s%s", g_szAdditionalMenuText, text)
- }
- ze_zombie_class.inc
- #include <ze_zombie_class_const>
- /*****************************************/
- /************ FORWARDS **************/
- /*****************************************/
- /**
- * Called when determining whether a class should be available to a player.
- *
- * Possible return values are:
- * - ZE_CLASS_AVAILABLE (show in menu, allow selection)
- * - ZE_CLASS_UNAVAILABLE (show in menu, don't allow selection)
- * - ZE_CLASS_DONT_SHOW (don't show in menu, don't allow selection)
- *
- * @param id Player index.
- * @param classid Internal zombie class ID.
- */
- forward ze_select_zombie_class_pre(id, classid)
- /**
- * Called right after a player selects a class from the menu.
- *
- * @param id Player index.
- * @param classid Internal zombie class ID.
- */
- forward ze_select_zombie_class_post(id, classid)
- /*****************************************/
- /************** NATIVES ******************/
- /*****************************************/
- /**
- * Returns a player's current zombie class ID.
- *
- * @param id Player index.
- * @return Internal zombie class ID, or ZE_WRONG_ZOMBIE_CLASS if not yet chosen.
- */
- native ze_get_current_zombie_class(id)
- /**
- * Returns a player's next zombie class ID (for the next infection).
- *
- * @param id Player index.
- * @return Internal zombie class ID, or ZE_WRONG_ZOMBIE_CLASS if not yet chosen.
- */
- native ze_get_next_zombie_class(id)
- /**
- * Sets a player's next zombie class ID (for the next infection).
- *
- * @param id Player index.
- * @param classid A valid zombie class ID.
- * @return True on success, false otherwise.
- */
- native ze_set_next_zombie_class(id, classid)
- /**
- * Returns the default maximum health for a specific zombie class.
- *
- * Note: does not take into account any kind of HP multipliers.
- *
- * @param id Player index.
- * @param classid A valid zombie class ID.
- * @return Maximum amount of health points, -1 on error.
- */
- native ze_get_zombie_class_health(id, classid)
- /**
- * Registers a custom class which will be added to the zombie classes menu of ZP.
- *
- * Note: The returned zombie class ID can be later used to identify
- * the class when calling the zp_get_user_zombie_class() natives.
- *
- * @param name Caption to display on the menu.
- * @param description Brief description of the class.
- * @param health Class health.
- * @param speed Class maxspeed (can be a multiplier).
- * @param gravity Class gravity multiplier.
- * @return An internal zombie class ID, or ZE_WRONG_ZOMBIE_CLASS on failure.
- */
- native ze_register_zombie_class(const name[], const description[], health, speed, gravity)
- /**
- * Returns a zombie class' ID.
- *
- * @param name Class name to look for.
- * @return Internal zombie class ID, or ZE_WRONG_ZOMBIE_CLASS if not found.
- */
- native ze_get_zombie_class_id(const real_name[])
- /**
- * Returns a zombie class' name.
- *
- * @param classid A valid zombie class ID.
- * @param name The buffer to store the string in.
- * @param len Character size of the output buffer.
- * @return True on success, false otherwise.
- */
- native ze_get_zombie_class_name(classid, name[], len)
- /**
- * Returns a zombie class' description.
- *
- * @param classid A valid zombie class ID.
- * @param description The buffer to store the string in.
- * @param len Character size of the output buffer.
- * @return True on success, false otherwise.
- */
- native ze_get_zombie_class_desc(classid, description[], len)
- /**
- * Returns number of registered zombie classes.
- *
- * @return Zombie class count.
- */
- native ze_get_zombie_class_number()
- /**
- * Shows menu with available zombie classes to a player.
- *
- * @param id Player index.
- */
- native ze_open_zombie_classes_menu(id)
- /**
- * Appends text to a class being displayed on the zombie classes menu.
- * Use this on the class select pre forward.
- *
- * @param text Additional text to display.
- */
- native ze_add_zombie_class_menu_text(const text[])
- ze_zombie_class_const.inc
- /* Zombie Class ID constants */
- #define ZE_WRONG_ZOMBIE_CLASS -1
- /* Class selection constants */
- #define ZE_CLASS_AVAILABLE 0
- #define ZE_CLASS_UNAVAILABLE 1
- #define ZE_CLASS_DONT_SHOW 2