Raised This Month: $51 Target: $400
 12% 

Unlock Gunxp some errors crashing server please help


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Godofwar
AlliedModders Donor
Join Date: Dec 2015
Location: Germany
Old 06-02-2020 , 08:12   Unlock Gunxp some errors crashing server please help
Reply With Quote #1

I need help about this errors, maybe anyone can help, the server is crashing sometimes about this file. Running an Swarm Mod and i need to use 1.8.3 Compiler for this. AMX Mod X Compiler 1.8.3-dev+5154

Code:
L 06/02/2020 - 13:17:39: [AMXX]    [0] fakemeta_util.inc::fm_find_ent_by_owner (line 81)
L 06/02/2020 - 13:17:39: [AMXX]    [1] fakemeta_util.inc::fm_get_user_weapon_entity (line 655)
L 06/02/2020 - 13:17:39: [AMXX]    [2] zpextrabalrog9.sma::Effect_ChargedAttack (line 337)
L 06/02/2020 - 13:17:44: [HAMSANDWICH] Entity out of range (1123024896)
L 06/02/2020 - 13:17:44: [AMXX] Displaying debug trace (plugin "zpextrabalrog9.amxx", version "1.0")
L 06/02/2020 - 13:17:44: [AMXX] Run time error 10: native error (native "ExecuteHamB")
L 06/02/2020 - 13:17:44: [AMXX]    [0] fakemeta_util.inc::fm_find_ent_by_owner (line 81)
L 06/02/2020 - 13:17:44: [AMXX]    [1] fakemeta_util.inc::fm_get_user_weapon_entity (line 655)
L 06/02/2020 - 13:17:44: [AMXX]    [2] zpextrabalrog9.sma::Effect_ChargedAttack (line 339)
Code:
#include <amxmodx>
#include <engine>
#include <amxmisc>
#include <fakemeta>
#include <fakemeta_util>
#include <hamsandwich>
#include <cstrike>
#include <xs>
#include <gxm_shop>

#define PLUGIN "Balrog-IX"
#define VERSION "1.0"
#define AUTHOR "Dias Pendragon"

#define ADMIN_ACCESS		ADMIN_RCON

// Draw Time
#define DRAW_TIME 1.0

// Next Attack Time
#define NEXTATTACK_MISS 0.5
#define NEXTATTACK_HIT 0.35

// Attack Distance
#define ATTACKDIS_SLASH 58.0
#define ATTACKDIS_CHARGE 68.0

// Attack Damage
#define DAMAGE_SLASH 200.0
#define DAMAGE_CHARGE 100.0

// Charge Mode
#define CHARGE_STARTTIME 0.75
#define CHARGE_ATTACKTIME 0.75
#define CHARGE_TIME 2.0
#define CHARGE_NEXTATTACK 1.0
#define CHARGE_EXPRADIUS 120

#define CHARGE_ATTACK_KNOCKPOWER 5000.0

// Task
#define TASK_CHARGE_STARTING 75675
#define TASK_CHARGING 464334

// Models
new const v_model[] = "models/gunxp/v_balrog9.mdl"
new const p_model[] = "models/gunxp/p_balrog9.mdl"

// Sprite
new const exp_spr[] = "sprites/balrogcritical.spr"
new const exp_spr2[] = "sprites/spear_exp.spr"

new const weapon_sound[9][] =
{
	"weapons/balrog9_draw.wav",
	"weapons/balrog9_slash1.wav",
	"weapons/balrog9_slash2.wav",
	"weapons/balrog9_hitwall.wav",
	"weapons/balrog9_hit1.wav",
	"weapons/balrog9_hit2.wav",
	"weapons/balrog9_charge_start1.wav",
	"weapons/balrog9_charge_finish1.wav",
	"weapons/balrog9_charge_attack2.wav"
}

enum
{
	B9_DRAW = 0,
	B9_SLASH1,
	B9_SLASH2,
	B9_HITWALL,
	B9_HIT1,
	B9_HIT2,
	B9_CHARGE_START,
	B9_CHARGE_FINISH,
	B9_CHARGE_ATTACK
}

new ItemIndex
new g_bot, g_exp_sprid, g_exp_sprid2
new g_had_balrog9[33], g_attack_mode[33], g_charging[33], g_charged[33], g_chargeattack[33]

enum
{
	MODE_NORMAL = 1,
	MODE_CHARGE
}

enum
{
	KNIFE_ANIM_IDLE = 0,
	KNIFE_ANIM_SLASH1,
	KNIFE_ANIM_SLASH2,
	KNIFE_ANIM_DRAW,
	KNIFE_ANIM_STAB_HIT,
	KNIFE_ANIM_STAB_MISS,
	KNIFE_ANIM_MIDSLASH1,
	KNIFE_ANIM_MIDSLASH2
}

enum
{
	BALROG9_ANIM_IDLE = 0,
	BALROG9_ANIM_SLASH1,
	BALROG9_ANIM_SLASH2,
	BALROG9_ANIM_SLASH3,
	BALROG9_ANIM_SLASH4,
	BALROG9_ANIM_SLASH5,
	BALROG9_ANIM_DRAW,
	BALROG9_ANIM_CHARGE_START,
	BALROG9_ANIM_CHARGE_FINISH,
	BALROG9_ANIM_CHARGE_IDLE1,
	BALROG9_ANIM_CHARGE_IDLE2,
	BALROG9_ANIM_CHARGE_ATTACK1,
	BALROG9_ANIM_CHARGE_ATTACK2
}

public plugin_init() 
{
	register_plugin(PLUGIN, VERSION, AUTHOR)
	
	register_event("CurWeapon", "Event_CurWeapon", "be", "1=1")
	
	register_forward(FM_EmitSound, "fw_EmitSound")
	register_forward(FM_CmdStart, "fw_CmdStart")
	register_forward(FM_TraceLine, "fw_TraceLine")
	register_forward(FM_TraceHull, "fw_TraceHull")		
	RegisterHam(Ham_CS_Weapon_SendWeaponAnim, "weapon_knife", "fw_Knife_SendAnim", 1)
	RegisterHam(Ham_TraceAttack, "player", "fw_TraceAttack")
	RegisterHam(Ham_TraceAttack, "player", "fw_TraceAttack_Post", 1)
	
	ItemIndex = gxm_register_knife("Balrog-9", 1600, 5, 2, 0, "KNIFE")
	
}

public gxm_knife_selected(id, itemid)
{
	if(ItemIndex == itemid)
	{
         get_balrog9(id)

}
}

public plugin_natives ( )
{
	register_native ( "give_barlog9", "get_balrog9", 1 );
}

public plugin_precache()
{
	engfunc(EngFunc_PrecacheModel, v_model)
	engfunc(EngFunc_PrecacheModel, p_model)
	
	for(new i = 0; i < sizeof(weapon_sound); i++)
		engfunc(EngFunc_PrecacheSound, weapon_sound[i])
		
		
	g_exp_sprid = engfunc(EngFunc_PrecacheModel, exp_spr)
	g_exp_sprid2 = engfunc(EngFunc_PrecacheModel, exp_spr2)
}

public get_balrog9(id)
{
	g_had_balrog9[id] = 1
	g_attack_mode[id] = 0
	g_charged[id] = 0
	g_charging[id] = 0
	g_chargeattack[id] = 0
	
	if(get_user_weapon(id) == CSW_KNIFE) 
	{
		Event_CurWeapon(id)
		set_weapon_anim(id, BALROG9_ANIM_DRAW)
	}
}


public remove_balrog9(id)
{
	g_had_balrog9[id] = 0
	g_attack_mode[id] = 0
	g_charged[id] = 0
	g_charging[id] = 0	
	g_chargeattack[id] = 0
	
	remove_task(id+TASK_CHARGE_STARTING)
	remove_task(id+TASK_CHARGING)
}

public client_putinserver(id)
{
	if(is_user_bot(id) && !g_bot)
	{
		g_bot = 1
		set_task(0.1, "Do_RegisterHamBot", id)
	}
}

public Do_RegisterHamBot(id)
{
	RegisterHamFromEntity(Ham_TraceAttack, id, "fw_TraceAttack")
	RegisterHamFromEntity(Ham_TraceAttack, id, "fw_TraceAttack_Post", 1)
}

public Event_CurWeapon(id)
{
	if(!is_user_alive(id) || get_user_team(id) != 2)
		return 1
	if(get_user_weapon(id) != CSW_KNIFE)
		return 1
	if(!g_had_balrog9[id])
		return 1
		
	set_pev(id, pev_viewmodel2, v_model)
	set_pev(id, pev_weaponmodel2, p_model)
		
	return 0
}

