/* * CSB VIP Objective Mod * Copyright (C) 2026 counter-strike-boost.com * * An assassination-style objective for any map. Each round a random CT becomes * the VIP: a glowing, heavily armored player with only a knife. CTs win by * escorting the VIP into an escape zone, and Terrorists win by killing them. * Escape zones are read from a per-map data file and checked in PlayerPreThink. * * 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. It 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 for details. */ #include #include #include #include #include new const PLUGIN[] = "CSB VIP Objective Mod" new const VERSION[] = "1.0.0" new const AUTHOR[] = "counter-strike-boost.com" #define MAX_ZONES 8 new g_pEnabled, g_pArmor new Float:g_fZone[MAX_ZONES][3] new Float:g_fZoneRadius[MAX_ZONES] new g_iZoneCount new g_iVip new bool:g_bRoundOver new g_iHudSync public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR) g_pEnabled = register_cvar("csb_vip_enabled", "1") g_pArmor = register_cvar("csb_vip_armor", "200") register_logevent("eventRoundStart", 2, "1=Round_Start") register_event("DeathMsg", "eventDeath", "a", "1>0") register_forward(FM_PlayerPreThink, "fwPreThink") g_iHudSync = CreateHudSyncObj() set_task(1.0, "taskHud", 0, _, _, "b") } public plugin_cfg() { loadZones() } loadZones() { g_iZoneCount = 0 new map[32] get_mapname(map, charsmax(map)) new dir[128], path[192] get_localinfo("amxx_configsdir", dir, charsmax(dir)) if (!dir[0]) copy(dir, charsmax(dir), "addons/amxmodx/configs") formatex(path, charsmax(path), "%s/csb_vip/%s.ini", dir, map) if (!file_exists(path)) return new line[96], len, pos = 0 while (g_iZoneCount < MAX_ZONES && (pos = read_file(path, pos, line, charsmax(line), len))) { trim(line) if (!line[0] || line[0] == ';' || line[0] == '#') continue new sx[16], sy[16], sz[16], sr[16] parse(line, sx, charsmax(sx), sy, charsmax(sy), sz, charsmax(sz), sr, charsmax(sr)) if (!sx[0] || !sy[0] || !sz[0]) continue g_fZone[g_iZoneCount][0] = str_to_float(sx) g_fZone[g_iZoneCount][1] = str_to_float(sy) g_fZone[g_iZoneCount][2] = str_to_float(sz) g_fZoneRadius[g_iZoneCount] = sr[0] ? str_to_float(sr) : 100.0 g_iZoneCount++ } } public eventRoundStart() { g_iVip = 0 g_bRoundOver = false if (!get_pcvar_num(g_pEnabled)) return set_task(2.5, "taskPickVip", 6161) } public taskPickVip() { /* pick a random alive CT */ new cts[32], num = 0 new players[32], total get_players(players, total, "ae", "CT") for (new i = 0; i < total; i++) cts[num++] = players[i] if (num == 0) return new vip = cts[random_num(0, num - 1)] makeVip(vip) } makeVip(id) { g_iVip = id strip_user_weapons(id) give_item(id, "weapon_knife") set_user_armor(id, get_pcvar_num(g_pArmor)) set_user_rendering(id, kRenderFxGlowShell, 255, 215, 0, kRenderNormal, 180) new name[32] get_user_name(id, name, charsmax(name)) client_print(0, print_chat, "^x04[VIP]^x01 %s is the VIP! CTs escort them to the escape zone, Ts hunt them down.", name) } public eventDeath() { new victim = read_data(2) if (victim != g_iVip || g_bRoundOver) return g_bRoundOver = true client_print(0, print_chat, "^x04[VIP]^x01 The VIP is dead - Terrorists win the objective!") set_task(2.0, "taskEndRound") } public fwPreThink(id) { if (g_bRoundOver || id != g_iVip || g_iZoneCount == 0) return if (!is_user_alive(id)) return static Float:fPos[3] pev(id, pev_origin, fPos) for (new z = 0; z < g_iZoneCount; z++) { new Float:dx = fPos[0] - g_fZone[z][0] new Float:dy = fPos[1] - g_fZone[z][1] new Float:dz = fPos[2] - g_fZone[z][2] new Float:r = g_fZoneRadius[z] if (dx*dx + dy*dy + dz*dz < r * r) { g_bRoundOver = true client_print(0, print_chat, "^x04[VIP]^x01 The VIP escaped - Counter-Terrorists win the objective!") set_task(2.0, "taskEndRound") return } } } public taskEndRound() { server_cmd("sv_restartround 1") } public taskHud() { if (g_iVip == 0 || !is_user_alive(g_iVip)) return new name[32] get_user_name(g_iVip, name, charsmax(name)) set_hudmessage(255, 215, 0, 0.02, 0.14, 0, 0.0, 1.1, 0.0, 0.0, -1) ShowSyncHudMsg(0, g_iHudSync, "VIP: %s (%d HP / %d AP)", name, get_user_health(g_iVip), get_user_armor(g_iVip)) }