.::| SMA |::.
.::| CONFIGURAÇÕES |::.
zp_crossbow_damage 1000 - Os danos causados por explosão
zp_crossbow_damage2 4000 - Danos ao parafuso
zp_crossbow_radius 300 - Crossbow raio
.::| DOWNLOAD |::.
Clique Aqui
Créditos: Zombie-mod.ru
- Código:
/*
--- Intro ---
This is Crossbow from HL.It costs 25 Ammo packs(default).To attack press attack1
button, to use zoom press attack2.If you shoot while zooming crossbow just hit enemy/
wall, but if you are shooting without zoom bolt will explode and do more damage.
You have 10 bolts in a clip and 25 in a back pack.
--- Credits ---
xman2030 - Plugin
VEN - Finding weapon entities
Arkshine - Ham_Item_Deploy/getting fov/weapon animation
meTaLiCroSS - Weapon touch
DeVconeS - Explosion kickback
--- Changelog ---
v1.0 - First release
v1.1 - Fixed :ammo was not updated correctly
- optimized bolt flight
- fixed: crap runtime error
v1.2 - Fixed some little bugs
v1.3 - Fixed bug with drop
v1.4 - Fixed bug when player could reload infinite times
- Fixed bug with score info
- Added knockback from explosion
--- Good Luck & Have Fun ;) ---
*/
#include <amxmodx>
#include <cstrike>
#include <engine>
#include <fakemeta>
#include < fun >
#include <hamsandwich>
#include <zombieplague>
// Plugin info
new const PLUGIN[] = "[ZP] Extra Item: Crossbow Gold"
new const VERSION[] = "1.4"
new const AUTHOR[] = "xman2030"
// Crossbow/Bolt models
new const P_MODEL[] = "models/p_crossbow_2.mdl"
new const V_MODEL[] = "models/v_crossbow_2.mdl"
new const W_MODEL[] = "models/w_crossbow_2.mdl"
new const BOLT_MODEL[] = "models/crossbow_bolt.mdl"
// Some sounds
new const XBOW_SHOOT[] = "weapons/xbow_fire1.wav"
new const XBOW_HITWALL[] = "weapons/xbow_hit1.wav"
new const XBOW_HITSTAB[] = "weapons/xbow_hitbod1.wav"
new const XBOW_RELOAD[] = "weapons/xbow_reload1.wav"
// Sprite
new const EXPLO_SPRITE[] = "sprites/zerogxplode.spr"
// Cached sprite indexes
new sExplo
// CVAR pointers
new pDamage, pDamage2, pRadius
// Item ID
new g_crossbow
// Player variables
new g_hasXbow[33] // whether playerhas Crossbow
new Float:g_last_shot_time[33] // Last time Crossbow used
// Max players
new g_maxplayers
// Global vars
new g_restarted
// Message ID's
new g_msgCurWeapon, g_msgAmmoX
// Weapon animation sequences
enum
{
crossbow_idle1,
crossbow_idle2,
crossbow_fidget1,
crossbow_fidget2,
crossbow_fire1,
crossbow_fire2,
crossbow_fire3,
crossbow_reload,
crossbow_draw1,
crossbow_draw2,
crossbow_holster1,
crossbow_holster2
}
// Item cost
#define COST 25
// Precache
public plugin_precache()
{
// Models
precache_model(P_MODEL)
precache_model(V_MODEL)
precache_model(W_MODEL)
precache_model(BOLT_MODEL)
// Sounds
precache_sound(XBOW_SHOOT)
precache_sound(XBOW_HITWALL)
precache_sound(XBOW_HITSTAB)
precache_sound(XBOW_RELOAD)
precache_sound("weapons/357_cock1.wav")
// Sprite
sExplo = precache_model(EXPLO_SPRITE)
}
// Init
public plugin_init()
{
// New plugin
register_plugin(PLUGIN, VERSION, AUTHOR)
register_cvar("zp_xbow_version", VERSION, FCVAR_SERVER)
// New extra item
g_crossbow = zp_register_extra_item("Crossbow", COST, ZP_TEAM_HUMAN)
// Events
register_event("HLTV", "Event_NewRound", "a", "1=0", "2=0");
register_event("TextMsg", "Event_GameRestart", "a", "2=#Game_Commencing", "2=#Game_will_restart_in");
// Forwards
register_forward(FM_CmdStart, "fw_CmdStart")
register_forward(FM_SetModel, "fw_SetModel")
RegisterHam(Ham_Item_Deploy, "weapon_awp", "fw_CrossbowDeploy", 1)
register_forward(FM_UpdateClientData, "fw_UpdateClientData_Post", 1)
register_forward(FM_Touch, "fw_Touch")
RegisterHam(Ham_Killed, "player", "fw_PlayerKilled_Post", 1)
RegisterHam(Ham_Weapon_Reload, "weapon_awp", "fw_WeaponReload", 1)
// Touches
register_touch("xbow_bolt", "*", "bolt_touch")
register_touch("xbow_bolt_xplode", "*", "bolt_touch2")
// CVARs
pDamage = register_cvar("zp_crossbow_damage", "1000") // Damage done by expl
pDamage2 = register_cvar("zp_crossbow_damage2", "4000") // Damage done by bolt
pRadius = register_cvar("zp_crossbow_radius", "300")
// Store maxplayers in a global variable
g_maxplayers = get_maxplayers()
// Messages
g_msgCurWeapon = get_user_msgid("CurWeapon")
g_msgAmmoX = get_user_msgid("AmmoX")
}
// When client connected, he cant have our weapon
public client_connect(id)
{
g_hasXbow[id] = false
}
// Someone wants to buy our extra item
public zp_extra_item_selected(id, itemid)
{
if (itemid == g_crossbow)
{
// Already have it
if (g_hasXbow[id] || user_has_weapon(id, CSW_AWP))
{
// Warn player
client_print(id, print_center, "Already have Crossbow!")
// Return ammo packs back
zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + COST)
}
// Otherwise you can buy it
else
{
// Notice
client_print(id, print_chat, "[ZP] You bought crossbow")
// Give him awp
give_item(id, "weapon_awp")
// Get weapon id
new weapon_id = find_ent_by_owner(-1, "weapon_awp", id)
if (weapon_id)
{
// Set clip ammo
cs_set_weapon_ammo(weapon_id, 10)
}
// Set bp ammo
cs_set_user_bpammo(id, CSW_AWP, 50)
//client_print(id, print_chat, "BP AMMO: %d", cs_get_user_bpammo(id, CSW_AWP))
// Change models
ChangeModels(id)
// Reset
g_hasXbow[id] = true
// Update HUD
UpdateHud(id)
}
}
}
// Target who have our weapon was infected - reset vars
public zp_user_infected_post(id, infector, nemesis)
{
if (g_hasXbow[id])
{
g_hasXbow[id] = false
UpdateHud(id)
}
}
// New round started
public Event_NewRound()
{
if (g_restarted)
{
// Strip from Crossnow if game have been restarted
for (new i = 1; i <= get_maxplayers(); i++)
{
if (g_hasXbow[i])
{
g_hasXbow[i] = false
}
}
g_restarted = false
}
}
// Restart
public Event_GameRestart()
{
g_restarted = true
}
// Called when player start a command(shoot, jump etc.)
public fw_CmdStart(id, uc_handle, seed)
{
// Ignore dead zombies/nemesis/those who haven't our weapons
if (!is_user_alive(id) || zp_get_user_zombie(id) || zp_get_user_nemesis(id) || !g_hasXbow[id])
return FMRES_IGNORED
// Get amo, clip, and weapon
new ammo, clip, weapon = get_user_weapon(id, clip, ammo)
// Not AWP
if (weapon != CSW_AWP)
return FMRES_IGNORED
// Buttons
new buttons = get_uc(uc_handle, UC_Buttons)
new ent = find_ent_by_owner(-1, "weapon_awp", id)
// Attack1 button was pressed
if (buttons & IN_ATTACK)
{
// We have enough ammo
if (ammo >= 1)
{
// Next shot time has come
if (get_gametime() - g_last_shot_time[id] > 2.0)
{
// Get FOV(Arkshine)
new fov; fov = pev(id, pev_fov)
// Default FOV
if (fov == 90)
{
FireCrossbow(id, 0)
}
// Is zooming?
else
FireCrossbow(id, 1)
// Decrease ammo
cs_set_weapon_ammo(ent, cs_get_weapon_ammo(get_pdata_cbase(id, 373)) - 1)
// Update HUD
UpdateHud(id)
// Remember last shot time
g_last_shot_time[id] = get_gametime()
}
}
else
{
// Play empty sound
emit_sound(id, CHAN_WEAPON, "weapons/357_cock1.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
}
// Remove attack button from their buttons mask
buttons &= ~IN_ATTACK
set_uc(uc_handle, UC_Buttons, buttons)
}
// Attack2 button was pressed
if (buttons & IN_ATTACK2)
{
// Update HUD(bugfix)
UpdateHud(id)
}
return FMRES_HANDLED
}
// Usually called after player dropped weapons
public fw_SetModel(ent, const model[])
{
// Prevent invalid entity messages
if (!pev_valid(ent))
return FMRES_IGNORED
// Not required model
if(!equali(model, "models/w_awp.mdl"))
return FMRES_IGNORED
// Get owner and classname
new owner = pev(ent, pev_owner)
new classname[33]; pev(ent, pev_classname, classname, charsmax(classname))
// Entity classname is a weaponbox
if(equal(classname, "weaponbox"))
{
// The weapon owner has a crossbow
if(g_hasXbow[owner])
{
// Strip from crossbow
g_hasXbow[owner] = false
// Set world model
engfunc(EngFunc_SetModel, ent, W_MODEL)
// Update HUD
UpdateHud(owner)
// Touch fix
set_task(0.1, "touch_fix", owner)
return FMRES_SUPERCEDE
}
}
return FMRES_IGNORED
}
// Called when player is holding this weapon
public fw_CrossbowDeploy(iEnt)
{
// Get ID
new id = get_pdata_cbase(iEnt, 41, 5)
if (g_hasXbow[id])
{
// Change models
ChangeModels(id)
// Play animation
UTIL_PlayWeaponAnimation(id, crossbow_draw1)
// Update HUD
UpdateHud(id)
}
}
// Update client data
public fw_UpdateClientData_Post(id, sw, cd_handle)
{
// Ignore dead zombies/nemesis/those who haven't our weapons
if (!is_user_alive(id) || zp_get_user_zombie(id) || zp_get_user_nemesis(id) || !g_hasXbow[id])
return FMRES_IGNORED
// Get ammo, clip and weapon
new ammo, clip, weapon = get_user_weapon(id, clip, ammo)
// Not AWP
if (weapon != CSW_AWP)
return FMRES_IGNORED
// Block default sounds
set_cd(cd_handle, CD_ID, 0)
return FMRES_HANDLED
}
// Called when player touch something
public fw_Touch(ptr, ptd)
{
// Invalid ent/toucher
if(!pev_valid(ptr) || !pev_valid(ptr))
return FMRES_IGNORED;
// Get model, toucherclass, entityclass
new model[33], toucherclass[33], entityclass[33]
pev(ptr, pev_model, model, charsmax(model))
pev(ptr, pev_classname, entityclass, charsmax(entityclass))
pev(ptd, pev_classname, toucherclass, charsmax(toucherclass))
// TOucher isn't player and entity isn't weapon
if (!equali(toucherclass, "player") || !equali(entityclass, "weaponbox"))
return FMRES_IGNORED
// Our world model
if(equali(model, W_MODEL))
{
// If allowed to touch
if(allowed_toucher(ptd))
{
// Pick up weapon
g_hasXbow[ptd] = true
}
}
return FMRES_IGNORED;
}
// Called after player died
public fw_PlayerKilled_Post(victim, attacker, shouldgib)
{
if (g_hasXbow[victim])
{
touch_fix(victim)
}
}
// Called on reload
public fw_WeaponReload(iEnt)
{
// Get ID
new id = get_pdata_cbase(iEnt, 41, 5)
//new ammo, clip = get_user_weapon(id, clip, ammo)
// Has crossbow
if (g_hasXbow[id])
{
set_pdata_int(iEnt, 54, 1, 4)
// Set animation
UTIL_PlayWeaponAnimation(id, crossbow_reload)
// Emit sound
emit_sound(id, CHAN_WEAPON, XBOW_RELOAD, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
// Update HUD
UpdateHud(id)
}
}
// Fire crossbow
public FireCrossbow(id, type)
{
// Play animation
UTIL_PlayWeaponAnimation(id, crossbow_fire1)
// Get origin, angle, and velocity
new Float:fOrigin[3], Float:fAngle[3], Float:fVelocity[3]
pev(id, pev_origin, fOrigin)
pev(id, pev_v_angle, fAngle)
// New ent
new ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
// Not ent
if (!ent) return PLUGIN_HANDLED
// If player shot while zooming...
if (type == 1)
{
// Set classnames
entity_set_string(ent, EV_SZ_classname, "xbow_bolt")
}
else
{
entity_set_string(ent, EV_SZ_classname, "xbow_bolt_xplode")
}
// Set bolt model
entity_set_model(ent, BOLT_MODEL)
// Size
new Float:mins[3] = {-1.0, -1.0, -1.0}
new Float:maxs[3] = {1.0, 1.0, 1.0}
entity_set_size(ent, mins, maxs)
// Movetype
entity_set_int(ent, EV_INT_movetype, MOVETYPE_FLY)
// Interaction
entity_set_int(ent, EV_INT_solid, SOLID_TRIGGER)
// Owner
entity_set_edict(ent, EV_ENT_owner, id)
new Float:origin[3];
// Velocity
velocity_by_aim(id, 64, fVelocity);
pev(id, pev_origin, origin);
fOrigin[0] += fVelocity[0];
fOrigin[1] += fVelocity[1];
// Set origin
engfunc(EngFunc_SetOrigin, ent, fOrigin)
// Set bolt velocity
new Float:velocity[3]
velocity_by_aim(id, 2000, velocity);
set_pev(ent, pev_velocity, velocity);
// Correct bolt flight
vector_to_angle(velocity, fAngle);
// Set angle
set_pev(ent, pev_angles, fAngle);
// Play sound
emit_sound(id, CHAN_WEAPON, XBOW_SHOOT, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
return PLUGIN_CONTINUE
}
// Normal bolt touched something
public bolt_touch(bolt, ent)
{
// Invalid ent
if (!pev_valid(bolt))
return
// GEt owner and classname
new owner = pev(bolt, pev_owner);
new classname[32]; pev(ent, pev_classname, classname, 31)
// Get it's origin
new Float:originF[3]
pev(bolt, pev_origin, originF)
// Loop through all players
for(new i = 1; i < g_maxplayers; i++)
{
// Alive...
if (is_user_alive(i) == 1)
{
// Zombie/Nemesis
if (zp_get_user_zombie(i) || zp_get_user_nemesis(i))
{
// We hit them
emit_sound(i, CHAN_WEAPON, XBOW_HITSTAB, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
// Do fake damage
fakedamage(i, "crossbow", 0.0, DMG_PARALYZE)
// Get victim origin and distance
new Float:VictimOrigin[3], Float:distance
pev(i, pev_origin, VictimOrigin)
distance = get_distance_f(originF, VictimOrigin)
if (distance <= 1.0)
{
// Health/Damage
new health = get_user_health(i)
new damage = get_pcvar_num(pDamage2)
if (health - damage >= 1)
set_user_health(i, health - damage)
else
{
// Kill them
user_silentkill(i)
// Log this
log_kill(owner, i, "crossbow", 0)
// Set new Ammo Packs
zp_set_user_ammo_packs(owner, zp_get_user_ammo_packs(owner) + 1)
}
}
// Destroy ent
set_pev(bolt, pev_flags, FL_KILLME)
}
}
}
// Not a player(wall etc.)
if (!equal(classname, "player"))
{
// Play sound
emit_sound(bolt, CHAN_WEAPON, XBOW_HITWALL, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
// Destroy ent
set_pev(bolt, pev_flags, FL_KILLME)
}
}
// Exploding bolt touched something
public bolt_touch2(bolt2, ent)
{
// Invalid ent
if (!pev_valid(bolt2))
return
// GEt owner and classname
new owner = pev(bolt2, pev_owner);
new classname[32]; pev(ent, pev_classname, classname, 31)
// Get it's origin
new Float:originV[3]
pev(bolt2, pev_origin, originV)
// Draw explosion
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_EXPLOSION)
engfunc(EngFunc_WriteCoord, originV[0])
engfunc(EngFunc_WriteCoord, originV[1])
engfunc(EngFunc_WriteCoord, originV[2])
write_short(sExplo)
write_byte(30)
write_byte(15)
write_byte(0)
message_end()
// Loop through all players
for(new i = 1; i < g_maxplayers; i++)
{
// Alive...
if (is_user_alive(i) == 1)
{
// Zombie/Nemesis
if (zp_get_user_zombie(i) || zp_get_user_nemesis(i))
{
// Do fake damage
fakedamage(i, "crossbow", 0.0, DMG_BLAST)
// Get origina and distance
new Float:VictimOrigin[3], Float:distance
pev(i, pev_origin, VictimOrigin)
distance = get_distance_f(originV, VictimOrigin)
make_knockback(owner, i, VictimOrigin)
if (distance <= get_pcvar_float(pRadius))
{
//fakedamage(i, "crossbow", 0.0, DMG_BLAST)
// Get health/dmg
new damage = get_pcvar_num(pDamage)
new health = get_user_health(i)
if (health - damage >= 1)
set_user_health(i, health - damage)
else
{
// Silently kill
user_silentkill(i)
// Log this
log_kill(owner, i, "crossbow", 0)
// Set ammo packs
zp_set_user_ammo_packs(owner, zp_get_user_ammo_packs(owner) + 1)
}
}
}
set_pev(bolt2, pev_flags, FL_KILLME)
}
}
// If breakable
if (equal(classname, "func_breakable"))
{
// Use it
dllfunc(DLLFunc_Use, ent, bolt2)
set_pev(bolt2, pev_flags, FL_KILLME)
}
}
// Touch fix
public touch_fix(id)
{
if (g_hasXbow[id])
g_hasXbow[id] = false
UpdateHud(id)
}
// Change models
stock ChangeModels(id)
{
set_pev(id, pev_viewmodel2, V_MODEL);
set_pev(id, pev_weaponmodel2, P_MODEL);
}
// Play animation(Arkshine)
stock UTIL_PlayWeaponAnimation(const Player, const Sequence)
{
set_pev(Player, pev_weaponanim, Sequence);
message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = Player);
write_byte(Sequence);
write_byte(pev(Player, pev_body));
message_end();
}
// Update HUD(Arkshine)
stock UpdateHud(Player)
{
// This set clip ammo
message_begin(MSG_ONE_UNRELIABLE, g_msgCurWeapon, .player = Player);
write_byte(true);
write_byte(CSW_AWP);
write_byte(cs_get_weapon_ammo(get_pdata_cbase(Player, 373)))
message_end()
// This set BP ammo
message_begin(MSG_ONE_UNRELIABLE, g_msgAmmoX, .player = Player);
write_byte(CSW_AWP);
write_byte(cs_get_user_bpammo(Player, CSW_AWP));
message_end();
}
// Log kill
stock log_kill(killer, victim, weapon[],headshot)
{
set_msg_block(get_user_msgid("DeathMsg"), BLOCK_SET)
user_kill(victim,1)
set_msg_block(get_user_msgid("DeathMsg"), BLOCK_NOT)
message_begin(MSG_ALL, get_user_msgid("DeathMsg"), {0,0,0}, 0)
write_byte(killer)
write_byte(victim)
write_byte(headshot)
write_string(weapon)
message_end()
if(zp_get_user_zombie(victim) || zp_get_user_nemesis(victim))
set_user_frags(killer,get_user_frags(killer) +1)
new kname[32], vname[32], kauthid[32], vauthid[32], kteam[10], vteam[10]
get_user_name(killer, kname, 31)
get_user_team(killer, kteam, 9)
get_user_authid(killer, kauthid, 31)
get_user_name(victim, vname, 31)
get_user_team(victim, vteam, 9)
get_user_authid(victim, vauthid, 31)
log_message("^"%s<%d><%s><%s>^" killed ^"%s<%d><%s><%s>^" with ^"%s^"",
kname, get_user_userid(killer), kauthid, kteam,
vname, get_user_userid(victim), vauthid, vteam, weapon)
return PLUGIN_CONTINUE
}
// Allowed toucher
stock allowed_toucher(player)
{
// Already has it
if (g_hasXbow[player])
return false
return true
}
// From WeaponMod
stock make_knockback(owner, player, const Float:origin[3])
{
new Float:velocity[3]
new Float:vecSpot[3]
new Float:vecSee[33]
new Float:invlen
new Float:vecPush[3]
new Float:tabsmin[3]
new Float:tabsmax[3]
new Float:aabsmin[3]
new Float:aabsmax[3]
new Float:tmpdmg = get_pcvar_float(pDamage)
pev(player, pev_absmin, tabsmin)
pev(player, pev_absmax, tabsmax)
vecSpot[0] = (tabsmin[0] + tabsmax[0]) * 0.5
vecSpot[1] = (tabsmin[1] + tabsmax[1]) * 0.5
vecSpot[2] = (tabsmin[2] + tabsmax[2]) * 0.5
pev(owner, pev_absmin, aabsmin)
pev(owner, pev_absmax, aabsmax)
vecSee[0] = (aabsmin[0] + aabsmax[0]) * 0.5
vecSee[1] = (aabsmin[1] + aabsmax[1]) * 0.5
vecSee[2] = (aabsmin[2] + aabsmax[2]) * 0.5
//origin[0] = vecSpot[0] - vecSee[0]
//origin[1] = vecSpot[1] - vecSee[1]
//origin[2] = vecSpot[2] - vecSee[2]
//invlen = 1.0/get_distance_f(vecSpot, vecSee)
vecPush[0] = origin[0] * invlen
vecPush[1] = origin[1] * invlen
vecPush[2] = origin[2] * invlen
pev(player, pev_velocity, velocity)
velocity[0] = velocity[0] + vecPush[0] * tmpdmg * 1.0
velocity[1] = velocity[1] + vecPush[1] * tmpdmg * 1.0
velocity[2] = velocity[2] + vecPush[2] * tmpdmg * 1.0
velocity[0] *= 12.0
velocity[1] *= 12.0
velocity[2] *= 12.0
if(velocity[0] != 0.0 || velocity[1] != 0.0 || velocity[2] != 0.0)
{
// There's some movement todo :)
set_pev(player, pev_velocity, velocity)
}
}
/*stock fm_get_weapon_id(index, const weapon[])
{
new ent = -1;
while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", weapon)) != 0)
{
if(index == pev(ent, pev_owner))
return ent;
}
return 1;
}
stock give_weapon(id, wpnID, ammo, bpammo)
{
new weapon[32]
get_weaponname(wpnID, weapon, 31)
give_item(id, weapon)
cs_set_weapon_ammo(fm_get_weapon_id(id, weapon), ammo);
cs_set_user_bpammo(id, wpnID, cs_get_user_bpammo(id, wpnID) + bpammo)
}*/
.::| CONFIGURAÇÕES |::.
zp_crossbow_damage 1000 - Os danos causados por explosão
zp_crossbow_damage2 4000 - Danos ao parafuso
zp_crossbow_radius 300 - Crossbow raio
.::| DOWNLOAD |::.
Clique Aqui
Créditos: Zombie-mod.ru