#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#define VERSION "1.0.0"
#define MAXPLAYERS 32 + 1
#define MAX_WEAPONS_INAIR 64
#define HANDLER_THINK_TIME 0.01
#define MIN_ROT_SPEED 1
#define MAX_ROT_SPEED 7
#define MAX_DIFF_FROM_HEAD 10.0
#define MIN_TOUCH_GMT 0.1
#define NULL 0.0
enum Data
{
EntID,
bFirstThink,
RotAngle,
RotSpeed,
WeaponIndex
}
enum iCvars
{
BaseSpeed,
UseDamage,
UseThrowing,
DropType,
DropC4,
OnlyUse
}
enum fCvars
{
Float:MinBaseDamage,
Float:MaxBaseDamage,
Float:HeadMulti
}
enum sCvars
{
BaseDamage
}
new const Float:g_WeaponWeight[CSW_P90 + 1] = {
NULL,
1.0, //p228
NULL, //shield
0.7, //scout
NULL, //he
0.7, //xm1014
0.75, //c4
0.9, //mac10
0.65, //aug
NULL, //smoke
0.8, //elite
1.0, //fiveseven
0.9, //ump45
0.6, //sg550
0.7, //galil
0.7, //famas
1.0, //usp
1.0, //glock
0.5, //awp
0.9, //mp5
0.5, //m249
0.6, //m3
0.7, //m4a1
1.0, //tmp
0.65, //g3sg1
NULL, //flash
0.9, //deagle
0.65, //sg552
0.7, //ak47
NULL, //knife
0.85 //p90
}
new c_sCvars[sCvars]
new c_fCvars[fCvars], Float:g_fCvars[fCvars]
new c_Cvars[iCvars], g_Cvars[iCvars]
new g_DeathMsg
new g_WeaponsOnGround
new g_WeaponData[MAX_WEAPONS_INAIR][Data]
new g_WeaponName[MAX_WEAPONS_INAIR][12]
new Float:g_WeaponDropGmt[MAX_WEAPONS_INAIR]
new Float:g_WeaponAngles[MAX_WEAPONS_INAIR][3]
new g_HandlerEnt
new cp_FF
public plugin_init() {
register_plugin("Weapon Throwing",VERSION,"shine")
register_cvar("weapon_throwing",VERSION,FCVAR_SERVER|FCVAR_SPONLY)
c_sCvars[sCvars:BaseDamage] = register_cvar("amx_wp_base_damage","20 40")
c_fCvars[fCvars:HeadMulti] = register_cvar("amx_wp_headshot_multi","3.0")
c_Cvars[iCvars:DropC4] = register_cvar("amx_wp_throw_c4","0")
c_Cvars[iCvars:OnlyUse] = register_cvar("amx_wp_use_e","1")
c_Cvars[iCvars:DropType] = register_cvar("amx_wp_throw_type","2")
c_Cvars[iCvars:UseDamage] = register_cvar("amx_wp_use_for_damage","1")
c_Cvars[iCvars:BaseSpeed] = register_cvar("amx_wp_base_throw_speed","1000")
c_Cvars[iCvars:UseThrowing] = register_cvar("amx_wp_use_for_throw_speed","1")
//Events
register_event("HLTV","RoundStart","a","1=0","2=0")
//Ham Forwards
RegisterHam(Ham_Touch,"weaponbox","HookTouch")
RegisterHam(Ham_Spawn,"weaponbox","HookSpawn",1)
RegisterHam(Ham_Think,"info_target","HandlerThink")
//Messages
g_DeathMsg = get_user_msgid("DeathMsg")
//Cvar Pointers
cp_FF = get_cvar_pointer("mp_friendlyfire")
//Load Cvars
LoadCvars()
//Make Handler
MakeHandler()
}
public MakeHandler() {
g_HandlerEnt = engfunc(EngFunc_CreateNamedEntity,engfunc(EngFunc_AllocString,"info_target"))
set_pev(g_HandlerEnt,pev_classname,"wpnTHandler")
set_pev(g_HandlerEnt,pev_nextthink,get_gametime() + HANDLER_THINK_TIME)
}
public HookTouch(Ent,id) {
static WeaponID
WeaponID = GetWeaponByEnt(Ent)
if(WeaponID > -1) {
static Owner
Owner = pev(Ent,pev_owner)
if(get_gametime() - g_WeaponDropGmt[WeaponID] <= MIN_TOUCH_GMT && id == Owner) {
return HAM_IGNORED
}
else {
if
(
Owner != id
&&
is_user_alive(id)
&&
(
(
get_pcvar_num(cp_FF)
&&
get_user_team(id) == get_user_team(Owner)
)
||
(
get_user_team(id) != get_user_team(Owner)
)
)
) {
static bool:HeadShot
static Float:Vel[3], Float:KnockVel[3], Float:EntOrigin[3], Float:HeadOrigin[3], Float:Damage, Float:rDamage
pev(Ent,pev_velocity,Vel)
pev(Ent,pev_origin,EntOrigin)
pev(id,pev_origin,HeadOrigin)
set_pev(Ent,pev_velocity,Float:{0.0, 0.0, 0.0})
HeadOrigin[2] += (pev(id,pev_button) & IN_DUCK) ? 6.0 : 22.0
HeadShot = (floatabs(HeadOrigin[2] - EntOrigin[2]) < MAX_DIFF_FROM_HEAD) ? true : false
//30.0 * 1.0 / 1.0 = 30.0
//30.0 * 3.0 / 1.0 = 90.0
//30.0 * 1.0 / 0.5 = 60.0
//20.0 * 1.0 / 0.5 = 40.0
//40.0 * 3.0 / 0.5 = 240.0
Damage =
(
random_float(g_fCvars[fCvars:MinBaseDamage],g_fCvars[fCvars:MaxBaseDamage])
) * (
HeadShot ? (g_fCvars[fCvars:HeadMulti]) : 1.0
) / (
g_Cvars[iCvars:UseDamage] ? (g_WeaponWeight[g_WeaponData[WeaponID][Data:WeaponIndex]]) : 1.0
)
rDamage = get_user_team(id) == get_user_team(Owner) ? Damage / 2.9 : Damage
if(pev(id,pev_health) - rDamage <= 0.0) {
user_silentkill2(id)
message_begin(MSG_ALL,g_DeathMsg)
write_byte(Owner)
write_byte(id)
write_byte(HeadShot ? 1 : 0)
write_string(g_WeaponName[WeaponID])
message_end()
}
else {
VecMulti(Vel,KnockVel,0.1)
ExecuteHam(Ham_TakeDamage,id,Owner,Owner,Damage,DMG_BULLET)
set_pev(id,pev_velocity,KnockVel)
}
}
//ClearVec(g_WeaponAngles[WeaponID])
g_WeaponAngles[WeaponID][0] = 0.0
g_WeaponAngles[WeaponID][2] = 0.0
set_pev(g_WeaponData[WeaponID][Data:EntID],pev_angles,g_WeaponAngles[WeaponID])
MoveWeaponIDDown(WeaponID)
}
}
return HAM_IGNORED
}
public RoundStart() {
static i, x
for(i = 0; i < MAX_WEAPONS_INAIR; i++) {
for(x = 0; x < _:Data; x++) {
g_WeaponData[i][Data:x] = 0
}
ClearVec(g_WeaponAngles[i])
}
g_WeaponsOnGround = 0
//Load Cvars
LoadCvars()
}
public HookSpawn(Ent) {
static Owner
Owner = pev(Ent,pev_owner)
if
(
is_user_alive(Owner)
&&
(
(
g_Cvars[iCvars:OnlyUse]
&&
pev(Owner,pev_button) & IN_USE
)
||
(
!g_Cvars[iCvars:OnlyUse]
)
)
) {
static Float:PlayerAngles[3], Type
pev(Owner,pev_v_angle,PlayerAngles)
g_WeaponData[g_WeaponsOnGround][Data:EntID] = Ent
g_WeaponData[g_WeaponsOnGround][Data:bFirstThink] = 1
g_WeaponDropGmt[g_WeaponsOnGround] = get_gametime()
Type = (g_Cvars[iCvars:DropType] == 2 ? random(2) : g_Cvars[iCvars:DropType])
if(Type) {
g_WeaponAngles[g_WeaponsOnGround][1] = PlayerAngles[1]
g_WeaponAngles[g_WeaponsOnGround][2] = 90.0
g_WeaponData[g_WeaponsOnGround][Data:RotAngle] = 0
g_WeaponData[g_WeaponsOnGround][Data:RotSpeed] = -random_num(MIN_ROT_SPEED,MAX_ROT_SPEED)
}
else {
g_WeaponAngles[g_WeaponsOnGround][2] = PlayerAngles[2]
g_WeaponData[g_WeaponsOnGround][Data:RotAngle] = 1
g_WeaponData[g_WeaponsOnGround][Data:RotSpeed] = random_num(MIN_ROT_SPEED,MAX_ROT_SPEED)
}
g_WeaponsOnGround++
}
}
public HandlerThink(Ent) {
if(Ent == g_HandlerEnt) {
static Item, i
for(i = 0; i < g_WeaponsOnGround; i++) {
if(pev_valid(g_WeaponData[i][Data:EntID])) {
if(g_WeaponData[i][Data:bFirstThink]) {
static Float:Vel[3], Float:PlayerVel[3], Model[64], WeaponName[33], Owner
pev(g_WeaponData[i][Data:EntID],pev_model,Model,63)
replace(Model,63,"models/w_","")
replace(Model,63,".mdl","")
replace(Model,63,"backpack","c4")
if(equal(Model,"c4") && !g_Cvars[iCvars:DropC4]) {
Item = i + 1
continue
}
copy(g_WeaponName[i],11,Model)
formatex(WeaponName,32,"weapon_%s",Model)
Owner = pev(g_WeaponData[i][Data:EntID],pev_owner)
pev(Owner,pev_velocity,PlayerVel)
g_WeaponData[i][Data:WeaponIndex] = get_weaponid(WeaponName)
velocity_by_aim(Owner,floatround(g_Cvars[iCvars:BaseSpeed] * (g_Cvars[iCvars:UseThrowing] == 1 ? (g_WeaponWeight[g_WeaponData[i][Data:WeaponIndex]]) : 1.0)),Vel)
VecAdd(Vel,PlayerVel,Vel)
set_pev(g_WeaponData[i][Data:EntID],pev_velocity,Vel)
g_WeaponData[i][Data:bFirstThink] = 0
}
g_WeaponAngles[i][g_WeaponData[i][Data:RotAngle]] += g_WeaponData[i][Data:RotSpeed]
if(g_WeaponAngles[i][g_WeaponData[i][Data:RotAngle]] >= float(degrees)) {
g_WeaponAngles[i][g_WeaponData[i][Data:RotAngle]] -= float(degrees)
}
set_pev(g_WeaponData[i][Data:EntID],pev_angles,g_WeaponAngles[i])
}
}
if(Item) {
MoveWeaponIDDown(Item - 1)
Item = 0
}
set_pev(Ent,pev_nextthink,get_gametime() + HANDLER_THINK_TIME)
}
}
public user_silentkill2(id) {
static MsgBlock
MsgBlock = get_msg_block(g_DeathMsg)
set_msg_block(g_DeathMsg,BLOCK_ONCE)
user_kill(id,1)
set_msg_block(g_DeathMsg,MsgBlock)
}
LoadCvars() {
//Load Cvars
static Cvar[10], Damage[2][5], i
get_pcvar_string(c_sCvars[sCvars:BaseDamage],Cvar,9)
parse(Cvar,Damage[0],4,Damage[1],4)
g_fCvars[fCvars:MinBaseDamage] = str_to_float(Damage[0])
g_fCvars[fCvars:MaxBaseDamage] = str_to_float(Damage[1])
for(i = 0; i < _:iCvars; i++) g_Cvars[iCvars:i] = get_pcvar_num(c_Cvars[iCvars:i])
for(i = 2; i < _:fCvars; i++) g_fCvars[fCvars:i] = get_pcvar_float(c_fCvars[fCvars:i])
}
ClearVec(Float:Vec[3]) {
Vec[0] = 0.0
Vec[1] = 0.0
Vec[2] = 0.0
}
CopyVec(Float:Vec[3],Float:eVec[3]) {
eVec[0] = Vec[0]
eVec[1] = Vec[1]
eVec[2] = Vec[2]
}
VecMulti(Float:Vec[3],Float:oVec[3],Float:Multi) {
oVec[0] = Vec[0] * Multi
oVec[1] = Vec[1] * Multi
oVec[2] = Vec[2] * Multi
}
VecAdd(Float:Vec[3],Float:aVec[3],Float:oVec[3]) {
oVec[0] = Vec[0] + aVec[0]
oVec[1] = Vec[1] + aVec[1]
oVec[2] = Vec[2] + aVec[2]
}
MoveWeaponIDDown(StartFrom) {
static i, x
for(i = StartFrom; i < g_WeaponsOnGround; i++) {
for(x = 0; x < _:Data; x++) {
g_WeaponData[i][Data:x] = g_WeaponData[i + 1][Data:x]
}
g_WeaponDropGmt[i] = g_WeaponDropGmt[i + 1]
copy(g_WeaponName[i + 1],15,g_WeaponName[i])
CopyVec(g_WeaponAngles[i + 1],g_WeaponAngles[i])
}
g_WeaponsOnGround--
}
GetWeaponByEnt(Ent) {
static i
for(i = 0; i < g_WeaponsOnGround; i++) {
if(g_WeaponData[i][Data:EntID] == Ent) return i
}
return -1
}
////