Code:
#include <amxmodx>
#include <engine>
#include <fakemeta_util>
#include <cstrike>
#include <hamsandwich>
#include <zombieplague>
#include <fun>
#define MAX_PLAYERS 32
#define MAX_BLOOD_DISTANCE 64
#define SHAKE_FORCE -3.0 //(must be negative value)
new const GUNSHOT_DECALS[] = {41, 42, 43, 44, 45} // Gunshot decal list
// Plugin information
new const PLUGIN[] = "weapon"
new const VERSION[] = "1.00"
new const AUTHOR[] = "inc"
// other
new bool:has_minigun[33], m249, bool:atk1[33],bool:beackup[33],g_fwid,g_MaxPlayers, Float:g_lastShot[33],DMGMG,bool:haswhpnnmg[33],
g_plAction[33],bool:canfire[33],bool:user_bot[33],
bool:is_alive[33],bool:is_connected[33]
// Blood
new g_blood
new g_bloodspray
// CS Player PData Offsets (win32)
const OFFSET_CSTEAMS = 114
// Linux diff's
const OFFSET_LINUX = 5 // offsets 5 higher in Linux builds
// Models
new P_MODEL[] = "models/model1.mdl"
new V_MODEL[] = "models/model2.mdl"
// Sounds
new m_SOUND[][] = {"weapons/shoot.wav", "weapons/gt_clipin.wav", "weapons/gt_clipon.wav", "weapons/gt_clipout.wav", "weapons/gt_dr.wav", "weapons/gt_draw.wav", "weapons/gt_in.wav", "weapons/guitar_clipon_on.wav", "weapons/guitar_clipout_ff.wav"}
//connect valid?
#define is_user_valid_connected(%1) (1 <= %1 <= g_MaxPlayers && is_connected[%1])
enum {
anim_idle,
anim_reload,
anim_draw,
anim_shoot1,
anim_shoot2,
anim_shoot3
}
// Types
enum {
act_none,
act_load_up,
act_run
}
public plugin_precache() {
precache_model(P_MODEL)
precache_model(V_MODEL)
precache_sound(m_SOUND[0])
precache_sound(m_SOUND[1])
precache_sound(m_SOUND[2])
precache_sound(m_SOUND[3])
precache_sound(m_SOUND[4])
precache_sound(m_SOUND[5])
precache_sound(m_SOUND[6])
precache_sound(m_SOUND[7])
precache_sound(m_SOUND[8])
g_blood = precache_model("sprites/blood.spr")
g_bloodspray = precache_model("sprites/bloodspray.spr")
}
public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHOR)
m249 = register_cvar("amx_minigun_speed","2.2")
DMGMG = register_cvar("amx_minigun_damage","1000")
register_event("CurWeapon","event_curweapon","be", "1=1")
register_forward(FM_ClientDisconnect, "fw_ClientDisconnect")
register_forward(FM_CmdStart, "fwd_CmdStart")
register_forward(FM_StartFrame, "fwd_StartFrame")
register_forward(FM_UpdateClientData, "UpdateClientData_Post", 1)
RegisterHam(Ham_Killed, "player", "fw_PlayerKilled")
RegisterHam(Ham_Spawn, "player", "fw_PlayerSpawn_Post", 1)
RegisterHam(Ham_TakeDamage, "player", "player_TakeDamage")
register_clcmd("drop","dropcmd", 0)
g_MaxPlayers = get_maxplayers()
register_clcmd("guitar_weapon", "give_weapon")
//events
register_logevent("event_start", 2, "1=Round_Start")
register_event("TextMsg", "fwEvGameWillRestartIn", "a", "2=#Game_will_restart_in")
register_event("HLTV", "event_start_freezetime", "a", "1=0", "2=0")
unregister_forward(FM_PrecacheEvent, g_fwid, 1)
}
// Client joins the game
public client_putinserver(id)
{
// Player joined
is_connected[id] = true
}
// Client leaving
public fw_ClientDisconnect(id)
{
is_connected[id] = false
is_alive[id] = false
}
public fw_PlayerSpawn_Post(id)
{
// Not alive or didn't join a team yet
if (!is_user_alive(id) || !fm_cs_get_user_team(id))
return;
// Player spawned
is_alive[id] = true
}
public fw_PlayerKilled(victim, attacker, shouldgib)
{
//player die
is_alive[victim] = false
}
//damage lvl
public player_TakeDamage(victim, inflictor, attacker, Float:damage, damagetype) {
if(damagetype & DMG_BULLET && haswhpnnmg[attacker] && has_minigun[attacker] == true && attacker!=victim)
{
damage = damage*get_pcvar_float(DMGMG)
SetHamParamFloat(4, damage)
return HAM_IGNORED
}
return HAM_IGNORED
}
public event_start(){
static iPlayers[32], iPlayersNum, i
get_players(iPlayers, iPlayersNum, "a")
for (i = 0; i <= iPlayersNum; ++i)
canfire[iPlayers[i]] = true
}
public fwEvGameWillRestartIn() {
static iPlayers[32], iPlayersNum, i
get_players(iPlayers, iPlayersNum, "a")
for (i = 0; i <= iPlayersNum; ++i)
has_minigun[iPlayers[i]] = false
}
public client_connect(id){
canfire[id]= false
has_minigun[id] = false
if(is_user_bot(id)) user_bot[id] = true
else user_bot[id] = false
}
//infect plaer
public zp_user_infected_pre(player, infector){
has_minigun[player] = false
dropcmd(player)
}
public dropcmd(id) {
if(has_minigun[id] && haswhpnnmg[id] && is_alive[id]) {
new Float:Aim[3],Float:origin[3]
VelocityByAim(id, 64, Aim)
entity_get_vector(id,EV_VEC_origin,origin)
origin[0] += Aim[0]
origin[1] += Aim[1]
new minigun = create_entity("info_target")
entity_set_string(minigun,EV_SZ_classname,"minigun")
entity_set_size(minigun,Float:{-2.0,-2.0,-2.0},Float:{5.0,5.0,5.0})
entity_set_int(minigun,EV_INT_solid,1)
entity_set_int(minigun,EV_INT_movetype,6)
entity_set_vector(minigun,EV_VEC_origin,origin)
has_minigun[id] = false
canfire[id] = false
g_plAction[id] = false
return PLUGIN_HANDLED
}
return PLUGIN_CONTINUE
}
public pfn_touch(ptr, ptd) {
if(is_valid_ent(ptr)) {
new classname[32]
entity_get_string(ptr,EV_SZ_classname,classname,31)
if(equal(classname, "minigun")) {
if(is_valid_ent(ptd)) {
new id = ptd
if(id > 0 && id < 34) {
if(!has_minigun[id] && is_alive[id] && !zp_get_user_zombie(id)) {
give_weapon(id,entity_get_int(ptr, EV_INT_iuser1), 0)
remove_entity(ptr)
}
}
}
}
}
}
//give wpn
public give_weapon(id, ammo, frst){
has_minigun[id] = true
strip_user_weapons (id)
give_item(id,"weapon_knife")
give_item(id,"weapon_p90")
give_item(id,"ammo_57mm")
give_item(id,"ammo_57mm")
give_item(id,"ammo_57mm")
canfire[id] = true
}
//set models
public event_curweapon(id){
if(!is_alive[id] || !is_connected[id] || user_bot[id]) return;
new clip, ammo, weapon = get_user_weapon(id, clip, ammo)
if((has_minigun[id]) && (weapon == CSW_P90)){
if(g_plAction[id] != act_run && beackup[id]){
beackup[id] = false
}
if(!haswhpnnmg[id]){
entity_set_string(id,EV_SZ_viewmodel,V_MODEL)
entity_set_string(id,EV_SZ_weaponmodel,P_MODEL)
haswhpnnmg[id] = true
}
new Ent = get_weapon_ent(id,weapon)
new Float:N_Speed
if(Ent)
{
N_Speed = get_pcvar_float(m249)
new Float:Delay = get_pdata_float( Ent, 46, 4) * N_Speed
if (Delay > 0.0){
set_pdata_float( Ent, 46, Delay, 4)
}
}
if(atk1[id]){
fire_mode(id)
}
}
if(weapon != CSW_P90) haswhpnnmg[id] = false
if((has_minigun[id]) && (!haswhpnnmg[id])) g_plAction[id] = act_none
return;
}
//play anim
public native_playanim(player,anim)
{
set_pev(player, pev_weaponanim, anim)
message_begin(MSG_ONE, SVC_WEAPONANIM, {0, 0, 0}, player)
write_byte(anim)
write_byte(pev(player, pev_body))
message_end()
}
//marks on hit
public native_gi_get_gunshot_decal()
{
return GUNSHOT_DECALS[random_num(0, sizeof(GUNSHOT_DECALS) - 1)]
}
//hit bulet
public testbulet(id){
// Find target
new aimOrigin[3], target, body
get_user_origin(id, aimOrigin, 3)
get_user_aiming(id, target, body)
if(target > 0 && target <= g_MaxPlayers)
{
new Float:fStart[3], Float:fEnd[3], Float:fRes[3], Float:fVel[3]
pev(id, pev_origin, fStart)
// Get ids view direction
velocity_by_aim(id, MAX_BLOOD_DISTANCE, fVel)
// Calculate position where blood should be displayed
fStart[0] = float(aimOrigin[0])
fStart[1] = float(aimOrigin[1])
fStart[2] = float(aimOrigin[2])
fEnd[0] = fStart[0]+fVel[0]
fEnd[1] = fStart[1]+fVel[1]
fEnd[2] = fStart[2]+fVel[2]
// Draw traceline from victims origin into ids view direction to find
// the location on the wall to put some blood on there
new res
engfunc(EngFunc_TraceLine, fStart, fEnd, 0, target, res)
get_tr2(res, TR_vecEndPos, fRes)
// Show some blood :)
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_BLOODSPRITE)
write_coord(floatround(fStart[0]))
write_coord(floatround(fStart[1]))
write_coord(floatround(fStart[2]))
write_short(g_bloodspray)
write_short(g_blood)
write_byte(70)
write_byte(random_num(1,2))
message_end()
} else {
new decal = native_gi_get_gunshot_decal()
// Check if the wall hit is an entity
if(target)
{
// Put decal on an entity
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_DECAL)
write_coord(aimOrigin[0])
write_coord(aimOrigin[1])
write_coord(aimOrigin[2])
write_byte(decal)
write_short(target)
message_end()
} else {
// Put decal on "world" (a wall)
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_WORLDDECAL)
write_coord(aimOrigin[0])
write_coord(aimOrigin[1])
write_coord(aimOrigin[2])
write_byte(decal)
message_end()
}
// Show sparcles
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_GUNSHOTDECAL)
write_coord(aimOrigin[0])
write_coord(aimOrigin[1])
write_coord(aimOrigin[2])
write_short(id)
write_byte(decal)
message_end()
}
}
//block anim standart wpn
public UpdateClientData_Post( player, sendweapons, CD_Handle ){
if ( !is_alive[player] ) return FMRES_IGNORED;
if(haswhpnnmg[player] && has_minigun[player])
set_cd ( CD_Handle, CD_flNextAttack, halflife_time ( ) + 0.001 )
return FMRES_HANDLED;
}
public fwd_CmdStart(id, uc_handle, seed)
{
if(!is_alive[id] || !has_minigun[id]) return FMRES_IGNORED
if(!canfire[id]) return FMRES_HANDLED
if(haswhpnnmg[id])
{
static buttons
buttons = get_uc(uc_handle, UC_Buttons)
if(buttons & IN_ATTACK)
{
atk1[id] = true
}
if(atk1[id] && (g_plAction[id] == act_none)){
buttons &= ~IN_ATTACK
set_uc(uc_handle, UC_Buttons, buttons)
fire_mode(id)
}
}
return FMRES_IGNORED
}
// in fire
fire_mode(id) {
static Float:gtime
gtime = get_gametime()
g_lastShot[id] = gtime
if(canfire[id]) {
switch(g_plAction[id]) {
case act_none: {
g_plAction[id] = act_load_up
}
case act_load_up: {
g_plAction[id] = act_run
}
}
}
if(g_plAction[id] == act_run)
{
if(atk1[id])
{
testbulet(id)
emit_sound(id, CHAN_WEAPON, m_SOUND[0],VOL_NORM, ATTN_NORM , 0, PITCH_NORM)
native_playanim(id, anim_shoot1)
}
}
atk1[id] = false
}
//sound and anim
public fwd_StartFrame() {
static Float:gtime, id
gtime = get_gametime()
for(id = 0; id <= g_MaxPlayers; id++) {
if(g_plAction[id] != act_none) {
if(!(pev(id, pev_button) & IN_ATTACK) && g_lastShot[id] + 0.1 < gtime) {
g_plAction[id] = act_none
}
}
}
}
//get weapon id
stock get_weapon_ent(id,wpnid=0,wpnName[]="")
{
// who knows what wpnName will be
static newName[24];
// need to find the name
if(wpnid) get_weaponname(wpnid,newName,23);
// go with what we were told
else formatex(newName,23,"%s",wpnName);
// prefix it if we need to
if(!equal(newName,"weapon_",7))
format(newName,23,"weapon_%s",newName);
return fm_find_ent_by_owner(get_maxplayers(),newName,id);
}
// Get User Team
stock fm_cs_get_user_team(id)
{
return get_pdata_int(id, OFFSET_CSTEAMS, OFFSET_LINUX);
}