Vous êtes sur la page 1sur 12

#include <amxmodx>

#include <amxmisc>
#include <cstrike>
#include <fakemeta>
#include <hamsandwich>
#include <fun>

#define PLUGIN "Ghost Spec"


#define VERSION "1.5"
#define AUTHOR "vato loco [GE-S]"

#define iRandomNum random_num(0,255)


#define MENU_KEYS_GHOST MENU_KEY_1|MENU_KEY_2
#define HUD_HIDE_FLAGS 1<<0 | 1<<1 | 1<<3 | 1<<4 | 1<<5 | 1<<6
#define SB_ATTRIB_DEAD 1<<0
#define MAX_LEN_LENGHT 100
#define GHOST_ORIGIN 3
#define XO_WEAPONS 4
#define XO_PLAYER 5
#define m_iHideHUD 361
#define m_iClientHideHUD 362
#define m_iRadiosLeft 192
#define m_pPlayer 41
#define m_flNextPrimaryAttack 46
#define m_flNextSecondaryAttack 47
#define IsPlayer(%1) (1 <= %1 <= g_iMaxPlayers)

enum (+= 11111)


{
TASK_CROSS = 11111,
TASK_SPAWN,
TASK_STRIP,
TASK_CACHE
}

new szPluginInfoMsg[MAX_LEN_LENGHT]
new szGhostInfoMsg[MAX_LEN_LENGHT]
new g_Cross[] = "+"
new g_GhostModel[] = "ghost"
new const Float:VEC_DUCK_HULL_MIN[GHOST_ORIGIN] = {-16.0, -16.0, -18.0}
new const Float:VEC_DUCK_HULL_MAX[GHOST_ORIGIN] = {16.0, 16.0, 18.0}
new g_iEntPlayerModel[MAX_PLAYERS + 1]
new g_iEntWeaponModel[MAX_PLAYERS + 1]
new g_iIsSpectator[MAX_PLAYERS + 1]
new Float:g_fSpwanPosition[MAX_PLAYERS + 1][GHOST_ORIGIN]
new Float:g_fGhostPosition[MAX_PLAYERS + 1][GHOST_ORIGIN]
new bool:g_bIsConnected[MAX_PLAYERS + 1]
new bool:g_bIsAlive[MAX_PLAYERS + 1]
new bool:g_bIsGhost[MAX_PLAYERS + 1]
new bool:g_bIsBot[MAX_PLAYERS + 1]
new bool:g_bAgree[MAX_PLAYERS + 1]
new bool:g_bFirstSpwan[MAX_PLAYERS + 1]
new bool:g_bRoundEnd
new bool:g_bBombIsPlanted
new Trie:g_tPlayerSound
new g_ScoreAttrib
new g_CurWeapon
new g_ClCorpse
new g_SyncCutomCross
new g_SyncPluginInfo
new g_SyncGhostInfo
new g_pCvar[8]
new g_iCachepCvar[8]
new g_iMaxPlayers

public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)

register_menu("Ghost Menu", MENU_KEYS_GHOST , "GhostMenuHandler")

register_event("HLTV", "ev_NewRound", "a", "1=0", "2=0")


register_event("SpecHealth2", "ev_SpecHealth2", "bd")
register_logevent("ev_RoundEnd",2,"1=Round_End")
register_logevent("ev_FunctionP", 3, "2=Planted_The_Bomb")

RegisterHam(Ham_Weapon_PrimaryAttack, "weapon_knife",
"fw_KnifePrimaryAttack")
RegisterHam(Ham_Weapon_SecondaryAttack, "weapon_knife",
"fw_KnifeSecondaryAttack")
RegisterHam(Ham_Touch, "weaponbox", "fw_WeaponTouch")
RegisterHam(Ham_Touch, "armoury_entity", "fw_WeaponTouch")
RegisterHam(Ham_Touch, "weapon_shield", "fw_WeaponTouch")
RegisterHam(Ham_Player_PreThink, "player", "fw_PreThink_Post", 1)
RegisterHam(Ham_Spawn, "player", "fw_PlayerSpawn", 1)
RegisterHam(Ham_Killed, "player", "fw_PlayerKilled", 1)

register_forward(FM_ClientKill,"fw_ClientKill")
register_forward(FM_AddToFullPack, "fw_AddToFullPack_Post", 1)
register_forward(FM_CmdStart, "fw_CmdStart")
register_forward(FM_EmitSound, "fw_EmitSound")