public fw_Knife_SendAnim(ent, anim, skip_local)
{
	if(!pev_valid(ent) && get_user_team(ent) != 2)
		return HAM_IGNORED
		
	new id
	id = get_pdata_cbase(ent, 41 , 4)
	
	if(!g_had_balrog9[id])
		return HAM_IGNORED
	
	static Float:PunchAngles[3]
	
	if(anim == KNIFE_ANIM_DRAW)
	{
		set_weapons_timeidle(id, DRAW_TIME)
		set_player_nextattack(id, DRAW_TIME)	
		
		set_weapon_anim(id, BALROG9_ANIM_DRAW)
		Remove_OldStuff(id)
	} else if(anim == KNIFE_ANIM_MIDSLASH1) {
		PunchAngles[0] = random_float(-1.0, -2.0)
		PunchAngles[1] = random_float(0.5, 1.5)
		PunchAngles[2] = 0.0
		
		set_pev(id, pev_punchangle, PunchAngles)
		set_weapon_anim(id, BALROG9_ANIM_SLASH1)
		Remove_OldStuff(id)
	} else if(anim == KNIFE_ANIM_MIDSLASH2) {
		PunchAngles[0] = random_float(-1.0, -2.0)
		PunchAngles[1] = random_float(-0.5, -1.5)
		PunchAngles[2] = 0.0
		
		set_pev(id, pev_punchangle, PunchAngles)
		set_weapon_anim(id, BALROG9_ANIM_SLASH2)
		Remove_OldStuff(id)
	} else if(anim == KNIFE_ANIM_STAB_HIT) {
		PunchAngles[0] = random_float(-0.5, 0.5)
		PunchAngles[1] = random_float(-0.5, -1.0)
		PunchAngles[2] = 0.0
		
		set_pev(id, pev_punchangle, PunchAngles)
		
		if(g_chargeattack[id] == 2) 
		{
			set_weapon_anim(id, BALROG9_ANIM_CHARGE_ATTACK2)
			set_task(0.1, "Effect_ChargedAttack", id)
		} else set_weapon_anim(id, BALROG9_ANIM_CHARGE_ATTACK1)
	} else if(anim == KNIFE_ANIM_STAB_MISS) {
		PunchAngles[0] = random_float(-0.5, 0.5)
		PunchAngles[1] = random_float(-0.5, -1.0)
		PunchAngles[2] = 0.0
		
		if(g_chargeattack[id] == 2) 
		{
			set_weapon_anim(id, BALROG9_ANIM_CHARGE_ATTACK2)
			set_task(0.1, "Effect_ChargedAttack", id)
		} else set_weapon_anim(id, BALROG9_ANIM_CHARGE_ATTACK1)
	}

	return HAM_IGNORED
}

public Remove_OldStuff(id)
{
	g_charging[id] = 0
	g_charged[id] = 0
	g_chargeattack[id] = 0

	remove_task(id+TASK_CHARGE_STARTING)
	remove_task(id+TASK_CHARGING)	
}

public Effect_ChargedAttack(id)
{
	static Float:Origin[3]
	get_position(id, 36.0, 0.0, 0.0, Origin)
	
	// DLight
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(27)
	engfunc(EngFunc_WriteCoord, Origin[0])
	engfunc(EngFunc_WriteCoord, Origin[1])
	engfunc(EngFunc_WriteCoord, Origin[2])
	write_byte(20)
	write_byte(200)
	write_byte(0)
	write_byte(0)
	write_byte(10)
	write_byte(60)
	message_end()
	
	// Exp
	message_begin(MSG_BROADCAST ,SVC_TEMPENTITY)
	write_byte(TE_EXPLOSION)
	engfunc(EngFunc_WriteCoord, Origin[0])
	engfunc(EngFunc_WriteCoord, Origin[1])
	engfunc(EngFunc_WriteCoord, Origin[2])
	write_short(g_exp_sprid)	// sprite index
	write_byte(1)	// scale in 0.1's
	write_byte(2)	// framerate
	write_byte(4)	// flags
	message_end()
	
	message_begin(MSG_BROADCAST ,SVC_TEMPENTITY)
	write_byte(TE_EXPLOSION)
	engfunc(EngFunc_WriteCoord, Origin[0])
	engfunc(EngFunc_WriteCoord, Origin[1])
	engfunc(EngFunc_WriteCoord, Origin[2])
	write_short(g_exp_sprid2)	// sprite index
	write_byte(7)	// scale in 0.1's
	write_byte(30)	// framerate
	write_byte(4)	// flags
	message_end()

	// Check Attack Damage
	HamRadiusDamage(id, fm_get_user_weapon_entity(id, CSW_KNIFE), float(CHARGE_EXPRADIUS), DAMAGE_CHARGE, DMG_BURN)
	//ExecuteHamB(Ham_TakeDamage, id, fm_get_user_weapon_entity(id, CSW_KNIFE), id, DAMAGE_CHARGE, DMG_BLAST)
	ExecuteHamB(Ham_TakeDamage, id, fm_get_user_weapon_entity(id, CSW_KNIFE), float(CHARGE_EXPRADIUS), DAMAGE_CHARGE, DMG_BURN)
	}


stock HamRadiusDamage(id, ent, Float:radius, Float:damage, bits) 
{ 
	static target, Float:origin[3] 
	
	target = -1
	pev(ent, pev_origin, origin) 
     
	while((target = find_ent_in_sphere(target, origin, radius) )) 
	{ 
		static Float:o[3] 
		pev(target, pev_origin, o) 
         
		xs_vec_sub(origin, o, o) 
         
		// Recheck if the entity is in radius 
		if (xs_vec_len(o) > radius) 
			continue 
		
		if(is_user_alive(target))
		{
			if(id == target)
				continue
			if(cs_get_user_team(id) == cs_get_user_team(target))
				continue
		}
         
		Ham_ExecDamageB(target, ent, id, damage * (xs_vec_len(o) / radius), HIT_GENERIC, bits) 
	} 
}  

stock Ham_ExecDamageB(victim, inflictor, attacker, Float:damage, hitgroup, bits)
{
	static const Float:hitgroup_multi[] =
	{
		1.0,  // HIT_GENERIC
		4.0,  // HIT_HEAD
		1.0,  // HIT_CHEST
		1.25, // HIT_STOMACH
		1.0,  // HIT_LEFTARM
		1.0,  // HIT_RIGHTARM
		0.75, // HIT_LEFTLEG
		0.75,  // HIT_RIGHTLEG
		0.0   // HIT_SHIELD
	} 
	
	set_pdata_int(victim, 75, hitgroup, 5)
	ExecuteHamB(Ham_TakeDamage, victim, inflictor, attacker, damage * hitgroup_multi[hitgroup], bits)
} 

public fw_TraceAttack(ent, attacker, Float:Damage, Float:Dir[3], ptr, DamageType)
{
	if(!is_user_alive(attacker) || get_user_team(attacker) != 2)
		return HAM_IGNORED
	if(get_user_weapon(attacker) != CSW_KNIFE || !g_had_balrog9[attacker])
		return HAM_IGNORED
		
	if(g_attack_mode[attacker] == MODE_NORMAL) SetHamParamFloat(3, DAMAGE_SLASH)
	else if(g_attack_mode[attacker] == MODE_CHARGE) SetHamParamFloat(3, DAMAGE_CHARGE)
	
	return HAM_HANDLED
}

public fw_TraceAttack_Post(ent, attacker, Float:Damage, Float:Dir[3], ptr, DamageType)
{
	if(!is_user_alive(attacker) || get_user_team(attacker) != 2)
		return HAM_IGNORED
	if(get_user_weapon(attacker) != CSW_KNIFE || !g_had_balrog9[attacker])
		return HAM_IGNORED
	if(g_attack_mode[attacker] == MODE_CHARGE) 
	{
		if(g_chargeattack[attacker] == 2) // Do KnockBack Here
		{
			static Float:Origin[3]
			pev(attacker, pev_origin, Origin)
			
			hook_ent2(ent, Origin, CHARGE_ATTACK_KNOCKPOWER, 2)
		}
	}
	
	return HAM_HANDLED
}

public fw_EmitSound(id, channel, const sample[], Float:volume, Float:attn, flags, pitch)
{
	if(!is_user_connected(id) || get_user_team(id) != 2)
		return FMRES_IGNORED
	if(get_user_weapon(id) != CSW_KNIFE || !g_had_balrog9[id])
		return FMRES_IGNORED
		
	if(sample[8] == 'k' && sample[9] == 'n' && sample[10] == 'i')
	{
		if(sample[14] == 's' && sample[15] == 'l' && sample[16] == 'a')
		{
			set_weapons_timeidle(id, NEXTATTACK_MISS)
			set_player_nextattack(id, NEXTATTACK_MISS)
			
			if(g_attack_mode[id] == MODE_CHARGE)
			{
				if(g_chargeattack[id] == 2)
					emit_sound(id, channel, weapon_sound[B9_CHARGE_ATTACK], volume, attn, flags, pitch)
				else
					emit_sound(id, channel, weapon_sound[random_num(B9_SLASH1, B9_SLASH2)], volume, attn, flags, pitch)
			} else emit_sound(id, channel, weapon_sound[random_num(B9_SLASH1, B9_SLASH2)], volume, attn, flags, pitch)
			return FMRES_SUPERCEDE
		}
		if (sample[14] == 'h' && sample[15] == 'i' && sample[16] == 't') // hit
		{
			if (sample[17] == 'w') // wall
			{
				set_weapons_timeidle(id, NEXTATTACK_HIT)
				set_player_nextattack(id, NEXTATTACK_HIT)	
				
				if(g_attack_mode[id] == MODE_CHARGE)
				{
					if(g_chargeattack[id] == 2)
						emit_sound(id, channel, weapon_sound[B9_CHARGE_ATTACK], volume, attn, flags, pitch)
					else
						emit_sound(id, channel, weapon_sound[B9_HITWALL], volume, attn, flags, pitch)
				} else emit_sound(id, channel, weapon_sound[B9_HITWALL], volume, attn, flags, pitch)
				return FMRES_SUPERCEDE
			} else {
				set_weapons_timeidle(id, NEXTATTACK_HIT)
				set_player_nextattack(id, NEXTATTACK_HIT)
				
				if(g_attack_mode[id] == MODE_CHARGE)
				{
					if(g_chargeattack[id] == 2)
						emit_sound(id, channel, weapon_sound[B9_CHARGE_ATTACK], volume, attn, flags, pitch)
					else
						emit_sound(id, channel, weapon_sound[random_num(B9_HIT1, B9_HIT2)], volume, attn, flags, pitch)
				} else emit_sound(id, channel, weapon_sound[random_num(B9_HIT1, B9_HIT2)], volume, attn, flags, pitch)
				return FMRES_SUPERCEDE
			}
		}
		if(sample[14] == 's' && sample[15] == 't' && sample[16] == 'a') // stab
		{
			if(g_chargeattack[id] == 2)
				emit_sound(id, channel, weapon_sound[B9_CHARGE_ATTACK], volume, attn, flags, pitch)
			else
				emit_sound(id, channel, weapon_sound[random_num(B9_HIT1, B9_HIT2)], volume, attn, flags, pitch)
				
			return FMRES_SUPERCEDE
		}
	}
	
	return FMRES_IGNORED
}

