/* * CSB Zombie Core * Copyright (C) 2026 counter-strike-boost.com * * A Zombie Plague style infection core. After a short countdown a random * player is turned into the first zombie: knife only, scaled health, speed and * gravity, and a zombie model. Zombies are Terrorists, humans are Counter- * Terrorists, so the round ends naturally when one side is wiped out. Knifing * a human converts them. Other plugins hook in through the exposed natives * (csb_is_zombie, csb_infect, csb_make_human). * * Inspired by Zombie Plague by MeRcyLeZZ. Independent GPL re-implementation. * * 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. Distributed WITHOUT ANY WARRANTY. See the GNU General * Public License for more details: . */ #include #include #include #include new const PLUGIN[] = "CSB Zombie Core" new const VERSION[] = "1.0.0" new const AUTHOR[] = "counter-strike-boost.com" #define TASK_RELEASE 4321 new g_pEnabled, g_pReleaseDelay, g_pZombieHp, g_pZombieSpeed, g_pZombieGravity, g_pModel new bool:g_bZombie[33] new bool:g_bRoundActive new g_iMaxPlayers new Forward:g_fwInfected public plugin_precache() { // Zombie model must be installed as models/player/zombie_source/*. // Nothing to precache for the player model itself here. } public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR) g_pEnabled = register_cvar("csb_zm_enabled", "1") g_pReleaseDelay = register_cvar("csb_zm_release_delay", "15.0") g_pZombieHp = register_cvar("csb_zm_zombie_hp", "1500") g_pZombieSpeed = register_cvar("csb_zm_zombie_speed", "270") g_pZombieGravity = register_cvar("csb_zm_zombie_gravity", "0.80") g_pModel = register_cvar("csb_zm_model", "zombie_source") RegisterHam(Ham_Spawn, "player", "fwSpawnPost", 1) RegisterHam(Ham_TakeDamage, "player", "fwTakeDamage", 0) register_event("HLTV", "evNewRound", "a", "1=0", "2=0") g_iMaxPlayers = get_maxplayers() // csb_zombie_infected(id, infector) -- infector is 0 for the first zombie g_fwInfected = CreateMultiForward("csb_zombie_infected", ET_IGNORE, FP_CELL, FP_CELL) set_task(1.0, "taskHud", _, _, _, "b") } public plugin_natives() { register_native("csb_is_zombie", "native_is_zombie", 1) register_native("csb_infect", "native_infect", 1) register_native("csb_make_human", "native_make_human", 1) } public native_is_zombie(plugin, params) { new id = get_param(1) if (id < 1 || id > g_iMaxPlayers) return 0 return g_bZombie[id] ? 1 : 0 } public native_infect(plugin, params) { new id = get_param(1) if (!is_user_alive(id)) return 0 makeZombie(id, 0) return 1 } public native_make_human(plugin, params) { new id = get_param(1) if (!is_user_connected(id)) return 0 makeHuman(id) return 1 } public client_disconnected(id) { g_bZombie[id] = false } public evNewRound() { if (!get_pcvar_num(g_pEnabled)) return g_bRoundActive = false remove_task(TASK_RELEASE) // Everyone starts human this round. for (new id = 1; id <= g_iMaxPlayers; id++) { if (!is_user_connected(id)) continue g_bZombie[id] = false } set_task(get_pcvar_float(g_pReleaseDelay), "taskFirstZombie", TASK_RELEASE) client_print(0, print_chat, "[Zombie] The infection begins in %d seconds. Run!", get_pcvar_num(g_pReleaseDelay)) } public taskFirstZombie() { new candidates[32], num = 0 for (new id = 1; id <= g_iMaxPlayers; id++) { if (is_user_alive(id)) candidates[num++] = id } if (num < 2) { client_print(0, print_chat, "[Zombie] Not enough players to start the infection.") return } g_bRoundActive = true new pick = candidates[random_num(0, num - 1)] makeZombie(pick, 0) new name[32] get_user_name(pick, name, charsmax(name)) client_print(0, print_chat, "[Zombie] %s is the first zombie!", name) } public fwSpawnPost(id) { if (!get_pcvar_num(g_pEnabled) || !is_user_alive(id)) return // Freshly spawned players are human until infected. makeHuman(id) } public fwTakeDamage(victim, inflictor, attacker, Float:damage, damagebits) { if (!get_pcvar_num(g_pEnabled) || !g_bRoundActive) return HAM_IGNORED if (attacker < 1 || attacker > g_iMaxPlayers || attacker == victim) return HAM_IGNORED // Only a zombie's knife infects, and only a living human can be infected. if (!g_bZombie[attacker] || g_bZombie[victim] || !is_user_alive(victim)) return HAM_IGNORED makeZombie(victim, attacker) return HAM_SUPERCEDE // absorb the hit; infection replaces the damage } makeZombie(id, infector) { g_bZombie[id] = true if (cs_get_user_team(id) != CS_TEAM_T) cs_set_user_team(id, CS_TEAM_T) strip_user_weapons(id) give_item(id, "weapon_knife") set_user_health(id, get_pcvar_num(g_pZombieHp)) set_user_gravity(id, get_pcvar_float(g_pZombieGravity)) set_user_maxspeed(id, get_pcvar_float(g_pZombieSpeed)) set_user_rendering(id, kRenderFxNone, 60, 120, 60, kRenderNormal, 20) new model[32] get_pcvar_string(g_pModel, model, charsmax(model)) if (model[0]) cs_set_user_model(id, model) new ret ExecuteForward(g_fwInfected, ret, id, infector) checkRoundBalance() } makeHuman(id) { g_bZombie[id] = false if (is_user_alive(id) && cs_get_user_team(id) != CS_TEAM_CT) cs_set_user_team(id, CS_TEAM_CT) set_user_gravity(id, 1.0) set_user_maxspeed(id, 240.0) set_user_rendering(id, kRenderFxNone, 0, 0, 0, kRenderNormal, 16) cs_reset_user_model(id) if (is_user_alive(id)) { give_item(id, "weapon_knife") give_item(id, "weapon_usp") cs_set_user_bpammo(id, CSW_USP, 24) } } checkRoundBalance() { new zombies, humans for (new id = 1; id <= g_iMaxPlayers; id++) { if (!is_user_alive(id)) continue if (g_bZombie[id]) zombies++ else humans++ } if (zombies == 0 && humans > 0) client_print(0, print_chat, "[Zombie] Humans have survived the outbreak!") else if (humans == 0 && zombies > 0) client_print(0, print_chat, "[Zombie] The zombies have consumed everyone!") } public taskHud() { if (!get_pcvar_num(g_pEnabled)) return new zombies, humans for (new id = 1; id <= g_iMaxPlayers; id++) { if (!is_user_alive(id)) continue if (g_bZombie[id]) zombies++ else humans++ } set_hudmessage(60, 200, 60, 0.02, 0.90, 0, 0.0, 1.1, 0.0, 0.0, -1) show_hudmessage(0, "Zombies: %d Humans: %d", zombies, humans) }