#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <hamsandwich>
#include <xs>
new const Plugin[] = "Easy Weapon Trade"
new const Author[] = "joaquimandrade and ConnorMcLeod"
new const Version[] = "1.0"
const m_pLastPrimaryItem = 368
const m_pLastSecondaryItem = 369
const m_pActiveItem = 373
const m_iId = 43
const m_iIdLinuxOffset = 4
const MaxSlots = 32
new IsTryingTradeWith[MaxSlots+1]
new IsTradingWith[MaxSlots+1]
new IsTradingItem[MaxSlots+1]
new WeaponType:IsTradingWeaponType[MaxSlots+1]
new Float:LastTradeStartTime[MaxSlots+1]
new Float:LastTradeEndTime[MaxSlots+1]
new Float:TradeMaxDistance
new CanTradeDiffCategoryWeapons
new TradeDelay
new Float:TradeCoolDown
new MsgBarTimeIndex
enum WeaponType
{
Primary,
Secondary
}
static PlayerWeaponsOffsets[WeaponType] = {m_pLastPrimaryItem,m_pLastSecondaryItem}
public plugin_init()
{
register_plugin(Plugin,Version,Author)
RegisterHam(Ham_ObjectCaps,"player","playerUse")
CanTradeDiffCategoryWeapons = get_pcvar_num( register_cvar("easy_weapon_trade_diff","1")) //A cvar a cserét határozza meg, tehát a játékos képes elcserélni Elsődleges fegyverét egy Másodlagosra.
TradeDelay = get_pcvar_num( register_cvar("easy_weapon_trade_delay","1")) // A csere késés/várakoztatási ideje.
TradeCoolDown = get_pcvar_float( register_cvar("easy_weapon_trade_cooldown","3.0")) //Az időt határozza meg, melytől újra lehet cserélni.
TradeMaxDistance = get_pcvar_float( register_cvar("easy_weapon_trade_maxdist","30.0")) //A távolságot határozza meg, melytől a játékosok tudnak cserélni.
MsgBarTimeIndex = get_user_msgid("BarTime")
register_cvar("easyWeaponTrade",Version,FCVAR_SERVER|FCVAR_SPONLY);
}
getLookingAt(id)
{
static Float:start[3],Float:viewOffset[3],Float:path[3],Float:dest[3]
pev(id,pev_origin,start);
pev(id,pev_view_ofs,viewOffset);
xs_vec_add(start,viewOffset,start);
pev(id,pev_v_angle,path);
engfunc(EngFunc_MakeVectors,path);
global_get(glb_v_forward,path);
xs_vec_mul_scalar(path,TradeMaxDistance,dest);
xs_vec_add(start,dest,dest);
engfunc(EngFunc_TraceLine,start,dest,0,id,0);
new hit = get_tr2(0,TR_pHit)
return 1 <= hit <= MaxSlots ? hit : 0
}
checkTrade(id)
{
if(!IsTradingWith[id])
{
new Float:currentTime = get_gametime()
if(currentTime >= (LastTradeEndTime[id] + TradeCoolDown))
{
new idLookingAt = getLookingAt(id)
if(idLookingAt && (get_user_team(id) == get_user_team(idLookingAt)) && currentTime >= (LastTradeEndTime[idLookingAt] + TradeCoolDown))
{
if((IsTryingTradeWith[id] = idLookingAt) && (IsTryingTradeWith[idLookingAt] == id))
{
new activeItem = get_pdata_cbase(id,m_pActiveItem)
new lookingAtActiveItem = get_pdata_cbase(idLookingAt,m_pActiveItem)
new bool:canTrade
if(CanTradeDiffCategoryWeapons)
{
new bool:idCanTrade
new bool:lookingAtCanTrade
for(new WeaponType:i=WeaponType:Primary;i<WeaponType;i++)
{
if(activeItem == get_pdata_cbase(id,PlayerWeaponsOffsets[i]))
{
IsTradingWeaponType[id] = i
idCanTrade = true
}
if(lookingAtActiveItem == get_pdata_cbase(idLookingAt,PlayerWeaponsOffsets[i]))
{
IsTradingWeaponType[idLookingAt] = i
lookingAtCanTrade = true
}
}
canTrade = idCanTrade && lookingAtCanTrade
}
else
{
for(new WeaponType:i=WeaponType:Primary;i<=WeaponType;i++)
{
if((activeItem == get_pdata_cbase(id,PlayerWeaponsOffsets[i])) && (lookingAtActiveItem == get_pdata_cbase(idLookingAt,PlayerWeaponsOffsets[i])))
{
canTrade = true
break;
}
}
}
if(canTrade)
{
if(TradeDelay)
{
startTrade(id,idLookingAt,activeItem,lookingAtActiveItem,TradeDelay)
}
else
{
finishTrade(id,idLookingAt)
}
}
}
}
}
}
else
{
new idLookingAt = getLookingAt(id)
if(idLookingAt)
{
new activeItem = get_pdata_cbase(id,m_pActiveItem)
new lookingAtActiveItem = get_pdata_cbase(idLookingAt,m_pActiveItem)
if((IsTradingWith[id] != idLookingAt) || (IsTradingWith[idLookingAt] != getLookingAt(idLookingAt)) || (lookingAtActiveItem != IsTradingItem[idLookingAt]) || (activeItem != IsTradingItem[id]))
{
stopTrade(id,IsTradingWith[id])
}
else if(get_gametime() >= (LastTradeStartTime[id] + TradeDelay))
{
finishTrade(id,IsTradingWith[id])
}
}
}
}
startTrade(id,id2,activeItem,activeItem2,tradeDelay)
{
IsTryingTradeWith[id] = IsTryingTradeWith[id2] = 0
LastTradeStartTime[id] = LastTradeStartTime[id2] = get_gametime()
IsTradingItem[id] = activeItem
IsTradingItem[id2] = activeItem2
IsTradingWith[id] = id2
IsTradingWith[id2] = id
showBar(id,tradeDelay)
showBar(id2,tradeDelay)
}
finishTrade(id,id2)
{
ExecuteHam(Ham_RemovePlayerItem,id,IsTradingItem[id])
ExecuteHam(Ham_RemovePlayerItem,id2,IsTradingItem[id2])
set_pdata_cbase(id,PlayerWeaponsOffsets[IsTradingWeaponType[id]],-1)
set_pdata_cbase(id2,PlayerWeaponsOffsets[IsTradingWeaponType[id2]],-1)
user_has_weapon(id,get_pdata_int(IsTradingItem[id],m_iId,m_iIdLinuxOffset),0)
user_has_weapon(id2,get_pdata_int(IsTradingItem[id2],m_iId,m_iIdLinuxOffset),0)
if(IsTradingWeaponType[id] != IsTradingWeaponType[id2])
{
static weaponClass[] = "weapon_smokegrenade"
new oldItem = get_pdata_cbase(id,PlayerWeaponsOffsets[IsTradingWeaponType[id2]])
if(oldItem != -1)
{
pev(oldItem,pev_classname,weaponClass,charsmax(weaponClass))
engclient_cmd(id,"drop",weaponClass)
}
new oldItem2 = get_pdata_cbase(id2,PlayerWeaponsOffsets[IsTradingWeaponType[id]])
if(oldItem2 != -1)
{
pev(oldItem2,pev_classname,weaponClass,charsmax(weaponClass))
engclient_cmd(id2,"drop",weaponClass)
}
}
ExecuteHam(Ham_AddPlayerItem,id,IsTradingItem[id2])
ExecuteHam(Ham_AddPlayerItem,id2,IsTradingItem[id])
stopTrade(id,id2)
LastTradeEndTime[id] = LastTradeEndTime[id2] = get_gametime()
}
stopTrade(id,id2)
{
IsTradingWith[id] = IsTradingWith[id2] = 0
showBar(id,0)
showBar(id2,0)
}
showBar(id,barTime)
{
message_begin(MSG_ONE_UNRELIABLE, MsgBarTimeIndex,.player=id)
write_short(barTime)
message_end()
}
public playerUse(id)
{
if(is_user_connected(id))
{
if(pev(id,pev_button) & IN_USE)
{
checkTrade(id)
}
else if(IsTradingWith[id])
{
stopTrade(id,IsTradingWith[id])
}
}
}