public fw_CmdStart(id, uc_handle, seed)
{
	if (!is_user_alive(id) || get_user_team(id) != 2) 
		return
	if(get_user_weapon(id) != CSW_KNIFE)
		return
	if(!g_had_balrog9[id])
		return
	
	static ent
	ent = find_ent_by_owner(-1, "weapon_knife", id)
	
	if(!pev_valid(ent))
		return
	
	static CurButton, OldButton
	
	CurButton = get_uc(uc_handle, UC_Buttons)
	OldButton = (pev(id, pev_oldbuttons) & IN_ATTACK2)
	
	if(CurButton & IN_ATTACK)
	{
		if(get_pdata_float(ent, 46, 4) > 0.0 || get_pdata_float(ent, 47, 4) > 0.0) 
			return
		
		g_attack_mode[id] = MODE_NORMAL
		set_uc(uc_handle, UC_Buttons, CurButton & ~IN_ATTACK2)
	} else {
		if(CurButton & IN_ATTACK2) 
		{
			set_uc(uc_handle, UC_Buttons, CurButton & ~IN_ATTACK2)
			set_uc(uc_handle, UC_Buttons, CurButton & ~IN_ATTACK)
			
			if(OldButton) // Holding This Button
			{
				if(g_charging[id] == 2)
				{
					if(get_pdata_float(ent, 46, 4) > 0.0 || get_pdata_float(ent, 47, 4) > 0.0) 
						return
					
					if(g_charged[id])
					{
						set_weapons_timeidle(id, 99999.0)
						set_player_nextattack(id, 99999.0)
						
						if(pev(id, pev_weaponanim) != BALROG9_ANIM_CHARGE_IDLE2)
							set_weapon_anim(id, BALROG9_ANIM_CHARGE_IDLE2)
					} else {
						set_weapons_timeidle(id, 99999.5)
						set_player_nextattack(id, 9999.5)
						
						if(pev(id, pev_weaponanim) != BALROG9_ANIM_CHARGE_IDLE1)
							set_weapon_anim(id, BALROG9_ANIM_CHARGE_IDLE1)
					}
				}
			}		
			
			if(get_pdata_float(ent, 46, 4) > 0.0 || get_pdata_float(ent, 47, 4) > 0.0) 
				return
			
			remove_task(id+TASK_CHARGE_STARTING)
			remove_task(id+TASK_CHARGING)	
			
			g_attack_mode[id] = MODE_CHARGE
			g_charging[id] = 1
			g_charged[id] = 0
			g_chargeattack[id] = 1
			
			set_weapons_timeidle(id, CHARGE_STARTTIME + 0.25)
			set_player_nextattack(id, CHARGE_STARTTIME + 0.25)
		
			set_weapon_anim(id, BALROG9_ANIM_CHARGE_START)
			
			set_task(CHARGE_STARTTIME, "Do_HoldCharge", id+TASK_CHARGE_STARTING)
			set_task(CHARGE_TIME, "Do_SetCharge", id+TASK_CHARGING)
		} else {
			if(OldButton) // After Press this Button (no Hold)
			{
				if(g_charging[id] == 2)
				{
					if(g_chargeattack[id])
					{
						ExecuteHamB(Ham_Weapon_SecondaryAttack, ent)
		
						set_weapons_timeidle(id, CHARGE_NEXTATTACK)
						set_player_nextattack(id, CHARGE_NEXTATTACK)
						
						g_charging[id] = 0
						g_charged[id] = 0
						g_chargeattack[id] = 0
						
						remove_task(id+TASK_CHARGE_STARTING)
						remove_task(id+TASK_CHARGING)
					}
				}
			}
		}
	}
}

public Do_SetCharge(id)
{
	id -= TASK_CHARGING
	
	if(!is_user_alive(id)|| get_user_team(id) != 2) 
		return
	if(get_user_weapon(id) != CSW_KNIFE)
		return
	if(!g_had_balrog9[id])
		return
		
	g_charging[id] = 2
	g_charged[id] = 1
	g_chargeattack[id] = 2
	
	set_weapons_timeidle(id, 0.25)
	set_player_nextattack(id, 0.25)
						
	set_weapon_anim(id, BALROG9_ANIM_CHARGE_FINISH)	
}

public Do_HoldCharge(id)
{
	id -= TASK_CHARGE_STARTING
	
	if(!is_user_alive(id)|| get_user_team(id) != 2) 
		return
	if(get_user_weapon(id) != CSW_KNIFE)
		return
	if(!g_had_balrog9[id])
		return
		
	if(!(pev(id, pev_button) & IN_ATTACK2) && !(pev(id, pev_oldbuttons) & IN_ATTACK2))
	{
		static ent
		ent = find_ent_by_owner(-1, "weapon_knife", id)
	
		if(!pev_valid(ent))
			return		
			
		ExecuteHamB(Ham_Weapon_SecondaryAttack, ent)
		
		set_weapons_timeidle(id, CHARGE_NEXTATTACK)
		set_player_nextattack(id, CHARGE_NEXTATTACK)
		
		g_charging[id] = 0
		g_charged[id] = 0
		g_chargeattack[id] = 0
		
		remove_task(id+TASK_CHARGE_STARTING)
		remove_task(id+TASK_CHARGING)
						
		return
	}
	
	g_charging[id] = 2
	g_chargeattack[id] = 1
	g_charged[id] = 0
		
	set_weapons_timeidle(id, CHARGE_TIME + 0.25)
	set_player_nextattack(id, CHARGE_TIME + 0.25)
		
	set_weapon_anim(id, BALROG9_ANIM_CHARGE_IDLE1)	
}

public fw_TraceLine(Float:vector_start[3], Float:vector_end[3], ignored_monster, id, handle)
{
	if (!is_user_alive(id)|| get_user_team(id) != 2)
		return FMRES_IGNORED	
	if (get_user_weapon(id) != CSW_KNIFE)
		return FMRES_IGNORED
	if(!g_had_balrog9[id])
		return FMRES_IGNORED
	
	static Float:vecStart[3], Float:vecEnd[3], Float:v_angle[3], Float:v_forward[3], Float:view_ofs[3], Float:fOrigin[3]
	
	pev(id, pev_origin, fOrigin)
	pev(id, pev_view_ofs, view_ofs)
	xs_vec_add(fOrigin, view_ofs, vecStart)
	pev(id, pev_v_angle, v_angle)
	
	engfunc(EngFunc_MakeVectors, v_angle)
	get_global_vector(GL_v_forward, v_forward)

	if(g_attack_mode[id] == MODE_NORMAL)
		xs_vec_mul_scalar(v_forward, ATTACKDIS_SLASH, v_forward)
	else if(g_attack_mode[id] == MODE_CHARGE)
		xs_vec_mul_scalar(v_forward, ATTACKDIS_CHARGE, v_forward)
	
	xs_vec_add(vecStart, v_forward, vecEnd)
	engfunc(EngFunc_TraceLine, vecStart, vecEnd, ignored_monster, id, handle)
	
	return FMRES_SUPERCEDE
}

public fw_TraceHull(Float:vector_start[3], Float:vector_end[3], ignored_monster, hull, id, handle)
{
	if (!is_user_alive(id)|| get_user_team(id) != 2)
		return FMRES_IGNORED
	if (get_user_weapon(id) != CSW_KNIFE)
		return FMRES_IGNORED
	if(!g_had_balrog9[id])
		return FMRES_IGNORED
	
	static Float:vecStart[3], Float:vecEnd[3], Float:v_angle[3], Float:v_forward[3], Float:view_ofs[3], Float:fOrigin[3]
	
	pev(id, pev_origin, fOrigin)
	pev(id, pev_view_ofs, view_ofs)
	xs_vec_add(fOrigin, view_ofs, vecStart)
	pev(id, pev_v_angle, v_angle)
	
	engfunc(EngFunc_MakeVectors, v_angle)
	get_global_vector(GL_v_forward, v_forward)

	if(g_attack_mode[id] == MODE_NORMAL)
		xs_vec_mul_scalar(v_forward, ATTACKDIS_SLASH, v_forward)
	else if(g_attack_mode[id] == MODE_CHARGE)
		xs_vec_mul_scalar(v_forward, ATTACKDIS_CHARGE, v_forward)
		
	xs_vec_add(vecStart, v_forward, vecEnd)
	engfunc(EngFunc_TraceHull, vecStart, vecEnd, ignored_monster, hull, id, handle)
	
	return FMRES_SUPERCEDE
}

