This plugin allows flashbang effects to work as if there are no walls between you and the flashbang.
There is only one problem. It doesn't make it partial alpha if you aren't looking at it.
PHP Code:
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <hamsandwich>
// From testing, I got these results:
//
// Max distance was ~1460
// Max duration was 12
//
// Duration - max / (max - distance)
// HoldTime - 1 ( in register_message(), holdtime is not 1, but it is in register_event() )
// Flags - 0
// Red - 255
// Green - 255
// Blue - 255
// Alpha - 255 (200 if angle of aim is 90 degrees or more away from the flashbang)
#define seconds_to_units(%1) (%1 * (1<<12))
#define MAX_DISTANCE 1460
#define MAX_DURATION 12
#define FLASH_HOLDTIME_FAKE 1
#define FLASH_FLAGS 0
#define FLASH_RED 255
#define FLASH_GREEN 255
#define FLASH_BLUE 255
#define FLASH_ALPHA1 200
#define FLASH_ALPHA2 255
new bool:g_allow_flashbang[33];
new g_flash_distance[33];
new ScreenFade;
new g_max_clients;
public plugin_init()
{
register_plugin("Flashbang Through Walls", "0.1", "Exolent");
RegisterHam(Ham_Think, "grenade", "FwdGrenadeThink");
register_message((ScreenFade = get_user_msgid("ScreenFade")), "MessageScreenFade");
g_max_clients = get_maxplayers();
}
public client_connect(client)
{
g_allow_flashbang[client] = false;
}
public FwdGrenadeThink(ent)
{
// HamSandwich should provide valid entities
// but I wanna be safe
if( !pev_valid(ent) ) return;
static Float:dmgtime;
pev(ent, pev_dmgtime, dmgtime);
if( dmgtime > get_gametime() ) return;
static model[32];
pev(ent, pev_model, model, sizeof(model) - 1);
if( containi(model, "flashbang") == -1 ) return;
// make sure we only detect 1 explosion per flash
if( pev(ent, pev_bInDuck) ) return;
set_pev(ent, pev_bInDuck, 1);
static Float:ent_origin[3];
pev(ent, pev_origin, ent_origin);
static alive, Float:client_origin[3], Float:angles[3];
for( new client = 1; client <= g_max_clients; client++ )
{
if( !is_user_connected(client) ) continue;
if( is_user_alive(client) )
{
alive = client;
}
else
{
alive = pev(client, pev_iuser1);
if( !is_user_alive(alive) )
{
alive = client;
}
}
engfunc(EngFunc_GetBonePosition, alive, 8, client_origin, angles);
g_flash_distance[client] = min(floatround(get_distance_f(ent_origin, client_origin) / 10.0, floatround_ceil) * 10, MAX_DISTANCE);
// 0.1 is the delay I found between the explosion and blinding
set_task(0.1, "TaskDoFlashbang", client);
}
}
public MessageScreenFade(msgid, dest, client)
{
if( !(1 <= client <= g_max_clients)
|| get_msg_arg_int(3) != FLASH_FLAGS
|| get_msg_arg_int(4) != FLASH_RED
|| get_msg_arg_int(5) != FLASH_GREEN
|| get_msg_arg_int(6) != FLASH_BLUE )
{
return PLUGIN_CONTINUE;
}
new alpha = get_msg_arg_int(7);
if( alpha != FLASH_ALPHA1 && alpha != FLASH_ALPHA2 ) return PLUGIN_CONTINUE;
if( g_allow_flashbang[client] )
{
g_allow_flashbang[client] = false;
return PLUGIN_CONTINUE;
}
return PLUGIN_HANDLED;
}
public TaskDoFlashbang(client)
{
new duration = seconds_to_units(floatround(float(MAX_DISTANCE - g_flash_distance[client]) / float(MAX_DISTANCE) * MAX_DURATION));
g_allow_flashbang[client] = true;
emessage_begin(MSG_ONE, ScreenFade, _, client);
ewrite_short(duration);
ewrite_short(FLASH_HOLDTIME_FAKE);
ewrite_short(FLASH_FLAGS);
ewrite_byte(FLASH_RED);
ewrite_byte(FLASH_GREEN);
ewrite_byte(FLASH_BLUE);
ewrite_byte(FLASH_ALPHA2); // TODO: Add support for 200 alpha (FLASH_ALPHA1)
emessage_end();
}
__________________