register_clcmd("radio1", "BlockCmd")
register_clcmd("radio2", "BlockCmd")
register_clcmd("radio3", "BlockCmd")

g_pCvar[0] = register_cvar("ghost_spawn", "1")


g_pCvar[1] = register_cvar("ghost_noclip", "0")
g_pCvar[2] = register_cvar("ghost_kill", "1")
g_pCvar[3] = register_cvar("ghost_visible", "0")
g_pCvar[4] = register_cvar("ghost_sound", "1")
g_pCvar[5] = register_cvar("ghost_menu", "1")
g_pCvar[6] = register_cvar("ghost_respawn_delay", "1.5")
g_pCvar[7] = register_cvar("ghost_effect", "0")

g_ScoreAttrib = get_user_msgid("ScoreAttrib")
g_CurWeapon = get_user_msgid("CurWeapon")
g_ClCorpse = get_user_msgid("ClCorpse")
register_message(g_ClCorpse, "MsgClCorpse")
register_message(g_ScoreAttrib, "MsgScoreAttrib")
register_message( g_CurWeapon, "MsgCurWeapon")
set_msg_block(g_ClCorpse, BLOCK_SET)

g_SyncCutomCross = CreateHudSyncObj()
g_SyncPluginInfo = CreateHudSyncObj()
g_SyncGhostInfo = CreateHudSyncObj()
g_iMaxPlayers = get_maxplayers()
new const g_iPlayerSound[][] = {
/*
"items/gunpickup2.wav",
"player/death6.wav",
"player/die1.wav",
"player/die2.wav",
"player/die3.wav",
"player/bhit_kevlar-1.wav",
"player/bhit_flesh-1.wav",
"player/bhit_flesh-2.wav",
"player/bhit_flesh-3.wav",
"player/pl_wade1.wav",
"player/pl_wade2.wav"
}
g_tPlayerSound = TrieCreate()
for(new i = 0; i < sizeof(g_iPlayerSound); i++)
{
TrieSetCell(g_tPlayerSound , g_iPlayerSound[i], i)
}
*/
formatex(szPluginInfoMsg, sizeof szPluginInfoMsg - 1, "ZM.ArminC.Tk")
formatex(szGhostInfoMsg, sizeof szGhostInfoMsg - 1, "You are a ghost until
the round end!")
set_task(1.0, "CustomCross", TASK_CROSS, _, _, "b")
}

public plugin_cfg()
{
set_task(0.5, "CacheCvars", TASK_CACHE)
}

public plugin_precache()
{
new modelpath[100]
formatex(modelpath, sizeof modelpath -1, "models/player/%s/%s.mdl",
g_GhostModel, g_GhostModel)
precache_model(modelpath)
}

public client_putinserver(id)
{
g_bIsAlive[id] = false
g_bIsConnected[id] = true
g_bIsGhost[id] = false
g_bAgree[id] = true
g_bFirstSpwan[id] = true
g_bIsBot[id] = bool:is_user_bot(id)
g_iIsSpectator[id] = 0
}

public client_disconnected(id)
{
if(g_bIsGhost[id])
{
fm_reset_user_model(id)
}
g_bIsAlive[id] = false
g_bIsConnected[id] = false
g_bIsGhost[id] = false
g_bIsBot[id] = false
g_bAgree[id] = true
g_bFirstSpwan[id] = true
g_iIsSpectator[id] = 0

if(!IsAlive(CS_TEAM_CT) || !IsAlive(CS_TEAM_T) && !g_bBombIsPlanted)


{
ForceRoundEnd()
}
}

public ev_FunctionP()
{
g_bBombIsPlanted = true
}

public ev_SpecHealth2(id)
{
g_iIsSpectator[id] = read_data(2)
}

public ev_NewRound()
{
g_bRoundEnd = false
g_bBombIsPlanted = false
CacheCvars()

for(new i = 1; i <= g_iMaxPlayers; i++)


{
if(g_bIsConnected[i])
{
remove_task(i + TASK_SPAWN)

if(g_bIsGhost[i])
{
cs_set_user_deaths(i, cs_get_user_deaths(i) - 1)
set_pdata_int(i, m_iClientHideHUD, 0)
set_pdata_int(i, m_iHideHUD, 0)
set_pev(i, pev_movetype, MOVETYPE_WALK)
set_pev(i, pev_takedamage, DAMAGE_AIM)
set_user_footsteps(i, 0)
fm_reset_user_model(i)
set_user_rendering(i)
}
g_bIsGhost[i] = false
}
}
}

public ev_RoundEnd()
{
if(!g_bRoundEnd)
{
ForceRoundEnd()
}
}

public fw_PlayerSpawn(id)
{
if(is_user_alive(id))
{
g_bIsAlive[id] = true
g_iIsSpectator[id] = 0
pev(id, pev_origin, g_fSpwanPosition[id])

if(g_bIsGhost[id])
{
StripWeapons(id)
SetUserGhost(id)
}
if(g_iCachepCvar[5] && g_bFirstSpwan[id] && !g_bIsBot[id])
{
GhostAgreeMenu(id)
}
g_bFirstSpwan[id] = false
}
}

public fw_PlayerKilled(id)
{
g_bIsAlive[id] = false

if(!g_bRoundEnd)
{
if(!IsAlive(CS_TEAM_CT) || !IsAlive(CS_TEAM_T) && !g_bBombIsPlanted)
{
ForceRoundEnd()
return
}
if(g_bIsGhost[id] && !g_iCachepCvar[2] && !g_bRoundEnd)
{
g_fGhostPosition[id] = g_fSpwanPosition[id]
set_task(float(g_iCachepCvar[6]), "RespawnGhost", id +
TASK_SPAWN)
}
if(!g_bIsGhost[id] && !g_bIsBot[id] && g_bAgree[id] && !g_bRoundEnd)
{
new CsTeams:iTeam = cs_get_user_team(id)
if(iTeam == CS_TEAM_T || iTeam == CS_TEAM_CT)
{
if(g_iCachepCvar[0])
{
pev(id, pev_origin, g_fGhostPosition[id])
}
set_task(float(g_iCachepCvar[6]), "RespawnGhost", id +
TASK_SPAWN)
}
}
}
else if(g_bIsGhost[id])
{
fm_reset_user_model(id)
}
}

public RespawnGhost(id)
{
id -= TASK_SPAWN
if(!g_bRoundEnd)
{
g_bIsGhost[id] = true
ExecuteHamB(Ham_CS_RoundRespawn, id)
}
}

public fw_KnifePrimaryAttack(iEnt)
{
new id = get_pdata_cbase(iEnt, m_pPlayer, XO_WEAPONS)
if(g_bIsGhost[id])
{
set_pdata_float(iEnt, m_flNextPrimaryAttack, 20.0, XO_WEAPONS)
return HAM_SUPERCEDE
}
return HAM_IGNORED
}

public fw_KnifeSecondaryAttack(iEnt)
{
new id = get_pdata_cbase(iEnt, m_pPlayer, XO_WEAPONS)
if(g_bIsGhost[id])
{
set_pdata_float(iEnt, m_flNextSecondaryAttack, 20.0, XO_WEAPONS)
return HAM_SUPERCEDE
}
return HAM_IGNORED
}

public fw_WeaponTouch(iEnt, id)


{
return (IsPlayer(id) && g_bIsGhost[id]) ? HAM_SUPERCEDE : HAM_IGNORED
}

public fw_CmdStart(id, uc, seed)


{
if(g_bIsGhost[id])
{
new Buttons = get_uc(uc, UC_Buttons)
new Impulse = get_uc(uc, UC_Impulse)

if(Buttons & IN_USE)


{
Buttons &= ~IN_USE
set_uc(uc, UC_Buttons, Buttons)
}
if(Impulse == 100 || Impulse == 201)
{
set_uc(uc, UC_Impulse, 0)
return FMRES_HANDLED
}
}
return FMRES_IGNORED
}

public fw_EmitSound(id, channel, const sound[])


{
if(TrieKeyExists(g_tPlayerSound, sound))
{
if(g_bIsGhost[id])
{
return FMRES_SUPERCEDE
}
}
return FMRES_IGNORED
}

public fw_ClientKill(id)
{
return g_bIsGhost[id] ? FMRES_SUPERCEDE : FMRES_IGNORED
}

public CustomCross()
{
for(new i = 1; i <= g_iMaxPlayers; i++)
{
if(g_bIsAlive[i] && g_bIsGhost[i])
{
ShowCustomSync(i, g_SyncCutomCross, g_Cross, iRandomNum,
iRandomNum, iRandomNum, -1.0, 1)
ShowCustomSync(i, g_SyncGhostInfo, szGhostInfoMsg, iRandomNum,
iRandomNum, iRandomNum, 0.04, 2)
ShowCustomSync(i, g_SyncPluginInfo, szPluginInfoMsg, 255, 50, 0,
0.95, 3)
}
}
}

public MsgScoreAttrib()
{
new id = get_msg_arg_int(1)

if(g_bIsGhost[id])
{
set_msg_arg_int(2, ARG_BYTE, SB_ATTRIB_DEAD)
}
}

public MsgCurWeapon(Msgid, Dest, id)


{
if(g_bIsAlive[id] && g_bIsGhost[id])
{
fm_set_user_weaponmodel(id)

static iWeapon
if(get_msg_arg_int(1))
{
iWeapon = get_msg_arg_int(2)
if(iWeapon != CSW_KNIFE)
{
set_task(0.2, "StripWeapons", id + TASK_STRIP)
}
}
}
}

public MsgClCorpse()
{
static id; id = get_msg_arg_int(12)

if(g_bIsAlive[id] && g_bIsGhost[id])


{
set_msg_arg_string(1, g_GhostModel)
}
}

public StripWeapons(id)
{
new pid = id < TASK_STRIP ? id : id - TASK_STRIP

if(g_bIsAlive[pid] && g_bIsGhost[pid])


{
strip_user_weapons(pid)
give_item(pid, "weapon_knife")
}
}

public BlockCmd(id)
{
return g_bIsGhost[id] ? PLUGIN_HANDLED : PLUGIN_CONTINUE
}

public fw_PreThink_Post(id)
{
if(!g_bIsAlive[id])
return

static i
for(i = 1; i <= g_iMaxPlayers; i++)
{
if(g_bIsGhost[id] != g_bIsGhost[i] || g_bIsGhost[id] && !g_bIsGhost[i])
{
if(g_bIsAlive[i])
{
set_pev(i, pev_solid, SOLID_NOT)
}
}
}
}

public client_PostThink(id)
{
if(!g_bIsAlive[id])
return

static i
for(i = 1; i <= g_iMaxPlayers; i++)
{
if(id != i)
{
if(g_bIsAlive[i] && !g_bIsGhost[i])
{
set_pev(i, pev_solid, SOLID_SLIDEBOX)
}
}
}
}

public fw_AddToFullPack_Post(es, e, ent, host, hostflags, player, pSet)


{
if(!get_orig_retval() || !g_bIsAlive[host] && !g_iIsSpectator[host])
{
return FMRES_IGNORED
}
if(player)
{
if(host != ent)
{
set_es(es, ES_Solid, SOLID_NOT)

if(g_bIsGhost[ent])
{
set_es(es, ES_RenderMode, kRenderTransAlpha)
set_es(es, ES_RenderAmt, 0)

if(!g_iCachepCvar[3] && !g_bIsGhost[host])


{
set_es(es, ES_Effects, get_es(es, ES_Effects) |
EF_NODRAW)
set_es(es, ES_Origin, Float:
{99999.9,99999.9,99999.9})
}
}
}
}
else
{
static owner ; owner = pev(ent, pev_owner)
if(IsPlayer(owner) && (ent == g_iEntPlayerModel[owner] || ent ==
g_iEntWeaponModel[owner]))
{
set_es(es, ES_Solid, SOLID_NOT)
set_es(es, ES_RenderFx, g_iCachepCvar[7] ? kRenderFxDistort :
kRenderFxHologram)
set_es(es, ES_RenderMode, kRenderTransAdd)
set_es(es, ES_RenderAmt, 175)
}
}
return FMRES_IGNORED
}

public CacheCvars()
{
g_iCachepCvar[0] = get_pcvar_num(g_pCvar[0])
g_iCachepCvar[1] = get_pcvar_num(g_pCvar[1])
g_iCachepCvar[2] = get_pcvar_num(g_pCvar[2])
g_iCachepCvar[3] = get_pcvar_num(g_pCvar[3])
g_iCachepCvar[4] = get_pcvar_num(g_pCvar[4])
g_iCachepCvar[5] = get_pcvar_num(g_pCvar[5])
g_iCachepCvar[6] = get_pcvar_num(g_pCvar[6])
g_iCachepCvar[7] = get_pcvar_num(g_pCvar[7])
}

public GhostAgreeMenu(id)
{
static menu[512]

new len = formatex(menu, sizeof menu -1,"\r Do you want to respawn as a ghost
after you die?^n")
len += formatex(menu[len], sizeof menu -1 -len,"\w1. Yes^n")
len += formatex(menu[len], sizeof menu -1 -len,"\w2. No")

show_menu(id, MENU_KEYS_GHOST , menu, -1)


}

public GhostMenuHandler(id, key)


{
switch(key)
{
case 0: g_bAgree[id] = true

case 1: g_bAgree[id] = false

}
}

SetUserGhost(id)
{
set_pdata_int(id, m_iRadiosLeft, 0, XO_PLAYER)
set_pdata_int(id, m_iClientHideHUD, 0)
set_pdata_int(id, m_iHideHUD, HUD_HIDE_FLAGS)
if(g_iCachepCvar[0])
{
engfunc(EngFunc_SetOrigin, id, g_fGhostPosition[id])
set_pev(id, pev_velocity, Float:{0.0,0.0,0.0})
SetUserDuck(id)
}
if(g_iCachepCvar[1])
{
set_pev(id, pev_movetype, MOVETYPE_NOCLIP)
}
set_pev(id, pev_solid, SOLID_NOT)
set_pev(id, pev_takedamage, DAMAGE_NO)
set_user_footsteps(id, 1)
if(g_iCachepCvar[4])
{
client_cmd(id,"spk ambience/thunder_clap.wav")
}
fm_set_user_model(id, g_GhostModel)
}

SetUserDuck(id)
{
set_pev(id, pev_flags, pev(id, pev_flags) | FL_DUCKING)
engfunc( EngFunc_SetSize, id, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX)
}

IsAlive(CsTeams:iTeam)
{
new iAliveNum

for(new i = 1; i <= g_iMaxPlayers; i++)


{
if(g_bIsAlive[i] && cs_get_user_team(i) == iTeam && !g_bIsGhost[i])
{
iAliveNum++
}
}
return iAliveNum
}

ForceRoundEnd()
{
g_bRoundEnd = true

for(new i = 1; i <= g_iMaxPlayers; i++)


{
if(g_bIsAlive[i] && g_bIsGhost[i])
{
set_pev(i, pev_takedamage, DAMAGE_AIM)
set_pev(i, pev_movetype, MOVETYPE_WALK)
user_silentkill(i)
}
}
}

fm_set_user_model(id, const model[])


{
set_pev(id, pev_rendermode, kRenderTransTexture)
set_pev(id, pev_renderamt, 1.0)

static modelpath[100]
formatex(modelpath, sizeof modelpath -1, "models/player/%s/%s.mdl", model,
model)

if(!pev_valid(g_iEntPlayerModel[id]))
{
g_iEntPlayerModel[id] = engfunc(EngFunc_CreateNamedEntity,
engfunc(EngFunc_AllocString, "info_target"))

if(!pev_valid(g_iEntPlayerModel[id])) return

set_pev(g_iEntPlayerModel[id], pev_classname, "ent_playermodel")


set_pev(g_iEntPlayerModel[id], pev_movetype, MOVETYPE_FOLLOW)
set_pev(g_iEntPlayerModel[id], pev_aiment, id)
set_pev(g_iEntPlayerModel[id], pev_owner, id)
}
engfunc(EngFunc_SetModel, g_iEntPlayerModel[id], modelpath)
}

fm_set_user_weaponmodel(id)
{
static model[100]
pev(id, pev_weaponmodel2, model, sizeof model -1)

if(!pev_valid(g_iEntWeaponModel[id]))
{
g_iEntWeaponModel[id] = engfunc(EngFunc_CreateNamedEntity,
engfunc(EngFunc_AllocString, "info_target"))

if (!pev_valid(g_iEntWeaponModel[id])) return

set_pev(g_iEntWeaponModel[id], pev_classname, "ent_weaponmodel")


set_pev(g_iEntWeaponModel[id], pev_movetype, MOVETYPE_FOLLOW)
set_pev(g_iEntWeaponModel[id], pev_aiment, id)
set_pev(g_iEntWeaponModel[id], pev_owner, id)
}
engfunc(EngFunc_SetModel, g_iEntWeaponModel[id], model)
}

fm_reset_user_model(id)
{
if(pev_valid(g_iEntPlayerModel[id]))
{
engfunc(EngFunc_RemoveEntity, g_iEntPlayerModel[id])
g_iEntPlayerModel[id] = 0
}
if(pev_valid(g_iEntWeaponModel[id]))
{
engfunc(EngFunc_RemoveEntity, g_iEntWeaponModel[id])
g_iEntWeaponModel[id] = 0
}
}

ShowCustomSync(id, SyncType, Msg[], Red, Green, Blue, Float:yPos, Channel)


{
set_hudmessage(Red, Green, Blue, -1.0, yPos, _, _, 2.0, _, _, Channel)
ShowSyncHudMsg(id, SyncType, Msg)
}