stock get_position(ent, Float:forw, Float:right, Float:up, Float:vStart[])
{
	new Float:vOrigin[3], Float:vAngle[3], Float:vForward[3], Float:vRight[3], Float:vUp[3]
	
	pev(ent, pev_origin, vOrigin)
	pev(ent, pev_view_ofs,vUp) //for player
	xs_vec_add(vOrigin,vUp,vOrigin)
	pev(ent, pev_v_angle, vAngle) // if normal entity ,use pev_angles
	
	angle_vector(vAngle,ANGLEVECTOR_FORWARD,vForward) //or use EngFunc_AngleVectors
	angle_vector(vAngle,ANGLEVECTOR_RIGHT,vRight)
	angle_vector(vAngle,ANGLEVECTOR_UP,vUp)
	
	vStart[0] = vOrigin[0] + vForward[0] * forw + vRight[0] * right + vUp[0] * up
	vStart[1] = vOrigin[1] + vForward[1] * forw + vRight[1] * right + vUp[1] * up
	vStart[2] = vOrigin[2] + vForward[2] * forw + vRight[2] * right + vUp[2] * up
}
	
stock set_weapons_timeidle(id, Float:TimeIdle)
{
	if(!is_user_alive(id)|| get_user_team(id) != 2)
		return
		
	new entwpn = fm_get_user_weapon_entity(id, CSW_KNIFE)
	if (pev_valid(entwpn)) 
	{
		set_pdata_float(entwpn, 46, TimeIdle, 4)
		set_pdata_float(entwpn, 47, TimeIdle, 4)
		set_pdata_float(entwpn, 48, TimeIdle + 1.0, 4)
	}
}

stock set_player_nextattack(id, Float:nexttime)
{
	if(!is_user_alive(id)|| get_user_team(id) != 2)
		return
		
	const m_flNextAttack = 83
	set_pdata_float(id, m_flNextAttack, nexttime, 5)
}

stock set_weapon_anim(id, anim)
{
	if(!is_user_alive(id)|| get_user_team(id) != 2)
		return
		
	set_pev(id, pev_weaponanim, anim)
	
	message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, _, id)
	write_byte(anim)
	write_byte(0)
	message_end()	
}

stock hook_ent2(ent, Float:VicOrigin[3], Float:speed, type)
{
	static Float:fl_Velocity[3]
	static Float:EntOrigin[3]
	
	pev(ent, pev_origin, EntOrigin)
	static Float:distance_f
	distance_f = get_distance_f(EntOrigin, VicOrigin)
	
	new Float:fl_Time = distance_f / speed
	
	VicOrigin[2] -= 36.0
	
	if(type == 1)
	{
		fl_Velocity[0] = ((VicOrigin[0] - EntOrigin[0]) / fl_Time) * 1.5
		fl_Velocity[1] = ((VicOrigin[1] - EntOrigin[1]) / fl_Time) * 1.5
		fl_Velocity[2] = ((VicOrigin[2] - EntOrigin[2]) / fl_Time) * 1.5
	} else if(type == 2) {
		fl_Velocity[0] = ((EntOrigin[0] - VicOrigin[0]) / fl_Time) * 1.5
		fl_Velocity[1] = ((EntOrigin[1] - VicOrigin[1]) / fl_Time) * 1.5
		fl_Velocity[2] = ((EntOrigin[2] - VicOrigin[2]) / fl_Time) * 1.5
	}

	entity_set_vector(ent, EV_VEC_velocity, fl_Velocity)
}
fakemeta_util.inc
Code:
/**
 * This file provides various utility functions that use the Fakemeta module.
 * This file is created and maintained by VEN.
 * For support and issues, see:
 * http://forums.alliedmods.net/showthread.php?t=28284
 */
 

/* Fakemeta Utilities
*
* by VEN
*
* This file is provided as is (no warranties).
*/

#if !defined _fakemeta_included
	#include <fakemeta>
#endif

#if defined _fakemeta_util_included
	#endinput
#endif
#define _fakemeta_util_included

#include <xs>


/* Engine functions */

#define fm_precache_generic(%1) engfunc(EngFunc_PrecacheGeneric, %1)
/* stock fm_precache_generic(const file[])
	return engfunc(EngFunc_PrecacheGeneric, file) */

#define fm_precache_event(%1,%2) engfunc(EngFunc_PrecacheEvent, %1, %2)
/* stock fm_precache_event(type, const name[])
	return engfunc(EngFunc_PrecacheEvent, type, name) */

// ported by v3x
#define fm_drop_to_floor(%1) engfunc(EngFunc_DropToFloor, %1)
/* stock fm_drop_to_floor(entity)
	return engfunc(EngFunc_DropToFloor, entity) */

#define fm_force_use(%1,%2) dllfunc(DLLFunc_Use, %2, %1)
/* stock fm_force_use(user, used)
	return dllfunc(DLLFunc_Use, used, user) */

#define fm_entity_set_size(%1,%2,%3) engfunc(EngFunc_SetSize, %1, %2, %3)
/* stock fm_entity_set_size(index, const Float:mins[3], const Float:maxs[3])
	return engfunc(EngFunc_SetSize, index, mins, maxs) */

#define fm_get_decal_index(%1) engfunc(EngFunc_DecalIndex, %1)
/* stock fm_get_decal_index(const decalname[])
	return engfunc(EngFunc_DecalIndex, decalname) */

stock Float:fm_entity_range(ent1, ent2) {
	new Float:origin1[3], Float:origin2[3];
	pev(ent1, pev_origin, origin1);
	pev(ent2, pev_origin, origin2);

	return get_distance_f(origin1, origin2);
}

// based on KoST's port, upgraded version fits into the macros
#define fm_create_entity(%1) engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, %1))
/* stock fm_create_entity(const classname[])
	return engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, classname)) */

#define fm_find_ent_by_class(%1,%2) engfunc(EngFunc_FindEntityByString, %1, "classname", %2)
/* stock fm_find_ent_by_class(index, const classname[])
	return engfunc(EngFunc_FindEntityByString, index, "classname", classname) */

stock fm_find_ent_by_owner(index, const classname[], owner, jghgtype = 0) {
	new strtype[11] = "classname", ent = index;
	switch (jghgtype) {
		case 1: strtype = "target";
		case 2: strtype = "targetname";
	}

	while ((ent = engfunc(EngFunc_FindEntityByString, ent, strtype, classname)) && pev(ent, pev_owner) != owner) {}

	return ent;
}

#define fm_find_ent_by_target(%1,%2) engfunc(EngFunc_FindEntityByString, %1, "target", %2)
/* stock fm_find_ent_by_target(index, const target[])
	return engfunc(EngFunc_FindEntityByString, index, "target", target) */

#define fm_find_ent_by_tname(%1,%2) engfunc(EngFunc_FindEntityByString, %1, "targetname", %2)
/* stock fm_find_ent_by_tname(index, const targetname[])
	return engfunc(EngFunc_FindEntityByString, index, "targetname", targetname) */

stock fm_find_ent_by_model(index, const classname[], const model[]) {
	new ent = index, mdl[72];
	while ((ent = fm_find_ent_by_class(ent, classname))) {
		pev(ent, pev_model, mdl, sizeof mdl - 1);
		if (equal(mdl, model))
			return ent;
	}

	return 0;
}

#define fm_find_ent_in_sphere(%1,%2,%3) engfunc(EngFunc_FindEntityInSphere, %1, %2, %3)
/* stock fm_find_ent_in_sphere(index, const Float:origin[3], Float:radius)
	return engfunc(EngFunc_FindEntityInSphere, index, origin, radius) */

#define fm_call_think(%1) dllfunc(DLLFunc_Think, %1)
/* stock fm_call_think(entity)
	return dllfunc(DLLFunc_Think, entity) */

#define fm_is_valid_ent(%1) pev_valid(%1)
/* stock fm_is_valid_ent(index)
	return pev_valid(index) */

stock fm_entity_set_origin(index, const Float:origin[3]) {
	new Float:mins[3], Float:maxs[3];
	pev(index, pev_mins, mins);
	pev(index, pev_maxs, maxs);
	engfunc(EngFunc_SetSize, index, mins, maxs);

	return engfunc(EngFunc_SetOrigin, index, origin);
}

#define fm_entity_set_model(%1,%2) engfunc(EngFunc_SetModel, %1, %2)
/* stock fm_entity_set_model(index, const model[])
	return engfunc(EngFunc_SetModel, index, model) */

// ported by v3x
#define fm_remove_entity(%1) engfunc(EngFunc_RemoveEntity, %1)
/* stock fm_remove_entity(index)
	return engfunc(EngFunc_RemoveEntity, index) */

#define fm_entity_count() engfunc(EngFunc_NumberOfEntities)
/* stock fm_entity_count()
	return engfunc(EngFunc_NumberOfEntities) */

#define fm_fake_touch(%1,%2) dllfunc(DLLFunc_Touch, %1, %2)
/* stock fm_fake_touch(toucher, touched)
	return dllfunc(DLLFunc_Touch, toucher, touched) */

#define fm_DispatchSpawn(%1) dllfunc(DLLFunc_Spawn, %1)
/* stock fm_DispatchSpawn(entity)
	return dllfunc(DLLFunc_Spawn, entity) */

