PHP Code:
#include <amxmodx>
#include <fakemeta>
#include <xs>
#include <zombieplague>
#define SUPPORT_BOT_TO_USE //Support BOT use.(Plus on top// That the abolition of technical assistance on BOT)
#define BOUNCE_EFFECT //Shockwave attack is whether it will be bounced to.(At the top plus / / that the cancellation of the results)
//#define DROP_GUN //Whether the attack was shock will fall in the hands of a gun. (At the top plus / / that the cancellation of the results)
#define Survivor_Speed_Multiplier 0.5 // Survivor slowing effect of the multiplier. Slowed after the original speed * = multiplier (as a multiplier of 1.0 would be tantamount to the original speed)
#define Human_Speed_Multiplier 0.1 //The multiplier effect of human retarder. Slowed after the original speed * = multiplier (as a multiplier of 1.0 would be tantamount to the original speed)
#define How_High_Invalid_Attack 60.0 //Shockwave attack targets within range, if the difference in height and attackers attack beyond judged invalid. (Height character models is about 60.0)
#define PLUGIN_NAME "[ZPA]Zombie:ShockWave "
#define PLUGIN_VERSION "1.1"
#define PLUGIN_AUTHOR "Jim"
const UNIT_SECOND = (1<<12)
#if defined DROP_GUN
// Weapon bitsums
const PRIMARY_WEAPONS_BIT_SUM = (1<<CSW_SCOUT)|(1<<CSW_XM1014)|(1<<CSW_MAC10)|(1<<CSW_AUG)|(1<<CSW_UMP45)|(1<<CSW_SG550)|(1<<CSW_GALIL)|(1<<CSW_FAMAS)|(1<<CSW_AWP)|(1<<CSW_MP5NAVY)|(1<<CSW_M249)|(1<<CSW_M3)|(1<<CSW_M4A1)|(1<<CSW_TMP)|(1<<CSW_G3SG1)|(1<<CSW_SG552)|(1<<CSW_AK47)|(1<<CSW_P90)
const SECONDARY_WEAPONS_BIT_SUM = (1<<CSW_P228)|(1<<CSW_ELITE)|(1<<CSW_FIVESEVEN)|(1<<CSW_USP)|(1<<CSW_GLOCK18)|(1<<CSW_DEAGLE)
#endif
// Shock Wave Zombie Attributes
new const zclass_name[] = { "ShockWave" } //Name
new const zclass_info[] = { "Can emit shock attack" } //Info
new const zclass_model[] = { "zombie_source" } //Model
new const zclass_clawmodel[] = { "v_knife_zombie.mdl" } //Claw models
const zclass_health = 1800 //Health(HP)
const zclass_speed = 220 //Speed
const Float:zclass_gravity = 1.0 //Gravity
const Float:zclass_knockback = 1.25 //Knockback
new const sound_shockwave[] = { "garg/gar_stomp1.wav" }
new bool:use_shockwave[33]
new bool:hit_key[33]
new bool:cooldown_started[33]
new bool:slowly_started[33], Float:slowly_begin_time[33]
new g_msgScreenShake, g_shokewaveSpr
new g_zclass_shockwave
new g_shockwave_jump_height, g_shockwave_range, g_shockwave_effect_time, g_shockwave_cooldown
new maxplayers
public plugin_init()
{
register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR)
g_shockwave_jump_height = register_cvar("zp_shockwave_jump_height", "320") //Jump height when using the shock attack
g_shockwave_range = register_cvar("zp_shockwave_range", "260") //Effective distance range shock attack
g_shockwave_effect_time = register_cvar("zp_shockwave_effect_time", "6.0") //Affected by seismic time length (unit: seconds)
g_shockwave_cooldown = register_cvar("zp_shockwave_cooldown", "20.0") //Shockwave attack cooldown after use (unit: seconds)
register_forward(FM_PlayerPostThink, "fw_PlayerPostThink", 1)
register_forward(FM_StartFrame, "fw_StartFrame")
register_event("ResetHUD","NewRound","be")
register_event("DeathMsg", "Death", "a")
g_msgScreenShake = get_user_msgid("ScreenShake")
maxplayers = get_maxplayers()
}
public plugin_precache()
{
engfunc(EngFunc_PrecacheSound, sound_shockwave)
g_shokewaveSpr = engfunc(EngFunc_PrecacheModel, "sprites/shockwave.spr")
g_zclass_shockwave = zp_register_zombie_class(zclass_name, zclass_info, zclass_model, zclass_clawmodel, zclass_health, zclass_speed, zclass_gravity, zclass_knockback)
}
public zp_user_infected_post(id, infector)
{
if (zp_get_user_zombie_class(id) == g_zclass_shockwave)
{
client_print(id, print_chat, "[Zombie:Tips] near the target, standing by the 'R' key on the ground can emit shock attack requires cooling time% 20.0 seconds!", get_pcvar_float(g_shockwave_cooldown))
}
}
public zp_user_humanized_post(id)
{
use_shockwave[id] = false
hit_key[id] = false
cooldown_started[id] = false
slowly_started[id] = false
}
public fw_StartFrame()
{
// Set Layout time to check and prevent fast refresh
static Float:last_check_time
if (get_gametime() - last_check_time < 0.1)
return;
last_check_time = get_gametime()
static id
for (id = 1; id <= 32; id++)
{
// Not alive or zombie
if (!is_user_alive(id) || zp_get_user_zombie(id))
continue;
if (slowly_started[id])
{
#if defined BOUNCE_EFFECT
new Float:time
time = get_gametime() - slowly_begin_time[id]
if (time >= (get_pcvar_float(g_shockwave_effect_time) + 1.0)) //The slowing effect of the end time delay of 1.0 seconds back
{
slowly_started[id] = false
}
else if (time > 1.0) //1.0 seconds after setting the delay to produce the effect of retarder to prevent the bounce effect is suppressed
{
if (zp_get_user_survivor(id))
set_speed_to_velocity(id, Survivor_Speed_Multiplier) //Slow down effect (for shock attack is to "Survivor" players)
else
set_speed_to_velocity(id, Human_Speed_Multiplier) //Slow down effect (for shock attack to be "human" players)
}
#else
if (zp_get_user_survivor(id))
set_speed_to_velocity(id, Survivor_Speed_Multiplier) //Slow down effect (for shock attack is to "Survivor" players)
else
set_speed_to_velocity(id, Human_Speed_Multiplier) //Slow down effect (for shock attack to be "human" players)
new Float:time
time = get_gametime() - slowly_begin_time[id]
if (time >= get_pcvar_float(g_shockwave_effect_time))
slowly_started[id] = false
#endif
}
}
}
public fw_PlayerPostThink(id)
{
if (!is_user_alive(id) || !zp_get_user_zombie(id) || (zp_get_user_zombie_class(id) != g_zclass_shockwave))
return PLUGIN_CONTINUE
if (zp_get_user_nemesis(id))
return PLUGIN_CONTINUE
if (cooldown_started[id])
return PLUGIN_CONTINUE
if (!use_shockwave[id])
{
#if defined SUPPORT_BOT_TO_USE
if (is_user_bot(id))
{
new enemy, body
get_user_aiming(id, enemy, body) //Check that you are aiming for a target
if ((1 <= enemy <= 32) && !zp_get_user_zombie(enemy)) //Check whether it is a valid target
{
new Float:origin1[3], Float:origin2[3], Float:range
pev(id, pev_origin, origin1);
pev(enemy, pev_origin, origin2);
range = get_distance_f(origin1, origin2)
if (is_user_on_ground(id) && (range <= get_pcvar_float(g_shockwave_range)) && (floatabs(origin2[2] - origin1[2]) <= How_High_Invalid_Attack))
{
new height = get_pcvar_num(g_shockwave_jump_height)
if (height > 0)
{
fm_set_user_jump_velocity(id, height) //Put the shock effect of the previous jumps
if (fm_get_speed(id) > 0)
use_shockwave[id] = true
}
else
{
use_shockwave[id] = true
}
}
}
}
else
{
#endif
static button, oldbutton
button = pev(id, pev_button)
oldbutton = pev(id, pev_oldbuttons)
if ((button & IN_RELOAD) && (oldbutton & IN_RELOAD))
{
if (!hit_key[id] && is_user_on_ground(id))
{
hit_key[id] = true
new height = get_pcvar_num(g_shockwave_jump_height)
if (height > 0)
{
fm_set_user_jump_velocity(id, height) //Put the shock effect of the previous jumps
if (fm_get_speed(id) > 0)
use_shockwave[id] = true
}
else
{
use_shockwave[id] = true
}
}
}
else
{
hit_key[id] = false
}
#if defined SUPPORT_BOT_TO_USE
}
#endif
}
else
{
if (is_user_on_ground(id))
{
use_shockwave[id] = false
screen_shake(id, 10) //Let's put the player screen to generate seismic shaking attack
//PlaySound(id, sound_shockwave) //Play shocking sound effects
engfunc(EngFunc_EmitSound, id, CHAN_VOICE, sound_shockwave, 1.0, ATTN_NORM, 0, PITCH_NORM) //Play shocking sound effects
new Float:origin[3]
pev(id, pev_origin, origin)
create_blast(origin, 100, 100, 100, 200) //Showing the effect of shock waves in the ring
search_in_range_target(id) //Search shockwave attack players within range
cooldown_started[id] = true
//remove_task(id)
set_task(get_pcvar_float(g_shockwave_cooldown), "cooldown_finish", id) //Cold start,when|between Reciprocal
}
}
return PLUGIN_CONTINUE
}
public search_in_range_target(id)
{
new Float:origin1[3], Float:origin2[3], Float:range
pev(id, pev_origin, origin1);
#if defined BOUNCE_EFFECT
new Float:velocity[3]
#endif
for (new i = 1; i <= 32; i++)
{
if ((i != id) && is_user_alive(i) && !zp_get_user_zombie(i))
{
pev(i, pev_origin, origin2);
range = get_distance_f(origin1, origin2)
if (range <= get_pcvar_float(g_shockwave_range))
{
//PlaySound(i, sound_shockwave) //Play shocking sound effects
if (floatabs(origin2[2] - origin1[2]) <= How_High_Invalid_Attack)
{
screen_shake(i, 10) //Let the players be attacked to produce shaking screen
#if defined BOUNCE_EFFECT
get_speed_vector_to_entity(id, i, 500.0, velocity) //Vector bounce when calculated, bounce speed to 500.0
velocity[2] += 150.0 //When coupled with bounce jump height 150.0
set_pev(i, pev_velocity, velocity)
#endif
#if defined DROP_GUN
if (!zp_get_user_survivor(i))
drop_current_weapon(i) //Players throw the gun in the hands of the current
#endif
slowly_started[i] = true
slowly_begin_time[i] = get_gametime() //speed effectively start time
}
}
}
}
}
public cooldown_finish(id)
{
if (cooldown_started[id] && (get_pcvar_float(g_shockwave_cooldown) >= 3.0)) //Cooling time is less than 3 seconds, does not display the prompt message
client_print(id, print_center, "Cooling time %20.0 Second has passed, you can then use the shock wave has been attacked!", get_pcvar_float(g_shockwave_cooldown))
cooldown_started[id] = false
}
public client_connect(id)
{
use_shockwave[id] = false
hit_key[id] = false
cooldown_started[id] = false
slowly_started[id] = false
return PLUGIN_CONTINUE
}
public client_disconnect(id)
{
use_shockwave[id] = false
hit_key[id] = false
cooldown_started[id] = false
slowly_started[id] = false
return PLUGIN_CONTINUE
}
public NewRound(id)
{
use_shockwave[id] = false
hit_key[id] = false
cooldown_started[id] = false
slowly_started[id] = false
}
public Death()
{
new player = read_data(2)
if ((player <= 0) || (player > maxplayers))
return;
use_shockwave[player] = false
hit_key[player] = false
cooldown_started[player] = false
slowly_started[player] = false
}
screen_shake(id, amplitude = 4, duration = 2, frequency = 10)
{
message_begin(MSG_ONE_UNRELIABLE, g_msgScreenShake, _, id)
write_short(UNIT_SECOND*amplitude) // Amplitude
write_short(UNIT_SECOND*duration) // Time
write_short(UNIT_SECOND*frequency) // Frequency
message_end()
}
create_blast(const Float:originF[3], red, green, blue, brightness)
{
// Smallest ring (Large halo)
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
write_byte(TE_BEAMCYLINDER) // TE id (TE Kod)
engfunc(EngFunc_WriteCoord, originF[0]) // x (X Coordinate)
engfunc(EngFunc_WriteCoord, originF[1]) // y (X Coordinate)
engfunc(EngFunc_WriteCoord, originF[2]) // z (Y Coordinate)
engfunc(EngFunc_WriteCoord, originF[0]) // x axis (X Axis)
engfunc(EngFunc_WriteCoord, originF[1]) // y axis (Y Axis)
engfunc(EngFunc_WriteCoord, originF[2]+400.0) // z axis (Z Axis)
write_short(g_shokewaveSpr) // sprite (Sprite Object code)
write_byte(0) // startframe (Frames begin)
write_byte(0) // framerate (Frequency frames)
write_byte(4) // life (The length of time)
write_byte(60) // width (Width)
write_byte(0) // noise (Sound)
write_byte(red) // red (Color R)
write_byte(green) // green(Color R)
write_byte(blue) // blue (Color B)
write_byte(brightness) // brightness (Color brightness)
write_byte(0) // speed (Speed)
message_end()
// Medium ring (The aura)
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
write_byte(TE_BEAMCYLINDER) // TE id
engfunc(EngFunc_WriteCoord, originF[0]) // x
engfunc(EngFunc_WriteCoord, originF[1]) // y
engfunc(EngFunc_WriteCoord, originF[2]) // z
engfunc(EngFunc_WriteCoord, originF[0]) // x axis
engfunc(EngFunc_WriteCoord, originF[1]) // y axis
engfunc(EngFunc_WriteCoord, originF[2]+300.0) // z axis
write_short(g_shokewaveSpr) // sprite
write_byte(0) // startframe
write_byte(0) // framerate
write_byte(4) // life
write_byte(60) // width
write_byte(0) // noise
write_byte(red) // red
write_byte(green) // green
write_byte(blue) // blue
write_byte(brightness) // brightness
write_byte(0) // speed
message_end()
// Largest ring (Small halo)
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, originF, 0)
write_byte(TE_BEAMCYLINDER) // TE id
engfunc(EngFunc_WriteCoord, originF[0]) // x
engfunc(EngFunc_WriteCoord, originF[1]) // y
engfunc(EngFunc_WriteCoord, originF[2]) // z
engfunc(EngFunc_WriteCoord, originF[0]) // x axis
engfunc(EngFunc_WriteCoord, originF[1]) // y axis
engfunc(EngFunc_WriteCoord, originF[2]+200.0) // z axis
write_short(g_shokewaveSpr) // sprite
write_byte(0) // startframe
write_byte(0) // framerate
write_byte(4) // life
write_byte(60) // width
write_byte(0) // noise
write_byte(red) // red
write_byte(green) // green
write_byte(blue) // blue
write_byte(brightness) // brightness
write_byte(0) // speed
message_end()
}
/*
PlaySound(id, const sound[])
{
if (equal(sound[strlen(sound)-4], ".mp3"))
client_cmd(id, "mp3 play ^"sound/%s^"", sound)
else
client_cmd(id, "spk ^"%s^"", sound)
}
*/
stock set_speed_to_velocity(id, Float:scalar = 1.0)
{
// Get our current velocity
static Float:velocity[3]
pev(id, pev_velocity, velocity)
xs_vec_mul_scalar(velocity, scalar, velocity)
set_pev(id, pev_velocity, velocity)
return 1;
}
stock bool:is_user_on_ground(index)
{
if (pev(index, pev_flags) & FL_ONGROUND)
return true;
return false;
}
stock fm_set_user_jump_velocity(index, jump_height)
{
static Float:velocity[3]
pev(index, pev_velocity, velocity)
velocity[2] = float(jump_height)
set_pev(index, pev_velocity, velocity)
return 1;
}
stock fm_get_speed(entity)
{
static Float:velocity[3]
pev(entity, pev_velocity, velocity)
return floatround(vector_length(velocity));
}
#if defined BOUNCE_EFFECT
stock get_speed_vector_to_entity(ent1, ent2, Float:speed, Float:new_velocity[3])
{
if(!pev_valid(ent1) || !pev_valid(ent2))
return 0;
static Float:origin1[3]
pev(ent1,pev_origin,origin1)
static Float:origin2[3]
pev(ent2,pev_origin,origin2)
new_velocity[0] = origin2[0] - origin1[0];
new_velocity[1] = origin2[1] - origin1[1];
new_velocity[2] = origin2[2] - origin1[2];
static Float:num
num = speed / vector_length(new_velocity);
new_velocity[0] *= num;
new_velocity[1] *= num;
new_velocity[2] *= num;
return 1;
}
#endif
#if defined DROP_GUN
stock drop_current_weapon(id)
{
static weapon_id, clip, ammo
weapon_id = get_user_weapon(id, clip, ammo)
if (((1<<weapon_id) & PRIMARY_WEAPONS_BIT_SUM) || ((1<<weapon_id) & SECONDARY_WEAPONS_BIT_SUM))
{
static weapon_name[32]
get_weaponname(weapon_id, weapon_name, sizeof weapon_name - 1)
engclient_cmd(id, "drop", weapon_name)
}
}
#endif