#include <amxmodx>
#include <engine>
#include <fakemeta>
#include <hamsandwich>
#include <cstrike>
#define PLUGIN "CT Bomb Defusing"
#define VERSION "1.0"
#define AUTHOR "voed"
//#define ROUNDCONTROL // закомментируйте, если хотите использовать плагин без модуля round control
#if defined ROUNDCONTROL
#include <roundcontrol>
#endif
#define DMG_RADIUS 400.0
#define TIME 30
new bool:g_defusing, g_defused // начало и конец дефьюзинга
new g_defuser, g_defusetime // id дефьюзера и время для таска
new msg_bartime
new Float:bombOrigin[3], bombEnt // координаты и ID энтити бомбы
new gMaxPlayers, gMessageDeathMsg
new g_iSpiteExlplosion
public plugin_precache()
{
g_iSpiteExlplosion = precache_model("sprites/eexplo.spr")
}
public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHOR)
msg_bartime = get_user_msgid("BarTime")
gMaxPlayers = get_maxplayers()
gMessageDeathMsg = get_user_msgid( "DeathMsg" )
register_forward(FM_CmdStart, "fw_cmdstart")
register_logevent("bomb_planted", 3, "2=Planted_The_Bomb")
register_message(gMessageDeathMsg, "evDeathMsg")
register_logevent("round_end", 2, "1=Round_End")
}
public round_end()
{
if(g_defused)
canceldefuse(g_defuser)
}
public evDeathMsg()
{
new victim = get_msg_arg_int(2)
new killer = get_msg_arg_int(1)
if(g_defusing && (g_defuser == victim) && (g_defusetime < (TIME * 2))) // если дефьюзера убили во время дефьюза, отменить дефьюз
{
canceldefuse(g_defuser)
}
#if !defined ROUNDCONTROL
if(g_defused && (killer == victim)) // скрыть сообщения о суициде
return PLUGIN_HANDLED
#endif
return PLUGIN_CONTINUE
}
public canceldefuse(id)
{
g_defusing = false
g_defused = false
g_defuser = 0
g_defusetime = 0
if(is_user_connected(id))
bartime(id, 0)
if(task_exists(id))
{
remove_task(id)
}
return PLUGIN_CONTINUE
}
public fw_cmdstart(id)
{
if(g_defused)
return
if(pev(id, pev_button) & IN_USE)
{
if(!is_user_alive(id) || !(get_user_team(id) == 2) || (g_defusing && g_defuser != id))
{
return
}
new Float:PlayerOrigin[3]
new Float:BombOrigin[3]
new bomb = engfunc( EngFunc_FindEntityByString, 0, "model", "models/w_backpack.mdl" )
if(pev_valid(bomb))
{
pev(bomb, pev_origin, BombOrigin)
pev(id, pev_origin, PlayerOrigin)
new Float:dist = get_distance_f(BombOrigin, PlayerOrigin)
if( dist > 50 )
{
canceldefuse(id)
return
}
if(g_defusing)
return
g_defusing = true
g_defuser = id
set_task(0.5, "task_defuse", id, _, _, "b")
bartime(id, TIME)
}
}
else if (g_defusing && g_defuser == id)
{
canceldefuse(id)
}
}
public task_defuse(id)
{
g_defusetime++
if(g_defusetime/2 >= TIME)
{
new CsTeams:player_team = cs_get_user_team(id)
new name[33]
get_user_name(id, name, charsmax(name))
static i
for(i=0; i<33;i++)
{
if(is_user_connected(i) && cs_get_user_team(i) == player_team)
{
client_print(i, print_center, "%s defused the bomb!", name)
}
}
canceldefuse(id)
g_defused = true
}
}
public bomb_planted()
{
if(!g_defused)
return PLUGIN_CONTINUE
bombEnt = engfunc( EngFunc_FindEntityByString, 0, "model", "models/w_c4.mdl" )
if ( !pev_valid( bombEnt ) )
return PLUGIN_CONTINUE
pev(bombEnt, pev_origin, bombOrigin)
//set_pdata_float(bombEnt, 100, 0.0)
draw_explosion(bombOrigin)
UTIL_Blast_ExplodeDamage(bombEnt, 400.0, DMG_RADIUS)
remove_entity(bombEnt)
#if defined ROUNDCONTROL
RoundEndForceControl()
#else
force_ctwin()
#endif
g_defuser = 0
g_defusing = false
return PLUGIN_CONTINUE
}
stock force_ctwin()
{
new g_players[32], num;
get_players(g_players, num);
new x;
for(new i = 0; i < num; i++)
{
x = g_players[i];
if(cs_get_user_team(x) == CS_TEAM_CT)
continue
user_silentkill(x);
cs_set_user_deaths(x, get_user_deaths(x) - 1)
}
}
stock bartime(id, time)
{
message_begin(MSG_ONE_UNRELIABLE, msg_bartime, _, id)
write_short(time)
message_end()
}
stock draw_explosion(Float:origin[3])
{
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
{
write_byte(TE_EXPLOSION);
write_coord(floatround(origin[0])) // x
write_coord(floatround(origin[1])) // y
write_coord(floatround(origin[2])) // z
write_short(g_iSpiteExlplosion) // sprite
write_byte(30) // sprite size
write_byte(10) // animation speed
write_byte(0)
}
message_end()
return PLUGIN_HANDLED;
}
stock UTIL_Blast_ExplodeDamage( entid, Float:damage, Float:range )
{
new Float:flOrigin1[ 3 ];
entity_get_vector( entid, EV_VEC_origin, flOrigin1 )
new Float:flDistance
new Float:flTmpDmg
new Float:flOrigin2[ 3 ]
for( new i = 1; i <= gMaxPlayers; i++ )
{
if( is_user_alive( i ) )
{
entity_get_vector( i, EV_VEC_origin, flOrigin2 )
flDistance = get_distance_f( flOrigin1, flOrigin2 )
static const szWeaponName[] = "c4"
if( flDistance <= range )
{
flTmpDmg = damage - ( damage / range ) * flDistance
fakedamage( i, szWeaponName, flTmpDmg, DMG_BLAST )
message_begin( MSG_BROADCAST, gMessageDeathMsg )
write_byte( g_defuser )
write_byte( i )
write_byte( 0 )
write_string( szWeaponName )
message_end()
}
}
}
}
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1049\\ f0\\ fs16 \n\\ par }
*/