// ported by v3x
#define fm_point_contents(%1) engfunc(EngFunc_PointContents, %1)
/* stock fm_point_contents(const Float:point[3])
	return engfunc(EngFunc_PointContents, point) */

stock fm_trace_line(ignoreent, const Float:start[3], const Float:end[3], Float:ret[3]) {
	engfunc(EngFunc_TraceLine, start, end, ignoreent == -1 ? 1 : 0, ignoreent, 0);

	new ent = get_tr2(0, TR_pHit);
	get_tr2(0, TR_vecEndPos, ret);

	return pev_valid(ent) ? ent : 0;
}

stock fm_trace_hull(const Float:origin[3], hull, ignoredent = 0, ignoremonsters = 0) {
	new result = 0;
	engfunc(EngFunc_TraceHull, origin, origin, ignoremonsters, hull, ignoredent > 0 ? ignoredent : 0, 0);

	if (get_tr2(0, TR_StartSolid))
		result += 1;
	if (get_tr2(0, TR_AllSolid))
		result += 2;
	if (!get_tr2(0, TR_InOpen))
		result += 4;

	return result;
}

stock fm_trace_normal(ignoreent, const Float:start[3], const Float:end[3], Float:ret[3]) {
	engfunc(EngFunc_TraceLine, start, end, 0, ignoreent, 0);
	get_tr2(0, TR_vecPlaneNormal, ret);

	new Float:fraction;
	get_tr2(0, TR_flFraction, fraction);
	if (fraction >= 1.0)
		return 0;

	return 1;
}

// note that for CS planted C4 has a "grenade" classname as well
stock fm_get_grenade_id(id, model[], len, grenadeid = 0) {
	new ent = fm_find_ent_by_owner(grenadeid, "grenade", id);
	if (ent && len > 0)
		pev(ent, pev_model, model, len);

	return ent;
}

#define fm_halflife_time() get_gametime()
/* stock Float:fm_halflife_time()
	return get_gametime() */

#define fm_attach_view(%1,%2) engfunc(EngFunc_SetView, %1, %2)
/* stock fm_attach_view(index, entity)
	return engfunc(EngFunc_SetView, index, entity) */

stock fm_playback_event(flags, invoker, eventindex, Float:delay, const Float:origin[3], const Float:angles[3], Float:fparam1, Float:fparam2, iparam1, iparam2, bparam1, bparam2) {
	return engfunc(EngFunc_PlaybackEvent, flags, invoker, eventindex, delay, origin, angles, fparam1, fparam2, iparam1, iparam2, bparam1, bparam2);
}

#define fm_eng_get_string(%1,%2,%3) engfunc(EngFunc_SzFromIndex, %1, %2, %3)
/* stock fm_eng_get_string(istring, string[], len)
	return engfunc(EngFunc_SzFromIndex, istring, string, len) */


/* HLSDK functions */

// the dot product is performed in 2d, making the view cone infinitely tall
stock bool:fm_is_in_viewcone(index, const Float:point[3]) {
	new Float:angles[3];
	pev(index, pev_angles, angles);
	engfunc(EngFunc_MakeVectors, angles);
	global_get(glb_v_forward, angles);
	angles[2] = 0.0;

	new Float:origin[3], Float:diff[3], Float:norm[3];
	pev(index, pev_origin, origin);
	xs_vec_sub(point, origin, diff);
	diff[2] = 0.0;
	xs_vec_normalize(diff, norm);

	new Float:dot, Float:fov;
	dot = xs_vec_dot(norm, angles);
	pev(index, pev_fov, fov);
	if (dot >= floatcos(fov * M_PI / 360))
		return true;

	return false;
}

stock bool:fm_is_visible(index, const Float:point[3], ignoremonsters = 0) {
	new Float:start[3], Float:view_ofs[3];
	pev(index, pev_origin, start);
	pev(index, pev_view_ofs, view_ofs);
	xs_vec_add(start, view_ofs, start);

	engfunc(EngFunc_TraceLine, start, point, ignoremonsters, index, 0);

	new Float:fraction;
	get_tr2(0, TR_flFraction, fraction);
	if (fraction == 1.0)
		return true;

	return false;
}


/* Engine_stocks functions */

stock fm_fakedamage(victim, const classname[], Float:takedmgdamage, damagetype) {
	new class[] = "trigger_hurt";
	new entity = fm_create_entity(class);
	if (!entity)
		return 0;

	new value[16];
	float_to_str(takedmgdamage * 2, value, sizeof value - 1);
	fm_set_kvd(entity, "dmg", value, class);

	num_to_str(damagetype, value, sizeof value - 1);
	fm_set_kvd(entity, "damagetype", value, class);

	fm_set_kvd(entity, "origin", "8192 8192 8192", class);
	fm_DispatchSpawn(entity);

	set_pev(entity, pev_classname, classname);
	fm_fake_touch(entity, victim);
	fm_remove_entity(entity);

	return 1;
}

#define fm_find_ent(%1,%2) engfunc(EngFunc_FindEntityByString, %1, "classname", %2)
/* stock fm_find_ent(index, const classname[])
	return engfunc(EngFunc_FindEntityByString, index, "classname", classname) */

#define fm_get_user_button(%1) pev(%1, pev_button)
/* stock fm_get_user_button(index)
	return pev(index, pev_button) */

#define fm_get_user_oldbutton(%1) pev(%1, pev_oldbuttons)
/* stock fm_get_user_oldbutton(index)
	return pev(index, pev_oldbuttons) */

#define fm_get_entity_flags(%1) pev(%1, pev_flags)
/* stock fm_get_entity_flags(index)
	return pev(index, pev_flags) */

#define fm_get_entity_distance(%1,%2) floatround(fm_entity_range(%1, %2))
/* stock fm_get_entity_distance(ent1, ent2)
	return floatround(fm_entity_range(ent1, ent2)) */

#define fm_get_grenade(%1) fm_get_grenade_id(%1, "", 0)
/* stock fm_get_grenade(id)
	return fm_get_grenade_id(id, "", 0) */

// optimization idea by Orangutanz
stock fm_get_brush_entity_origin(index, Float:origin[3]) {
	new Float:mins[3], Float:maxs[3];

	pev(index, pev_origin, origin);
	pev(index, pev_mins, mins);
	pev(index, pev_maxs, maxs);

	origin[0] += (mins[0] + maxs[0]) * 0.5;
	origin[1] += (mins[1] + maxs[1]) * 0.5;
	origin[2] += (mins[2] + maxs[2]) * 0.5;

	return 1;
}

// based on v3x's port, upgraded version returns number of removed entities
stock fm_remove_entity_name(const classname[]) {
	new ent = -1, num = 0;
	while ((ent = fm_find_ent_by_class(ent, classname)))
		num += fm_remove_entity(ent);

	return num;
}

stock fm_ViewContents(id) {
	new origin[3], Float:Orig[3];
	get_user_origin(id, origin, 3);
	IVecFVec(origin, Orig);

	return fm_point_contents(Orig);
}

stock fm_get_speed(entity) {
	new Float:Vel[3];
	pev(entity, pev_velocity, Vel);

	return floatround(vector_length(Vel));
}

stock fm_set_rendering(entity, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16) {
	new Float:RenderColor[3];
	RenderColor[0] = float(r);
	RenderColor[1] = float(g);
	RenderColor[2] = float(b);

	set_pev(entity, pev_renderfx, fx);
	set_pev(entity, pev_rendercolor, RenderColor);
	set_pev(entity, pev_rendermode, render);
	set_pev(entity, pev_renderamt, float(amount));

	return 1;
}

stock fm_set_entity_flags(index, flag, onoff) {
	new flags = pev(index, pev_flags);
	if ((flags & flag) > 0)
		return onoff == 1 ? 2 : 1 + 0 * set_pev(index, pev_flags, flags - flag);
	else
		return onoff == 0 ? 2 : 1 + 0 * set_pev(index, pev_flags, flags + flag);

	return 0;
}

stock fm_set_entity_visibility(index, visible = 1) {
	set_pev(index, pev_effects, visible == 1 ? pev(index, pev_effects) & ~EF_NODRAW : pev(index, pev_effects) | EF_NODRAW);

	return 1;
}

#define fm_get_entity_visibility(%1) (!(pev(%1, pev_effects) & EF_NODRAW))
/* stock fm_get_entity_visibility(index)
	return !(pev(index, pev_effects) & EF_NODRAW) */

stock fm_set_user_velocity(entity, const Float:vector[3]) {
	set_pev(entity, pev_velocity, vector);

	return 1;
}

#define fm_get_user_velocity(%1,%2) pev(%1, pev_velocity, %2)
/* stock fm_get_user_velocity(entity, Float:vector[3])
	return pev(entity, pev_velocity, vector) */


/* Fun functions */

#define fm_get_client_listen(%1,%2) engfunc(EngFunc_GetClientListening, %1, %2)
/* stock fm_get_client_listen(receiver, sender)
	return engfunc(EngFunc_GetClientListening, receiver, sender) */

#define fm_set_client_listen(%1,%2,%3) engfunc(EngFunc_SetClientListening, %1, %2, %3)
/* stock fm_set_client_listen(receiver, sender, listen)
	return engfunc(EngFunc_SetClientListening, receiver, sender, listen) */

stock fm_get_user_godmode(index) {
	new Float:val;
	pev(index, pev_takedamage, val);

	return (val == DAMAGE_NO);
}

