/* * CSB Ammo Packs * Copyright (C) 2026 counter-strike-boost.com * * An ammo-pack currency for zombie / boss servers. Packs are earned for kills, * headshots and round wins, persisted per SteamID in nVault, and exposed to * other plugins through natives (csb_get_packs / csb_set_packs / csb_add_packs) * so a shop or extra-items plugin can spend them. /packs shows the balance. * * Inspired by the ammo-pack economy of Zombie Plague. This is an independent * GPL re-implementation; no original code is reused. * * 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 the GNU General * Public License for more details: . */ #include #include #include new const PLUGIN[] = "CSB Ammo Packs" new const VERSION[] = "1.0.0" new const AUTHOR[] = "counter-strike-boost.com" #define NO_VAULT (-1) new g_iVault = NO_VAULT new g_iPacks[33] new g_szAuth[33][35] new bool:g_bLoaded[33] new g_pStart, g_pKill, g_pHeadshot, g_pRoundWin, g_pMax public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR) g_pStart = register_cvar("csb_packs_start", "5") g_pKill = register_cvar("csb_packs_kill", "1") g_pHeadshot = register_cvar("csb_packs_headshot", "1") g_pRoundWin = register_cvar("csb_packs_roundwin", "2") g_pMax = register_cvar("csb_packs_max", "1000000") register_event("DeathMsg", "eDeath", "a") register_event("SendAudio", "eTerWin", "a", "2&%!MRAD_terwin") register_event("SendAudio", "eCtWin", "a", "2&%!MRAD_ctwin") register_clcmd("say /packs", "cmdPacks") register_clcmd("say_team /packs", "cmdPacks") register_clcmd("csb_packs", "cmdPacks") register_concmd("csb_givepacks", "cmdGive", ADMIN_LEVEL_A, " ") } public plugin_natives() { register_native("csb_get_packs", "native_get_packs") register_native("csb_set_packs", "native_set_packs") register_native("csb_add_packs", "native_add_packs") } public plugin_cfg() { g_iVault = nvault_open("csb_ammo_packs") if (g_iVault == NO_VAULT) log_amx("[CSB Packs] could not open the nVault file 'csb_ammo_packs' - balances will not persist.") } public plugin_end() { if (g_iVault != NO_VAULT) nvault_close(g_iVault) } /* ---------- persistence ---------- */ public client_authorized(id) { g_bLoaded[id] = false g_iPacks[id] = 0 g_szAuth[id][0] = 0 if (is_user_bot(id) || is_user_hltv(id)) return get_user_authid(id, g_szAuth[id], charsmax(g_szAuth[])) new value[16] if (g_iVault != NO_VAULT && nvault_get(g_iVault, g_szAuth[id], value, charsmax(value))) g_iPacks[id] = str_to_num(value) else g_iPacks[id] = get_pcvar_num(g_pStart) g_bLoaded[id] = true } public client_disconnected(id) { savePacks(id) g_bLoaded[id] = false g_szAuth[id][0] = 0 } savePacks(id) { if (g_iVault == NO_VAULT || !g_bLoaded[id] || !g_szAuth[id][0]) return new value[16] num_to_str(g_iPacks[id], value, charsmax(value)) nvault_pset(g_iVault, g_szAuth[id], value) } /* ---------- earning ---------- */ givePacks(id, amount) { if (id < 1 || id > 32 || !g_bLoaded[id] || amount == 0) return new maxPacks = get_pcvar_num(g_pMax) g_iPacks[id] += amount if (g_iPacks[id] < 0) g_iPacks[id] = 0 if (maxPacks > 0 && g_iPacks[id] > maxPacks) g_iPacks[id] = maxPacks savePacks(id) } public eDeath() { new killer = read_data(1) new victim = read_data(2) new headshot = read_data(3) if (killer < 1 || killer > 32 || killer == victim || !is_user_connected(killer)) return new reward = get_pcvar_num(g_pKill) if (headshot) reward += get_pcvar_num(g_pHeadshot) if (reward > 0) { givePacks(killer, reward) client_print(killer, print_center, "+%d ammo pack(s)", reward) } } public eTerWin() { awardTeam(1) } public eCtWin() { awardTeam(2) } awardTeam(team) { new reward = get_pcvar_num(g_pRoundWin) if (reward <= 0) return new players[32], num get_players(players, num, "ae") for (new i = 0; i < num; i++) { new id = players[i] if (get_user_team(id) == team) givePacks(id, reward) } } /* ---------- commands ---------- */ public cmdPacks(id) { client_print(id, print_chat, "[CSB] You have %d ammo pack(s).", g_iPacks[id]) return PLUGIN_HANDLED } public cmdGive(id, level, cid) { if (!cmd_access(id, level, cid, 3)) return PLUGIN_HANDLED new arg[32], amtArg[16] read_argv(1, arg, charsmax(arg)) read_argv(2, amtArg, charsmax(amtArg)) new target = cmd_target(id, arg, 0) if (!target) return PLUGIN_HANDLED new amount = str_to_num(amtArg) givePacks(target, amount) new tname[32] get_user_name(target, tname, charsmax(tname)) console_print(id, "[CSB] %s now has %d ammo pack(s).", tname, g_iPacks[target]) return PLUGIN_HANDLED } /* ---------- natives ---------- */ public native_get_packs(plugin, params) { new id = get_param(1) if (id < 1 || id > 32) return 0 return g_iPacks[id] } public native_set_packs(plugin, params) { new id = get_param(1) new amount = get_param(2) if (id < 1 || id > 32) return 0 g_iPacks[id] = amount < 0 ? 0 : amount savePacks(id) return 1 } public native_add_packs(plugin, params) { new id = get_param(1) new amount = get_param(2) if (id < 1 || id > 32) return 0 givePacks(id, amount) return g_iPacks[id] }