/* * CSB Prop Hunt * Copyright (C) 2026 counter-strike-boost.com * * Prop Hunt. Hiders (Terrorists) are disguised as map props: their player model * is swapped to a chosen prop model and its animation is frozen, so a still hider * blends in with the scenery. Seekers (CTs) are frozen for a countdown, then hunt * them down. A recurring taunt plays a sound and briefly glows every hider so the * round always ends. * * 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 new const PLUGIN[] = "CSB Prop Hunt" new const VERSION[] = "1.0.0" new const AUTHOR[] = "counter-strike-boost.com" new const g_szProps[][] = { "models/w_backpack.mdl", "models/w_kevlar.mdl", "models/w_smokegrenade.mdl", "models/w_flashbang.mdl" } #define TAUNT_SOUND "items/suitchargeok1.wav" new g_pEnabled, g_pHiderTeam, g_pCountdown, g_pTaunt new bool:g_bHider[33] new bool:g_bHunting new g_iHudSync new g_iValidProps public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR) g_pEnabled = register_cvar("csb_ph_enabled", "1") g_pHiderTeam = register_cvar("csb_ph_hiderteam", "1") /* 1=T 2=CT */ g_pCountdown = register_cvar("csb_ph_countdown", "15") g_pTaunt = register_cvar("csb_ph_taunt", "25") RegisterHam(Ham_Spawn, "player", "fwSpawnPost", 1) register_event("DeathMsg", "eventDeath", "a", "1>0") register_logevent("eventRoundStart", 2, "1=Round_Start") g_iHudSync = CreateHudSyncObj() set_task(1.0, "taskTauntLoop", 0, _, _, "b") } public plugin_precache() { g_iValidProps = 0 for (new i = 0; i < sizeof(g_szProps); i++) { if (file_exists(g_szProps[i])) { engfunc(EngFunc_PrecacheModel, g_szProps[i]) g_iValidProps++ } } precache_sound(TAUNT_SOUND) } public eventRoundStart() { g_bHunting = false if (!get_pcvar_num(g_pEnabled)) return set_task(2.5, "taskAssign", 8181) } public taskAssign() { new hiderTeam = get_pcvar_num(g_pHiderTeam) new players[32], num get_players(players, num, "a") for (new i = 0; i < num; i++) { new id = players[i] if (get_user_team(id) == hiderTeam) makeHider(id) else set_user_maxspeed(id, 1.0) /* freeze seekers during countdown */ } client_print(0, print_chat, "^x04[PropHunt]^x01 Hiders, disguise! Seekers unfreeze in %d seconds.", get_pcvar_num(g_pCountdown)) set_task(float(get_pcvar_num(g_pCountdown)), "taskRelease", 8282) } public fwSpawnPost(id) { g_bHider[id] = false } makeHider(id) { if (!is_user_alive(id)) return g_bHider[id] = true if (g_iValidProps > 0) { new pick = pickValidProp() if (pick >= 0) { engfunc(EngFunc_SetModel, id, g_szProps[pick]) set_pev(id, pev_sequence, 0) set_pev(id, pev_framerate, 0.0) } } client_print(id, print_chat, "[CSB] You are a prop. Stay still to blend in.") } pickValidProp() { /* choose a random model that actually exists */ new tries = 0 while (tries < 20) { new i = random_num(0, sizeof(g_szProps) - 1) if (file_exists(g_szProps[i])) return i tries++ } return -1 } public taskRelease() { g_bHunting = true new players[32], num get_players(players, num, "a") for (new i = 0; i < num; i++) { if (!g_bHider[players[i]]) set_user_maxspeed(players[i], 250.0) } client_print(0, print_chat, "^x04[PropHunt]^x01 The hunt is on!") } public eventDeath() { new victim = read_data(2) if (victim >= 1 && victim <= 32 && g_bHider[victim]) g_bHider[victim] = false } public taskTauntLoop() { static counter counter++ if (!g_bHunting) { counter = 0 return } new interval = get_pcvar_num(g_pTaunt) if (interval < 5) interval = 5 if (counter % interval == 0) taunt() /* HUD */ new hiders = countHiders() set_hudmessage(0, 200, 255, 0.02, 0.12, 0, 0.0, 1.1, 0.0, 0.0, -1) ShowSyncHudMsg(0, g_iHudSync, "Props left: %d", hiders) } taunt() { new players[32], num get_players(players, num, "a") for (new i = 0; i < num; i++) { new id = players[i] client_cmd(id, "play %s", TAUNT_SOUND) if (g_bHider[id]) { /* briefly reveal */ set_user_rendering(id, kRenderFxGlowShell, 255, 180, 0, kRenderNormal, 120) set_task(1.5, "taskUnglow", id) } } } public taskUnglow(id) { if (is_user_connected(id)) set_user_rendering(id, kRenderFxNone, 0, 0, 0, kRenderNormal, 0) } countHiders() { new c = 0 for (new id = 1; id <= 32; id++) if (g_bHider[id] && is_user_alive(id)) c++ return c }