/*	Copyright © 2009, ConnorMcLeod

	Drop All Weapons On Death is free software;
	you can redistribute it and/or modify it under the terms of the
	GNU General Public License as published by the Free Software Foundation.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with Drop All Weapons On Death; if not, write to the
	Free Software Foundation, Inc., 59 Temple Place - Suite 330,
	Boston, MA 02111-1307, USA.
*/

#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>

#define PLUGIN "Drop All Weapons On Death"
#define AUTHOR "ConnorMcLeod"
#define VERSION "0.0.1"

#define	DONT_DROP_WEAPONS	((1<<CSW_KNIFE)|(1<<CSW_C4))

// "weapon_..." offsets
#define	m_pPlayer			41
#define	m_pNext			42
#define	m_iId			43

// "player" offsets
#define	m_pActiveItem			373
#define	m_rgAmmo_Player_Slot0	376

// "weaponbox" offsets
#define MAX_ITEMS_SLOTS	6
#define	m_rgiszAmmo_Slot0		41
new const m_rgpPlayerItems[MAX_ITEMS_SLOTS] = {34, 35, 36, 37, 38, 39}

new const g_szAmmoNames[][] = {
	"", "338Magnum", "762Nato", "556NatoBox", "556Nato",
	"buckshot", "45ACP", "57mm", "50AE", "357SIG",
	"9mm", "Flashbang", "HEGrenade", "SmokeGrenade", "C4"
}

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

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

	RegisterHam(Ham_Killed, "player", "Player_Killed")
}

public Event_HLTV_New_Round()
{
	new iWpnBx = engfunc(EngFunc_FindEntityByString, FM_NULLENT, "classname", "weaponbox")
	while( iWpnBx > 0 )
	{
		set_pev(iWpnBx, pev_flags, FL_KILLME)
		iWpnBx = engfunc(EngFunc_FindEntityByString, iWpnBx, "classname", "weaponbox")
	}
}

public Player_Killed( id, idKiller, bGibs )
{
	new iActiveItem = get_pdata_cbase(id, m_pActiveItem, 5)
	if( iActiveItem )
	{
		ExecuteHam(Ham_Item_Holster, iActiveItem, 1)
	}

	new iWeapon, iWeaponBox, iAmmoId, iBpAmmo
	new szWeapon[20], szModel[26], szAmmo[13]
	new Float:flOrigin[3], Float:flAngles[3], Float:flWpnBxOrig[3]

	new iWeapons = pev(id, pev_weapons)	
	pev(id, pev_origin, flOrigin)
	pev(id, pev_angles, flAngles)

	flAngles[0] = 0.0
	flAngles[2] = 0.0

	for(new i=1; i<=CSW_P90 && !(DONT_DROP_WEAPONS & i); i++)
	{
		if( iWeapons & (1<<i) )
		{
			get_weaponname(i, szWeapon, charsmax(szWeapon))
			iWeapon = FM_NULLENT
			while(	(iWeapon = engfunc(EngFunc_FindEntityByString, iWeapon, "classname", szWeapon)) > 0
				&&	get_pdata_cbase(iWeapon, m_pPlayer, 4) != id ) {}

			if( iWeapon )
			{
				iWeaponBox = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "weaponbox"))
				if( !pev_valid(iWeaponBox) )
				{
					continue
				}

				set_pev(iWeaponBox, pev_owner, id)

				flWpnBxOrig[0] = flOrigin[0] + random_num(-50,50)
				flWpnBxOrig[1] = flOrigin[1] + random_num(-50,50)
				flWpnBxOrig[2] = flOrigin[2]
				engfunc(EngFunc_SetOrigin, iWeaponBox, flWpnBxOrig)

				set_pev(iWeaponBox, pev_angles, flAngles)
				ExecuteHam(Ham_Spawn, iWeaponBox)

				if( !WeaponBox_PackWeapon(iWeaponBox, iWeapon) )
				{
					set_pev(iWeaponBox, pev_flags, FL_KILLME)
					dllfunc(DLLFunc_Think, iWeaponBox)
					continue
				}

				iAmmoId = ExecuteHam(Ham_Item_PrimaryAmmoIndex, iWeapon)
				
				if( 1 <= iAmmoId <= 14 )
				{
					copy(szAmmo, charsmax(szAmmo), g_szAmmoNames[iAmmoId])

					iBpAmmo = get_pdata_int(id, m_rgAmmo_Player_Slot0 + iAmmoId, 5)
					set_pdata_int(id, m_rgAmmo_Player_Slot0 + iAmmoId, 0, 5)				

					WeaponBox_PackAmmo(iWeaponBox, szAmmo, iBpAmmo)
				}

				replace(szWeapon, charsmax(szWeapon), "navy", "")
				replace(szWeapon, charsmax(szWeapon), "eapon", "")
				formatex(szModel, charsmax(szModel), "models/%s.mdl", szWeapon)
				engfunc(EngFunc_SetModel, iWeaponBox, szModel)				
			}
		}
	}
	return HAM_HANDLED
}

WeaponBox_PackWeapon(iWeaponBox, iWeapon)
{
	new iWeaponSlot = ExecuteHam(Ham_Item_ItemSlot, iWeapon)
	if( iWeaponSlot == 3 || iWeaponSlot == 5 )
	{
		return 0
	}

	new id = get_pdata_cbase(iWeapon, m_pPlayer, 4)
	if( id )
	{
		if( !ExecuteHam(Ham_RemovePlayerItem, id, iWeapon) )
		{
			return 0
		}
	}

	set_pdata_cbase(iWeaponBox, m_rgpPlayerItems[ iWeaponSlot ], iWeapon, 4)
	set_pdata_cbase(iWeapon, m_pNext, -1, 4)

	set_pev(iWeapon, pev_spawnflags, pev(iWeapon, pev_spawnflags) | SF_NORESPAWN)
	set_pev(iWeapon, pev_movetype, MOVETYPE_NONE)
	set_pev(iWeapon, pev_solid, SOLID_NOT)
	set_pev(iWeapon, pev_effects, EF_NODRAW)
	set_pev(iWeapon, pev_modelindex, 0)
	set_pev(iWeapon, pev_model, 0)
	set_pev(iWeapon, pev_owner, iWeaponBox)
	set_pdata_cbase(iWeapon, m_pPlayer, -1, 4)

	return 1
}

WeaponBox_PackAmmo(iWeaponBox, szAmmo[], iCount)
{
	if( !szAmmo[0] )
	{
		return
	}
	
	new iMaxCarry = MaxAmmoCarry( szAmmo )

	if ( iMaxCarry != -1 && iCount > 0 )
	{
		if( iCount > iMaxCarry )
		{
			iCount = iMaxCarry
		}
		set_pdata_int(iWeaponBox, m_rgiszAmmo_Slot0, engfunc(EngFunc_AllocString, szAmmo), 4)
		set_pdata_int(iWeaponBox, m_rgiszAmmo_Slot0 + 32, iCount, 4)

	}
}

MaxAmmoCarry(const szAmmo[])
{
	switch( szAmmo[0] )
	{
		case '3':
		{
			switch( szAmmo[1] )
			{
				case '3':return 30
				case '5':return 52
			}
		}
		case '4':return 100
		case '5':
		{
			switch( szAmmo[1] )
			{
				case '0':return 35
				case '5':return 90
				case '7':return 100
			}
		}
		case '7':return 90
		case '9':return 120
		case 'b':return 32
		case 'C','H','S':return 1
		case 'F':return 2
		default:
		{
			log_amx("Unidentified Ammo : %s", szAmmo)
			return -1
		}
	}
	return 1
}