stock fm_set_user_godmode(index, godmode = 0) {
	set_pev(index, pev_takedamage, godmode == 1 ? DAMAGE_NO : DAMAGE_AIM);

	return 1;
}

stock fm_set_user_armor(index, armor) {
	set_pev(index, pev_armorvalue, float(armor));

	return 1;
}

stock fm_set_user_health(index, health) {
	health > 0 ? set_pev(index, pev_health, float(health)) : dllfunc(DLLFunc_ClientKill, index);

	return 1;
}

stock fm_set_user_origin(index, /* const */ origin[3]) {
	new Float:orig[3];
	IVecFVec(origin, orig);

	return fm_entity_set_origin(index, orig);
}

stock fm_set_user_rendering(index, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16) {
	return fm_set_rendering(index, fx, r, g, b, render, amount);
}

stock fm_give_item(index, const item[]) {
	if (!equal(item, "weapon_", 7) && !equal(item, "ammo_", 5) && !equal(item, "item_", 5) && !equal(item, "tf_weapon_", 10))
		return 0;

	new ent = fm_create_entity(item);
	if (!pev_valid(ent))
		return 0;

	new Float:origin[3];
	pev(index, pev_origin, origin);
	set_pev(ent, pev_origin, origin);
	set_pev(ent, pev_spawnflags, pev(ent, pev_spawnflags) | SF_NORESPAWN);
	dllfunc(DLLFunc_Spawn, ent);

	new save = pev(ent, pev_solid);
	dllfunc(DLLFunc_Touch, ent, index);
	if (pev(ent, pev_solid) != save)
		return ent;

	engfunc(EngFunc_RemoveEntity, ent);

	return -1;
}

stock fm_set_user_maxspeed(index, Float:speed = -1.0) {
	engfunc(EngFunc_SetClientMaxspeed, index, speed);
	set_pev(index, pev_maxspeed, speed);

	return 1;
}

stock Float:fm_get_user_maxspeed(index) {
	new Float:speed;
	pev(index, pev_maxspeed, speed);

	return speed;
}

stock fm_set_user_gravity(index, Float:gravity = 1.0) {
	set_pev(index, pev_gravity, gravity);

	return 1;
}

stock Float:fm_get_user_gravity(index) {
	new Float:gravity;
	pev(index, pev_gravity, gravity);

	return gravity;
}

/* interferes with FM_Spawn enum, just use fm_DispatchSpawn
stock fm_spawn(entity) {
	return dllfunc(DLLFunc_Spawn, entity)
}
*/

stock fm_set_user_noclip(index, noclip = 0) {
	set_pev(index, pev_movetype, noclip == 1 ? MOVETYPE_NOCLIP : MOVETYPE_WALK);

	return 1;
}

#define fm_get_user_noclip(%1) (pev(%1, pev_movetype) == MOVETYPE_NOCLIP)
/* stock fm_get_user_noclip(index)
	return (pev(index, pev_movetype) == MOVETYPE_NOCLIP) */

// note: get_user_weapon will still return former weapon index
stock fm_strip_user_weapons(index) {
	new ent = fm_create_entity("player_weaponstrip");
	if (!pev_valid(ent))
		return 0;

	dllfunc(DLLFunc_Spawn, ent);
	dllfunc(DLLFunc_Use, ent, index);
	engfunc(EngFunc_RemoveEntity, ent);

	return 1;
}

stock fm_set_user_frags(index, frags) {
	set_pev(index, pev_frags, float(frags));

	return 1;
}


/* Cstrike functions */

stock fm_cs_user_spawn(index) {
	set_pev(index, pev_deadflag, DEAD_RESPAWNABLE);
	dllfunc(DLLFunc_Spawn, index);
	set_pev(index, pev_iuser1, 0);

	return 1;
}


/* Custom functions */

// based on Basic-Master's set_keyvalue, upgraded version accepts an optional classname (a bit more efficient if it is passed)
stock fm_set_kvd(entity, const key[], const value[], const classname[] = "") {
	if (classname[0])
		set_kvd(0, KV_ClassName, classname);
	else {
		new class[32];
		pev(entity, pev_classname, class, sizeof class - 1);
		set_kvd(0, KV_ClassName, class);
	}

	set_kvd(0, KV_KeyName, key);
	set_kvd(0, KV_Value, value);
	set_kvd(0, KV_fHandled, 0);

	return dllfunc(DLLFunc_KeyValue, entity, 0);
}

stock fm_find_ent_by_integer(index, pev_field, value) {
	static maxents;
	if (!maxents)
		maxents = global_get(glb_maxEntities);

	for (new i = index + 1; i < maxents; ++i) {
		if (pev_valid(i) && pev(i, pev_field) == value)
			return i;
	}

	return 0;
}

stock fm_find_ent_by_flags(index, pev_field, flags) {
	static maxents;
	if (!maxents)
		maxents = global_get(glb_maxEntities);

	for (new i = index + 1; i < maxents; ++i) {
		if (pev_valid(i) && (pev(i, pev_field) & flags) == flags)
			return i;
	}

	return 0;
}

stock Float:fm_distance_to_box(const Float:point[3], const Float:mins[3], const Float:maxs[3]) {
	new Float:dist[3];
	for (new i = 0; i < 3; ++i) {
		if (point[i] > maxs[i])
			dist[i] = point[i] - maxs[i];
		else if (mins[i] > point[i])
			dist[i] = mins[i] - point[i];
	}

	return vector_length(dist);
}

stock Float:fm_boxes_distance(const Float:mins1[3], const Float:maxs1[3], const Float:mins2[3], const Float:maxs2[3]) {
	new Float:dist[3];
	for (new i = 0; i < 3; ++i) {
		if (mins1[i] > maxs2[i])
			dist[i] = mins1[i] - maxs2[i];
		else if (mins2[i] > maxs1[i])
			dist[i] = mins2[i] - maxs1[i];
	}

	return vector_length(dist);
}

stock Float:fm_distance_to_boxent(entity, boxent) {
	new Float:point[3];
	pev(entity, pev_origin, point);

	new Float:mins[3], Float:maxs[3];
	pev(boxent, pev_absmin, mins);
	pev(boxent, pev_absmax, maxs);

	return fm_distance_to_box(point, mins, maxs);
}

stock Float:fm_boxents_distance(boxent1, boxent2) {
	new Float:mins1[3], Float:maxs1[3];
	pev(boxent1, pev_absmin, mins1);
	pev(boxent1, pev_absmax, maxs1);

	new Float:mins2[3], Float:maxs2[3];
	pev(boxent2, pev_absmin, mins2);
	pev(boxent2, pev_absmax, maxs2);

	return fm_boxes_distance(mins1, maxs1, mins2, maxs2);
}

// projects a center of a player's feet base (originally by P34nut, improved)
stock Float:fm_distance_to_floor(index, ignoremonsters = 1) {
	new Float:start[3], Float:dest[3], Float:end[3];
	pev(index, pev_origin, start);
	dest[0] = start[0];
	dest[1] = start[1];
	dest[2] = -8191.0;

	engfunc(EngFunc_TraceLine, start, dest, ignoremonsters, index, 0);
	get_tr2(0, TR_vecEndPos, end);

	pev(index, pev_absmin, start);
	new Float:ret = start[2] - end[2];

	return ret > 0 ? ret : 0.0;
}

// potential to crash (?) if used on weaponbox+weapon_* entity pair (use fm_remove_weaponbox instead)
stock fm_kill_entity(index) {
	set_pev(index, pev_flags, pev(index, pev_flags) | FL_KILLME);

	return 1;
}

// if weapon index isn't passed then assuming that it's the current weapon
stock fm_get_user_weapon_entity(id, wid = 0) {
	new weap = wid, clip, ammo;
	if (!weap && !(weap = get_user_weapon(id, clip, ammo)))
		return 0;
	
	new class[32];
	get_weaponname(weap, class, sizeof class - 1);

	return fm_find_ent_by_owner(-1, class, id);
}

// only weapon index or its name can be passed, if neither is passed then the current gun will be stripped
stock bool:fm_strip_user_gun(index, wid = 0, const wname[] = "") {
	new ent_class[32];
	if (!wid && wname[0])
		copy(ent_class, sizeof ent_class - 1, wname);
	else {
		new weapon = wid, clip, ammo;
		if (!weapon && !(weapon = get_user_weapon(index, clip, ammo)))
			return false;
		
		get_weaponname(weapon, ent_class, sizeof ent_class - 1);
	}

	new ent_weap = fm_find_ent_by_owner(-1, ent_class, index);
	if (!ent_weap)
		return false;

	engclient_cmd(index, "drop", ent_class);

	new ent_box = pev(ent_weap, pev_owner);
	if (!ent_box || ent_box == index)
		return false;

	dllfunc(DLLFunc_Think, ent_box);

	return true;
}

// only weapon index or its name can be passed, if neither is passed then the current gun will be transferred
stock bool:fm_transfer_user_gun(index1, index2, wid = 0, const wname[] = "") {
	new ent_class[32];
	if (!wid && wname[0])
		copy(ent_class, sizeof ent_class - 1, wname);
	else {
		new weapon = wid, clip, ammo;
		if (!weapon && !(weapon = get_user_weapon(index1, clip, ammo)))
			return false;
		
		get_weaponname(weapon, ent_class, sizeof ent_class - 1);
	}

	new ent_weap = fm_find_ent_by_owner(-1, ent_class, index1);
	if (!ent_weap)
		return false;

	engclient_cmd(index1, "drop", ent_class);

	new ent_box = pev(ent_weap, pev_owner);
	if (!ent_box || ent_box == index1)
		return false;

	set_pev(ent_box, pev_flags, pev(ent_box, pev_flags) | FL_ONGROUND);
	dllfunc(DLLFunc_Touch, ent_box, index2);
	if (pev(ent_weap, pev_owner) != index2)
		return false;

	return true;
}

