/* * CSB Paintball * Copyright (C) 2026 counter-strike-boost.com * * Turns bullets into paint. In a Ham_TraceAttack hook every shot draws a coloured * beam from the shooter to the impact point and stamps a decal there, with each * player assigned a colour. Damage can be normalised to a fixed value or set to a * guaranteed one-hit kill. * * Inspired by Paintball Mod by dnz. 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. 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 new const PLUGIN[] = "CSB Paintball" new const VERSION[] = "1.0.0" new const AUTHOR[] = "counter-strike-boost.com" new g_pEnabled, g_pOneHit, g_pDamage new g_iBeamSpr new const g_iColors[][3] = { { 255, 40, 40 }, { 40, 120, 255 }, { 40, 255, 80 }, { 255, 220, 40 }, { 255, 40, 255 }, { 40, 255, 255 }, { 255, 140, 20 }, { 200, 200, 200 } } public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR) g_pEnabled = register_cvar("csb_pb_enabled", "1") g_pOneHit = register_cvar("csb_pb_onehit", "0") g_pDamage = register_cvar("csb_pb_damage", "35.0") RegisterHam(Ham_TraceAttack, "player", "fwTraceAttack", 0) } public plugin_precache() { g_iBeamSpr = precache_model("sprites/laserbeam.spr") } public fwTraceAttack(victim, attacker, Float:damage, Float:direction[3], ptr, damagebits) { if (!get_pcvar_num(g_pEnabled)) return HAM_IGNORED if (attacker < 1 || attacker > 32 || !is_user_connected(attacker)) return HAM_IGNORED static Float:fEye[3], Float:fOfs[3], Float:fEnd[3] pev(attacker, pev_origin, fEye) pev(attacker, pev_view_ofs, fOfs) fEye[0] += fOfs[0] fEye[1] += fOfs[1] fEye[2] += fOfs[2] get_tr2(ptr, TR_vecEndPos, fEnd) new c = attacker % sizeof(g_iColors) /* paint beam from muzzle to impact */ message_begin(MSG_BROADCAST, SVC_TEMPENTITY) write_byte(TE_BEAMPOINTS) engfunc(EngFunc_WriteCoord, fEye[0]) engfunc(EngFunc_WriteCoord, fEye[1]) engfunc(EngFunc_WriteCoord, fEye[2]) engfunc(EngFunc_WriteCoord, fEnd[0]) engfunc(EngFunc_WriteCoord, fEnd[1]) engfunc(EngFunc_WriteCoord, fEnd[2]) write_short(g_iBeamSpr) write_byte(0) write_byte(0) write_byte(4) write_byte(12) write_byte(0) write_byte(g_iColors[c][0]) write_byte(g_iColors[c][1]) write_byte(g_iColors[c][2]) write_byte(200) write_byte(0) message_end() /* paint splat at impact */ message_begin(MSG_BROADCAST, SVC_TEMPENTITY) write_byte(TE_GUNSHOTDECAL) engfunc(EngFunc_WriteCoord, fEnd[0]) engfunc(EngFunc_WriteCoord, fEnd[1]) engfunc(EngFunc_WriteCoord, fEnd[2]) write_short(victim > 0 ? victim : 0) write_byte(random_num(41, 45)) message_end() if (get_pcvar_num(g_pOneHit)) { SetHamParamFloat(3, 1000.0) } else { new Float:d = get_pcvar_float(g_pDamage) if (d > 0.0) SetHamParamFloat(3, d) } return HAM_IGNORED }