diff --git a/cstrike/addons/sourcemod/translations/zombiereloaded.phrases.txt b/cstrike/addons/sourcemod/translations/zombiereloaded.phrases.txt index ec07a19..2d64df1 100644 --- a/cstrike/addons/sourcemod/translations/zombiereloaded.phrases.txt +++ b/cstrike/addons/sourcemod/translations/zombiereloaded.phrases.txt @@ -28,55 +28,12 @@ "en" "You have randomly been assigned to the @green\"{1}\" @defaultclass." "ru" "Вам был случайным образом установлен класс \"{1}\"." } - - "Random class is enabled" - { - "en" "Class selection is locked. A random class will be assigned to you every round." - "ru" "Выбор класса отключен. Каждый раунд вам будет установлен случайнй класс." - } - - "Feature is disabled" - { - "en" "This feature has been disabled by the server host." - "ru" "Данная функция отключена." - } - - "Must be admin" - { - "en" "Can only be used by admins." - "ru" "Может быть использовано только, когда жив." - } - - "Must be alive" - { - "en" "Can only be used when alive." - "ru" "Может быть использовано только, когда жив." - } - - "Must be dead" - { - "en" "Can only be used when dead." - "ru" "Может быть использовано только, когда мертв." - } - - "Must be zombie" - { - "en" "Can only be used while zombie." - "ru" "Может быть использовано только, когда зомби." - } "!zmenu reminder" { "en" "Type !zmenu in chat to view all ZR commands." "ru" "Напишите !zmenu в чате для просмотра всех команд." } - - "Class select" - { - "#format" "{1:s}" - "en" "Switched zombie class to \"{1}\"" - "ru" "Класс зомби переключен на \"{1}\"" - } "!ztele amount" { @@ -143,12 +100,59 @@ // Generic // =========================== + // General + + "Console restricted" + { + "en" "Command not usable from console." + "ru" "Команда не используется для консоли." + } + + "Feature is disabled" + { + "en" "This feature has been disabled by the server host." + "ru" "Данная функция отключена." + } + + "Must be admin" + { + "en" "Can only be used by admins." + "ru" "Может быть использовано только, когда жив." + } + + "Must be alive" + { + "en" "Can only be used when alive." + "ru" "Может быть использовано только, когда жив." + } + + "Must be dead" + { + "en" "Can only be used when dead." + "ru" "Может быть использовано только, когда мертв." + } + + "Must be zombie" + { + "en" "Can only be used while zombie." + "ru" "Может быть использовано только, когда зомби." + } + // Menu "Menu empty" { "en" "(Empty)" } + + // =========================== + // (Core) Damage + // =========================== + + "Damage suicide intercept" + { + "en" "Suicide attempt intercepted." + } // =========================== // Weapons @@ -344,13 +348,6 @@ "en" "HP: {1}" "ru" "Здоровье: {1}" } - - - "Suicide text" - { - "en" "Nice try n00b!" - "ru" "Неплохая попытка n00b!" - } "Unfair camping" { @@ -466,11 +463,6 @@ { "en" "Toggle Admin Mode" } - - "!zclass not found" - { - "en" "No classes found." - } // =========================== // ZAdmin Menu @@ -645,12 +637,6 @@ "ru" "-----------| Zombie:Reloaded Загружен |----------" } - "Console restricted" - { - "en" "Command not usable from console." - "ru" "Команда не используется для консоли." - } - "Models loaded" { "en" "--- Models Loaded ---" diff --git a/src/zombiereloaded.sp b/src/zombiereloaded.sp index 8c46ea1..6a1876b 100644 --- a/src/zombiereloaded.sp +++ b/src/zombiereloaded.sp @@ -38,6 +38,9 @@ // Round end (core) #include "zr/roundend" +// Damage (core) +#include "zr/damage" + // Class system (module) #include "zr/playerclasses/playerclasses" @@ -75,7 +78,6 @@ #include "zr/zhp" #include "zr/zadmin" -#include "zr/damagecontrol" #include "zr/commands" #include "zr/event" @@ -119,7 +121,8 @@ public OnPluginStart() // Weapons WeaponsInit(); - InitDmgControl(); + // Damage + DamageInit(); // ====================================================================== @@ -205,7 +208,8 @@ public OnClientPutInServer(client) bMotherInfectImmune[client] = false; // Forward event to modules. - RoundEndGetClientDXLevel(client); + RoundEndClientInit(client); + DamageClientInit(client); ClassClientInit(client); SEffectsClientInit(client); WeaponsClientInit(client); @@ -213,8 +217,6 @@ public OnClientPutInServer(client) RespawnClientInit(client); ZHPClientInit(client); - ClientHookAttack(client); - for (new x = 0; x < MAXTIMERS; x++) { tHandles[client][x] = INVALID_HANDLE; @@ -223,11 +225,10 @@ public OnClientPutInServer(client) public OnClientDisconnect(client) { - ClientUnHookAttack(client); - PlayerLeft(client); // Forward event to modules. + DamageOnClientDisconnect(client); ClassOnClientDisconnect(client); WeaponsOnClientDisconnect(client); ZTeleResetClient(client); diff --git a/src/zr/commands.inc b/src/zr/commands.inc index 7ec4b6c..5be84e0 100644 --- a/src/zr/commands.inc +++ b/src/zr/commands.inc @@ -319,7 +319,7 @@ public Action:Command_LogFlags(client, argc) StrCat(message, sizeof(message), "LOG_MODULE_WEAPONRESTICT (65536) - weaponrestrict.inc\n"); StrCat(message, sizeof(message), "LOG_MODULE_COMMANDS (131072) - commands.inc\n"); StrCat(message, sizeof(message), "LOG_MODULE_ANTICAMP (262144) - anticamp.inc\n"); - StrCat(message, sizeof(message), "LOG_MODULE_DAMAGECONTROL (524288) - damagecontrol.inc\n"); + StrCat(message, sizeof(message), "LOG_MODULE_DAMAGE (524288) - damage.inc\n"); StrCat(message, sizeof(message), "LOG_MODULE_OFFSETS (524288) - offsets.inc"); ReplyToCommand(client, message); diff --git a/src/zr/cvars.inc b/src/zr/cvars.inc index 7641d24..9a10aef 100644 --- a/src/zr/cvars.inc +++ b/src/zr/cvars.inc @@ -56,7 +56,7 @@ enum ZRSettings Handle:CVAR_RESPAWN_DELAY, Handle:CVAR_SUICIDE_ZOMBIE, Handle:CVAR_SUICIDE_HUMAN, - Handle:CVAR_SUICIDE_ECHO, + Handle:CVAR_SUICIDE_CMDS, Handle:CVAR_SUICIDE_WORLD_DAMAGE, Handle:CVAR_SPAWN_MIN, Handle:CVAR_SPAWN_MAX, @@ -144,9 +144,10 @@ CreateCvars() gCvars[CVAR_RESPAWN] = CreateConVar("zr_respawn", "0", "When player is killed, player will respawn"); gCvars[CVAR_RESPAWN_ZOMBIE] = CreateConVar("zr_respawn_zombie", "1", "Respawn player as zombie (0: Respawn as human)"); gCvars[CVAR_RESPAWN_DELAY] = CreateConVar("zr_respawn_delay", "1", "How long to wait after death to respawn, in seconds"); - gCvars[CVAR_SUICIDE_ZOMBIE] = CreateConVar("zr_suicide_zombie", "1", "Stops zombies from suiciding"); - gCvars[CVAR_SUICIDE_HUMAN] = CreateConVar("zr_suicide_human", "1", "Stops humans from suiciding"); - gCvars[CVAR_SUICIDE_ECHO] = CreateConVar("zr_suicide_echo", "0", "Log suicide attempts to admin chat."); + gCvars[CVAR_SUICIDE_ZOMBIE] = CreateConVar("zr_suicide_zombie", "1", "Intercept human suicide attempts."); + gCvars[CVAR_SUICIDE_HUMAN] = CreateConVar("zr_suicide_human", "1", "Intercept zombie suicide attempts."); + gCvars[CVAR_SUICIDE_CMDS] = CreateConVar("zr_suicide_cmds", "kill, spectate, jointeam", "List of suicide commands to intercept. (Delimited by \", \""); + /** Note: CVAR_SUICIDE_WORLD_DAMAGE should be renamed as it is not part of the suicide intercept function*/ gCvars[CVAR_SUICIDE_WORLD_DAMAGE] = CreateConVar("zr_suicide_world_damage", "1", "Respawn zombies as zombies if they were killed by the world, like elevators, doors and lasers. (0: Disable)"); gCvars[CVAR_SPAWN_MIN] = CreateConVar("zr_spawn_min", "30", "Minimum time a player is picked to be zombie after the round starts, in seconds"); gCvars[CVAR_SPAWN_MAX] = CreateConVar("zr_spawn_max", "50", "Maximum time a player is picked to be zombie after the round starts, in seconds"); diff --git a/src/zr/damage.inc b/src/zr/damage.inc new file mode 100644 index 0000000..dfd3314 --- /dev/null +++ b/src/zr/damage.inc @@ -0,0 +1,304 @@ +/* + * ============================================================================ + * + * Zombie:Reloaded + * + * File: damage.inc + * Description: (Core) Modify damage stuff here. + * + * ============================================================================ + */ + +/** + * @section Damage type flags. + */ +#define DMG_GENERIC 0 // generic damage was done +#define DMG_BULLET (1 << 1) // shot +#define DMG_SLASH (1 << 2) // cut, clawed, stabbed +#define DMG_BURN (1 << 3) // heat burned +#define DMG_FALL (1 << 5) // fell too far +#define DMG_BLAST (1 << 6) // explosive blast damage +#define DMG_DROWN (1 << 14) // Drowning +/** + * @endsection + */ + +/** + * @section Suicide intercept defines. + */ +#define DAMAGE_SUICIDE_MAX_CMDS 5 +#define DAMAGE_SUICIDE_MAX_LENGTH 16 +/** + * @endsection + */ + +/** + * List of damage-related hooks. + */ +enum DamageHooks +{ + Hook_TraceAttack, + Hook_OnTakeDamage, +} + +new g_iDamageHooks[MAXPLAYERS + 1][DamageHooks]; + +/** + * Damage module init function. + */ +DamageInit() +{ + // Create command callbacks (intercepts) for listed suicide commands. + decl String:suicidecmds[64]; + GetConVarString(gCvars[CVAR_SUICIDE_CMDS], suicidecmds, sizeof(suicidecmds)); + + // Create array to store cmds + new String:arrayCmds[DAMAGE_SUICIDE_MAX_CMDS][DAMAGE_SUICIDE_MAX_LENGTH]; + + // Explode string into array indexes. + new cmdcount = ExplodeString(suicidecmds, ", ", arrayCmds, DAMAGE_SUICIDE_MAX_CMDS, DAMAGE_SUICIDE_MAX_LENGTH); + + // x = array index. + // arrayCmds[x] = suicide command. + for (new x = 0; x <= cmdcount - 1; x++) + { + // Prepare intercept for this command. + RegConsoleCmd(arrayCmds[x], DamageSuicideIntercept); + } +} + +/** + * Client is joining the server. + * + * @param client The client index. + */ +DamageClientInit(client) +{ + g_iDamageHooks[client][Hook_TraceAttack] = Hacks_Hook(client, HACKS_HTYPE_TRACEATTACK, DamageTraceAttack, false); + g_iDamageHooks[client][Hook_OnTakeDamage] = Hacks_Hook(client, HACKS_HTYPE_ONTAKEDAMAGE, DamageOnTakeDamage, false); +} + +/** + * Client is leaving the server. + * + * @param client The client index. + */ +DamageOnClientDisconnect(client) +{ + Hacks_Unhook(g_iDamageHooks[client][Hook_TraceAttack]); + Hacks_Unhook(g_iDamageHooks[client][Hook_OnTakeDamage]); +} + +/** + * Hook: TraceAttack + * Called right before the bullet enters a client. + * + * @param client The client index. + * @param inflictor Entity index of damage-causing entity. + * @param attacker The client doing the damage. + * @param damage The amount of damage that will be inflicted. + * @param hitbox The hitbox index. + * @param hitgroup The hitgroup index. + * @return Hacks_Continue allows shot to be made. + * 0 stops the bullet from impacting. + */ +public DamageTraceAttack(client, inflictor, attacker, damage, hitbox, hitgroup) +{ + // Disabled + // new bool:enabled = GetConVarBool(gCvars[CVAR_ENABLE]); + + // If attacker isn't valid, then stop. + if (!ZRIsValidClient(attacker)) + { + return Hacks_Continue; + } + + // Get zombie flag for each client. + new bool:clientzombie = IsPlayerZombie(client); + new bool:attackerzombie = IsPlayerZombie(attacker); + + // If the flags are the same on both clients, then stop. + if (clientzombie == attackerzombie) + { + return 0; + } + + // Players are on differen't teams. + return Hacks_Continue; +} + +/** + * Hook: OnTakeDamage + * Called right before damage is done. + * + * @param client The client index. + * @param inflictor Entity index of damage-causing entity. + * @param attacker The client doing the damage. + * @param damage The amount of damage that will be inflicted. + * @param damagetype The type of damage done (see damage flag defines) + * @param ammotype Type of ammo attacker shot at client. + * @return Hacks_Continue allows shot to be made. + * 0 stops the bullet from doing damage. + */ +public DamageOnTakeDamage(client, inflictor, attacker, damage, damagetype, ammotype) +{ + // Disabled. + /** + new bool:enabled = GetConVarBool(gCvars[CVAR_ENABLE]); + if (!enabled) + { + return Hacks_Continue; + }*/ + + // Get classname of the inflictor. + decl String:classname[64]; + GetEdictClassname(inflictor, classname, sizeof(classname)); + + // If entity is a trigger, then allow damage. (Map is damaging client) + if (StrContains(classname, "trigger") > -1) + { + return Hacks_Continue; + } + + switch(damagetype) + { + // Client fell too far. + case DMG_FALL: + { + // If client isn't a zombie, then allow damage. + if (!IsPlayerZombie(client)) + { + return Hacks_Continue; + } + + // If class has "nofalldamage" disabled, then allow damage. + new bool:blockfalldamage = ClassGetNoFallDamage(client); + if (!blockfalldamage) + { + return Hacks_Continue; + } + + // Stop damage. + return 0; + } + // Client is being damaged by a blast. + case DMG_BLAST: + { + // If attacker isn't valid, then allow damage. + if (!ZRIsValidClient(attacker)) + { + return Hacks_Continue; + } + + // If client is a zombie, then allow damage. + if (IsPlayerZombie(client)) + { + return Hacks_Continue; + } + + // Stop damage. + return 0; + } + // Client is being shot. + case DMG_BULLET: + { + // If attacker isn't valid, then allow damage. + if (!ZRIsValidClient(attacker)) + { + return Hacks_Continue; + } + + // Get zombie flag for each client. + new bool:clientzombie = IsPlayerZombie(client); + new bool:attackerzombie = IsPlayerZombie(attacker); + + // If client and attacker are on the same team, then let CS:S handle the rest. + if (clientzombie == attackerzombie) + { + return Hacks_Continue; + } + + // We know that clientzombie is the opposite of attacker zombie. + + // If the client is a zombie, then allow damage. + if (clientzombie) + { + return Hacks_Continue; + } + + // Client is about to be infected, re-add HP so they aren't killed by knife. + new health = GetClientHealth(client); + SetEntityHealth(client, health + damage); + + // Allow damage. + return Hacks_Continue; + } + } + + // Allow damage. + return Hacks_Continue; +} + +/** + * Command callback (kill, jointeam, spectate) + * Block command if plugin thinks they are trying to commit suicide. + * + * @param client The client index. + * @param argc The number of arguments in command string. + */ +public Action:DamageSuicideIntercept(client, argc) +{ + // Disabled. + /** + new bool:enabled = GetConVarBool(gCvars[CVAR_ENABLE]); + if (!enabled) + { + return Plugin_Continue; + }*/ + + // If zombie hasn't spawned, then stop. + if (!g_bZombieSpawned) + { + return Plugin_Continue; + } + + // If client is invalid, then stop. (Stop console.) + if (!ZRIsValidClient(client)) + { + return Plugin_Continue; + } + + // If client is dead, then stop. + if (!IsPlayerAlive(client)) + { + return Plugin_Continue; + } + + // Get zombie flag on client. + new bool:clientzombie = IsPlayerZombie(client); + + // Get cvar values for suicide interception. + new bool:suicidezombie = GetConVarBool(gCvars[CVAR_SUICIDE_ZOMBIE]); + new bool:suicidehuman = GetConVarBool(gCvars[CVAR_SUICIDE_HUMAN]); + + // Determine whether to block suicide based off of the client's zombie flag and cvar values. + new bool:blocksuicide = clientzombie ? suicidezombie : suicidehuman; + + // If cvar for this team is disabled, then stop. + if (!blocksuicide) + { + return Plugin_Continue; + } + + // Tell client their command has been intercepted. + ZR_ReplyToCommand(client, "Damage suicide intercept"); + + // Log attempt. + if (LogFlagCheck(LOG_GAME_EVENTS, LOG_MODULE_DAMAGE)) + { + ZR_LogMessageFormatted(client, "Damage", "Suicide Intercept", "Player %N attempted suicide.", LOG_FORMAT_TYPE_FULL, client); + } + + // Block command. + return Plugin_Handled; +} \ No newline at end of file diff --git a/src/zr/damagecontrol.inc b/src/zr/damagecontrol.inc deleted file mode 100644 index baca8db..0000000 --- a/src/zr/damagecontrol.inc +++ /dev/null @@ -1,185 +0,0 @@ -/** - * ==================== - * Zombie:Reloaded - * File: damagecontrol.inc - * Author: Greyscale - * ==================== - */ - -#define DMG_GENERIC 0 // generic damage was done -#define DMG_BULLET (1 << 1) // shot -#define DMG_SLASH (1 << 2) // cut, clawed, stabbed -#define DMG_BURN (1 << 3) // heat burned -#define DMG_FALL (1 << 5) // fell too far -#define DMG_BLAST (1 << 6) // explosive blast damage -#define DMG_DROWN (1 << 14) // Drowning - -enum ZRHooks -{ - Hook_TraceAttack, - Hook_OnTakeDamage -} - -new gHooks[MAXPLAYERS + 1][ZRHooks]; - -InitDmgControl() -{ - RegConsoleCmd("kill", Attempt_Suicide); - RegConsoleCmd("jointeam", Attempt_Suicide); - RegConsoleCmd("spectate", Attempt_Suicide); -} - -ClientHookAttack(client) -{ - gHooks[client][Hook_TraceAttack] = Hacks_Hook(client, HACKS_HTYPE_TRACEATTACK, TraceAttack, false); - gHooks[client][Hook_OnTakeDamage] = Hacks_Hook(client, HACKS_HTYPE_ONTAKEDAMAGE, OnTakeDamage, false); -} - -ClientUnHookAttack(client) -{ - Hacks_Unhook(gHooks[client][Hook_TraceAttack]); - Hacks_Unhook(gHooks[client][Hook_OnTakeDamage]); -} - -public TraceAttack(client, inflictor, attacker, damage, hitbox, hitgroup) -{ - new bool:enabled = GetConVarBool(gCvars[CVAR_ENABLE]); - - if (!attacker || !ZRIsValidClient(attacker) || !IsClientInGame(attacker) || !enabled) - { - return Hacks_Continue; - } - - if (IsPlayerZombie(client) && IsPlayerZombie(attacker)) - { - return 0; - } - - if (IsPlayerHuman(client) && IsPlayerHuman(attacker)) - { - return 0; - } - - return Hacks_Continue; -} - -public OnTakeDamage(client, inflictor, attacker, damage, damagetype, ammotype) -{ - new bool:enabled = GetConVarBool(gCvars[CVAR_ENABLE]); - if (!enabled) - { - return Hacks_Continue; - } - - decl String:classname[64]; - GetEdictClassname(inflictor, classname, sizeof(classname)); - if (StrContains(classname, "trigger") > -1) - { - return Hacks_Continue; - } - - if (damagetype & DMG_FALL) - { - if (!IsPlayerZombie(client)) - { - return Hacks_Continue; - } - - new bool:blockfalldamage = ClassGetNoFallDamage(client); - if (!blockfalldamage) - { - return Hacks_Continue; - } - - return 0; - } - - if (damagetype & DMG_BLAST) - { - if (!IsPlayerHuman(client) || !ZRIsValidClient(attacker) || !IsClientInGame(attacker)) - { - return Hacks_Continue; - } - - return 0; - } - - if (damagetype & DMG_BULLET) - { - if (!client || !ZRIsValidClient(client) || !IsClientInGame(client)) - { - return Hacks_Continue; - } - - if (!attacker || !ZRIsValidClient(attacker) || !IsClientInGame(attacker)) - { - return Hacks_Continue; - } - - if (IsPlayerZombie(client) && IsPlayerHuman(attacker)) - { - return Hacks_Continue; - } - - if (IsPlayerHuman(client) && IsPlayerZombie(attacker)) - { - new health = GetClientHealth(client); - SetEntityHealth(client, health + damage); - - return Hacks_Continue; - } - - return 0; - } - - return Hacks_Continue; -} - -public Action:Attempt_Suicide(client, argc) -{ - if (!client) - { - return Plugin_Continue; - } - - new bool:enabled = GetConVarBool(gCvars[CVAR_ENABLE]); - if (!enabled) - { - return Plugin_Continue; - } - - - - new bool:suicide = IsPlayerZombie(client) ? GetConVarBool(gCvars[CVAR_SUICIDE_ZOMBIE]) : GetConVarBool(gCvars[CVAR_SUICIDE_HUMAN]); - if (!suicide) - { - return Plugin_Continue; - } - - decl String:cmd[16]; - GetCmdArg(0, cmd, sizeof(cmd)); - - if (!IsPlayerAlive(client)) - { - return Plugin_Continue; - } - - ZR_ReplyToCommand(client, "Suicide text"); - ZR_PrintToChat(client, "Suicide text"); - - decl String:clientname[64]; - decl String:buffer[192]; - - GetClientName(client, clientname, sizeof(clientname)); - if (LogFlagCheck(LOG_GAME_EVENTS, LOG_MODULE_DAMAGECONTROL)) - { - ZR_LogMessageFormatted(client, "damage control", "suicide", "Player \"%s\" attempted suicide.", true, clientname); - } - if (GetConVarBool(gCvars[CVAR_SUICIDE_ECHO])) - { - Format(buffer, sizeof(buffer), "Player '%s' attempted suicide.", clientname); - ZR_PrintToAdminChat(buffer); - } - - return Plugin_Handled; -} \ No newline at end of file diff --git a/src/zr/event.inc b/src/zr/event.inc index 1b1c8f9..4d0455e 100644 --- a/src/zr/event.inc +++ b/src/zr/event.inc @@ -54,9 +54,6 @@ public Action:RoundStart(Handle:event, const String:name[], bool:dontBroadcast) bZombie[x] = false; } - // Balance teams, and respawn all players. - BalanceTeams(true); - ZR_PrintToChat(0, "Round objective"); // Forward event to sub-modules. @@ -107,9 +104,6 @@ public Action:RoundEnd(Handle:event, const String:name[], bool:dontBroadcast) bZombie[x] = false; } - // Balance teams. - BalanceTeams(); - // Forward event to modules. RoundEndOnRoundEnd(reason); ZTeleReset(); diff --git a/src/zr/hitgroups.inc b/src/zr/hitgroups.inc index 54d1e98..7efce45 100644 --- a/src/zr/hitgroups.inc +++ b/src/zr/hitgroups.inc @@ -5,7 +5,6 @@ * * File: hitgroup.inc * Description: API for loading hitgroup specific settings. - * Author: Greyscale, Richard Helgeby * * ============================================================================ */ diff --git a/src/zr/menu.inc b/src/zr/menu.inc index dd8d652..fb0e64b 100644 --- a/src/zr/menu.inc +++ b/src/zr/menu.inc @@ -97,80 +97,4 @@ public MainMenuHandle(Handle:menu_main, MenuAction:action, client, slot) { CloseHandle(menu_main); } -} - -/**ClassMenu(client) -{ - new Handle:menu_classes = CreateMenu(ClassMenuHandle); - - decl String:menu_description[256]; - decl String:display[288]; // 32 + 256 - - SetGlobalTransTarget(client); - - SetMenuTitle(menu_classes, "%t\n ", "!zclass title"); - - for (new x = 0; x < classCount; x++) - { - GetClassName(x, display, sizeof(display)); - GetClassMenuDescription(x, menu_description, sizeof(menu_description)); - - if (pNextClass[client] == -1) - { - if (x == pClass[client]) - { - Format(display, sizeof(display), "%s (current)", display); - } - } - else if (x == pNextClass[client]) - { - Format(display, sizeof(display), "%s (current)", display); - } - - Format(display, sizeof(display), "%s\n %s", display, menu_description); - - AddMenuItem(menu_classes, "", display); - } - - SetMenuExitBackButton(menu_classes, true); - - DisplayMenu(menu_classes, client, MENU_TIME_FOREVER); -} - -public ClassMenuHandle(Handle:menu_classes, MenuAction:action, client, slot) -{ - if (action == MenuAction_Select) - { - if (IsPlayerHuman(client) || !IsPlayerAlive(client)) - { - Call_StartForward(hOnZClassChanged); - Call_PushCell(client); - Call_PushCell(pClass[client]); - Call_PushCell(slot); - Call_Finish(); - - pClass[client] = slot; - } - else - { - pNextClass[client] = slot; - } - - decl String:name[64]; - GetClassName(slot, name, sizeof(name)); - - ZR_PrintToChat(client, "Class select", name); - } - - if (action == MenuAction_Cancel) - { - if (slot == MenuCancel_ExitBack) - { - MainMenu(client); - } - } - else if (action == MenuAction_End) - { - CloseHandle(menu_classes); - } -}*/ +} \ No newline at end of file diff --git a/src/zr/roundend.inc b/src/zr/roundend.inc index 30f911a..57f9c43 100644 --- a/src/zr/roundend.inc +++ b/src/zr/roundend.inc @@ -76,6 +76,17 @@ RoundEndOnMapStart() tRoundEnd = INVALID_HANDLE; } +/** + * Client is joining the server. + * + * @param client The client index. + */ +RoundEndClientInit(client) +{ + // Get client's DX level. + RoundEndGetClientDXLevel(client); +} + /** * The round is starting. */ @@ -90,6 +101,9 @@ RoundEndOnRoundStart() // Reset timer handle. tRoundEnd = INVALID_HANDLE; } + + // Balance teams, and respawn all players. + RoundEndBalanceTeams(true); } /** @@ -130,6 +144,9 @@ RoundEndOnRoundEnd(reason) // Display the overlay to all clients. RoundEndOverlayStart(ROUNDEND_DELAY_NORMAL, outcome); + + // Balance teams. + RoundEndBalanceTeams(); } /** @@ -298,6 +315,75 @@ RoundEndTerminateRound(RoundEndOutcome:outcome) } } +/** + * Balances teams + * + * @param spawn If true, it will respawn player after switching their team. + */ +RoundEndBalanceTeams(bool:spawn = false) +{ + // Create eligible player list. + new Handle:arrayEligibleClients = INVALID_HANDLE; + new eligibleclients = CreateEligibleClientList(arrayEligibleClients, true); + + // If there are no eligible client's then stop. + if (!eligibleclients) + { + return; + } + + new client; + + // Move all clients to T + + // x = array index. + // client = client index. + for (new x = 0; x < eligibleclients; x++) + { + // Get client stored in array index. + client = GetArrayCell(arrayEligibleClients, x); + + // Switch client to T + CS_SwitchTeam(client, CS_TEAM_T); + } + + // Move every other client back to CT + + // x = array index + // client = client index. + for (new x = 0; x < eligibleclients; x += 2) + { + // Get client stored in array index. + client = GetArrayCell(arrayEligibleClients, x); + + // Switch client to CT + CS_SwitchTeam(client, CS_TEAM_CT); + } + + // If spawn is false, then stop. + if (!spawn) + { + return; + } + + // x = array index. + // client = client index. + for (new x = 0; x < eligibleclients; x++) + { + // Get client stored in array index. + client = GetArrayCell(arrayEligibleClients, x); + + // If client is dead, then stop. + if (!IsPlayerAlive(client)) + { + continue; + } + + // Respawn client. + CS_RespawnPlayer(client); + } +} + /** * Displays overlay to client, or prints unsupported message on client's screen. * diff --git a/src/zr/weapons/weapons.inc b/src/zr/weapons/weapons.inc index e54426f..e311e90 100644 --- a/src/zr/weapons/weapons.inc +++ b/src/zr/weapons/weapons.inc @@ -101,7 +101,7 @@ WeaponsValidateConfig() * Client is joining the server. * * @param client The client index. - */ + */ WeaponsClientInit(client) { // Forward event to sub-module. @@ -112,7 +112,7 @@ WeaponsClientInit(client) * Client is leaving the server. * * @param client The client index. - */ + */ WeaponsOnClientDisconnect(client) { // Forward event to sub-module. diff --git a/src/zr/zadmin.inc b/src/zr/zadmin.inc index 3232f89..e8a3ab6 100644 --- a/src/zr/zadmin.inc +++ b/src/zr/zadmin.inc @@ -523,7 +523,7 @@ ZRLogFlagsMenu(client) decl String:z_log_module_hitgroups[64]; decl String:z_log_module_commands[64]; decl String:z_log_module_anticamp[64]; - decl String:z_log_module_damagecontrol[64]; + decl String:z_log_module_damage[64]; decl String:z_log_module_offsets[64]; Format(z_log_core, sizeof(z_log_core), "Log core events (%d)", LogHasFlag(LOG_CORE_EVENTS)); @@ -546,7 +546,7 @@ ZRLogFlagsMenu(client) Format(z_log_module_hitgroups, sizeof(z_log_module_hitgroups), "Hitgroups (%d)", LogHasFlag(LOG_MODULE_HITGROUPS)); Format(z_log_module_commands, sizeof(z_log_module_commands), "Admin commands (%d)", LogHasFlag(LOG_MODULE_COMMANDS)); Format(z_log_module_anticamp, sizeof(z_log_module_anticamp), "Anticamp (%d)", LogHasFlag(LOG_MODULE_ANTICAMP)); - Format(z_log_module_damagecontrol, sizeof(z_log_module_damagecontrol), "Damage control (suicides) (%d)", LogHasFlag(LOG_MODULE_DAMAGECONTROL)); + Format(z_log_module_damage, sizeof(z_log_module_damage), "Damage (Suicide Intercept) (%d)", LogHasFlag(LOG_MODULE_DAMAGE)); Format(z_log_module_offsets, sizeof(z_log_module_offsets), "Offsets (properties) (%d)", LogHasFlag(LOG_MODULE_OFFSETS)); AddMenuItem(menu_log_flags, z_log_core, z_log_core, item_state); @@ -568,7 +568,7 @@ ZRLogFlagsMenu(client) AddMenuItem(menu_log_flags, z_log_module_weapons, z_log_module_weapons, item_state); AddMenuItem(menu_log_flags, z_log_module_commands, z_log_module_commands, item_state); AddMenuItem(menu_log_flags, z_log_module_anticamp, z_log_module_anticamp, item_state); - AddMenuItem(menu_log_flags, z_log_module_damagecontrol, z_log_module_damagecontrol, item_state); + AddMenuItem(menu_log_flags, z_log_module_damage, z_log_module_damage, item_state); AddMenuItem(menu_log_flags, z_log_module_offsets, z_log_module_offsets, item_state); SetMenuExitBackButton(menu_log_flags, true); @@ -683,7 +683,7 @@ public ZRLogFlagsMenuHandle(Handle:menu_log_flags, MenuAction:action, client, sl } case 20: { - ToggleLogFlag(LOG_MODULE_DAMAGECONTROL); + ToggleLogFlag(LOG_MODULE_DAMAGE); ZRLogFlagsMenu(client); } case 21: diff --git a/src/zr/zombie.inc b/src/zr/zombie.inc index 7e55301..2f4f2f6 100644 --- a/src/zr/zombie.inc +++ b/src/zr/zombie.inc @@ -457,68 +457,6 @@ PlayerLeft(client) CloseHandle(arrayEligibleClients); } -/** - * Balances teams - * - * @param spawn If true, it will respawn player after switching their team. - */ -BalanceTeams(bool:spawn = false) -{ - // Create eligible player list. - new Handle:arrayEligibleClients = INVALID_HANDLE; - new eligibleclients = CreateEligibleClientList(arrayEligibleClients, true); - - // If there are no eligible client's then stop. - if (!eligibleclients) - { - return; - } - - new client; - - // Move all clients to T - - // x = array index. - // client = client index. - for (new x = 0; x < eligibleclients; x++) - { - // Get client stored in array index. - client = GetArrayCell(arrayEligibleClients, x); - - // Switch client to T - CS_SwitchTeam(client, CS_TEAM_T); - - // If spawn is false, then stop. - if (!spawn) - { - continue; - } - - CS_RespawnPlayer(client); - } - - // Move every other client back to CT - - // x = array index - // client = client index. - for (new x = 0; x < eligibleclients; x += 2) - { - // Get client stored in array index. - client = GetArrayCell(arrayEligibleClients, x); - - // Switch client to CT - CS_SwitchTeam(client, CS_TEAM_CT); - - // If spawn is false, then stop. - if (!spawn) - { - continue; - } - - CS_RespawnPlayer(client); - } -} - RemoveObjectives() { decl String:classname[64]; diff --git a/src/zr/zombiereloaded.inc b/src/zr/zombiereloaded.inc index 93e8281..eecf981 100644 --- a/src/zr/zombiereloaded.inc +++ b/src/zr/zombiereloaded.inc @@ -32,7 +32,7 @@ #define LOG_MODULE_WEAPONS 262144 /** Weapons module - weapons/ *.inc */ #define LOG_MODULE_HITGROUPS 524288 /** hitgroups.inc */ #define LOG_MODULE_ANTICAMP 1048576 /** anticamp.inc */ -#define LOG_MODULE_DAMAGECONTROL 2097152 /** damagecontrol.inc */ +#define LOG_MODULE_DAMAGE 2097152 /** damage.inc */ #define LOG_MODULE_OFFSETS 4194304 /** offsets.inc */ /* * @endsection