stock bool:fm_is_ent_visible(index, entity, ignoremonsters = 0) {
	new Float:start[3], Float:dest[3];
	pev(index, pev_origin, start);
	pev(index, pev_view_ofs, dest);
	xs_vec_add(start, dest, start);

	pev(entity, pev_origin, dest);
	engfunc(EngFunc_TraceLine, start, dest, ignoremonsters, index, 0);

	new Float:fraction;
	get_tr2(0, TR_flFraction, fraction);
	if (fraction == 1.0 || get_tr2(0, TR_pHit) == entity)
		return true;

	return false;
}

// ported from AMXX's core get_user_origin(..., 3) (suggested by Greenberet)
stock fm_get_aim_origin(index, Float:origin[3]) {
	new Float:start[3], Float:view_ofs[3];
	pev(index, pev_origin, start);
	pev(index, pev_view_ofs, view_ofs);
	xs_vec_add(start, view_ofs, start);

	new Float:dest[3];
	pev(index, pev_v_angle, dest);
	engfunc(EngFunc_MakeVectors, dest);
	global_get(glb_v_forward, dest);
	xs_vec_mul_scalar(dest, 9999.0, dest);
	xs_vec_add(start, dest, dest);

	engfunc(EngFunc_TraceLine, start, dest, 0, index, 0);
	get_tr2(0, TR_vecEndPos, origin);

	return 1;
}

stock bool:fm_get_user_longjump(index) {
	new value[2];
	engfunc(EngFunc_GetPhysicsKeyValue, index, "slj", value, 1);
	switch (value[0]) {
		case '1': return true;
	}

	return false;
}

stock fm_set_user_longjump(index, bool:longjump = true, bool:tempicon = true) {
	if (longjump == fm_get_user_longjump(index))
		return;

	if (longjump) {
		engfunc(EngFunc_SetPhysicsKeyValue, index, "slj", "1");
		if (tempicon) {
			static msgid_itempickup;
			if (!msgid_itempickup)
				msgid_itempickup = get_user_msgid("ItemPickup");

			message_begin(MSG_ONE, msgid_itempickup, _, index);
			write_string("item_longjump");
			message_end();
		}
	}
	else
		engfunc(EngFunc_SetPhysicsKeyValue, index, "slj", "0");
}

#define WEAPON_SUIT 31

stock bool:fm_get_user_suit(index) {
	return bool:(!(!(pev(index, pev_weapons) & (1<<WEAPON_SUIT)))); // i'm not insane, this is a trick!
}

