/*
* ---------------------------------------------------------------------------------------------------------
* ------------------------------------[ZP] Zombie Class: Spitter (better)----------------------------------
* ---------------------------------------------------------------------------------------------------------
* ------------------------------------Author: SNAKER_BEATTER-----------------------------------------------
* ---------------------------------------------------------------------------------------------------------
* About:
* When i was using a special infected in L4D2 i was thinking about this class. Then i search first
* before creating because people may say its already created, but its created i found at a website.
* WELL THIS IS JUST A BETTER VERSION OF THAT SPITTER...
* ---------------------------------------------------------------------------------------------------------
* Description:
* This is another zombie class for zombie plague 4.3 or later. This zombie class is called spitter.
* She(this zombie class is female) can launch a spit/acid to an enemy. while the enemy will be damaged
* (according to spit's mode and a cvar) 25. And also as the better part when spitter die an acid
* ring will release at spitter's body, and when radiused(according to cvar) you will damaged (according-
* to a cvar)50...
*
* Okay: in this version i removed the old buggy cooldown but i replaced it with a new better cooldown
* (according to cvar) and you must wait to spit again...
* ---------------------------------------------------------------------------------------------------------
* Credits:
* Hidanz + zombie-portal website - for the acual stupid spitter that use tank's code...
* mercylezz - i copied TE_BEAMCYLINDER message for the main death acid (code from zombie_plague40.sma)
* ---------------------------------------------------------------------------------------------------------
* Cvars:
* zp_Spitter_spit_speed 700 // spit Speed Launched by Spitter
* zp_Spitter_spit_damage 25 // damage done by the spit
* zp_Spitter_spit_reward 1 // Ammo Pack's Reward by touching the enemy with the spit
* zp_Spitter_spit_mode 1 // spit Mode / 1 = Take Damage / 2 = Killing / 3 = Infect
* zp_Spitter_spit_deal_damage 250 // Damage spitter when launch a spit / 0 = Kill spitter if lauched a spit
*
* zp_Spitter_spit_cooldown 20 // (Only if defined BETTER_COOLDOWN) How many seconds spitter waits to spit again
*
* zp_Spitter_death_acid_damage 50 // When spitter die. all players arounnd him will be damaged
* zp_Spitter_death_acid_distance 250 // Spitter death acid distance
* ----------------------------------------------------------------------------------------------------------
* Modules:
* hamsandwich
* fakemeta
* engine
* fun
* -----------------------------------------------------------------------------------------------------------
* Change log:
* 1.0 (Oct 15, 2011)
* {
* public release.
* }
* 1.1 (Oct 16, 2011)
* {
* Fix if spitter is human, death acid works
* Added spit/acid hit sound
* }
* 1.2 (Oct 17, 2011)
* {
* Added bubbles when spit hit
* As remake added clcmd
* Fix if spitter is survivor, death acid works
* (best of all) Changed cooldown(buggy) to deal damage
* Changed some resources names
* }
* 1.3 (Oct 18, 2011)
* {
* Fix if spitter is nemesis, death acid works
* Added zombie support if spit hit zombie
* Added define SPIT_CHEAT_BLOCK for block some cheaty tricks
* Added colorchat when you lauched a spit
* }
* 1.4 (Oct 23, 2011)
* {
* Changed when you launch a spit message mistype
* Removed if deal_damage cvar set to 0 kill spitter if launch a spit
* }
* 1.5 (Oct 24, 2011)
* {
* (Asked) New cooldown better than the old buggy cooldown (Controlled by BETTER_COOLDOWN)
* (Asked) Added BETTER_COOLDOWN (define) to allow/disallow cooldown
* SPIT_CHEAT_BLOCK define more codes
* Added death acid bubble break
* }
*/
/******************************************************
[Include files]
******************************************************/
#include <zombie_escape>
#include <ze_zombie_class>
#include <fakemeta>
#include <engine>
#include <fun>
/******************************************************
[Plugin infos]
******************************************************/
#define PLUGIN_NAME "[ZE] ZCLASS = L4D spitter"
#define PLUGIN_VERSION "1.5"
#define PLUGIN_AUTHOR "snaker-beatter"
/******************************************************
[Id(s)]
******************************************************/
#define SPIT_CHEAT_BLOCK // Disallow some cheatty trick
#define BETTER_COOLDOWN // Than the old buggy cooldown this works more better
#if defined BETTER_COOLDOWN
new Float:g_LastSpitTime[33]
new cvar_spit_cooldown
#endif
new const zclass_name[] = "Spitter"
new const zclass_info[] = "Launch an acid"
const zclass_health = 3422
const zclass_speed = 267
const zclass_gravity = 780
new g_L4dSpitter
new g_trailSprite
new const g_trail[] = "sprites/xbeam3.spr"
new const spit_model[] = "models/spit.mdl" // HAlF-Life model
new const bubble_model_const[] = "sprites/bubble.spr"
new const Spitter_spitlaunch[] = "zombie_plague/spitter_spit.wav"
new const Spitter_spithit[] = "bullchicken/bc_spithit2.wav" // HAlF-Life model
new const Spitter_dieacid_start[] = "bullchicken/bc_acid1.wav"
new const g_ringspr[] = "sprites/shockwave.spr"
new g_ring, bubble_model
new cvar_spit_damage, cvar_spit_reward, cvar_spitmode, cvar_spit_speed, cvar_spit_deal_damage
new cvar_dthacid_damage, cvar_dthacid_distance
/******************************************************
[Main event]
******************************************************/
public plugin_init()
{
register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR)
register_event("DeathMsg", "spitter_death", "a")
cvar_spit_speed = register_cvar("zp_Spitter_spit_speed", "700")
cvar_spit_damage = register_cvar("zp_Spitter_spit_damage", "25")
cvar_spit_reward = register_cvar("zp_Spitter_spit_reward", "1")
cvar_spitmode = register_cvar("zp_Spitter_spit_mode", "1")
cvar_spit_deal_damage = register_cvar("zp_Spitter_spit_deal_damage", "250")
#if defined BETTER_COOLDOWN
cvar_spit_cooldown = register_cvar("zp_Spitter_spit_cooldown", "20")
#endif
cvar_dthacid_damage = register_cvar("zp_Spitter_death_acid_damage", "50")
cvar_dthacid_distance = register_cvar("zp_Spitter_death_acid_distance", "250")
register_clcmd("spitter_spit", "clcmd_spit")
register_touch("spit_ent","*","spitTouch")
register_forward(FM_PlayerPreThink, "CmdStart")
}
/****************************************************
[Events]
****************************************************/
public plugin_precache()
{
g_L4dSpitter = ze_register_zombie_class(zclass_name, zclass_info, zclass_health, zclass_speed, zclass_gravity)
g_trailSprite = precache_model(g_trail)
g_ring = precache_model(g_ringspr)
bubble_model = precache_model(bubble_model_const)
precache_model(spit_model)
precache_sound(Spitter_spitlaunch)
precache_sound(Spitter_spithit)
precache_sound(Spitter_dieacid_start)
}
public ze_user_infected(id)
{
if (ze_get_current_zombie_class(id) == g_L4dSpitter)
{
ze_colored_print(id, "!gYou can launch a spit by +use key(such as e)")
}
}
public CmdStart(id)
{
new button = pev(id, pev_button)
new oldbutton = pev(id, pev_oldbuttons)
if (ze_is_user_zombie(id) && (ze_get_current_zombie_class(id) == g_L4dSpitter))
{
if(oldbutton & IN_USE && !(button & IN_USE))
{
clcmd_spit(id)
}
}
return FMRES_IGNORED
}
public clcmd_spit(id)
{
if(!is_user_alive(id))
{
ze_colored_print(id, "You are not allowed to spit if you're death")
return PLUGIN_HANDLED
}
if (ze_is_user_zombie(id) && ze_get_current_zombie_class(id) == g_L4dSpitter)
{
if (get_gametime() - g_LastSpitTime[id] < get_pcvar_float(cvar_spit_cooldown))
{
ze_colored_print(id, "You have to wait %.f0 secs. To spit again", get_pcvar_float(cvar_spit_cooldown) - (get_gametime() - g_LastSpitTime[id]))
return PLUGIN_HANDLED;
}
Makespit(id)
emit_sound(id, CHAN_STREAM, Spitter_spitlaunch, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
g_LastSpitTime[id] = get_gametime()
new Float:dam = get_pcvar_float(cvar_spit_deal_damage);
if(get_user_health(id) - get_pcvar_float(cvar_spit_deal_damage) > 0)
{
#if defined SPIT_CHEAT_BLOCK
fakedamage(id, "Spit acid", dam, 256);
#else
fakedamage(id, "Spit acid", 10.0, 256);
#endif
static origin1[3]
get_user_origin(id, origin1)
bubble_break(id, origin1)
ze_colored_print(id, "You'd !tbeen damaged %d by launching a spit", get_pcvar_num(cvar_spit_deal_damage))
}
}
else
{
ze_colored_print(id, "You are not !tallowed to spit unless you're a zombie spitter")
return PLUGIN_HANDLED
}
return PLUGIN_CONTINUE
}
public spitTouch(spitEnt, Touched)
{
if (!pev_valid (spitEnt) )
return
static Class[ 32 ]
entity_get_string(Touched, EV_SZ_classname, Class, charsmax(Class) )
new Float:origin[3]
pev(Touched,pev_origin,origin)
if(equal(Class, "player"))
{
if (is_user_alive(Touched))
{
if(!ze_is_user_zombie(Touched))
{
new SpitterKiller = entity_get_edict(spitEnt, EV_ENT_owner)
switch(get_pcvar_num(cvar_spitmode))
{
case 1: // Health mode
{
new iHealth = get_user_health(Touched)
if(iHealth >= 1 && iHealth <= get_pcvar_num(cvar_spit_damage))
{
emit_sound(Touched, CHAN_BODY, Spitter_spithit, 1.0, ATTN_NORM, 0, PITCH_NORM)
ExecuteHamB(Ham_Killed, Touched, SpitterKiller, 0)
ze_colored_print(SpitterKiller, "You receive !t%d!y Ammo Packs By launching a spit to a human", get_pcvar_num(cvar_spit_reward))
ze_set_escape_coins(SpitterKiller, ze_get_escape_coins(SpitterKiller) + get_pcvar_num(cvar_spit_reward))
static origin1[3]
get_user_origin(Touched, origin1)
bubble_break(Touched, origin1)
}
else
{
emit_sound(Touched, CHAN_BODY, Spitter_spithit, 1.0, ATTN_NORM, 0, PITCH_NORM)
set_user_health(Touched, get_user_health(Touched) - get_pcvar_num(cvar_spit_damage))
ze_colored_print(SpitterKiller, "You receive !t%d!n Ammo Packs By launching a spit to a human", get_pcvar_num(cvar_spit_reward))
ze_set_escape_coins(SpitterKiller, ze_get_escape_coins(SpitterKiller) + get_pcvar_num(cvar_spit_reward))
static origin1[3]
get_user_origin(Touched, origin1)
bubble_break(Touched, origin1)
}
}
case 2: // Kill mode
{
emit_sound(Touched, CHAN_BODY, Spitter_spithit, 1.0, ATTN_NORM, 0, PITCH_NORM)
ExecuteHamB(Ham_Killed, Touched, SpitterKiller, 0)
ze_set_escape_coins(SpitterKiller, ze_get_escape_coins(SpitterKiller) + get_pcvar_num(cvar_spit_reward))
ze_colored_print(SpitterKiller, "You receive !t%d!n Ammo Packs By launching a spit to a human", get_pcvar_num(cvar_spit_reward))
static origin1[3]
get_user_origin(Touched, origin1)
bubble_break(Touched, origin1)
}
case 3: //infect mode
{
emit_sound(Touched, CHAN_BODY, Spitter_spithit, 1.0, ATTN_NORM, 0, PITCH_NORM)
ze_set_user_zombie(Touched)
ze_colored_print(SpitterKiller, "You receive !t%d!n Ammo Packs By launching a spit to a human", get_pcvar_num(cvar_spit_reward))
ze_set_escape_coins(SpitterKiller, ze_get_escape_coins(SpitterKiller) + get_pcvar_num(cvar_spit_reward))
static origin1[3]
get_user_origin(Touched, origin1)
bubble_break(Touched, origin1)
}
}
}
else
{
emit_sound(Touched, CHAN_BODY, Spitter_spithit, 1.0, ATTN_NORM, 0, PITCH_NORM)
static origin1[3]
get_user_origin(Touched, origin1)
bubble_break(Touched, origin1)
}
}
}
if(equal(Class, "func_breakable") && entity_get_int(Touched, EV_INT_solid) != SOLID_NOT)
{
force_use(spitEnt, Touched)
}
remove_entity(spitEnt)
}
public bubble_break(id, origin1[3])
{
message_begin(MSG_BROADCAST,SVC_TEMPENTITY, origin1)
write_byte(TE_BREAKMODEL)
write_coord(origin1[0])
write_coord(origin1[1])
write_coord(origin1[2] + 24)
write_coord(16)
write_coord(16)
write_coord(16)
write_coord(random_num(-50,50))
write_coord(random_num(-50,50))
write_coord(25)
write_byte(10)
write_short(bubble_model)
write_byte(10)
write_byte(38)
write_byte(0x01)
message_end();
}
public Makespit(id)
{
new Float:Origin[3]
new Float:Velocity[3]
new Float:vAngle[3]
new spitSpeed = get_pcvar_num(cvar_spit_speed)
entity_get_vector(id, EV_VEC_origin , Origin)
entity_get_vector(id, EV_VEC_v_angle, vAngle)
new NewEnt = create_entity("info_target")
entity_set_string(NewEnt, EV_SZ_classname, "spit_ent")
entity_set_model(NewEnt, spit_model)
entity_set_size(NewEnt, Float:{-1.5, -1.5, -1.5}, Float:{1.5, 1.5, 1.5})
entity_set_origin(NewEnt, Origin)
entity_set_vector(NewEnt, EV_VEC_angles, vAngle)
entity_set_int(NewEnt, EV_INT_solid, 2)
entity_set_int(NewEnt, EV_INT_rendermode, 5)
entity_set_float(NewEnt, EV_FL_renderamt, 200.0)
entity_set_float(NewEnt, EV_FL_scale, 1.00)
entity_set_int(NewEnt, EV_INT_movetype, 5)
entity_set_edict(NewEnt, EV_ENT_owner, id)
velocity_by_aim(id, spitSpeed , Velocity)
entity_set_vector(NewEnt, EV_VEC_velocity ,Velocity)
spit_trail(id, NewEnt)
return PLUGIN_HANDLED
}
public spit_trail(id, Entity)
{
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_BEAMFOLLOW)
write_short(Entity)
write_short(g_trailSprite)
write_byte(10)
write_byte(10)
write_byte(0)
write_byte(250)
write_byte(0)
write_byte(200)
message_end()
}
public spitter_death()
{
new id = read_data(2)
if (ze_is_user_zombie(id))
{
if (ze_get_current_zombie_class(id) == g_L4dSpitter)
{
new Float:originF[3]
pev(id, pev_origin, originF);
spit_death(id, originF)
}
}
}
public spit_death(id, const Float:originF[3])
{
if (ze_is_user_zombie(id))
{
if (ze_get_current_zombie_class(id) == g_L4dSpitter)
{
spit_death_effect(id, originF)
ring_effect(id)
}
}
else
{
return PLUGIN_HANDLED
}
return PLUGIN_HANDLED
}
public ring_effect(id)
{
new Float:origin[3]
pev(id, pev_origin, origin)
ring(origin)
}
public spit_death_effect(id, const Float:originF[3])
{
for(new i = 1; i <= get_maxplayers(); i ++)
{
if (ze_is_user_zombie(i) || get_entity_distance(id, i) > get_pcvar_num(cvar_dthacid_distance))
{
return PLUGIN_HANDLED
}
new origin1[3]
get_user_origin(id, origin1)
bubble_break(id, origin1)
emit_sound(id, CHAN_BODY, Spitter_dieacid_start, 1.0, ATTN_NORM, 0, PITCH_NORM)
ze_colored_print(id, "You rewarded !t2 ammopacks by aciding to a victim")
ze_set_escape_coins(id, ze_get_escape_coins(id) + 2)
new Float:dam = get_pcvar_float(cvar_dthacid_damage);
if(get_user_health(i) - get_pcvar_float(cvar_dthacid_damage) > 0)
{
emit_sound(i, CHAN_BODY, Spitter_spithit, 1.0, ATTN_NORM, 0, PITCH_NORM)
ze_colored_print(i, "You'd been !tdamaged by spitter's death acid")
fakedamage(i, "Spit acid", dam, 256);
new origin1[3]
get_user_origin(i, origin1)
bubble_break(i, origin1)
}
if(get_user_health(i) - get_pcvar_float(cvar_dthacid_damage) == 0)
{
#if defined SPIT_CHEAT_BLOCK
ExecuteHamB(Ham_Killed, i, id, 0)
#else
//ExecuteHamB(Ham_Killed, i, id, 0)
#endif
emit_sound(i, CHAN_BODY, Spitter_spithit, 1.0, ATTN_NORM, 0, PITCH_NORM)
ze_colored_print(i, "You'd been !tKilled by spitter's death acd")
new origin1[3]
get_user_origin(i, origin1)
bubble_break(i, origin1)
}
}
return PLUGIN_HANDLED
}
public ring(const Float:originF[3])
{
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]+385.0) // z axis
write_short(g_ring) // sprite
write_byte(0) // startframe
write_byte(0) // framerate
write_byte(4) // life
write_byte(60) // width
write_byte(0) // noise
write_byte(0) // red
write_byte(200) // green
write_byte(0) // blue
write_byte(200) // brightness
write_byte(0) // speed
message_end()
}]