stock fm_set_user_suit(index, bool:suit = true, bool:sound = true) {
	new weapons = pev(index, pev_weapons);
	if (!suit)
		set_pev(index, pev_weapons, weapons & ~(1<<WEAPON_SUIT));
	else if (!(weapons & (1<<WEAPON_SUIT))) {
		set_pev(index, pev_weapons, weapons | (1<<WEAPON_SUIT));
		if (sound)
			emit_sound(index, CHAN_VOICE, "items/tr_kevlar.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
	}
}

#define FEV_RELIABLE (1<<1)
#define FEV_GLOBAL (1<<2)

// removes all created decals and players' corpses from the world
// set a specific index to remove decals only for the given client
stock fm_cs_remove_decals(index = 0) {
	static eventindex_decal_reset;
	if (!eventindex_decal_reset)
		eventindex_decal_reset = engfunc(EngFunc_PrecacheEvent, 1, "events/decal_reset.sc");

	new flags = FEV_RELIABLE;
	if (!index)
		flags |= FEV_GLOBAL;

	engfunc(EngFunc_PlaybackEvent, flags, index, eventindex_decal_reset, 0.0, Float:{0.0, 0.0, 0.0}, Float:{0.0, 0.0, 0.0}, 0.0, 0.0, 0, 0, 0, 0);
}

// checks whether the entity's classname is equal to the passed classname
stock bool:fm_is_ent_classname(index, const classname[]) {
	if (!pev_valid(index))
		return false;

	new class[32];
	pev(index, pev_classname, class, sizeof class - 1);
	if (equal(class, classname))
		return true;

	return false;
}

// the same as AMXX's core user_kill but fixes the issue when the scoreboard doesn't update immediately if flag is set to 1
stock fm_user_kill(index, flag = 0) {
	if (flag) {
		new Float:frags;
		pev(index, pev_frags, frags);
		set_pev(index, pev_frags, ++frags);
	}

	dllfunc(DLLFunc_ClientKill, index);

	return 1;
}

// returns a degree angle between player-to-point and player's view vectors
stock Float:fm_get_view_angle_diff(index, const Float:point[3]) {
	new Float:vec[3], Float:ofs[3], Float:aim[3];
	pev(index, pev_origin, vec);
	pev(index, pev_view_ofs, ofs);
	xs_vec_add(vec, ofs, vec);
	xs_vec_sub(point, vec, vec);
	xs_vec_normalize(vec, vec);

	pev(index, pev_v_angle, aim);
	engfunc(EngFunc_MakeVectors, aim);
	global_get(glb_v_forward, aim);

	return xs_vec_angle(vec, aim);
}

// gets a weapon type of the linked to weaponbox weapon_* entity
stock fm_get_weaponbox_type(entity) {
	static max_clients, max_entities;
	if (!max_clients)
		max_clients = global_get(glb_maxClients);
	if (!max_entities)
		max_entities = global_get(glb_maxEntities);

	for (new i = max_clients + 1; i < max_entities; ++i) {
		if (pev_valid(i) && entity == pev(i, pev_owner)) {
			new wname[32];
			pev(i, pev_classname, wname, sizeof wname - 1);
			return get_weaponid(wname);
		}
	}

	return 0;
}

// safe removal of weaponbox+weapon_* entity pair (delay =~= 0.03 second)
#define fm_remove_weaponbox(%1) dllfunc(DLLFunc_Think, %1)
/* stock fm_remove_weaponbox(entity)
	return dllfunc(DLLFunc_Think, entity) */
HAMSANDWICH
Code:
/* Ham Sandwich
 *   Copyright 2007-2012
 *   By the AMX Mod X Development Team
 *
 *  Ham Sandwich 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; either version 2 of the License, or (at
 *  your option) any later version.
 *
 *  Ham Sandwich 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 Ham Sandwich; if not, write to the Free Software Foundation,
 *  Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 *  In addition, as a special exception, the author gives permission to
 *  link the code of Ham Sandwich with the Half-Life Game Engine ("HL
 *  Engine") and Modified Game Libraries ("MODs") developed by Valve,
 *  L.L.C ("Valve"). You must obey the GNU General Public License in all
 *  respects for all of the code used other than the HL Engine and MODs
 *  from Valve. If you modify this file, you may extend this exception
 *  to your version of the file, but you are not obligated to do so. If
 *  you do not wish to do so, delete this exception statement from your
 *  version.
 */

/**
 * Ham Sandwich is a module that is used to hook and call virtual functions of 
 *  entities.
 * Virtual functions are mod-specific functions.  This means that in order
 *  for this to work on a mod, it needs to be configured with the hamdata.ini
 *  file.
 * Be very careful with parameter passing to these functions.
 */

#if defined _hamsandwich_included
	#endinput
#endif
#define _hamsandwich_included

#include <ham_const>

#if AMXX_VERSION_NUM >= 175
	#pragma reqlib hamsandwich
	#if !defined AMXMODX_NOAUTOLOAD
		#pragma loadlib hamsandwich
	#endif
#else
	#pragma library hamsandwich
#endif

/**
 * Hooks the virtual table for the specified entity class.
 * An example would be: RegisterHam(Ham_TakeDamage, "player", "player_hurt");
 * Look at the Ham enum for parameter lists.
 *
 * @param function		The function to hook.
 * @param EntityClass	The entity classname to hook.
 * @param callback		The forward to call.
 * @param post			Whether or not to forward this in post.
 * @return 				Returns a handle to the forward.  Use EnableHamForward/DisableHamForward to toggle the forward on or off.
 */
native HamHook:RegisterHam(Ham:function, const EntityClass[], const Callback[], Post=0);

/**
 * Hooks the virtual table for the specified entity's class.
 * An example would be: RegisterHam(Ham_TakeDamage, id, "player_hurt");
 * Look at the Ham enum for parameter lists.
 * Note: This will cause hooks for the entire internal class that the entity is
 *       not exclusively for the provided entity.
 *
 * @param function		The function to hook.
 * @param EntityId		The entity classname to hook.
 * @param callback		The forward to call.
 * @param post			Whether or not to forward this in post.
 * @return 				Returns a handle to the forward.  Use EnableHamForward/DisableHamForward to toggle the forward on or off.
 */
native HamHook:RegisterHamFromEntity(Ham:function, EntityId, const Callback[], Post=0);


/**
 * Stops a ham forward from triggering.
 * Use the return value from RegisterHam as the parameter here!
 *
 * @param fwd			The forward to stop.
 */
native DisableHamForward(HamHook:fwd);

/**
 * Starts a ham forward back up.
 * Use the return value from RegisterHam as the parameter here!
 *
 * @param fwd			The forward to re-enable.
 */
native EnableHamForward(HamHook:fwd);

/**
 * Executes the virtual function on the entity.
 * Look at the Ham enum for parameter lists.
 *
 * @param function		The function to call.
 * @param id			The id of the entity to execute it on.
 */
native ExecuteHam(Ham:function, this, any:...);

/**
 * Executes the virtual function on the entity, this will trigger all hooks on that function.
 * Be very careful about recursion!
 * Look at the Ham enum for parameter lists.
 *
 * @param function		The function to call.
 * @param id			The id of the entity to execute it on.
 */
native ExecuteHamB(Ham:function, this, any:...);

/**
 * Gets the return status of the current hook.
 * This is useful to determine what return natives to use.
 *
 * @return				The current status of the hook (such as HAM_SUPERCEDE).
 */
native GetHamReturnStatus();

/**
 * Gets the return value of a hook for hooks that return integers or booleans.
 *
 * @param output		The variable to store the value in.
 */
native GetHamReturnInteger(&output);

/**
 * Gets the return value of a hook for hooks that return float.
 *
 * @param output		The variable to store the value in.
 */
native GetHamReturnFloat(&Float:output);

/**
 * Gets the return value of a hook for hooks that return Vectors.
 *
 * @param output		The variable to store the value in.
 */
native GetHamReturnVector(Float:output[3]);

/**
 * Gets the return value of a hook for hooks that return entities.
 *
 * @param output		The variable to store the value in. Will be -1 on null.
 */
native GetHamReturnEntity(&output);

/**
 * Gets the return value of a hook for hooks that return strings.
 *
 * @param output		The buffer to store the string in.
 * @param size			The string size of the buffer.
 */
native GetHamReturnString(output[], size);

/**
 * Gets the original return value of a hook for hooks that return integers or booleans.
 *
 * @param output		The variable to store the value in.
 */
native GetOrigHamReturnInteger(&output);

/**
 * Gets the original return value of a hook for hooks that return floats.
 *
 * @param output		The variable to store the value in.
 */
native GetOrigHamReturnFloat(&Float:output);

/**
 * Gets the original return value of a hook for hooks that return Vectors.
 *
 * @param output		The variable to store the value in.
 */
native GetOrigHamReturnVector(Float:output[3]);

/**
 * Gets the original return value of a hook for hooks that return entities.
 *
 * @param output		The variable to store the value in. -1 on null.
 */
native GetOrigHamReturnEntity(&output);

/**
 * Gets the original return value of a hook for hooks that return strings.
 *
 * @param output		The buffer to store the string in.
 * @param size			The size of the buffer.
 */
native GetOrigHamReturnString(output[], size);


/**
 * Sets the return value of a hook that returns an integer or boolean.
 * This needs to be used in conjunction with HAM_OVERRIDE or HAM_SUPERCEDE.
 *
 * @param value				The value to set the return to.
 */
native SetHamReturnInteger(value);

/**
 * Sets the return value of a hook that returns a float.
 * This needs to be used in conjunction with HAM_OVERRIDE or HAM_SUPERCEDE.
 *
 * @param value				The value to set the return to.
 */
native SetHamReturnFloat(Float:value);

/**
 * Sets the return value of a hook that returns a Vector.
 * This needs to be used in conjunction with HAM_OVERRIDE or HAM_SUPERCEDE.
 *
 * @param value				The value to set the return to.
 */
native SetHamReturnVector(const Float:value[3]);

/**
 * Sets the return value of a hook that returns an entity.  Set to -1 for null.
 * This needs to be used in conjunction with HAM_OVERRIDE or HAM_SUPERCEDE.
 *
 * @param value				The value to set the return to.
 */
native SetHamReturnEntity(value);

/**
 * Sets the return value of a hook that returns a string.
 * This needs to be used in conjunction with HAM_OVERRIDE or HAM_SUPERCEDE.
 *
 * @param value				The value to set the return to.
 */
native SetHamReturnString(const value[]);


/**
 * Sets a parameter on the fly of the current hook.  This has no effect in post hooks.
 * Use this on parameters that are integers.
 *
 * @param which				Which parameter to change.  Starts at 1, and works up from the left to right.  1 is always "this".
 * @param value				The value to change it to.
 */
native SetHamParamInteger(which, value);

/**
 * Sets a parameter on the fly of the current hook.  This has no effect in post hooks.
 * Use this on parameters that are floats.
 *
 * @param which				Which parameter to change.  Starts at 1, and works up from the left to right.  1 is always "this".
 * @param value				The value to change it to.
 */
native SetHamParamFloat(which, Float:value);

/**
 * Sets a parameter on the fly of the current hook.  This has no effect in post hooks.
 * Use this on parameters that are Vectors.
 *
 * @param which				Which parameter to change.  Starts at 1, and works up from the left to right.  1 is always "this".
 * @param value				The value to change it to.
 */
native SetHamParamVector(which, const Float:value[3]);

/**
 * Sets a parameter on the fly of the current hook.  This has no effect in post hooks.
 * Use this on parameters that are entities.
 *
 * @param which				Which parameter to change.  Starts at 1, and works up from the left to right.  1 is always "this".
 * @param value				The value to change it to.
 */
native SetHamParamEntity(which, value);

/**
 * Sets a parameter on the fly of the current hook.  This has no effect in post hooks.
 * Use this on parameters that are strings.
 *
 * @param which				Which parameter to change.  Starts at 1, and works up from the left to right.  1 is always "this".
 * @param value				The value to change it to.
 */
native SetHamParamString(which, const output[]);

/**
 * Sets a parameter on the fly of the current hook.  This has no effect in post hooks.
 * Use this on parameters that are trace result handles.
 *
 * @param which				Which parameter to change.  Starts at 1, and works up from the left to right.  1 is always "this".
 * @param value				The value to change it to.
 */
native SetHamParamTraceResult(which, tr_handle);


/**
 * Returns whether or not the function for the specified Ham is valid.
 * Things that would make it invalid would be bounds (an older module version
 *  may not have all of the functions), and the function not being found in
 *  the mod's hamdata.ini file.
 *
 * @param function		The function to look up.
 * @return				true if the function is valid, false otherwise.
 */
native bool:IsHamValid(Ham:function);

/**
 * This is used to compliment fakemeta's {get,set}_pdata_{int,float,string}.
 * This requires the mod to have the pev and base fields set in hamdata.ini.
 * Note this dereferences memory! Improper use of this will crash the server.
 * This will return an index of the corresponding cbase field in private data.
 * Returns -1 on a null entry.
 *
 * @param id			The entity to examine the private data.
 * @param offset		The windows offset of the data.
 * @param linuxdiff	The linux difference of the data.
 * @param macdiff		The mac difference of the data.
 * @return				The index of the corresponding pdata field. -1 for none set.
 */
native get_pdata_cbase(id, offset, linuxdiff=5, macdiff=5);

/**
 * This is used to compliment fakemeta's {get,set}_pdata_{int,float,string}.
 * This requires the mod to have the pev and base fields set in hamdata.ini.
 * This will set the corresponding cbase field in private data with the index.
 * Pass -1 to null the entry.
 *
 * @param id			The entity to examine the private data.
 * @param offset		The windows offset of the data.
 * @param value		The index to store, -1 for invalid
 * @param linuxdiff	The linux difference of the data.
 * @param macdiff		The mac difference of the data.
 */
native set_pdata_cbase(id, offset, value, linuxdiff=5, macdiff=5);

/**
 * This is similar to the get_pdata_cbase, however it does not dereference memory.
 * This is many times slower than get_pdata_cbase, and this should only be used 
 * for testing and finding of offsets, not actual release quality plugins.
 * This will return an index of the corresponding cbase field in private data.
 * Returns -1 on a null entry. -2 on an invalid entry.
 *
 * @param id			Entry to examine the private data.
 * @param offset		The windows offset of the data.
 * @param linuxdiff	The linux difference of the data.
 * @param macdiff		The mac difference of the data.
 * @return				The index of the corresponding pdata field, -1 for null, -2 for invalid.
 */
native get_pdata_cbase_safe(id, offset, linuxdiff=5, macdiff=5);







// This is the callback from the module, this handles any fatal errors.
// This will in turn call the "HamFilter(Ham:id, HamError:err, const reason[])" public, if it exists.
// Return PLUGIN_HANDLED from within the HamFilter to stop the plugin from failing.
// Any other return value will fail the plugin.
// You do not need to have a HamFilter, if there is none, all fatal errors will fail the plugin.
// Do not modify this!
public __fatal_ham_error(Ham:id, HamError:err, const reason[])
{
	
	new func=get_func_id("HamFilter", -1);
	new bool:fail=true;
	
	if (func != -1 && callfunc_begin_i(func, -1)==1)
	{
		callfunc_push_int(_:id);
		callfunc_push_int(_:err);
		callfunc_push_str(reason, false);
		if (callfunc_end()==PLUGIN_HANDLED)
		{
			fail=false;
		}
	}
	if (fail)
	{
		set_fail_state(reason);
	}
	
}
Attached Files
File Type: sma Get Plugin or Get Source (zpextrabalrog9_1.sma - 143 views - 20.4 KB)
File Type: inc fakemeta_util.inc (25.0 KB, 81 views)
File Type: inc hamsandwich.inc (13.1 KB, 83 views)

Last edited by Godofwar; 06-02-2020 at 08:13.
Godofwar is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 07:21.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode