/***********************************************************************
		Precaching FUNCTIONS (idea from war3x)
***********************************************************************/

public WAR3_precache() {
	#if ADVANCED_DEBUG == 1
		writeDebugInfo("WAR3_precache",0)
	#endif

    #if PRECACHE_WAR3FTSOUNDS
		copy( SOUND_VENGEANCE, 63,			"warcraft3/MiniSpiritPissed1.wav"				)  // Warden's Ultimate
		copy( SOUND_SUICIDE, 63,			"ambience/particle_suck1.wav"					)  // Undead's Ultimate
		copy( SOUND_BANISH, 63,				"warcraft3/banishcaster.wav"					)  // Banish
		copy( SOUND_LOCUSTSWARM, 63,		"warcraft3/locustswarmloop.wav"					)  // Locust Swarm
		copy( SOUND_SHADOWSTRIKE,63,		"warcraft3/shadowstrikebirth.wav"				)  // Shadow Strike
		copy( SOUND_CARRION, 63,			"warcraft3/carrionswarmlaunch1.wav"				)  // Carrion Beetles
		copy( SOUND_IMPALE, 63,				"warcraft3/impalehit.wav"						)  // Impale
		copy( SOUND_VOODOO, 63,				"warcraft3/divineshield.wav"					)  // Big Bad Voodoo
		copy( SOUND_FLAMESTRIKE, 63,		"warcraft3/flamestriketargetwavenonloop1.wav"	)  // Flame Strike
		copy( SOUND_ENTANGLING, 63,			"warcraft3/entanglingrootstarget1.wav"			)  // Entangling Roots
		copy( SOUND_LIGHTNING, 63,			"warcraft3/lightningbolt.wav"					)  // Chain Lightning
		copy( SOUND_TELEPORT, 63,			"warcraft3/massteleporttarget.wav"				)  // Teleport
		copy( SOUND_BLINK, 63,				"warcraft3/blinkarrival.wav"					)  // Blink Teleport
		copy( SOUND_LEVELUP, 63,			"warcraft3/Levelupcaster.wav"					)  // Level up
		copy( SOUND_PICKUPITEM, 63,			"warcraft3/PickUpItem.wav"						)  // Buy / Pick up item
		copy( SOUND_ITEM_TOME, 63,				"warcraft3/Tomes.wav"							)  // Tome of Experience
		copy( SOUND_ULTIMATESCAN, 63,		"turret/tu_ping.wav"							)  // Ultimate Beep
		copy( SOUND_ULTIMATEREADY, 63,		"warcraft3/ResurrectTarget.wav"					)  // Ultimate Beep
	#else
		copy( SOUND_VENGEANCE, 63,			"ambience/des_wind2.wav"						)  // Warden's Ultimate
		copy( SOUND_SUICIDE, 63,			"ambience/particle_suck1.wav"					)  // Undead's Ultimate
		copy( SOUND_BANISH, 63,				"player/pl_fallpain3.wav"						)  // Banish
		copy( SOUND_LOCUSTSWARM, 63,		"ambience/bee1.wav"								)  // Locust Swarm
		copy( SOUND_SHADOWSTRIKE,63,		"ambience/alienlaser1.wav"						)  // Shadow Strike
		copy( SOUND_CARRION, 63,			"player/sqk_blast1.wav"							)  // Carrion Beetles
		copy( SOUND_IMPALE, 63,				"doors/aliendoor3.wav"							)  // Impale
		copy( SOUND_VOODOO, 63,				"turret/tu_die2.wav"							)  // Big Bad Voodoo
		copy( SOUND_FLAMESTRIKE, 63,		"garg/gar_flameoff1.wav"						)  // Flame Strike
		copy( SOUND_ENTANGLING, 63,			"weapons/electro5.wav"							)  // Entangling Roots
		copy( SOUND_LIGHTNING, 63,			"weapons/gauss2.wav"							)  // Chain Lightning
		copy( SOUND_TELEPORT, 63,			"x/x_shoot1.wav"								)  // Teleport
		copy( SOUND_BLINK, 63,				"x/x_shoot1.wav"								)  // Blink Teleport
		copy( SOUND_LEVELUP, 63,			"plats/elevbell1.wav"							)  // Level up
		copy( SOUND_PICKUPITEM, 63,			"items/ammopickup1.wav"							)  // Buy / Pick up item
		copy( SOUND_ITEM_TOME, 63,				"items/suitchargeok1.wav"						)  // Tome of Experience
		copy( SOUND_ULTIMATESCAN, 63,		"turret/tu_ping.wav"							)  // Ultimate Beep
		copy( SOUND_ULTIMATEREADY, 63,		"buttons/bell1.wav"								)  // Ultimate Beep
	#endif

	// Skills / Ultimates
	precache_sound(SOUND_VENGEANCE)
	precache_sound(SOUND_SUICIDE)
	precache_sound(SOUND_BANISH)
	precache_sound(SOUND_LOCUSTSWARM)	
	precache_sound(SOUND_SHADOWSTRIKE)
	precache_sound(SOUND_CARRION)
	precache_sound(SOUND_IMPALE)
	precache_sound(SOUND_VOODOO)
	precache_sound(SOUND_FLAMESTRIKE)
	precache_sound(SOUND_ENTANGLING)
	precache_sound(SOUND_LIGHTNING)
	precache_sound(SOUND_TELEPORT)
	precache_sound(SOUND_BLINK)

	// Miscellaneous
	precache_sound(SOUND_LEVELUP)
	precache_sound(SOUND_PICKUPITEM)
	precache_sound(SOUND_ITEM_TOME)
	precache_sound(SOUND_ULTIMATESCAN)
	precache_sound(SOUND_ULTIMATEREADY)
	precache_sound("warcraft3/soundpack/reincarnation.wav")
	precache_sound("warcraft3/antend.wav")
	precache_sound("warcraft3/bonus/Error.wav")
}

public WAR3_exec_config(){
	#if ADVANCED_DEBUG == 1
		writeDebugInfo("WAR3_exec_config",0)
	#endif

	new configsDir[64]
	get_configsdir(configsDir, 63)
	server_cmd("exec %s/war3FT.cfg", configsDir)
}

public WAR3_check(){
	if(!warcraft3)
		return false

	return true
}

public WAR3_CD_installed(id){
	#if ADVANCED_DEBUG == 1
		writeDebugInfo("has_CD",id)
	#endif

	new playername[32]

	get_user_name(id,playername,31)
	if(containi(playername,"[No C-D]") != -1)
		return false
	else
		return true
	
	return false
}

public WAR3_chooserace(id){
	if(get_user_team(id) == CTS || get_user_team(id) == TS){
		if(get_cvar_num("mp_savexp"))
			get_xp_from_file(id,1)
		else
			WAR3_select_race(id,{0,0,0,0,0,0,0,0,0})
	}
}

public WAR3_ClearItems(id){
	#if ADVANCED_DEBUG == 1
		writeDebugInfo("WAR3_ClearItems",id)
	#endif

	if (warcraft3==false)
		return PLUGIN_CONTINUE

	// Remove created clones
	clone_destroy(id,0)
	clone_destroy(id,1)

	// Remove Helm
	if(p_data[id][P_ITEM2]==ITEM_HELM)
		Item_Set_Helm(id,0)

	// Reset Skin
	if (p_data[id][P_ITEM2]==ITEM_CHAMELEON)
		changeskin(id,1)		

	// Reset rings and footsteps
	p_data[id][P_RINGS]=0
	p_data_b[id][PB_SILENT] = false

	return PLUGIN_CONTINUE
}

public WAR3_damage(victim,attacker,damage, weapon, bodypart){	// one who is attacked, attacker ,damage
	#if ADVANCED_DEBUG == 1
		writeDebugInfo("WAR3_damage",victim)
	#endif

	if (!warcraft3)
		return PLUGIN_CONTINUE

	if(g_mapDisabled)
		return PLUGIN_CONTINUE

	if(!is_user_alive(victim))
		return PLUGIN_CONTINUE

	if(p_data_b[victim][PB_WARDENBLINK] && (weapon == CSW_LIGHTNING || weapon == CSW_SUICIDE || weapon == CSW_FLAME || weapon == CSW_LOCUSTS))
		return PLUGIN_CONTINUE

	new bool:userkilled = false
	new headshot = 0
#if MOD == 0
	if (bodypart == 1)
		headshot = 1
#endif

	if (get_user_health(victim) - damage<=0)
		userkilled = true
	else if (get_user_health(victim) - damage<=1024 && get_user_health(victim)>500)	// Evasion Kill
		userkilled = true

	if (userkilled)
		WAR3_death(victim, attacker, weapon, headshot)
	else
		set_user_health(victim, get_user_health(victim) - damage)

	return PLUGIN_CONTINUE
}

public WAR3_death_victim(victim_id, killer_id){
	#if ADVANCED_DEBUG == 1
		writeDebugInfo("WAR3_death_victim",victim_id)
	#endif

	if (warcraft3==false)
		return PLUGIN_CONTINUE

	// In case they respawn, continue ultimate delay check
	if(!task_exists(TASK_UDELAY+victim_id)){
		new parm[1]
		parm[0] = victim_id

		p_data[victim_id][P_ULTIMATEDELAY] = FT_ULTIMATE_COOLDOWN
		_WAR3_Ultimate_Delay(parm)
	}

	// Remove icon because you don't have an ultimate when you're dead
	icon_controller(victim_id,ICON_HIDE)	

	// Player is no longer a mole after they die, right?
	p_data_b[victim_id][PB_MOLE] = false

	p_data_b[victim_id][PB_DIEDLASTROUND] = true

	// Save Items for Weapon Reincarnation
	#if MOD == 0
		if(is_user_connected(victim_id)){
			if(cs_get_user_nvg(victim_id))
				p_data_b[victim_id][PB_NIGHTVISION] = true
			if(cs_get_user_defuse(victim_id))
				p_data_b[victim_id][PB_DEFUSE] = true
		}
		saveweapons(victim_id)
	#endif


	// Remove task that makes the victim jump

	if (task_exists(TASK_JUMPER+victim_id))		// Remove the function that makes you jump from Hex
		remove_task(TASK_JUMPER+victim_id)

	// Clear Item Information because the player just died

	WAR3_ClearItems(victim_id)

	// Check for Ultimate abilities

	if (((p_data[victim_id][P_RACE] == 9 && race9Options[4] == 7) || p_data[victim_id][P_RACE] == 7) && p_data[victim_id][P_ULTIMATE] && !p_data_b[victim_id][PB_CHANGINGTEAM] && (!p_data_b[killer_id][PB_WARDENBLINK] || killer_id==victim_id) && !g_ultimateDelay && !p_data_b[victim_id][PB_ULTIMATEUSED] && !endround){	// Vengeance
		new parm[2]
		parm[0]=victim_id
		parm[1]=6

		p_data_b[victim_id][PB_ULTIMATEUSED]=true

		p_data[victim_id][P_ULTIMATEDELAY] = FT_ULTIMATE_COOLDOWN

		if(task_exists(TASK_UDELAY+victim_id))
			remove_task(TASK_UDELAY+victim_id)
		
		_WAR3_Ultimate_Delay(parm)

		set_task(1.2,"func_spawn",TASK_VENGEANCE+victim_id,parm,2)

	}
	else if (((p_data[victim_id][P_RACE] == 9 && race9Options[4] == 1) || p_data[victim_id][P_RACE] == 1) && p_data[victim_id][P_ULTIMATE] && !p_data_b[victim_id][PB_CHANGINGTEAM] && !g_ultimateDelay){	// Suicide Bomber
		emit_sound(victim_id, CHAN_STATIC, SOUND_SUICIDE, 1.0, ATTN_NORM, 0, PITCH_NORM)
		new parm[5], origin[3]
		get_user_origin(victim_id,origin)

		parm[0]=victim_id
		parm[1]=6
		parm[2]=origin[0]
		parm[3]=origin[1]
		parm[4]=origin[2]
	
		set_task(0.5,"apacheexplode",TASK_EXPLOSION+victim_id,parm,5)
		set_task(0.5,"blastcircles",TASK_BEAMCYLINDER+victim_id,parm,5)

		Create_TE_IMPLOSION(origin, 100, 20, 5)

		p_data[victim_id][P_ULTIMATEDELAY] = FT_ULTIMATE_COOLDOWN

		if(task_exists(TASK_UDELAY+victim_id))
			remove_task(TASK_UDELAY+victim_id)

		_WAR3_Ultimate_Delay(parm)
	}


	// Check to see if player should respawn from an item

	if(p_data[victim_id][P_ITEM2]==ITEM_SCROLL && !endround){
		new parm[2]
		parm[0]=victim_id
		parm[1]=6
		if(p_data[victim_id][P_ITEM2]!=ITEM_MOLE){
			p_data[victim_id][P_ITEM2]=0
			p_data[victim_id][P_RINGS]=0
		}
		p_data[victim_id][P_ITEM]=0
		set_task(1.2,"func_spawn",TASK_ITEM_SCROLL+victim_id,parm,2)
		p_data_b[victim_id][PB_SPAWNEDFROMITEM] = true
	}


	// Check to see if a player should be revived
	new players[32], numberofplayers, y
	get_players(players, numberofplayers)

	if(get_user_team(victim_id)==TS && g_pheonixExistsT>0){
		for (y = 0; y < numberofplayers; ++y){
			new id = players[y]
			if (p_data_b[id][PB_PHEONIXCASTER] && !p_data_b[victim_id][PB_TOBEREVIVED] && !endround && id!=victim_id && is_user_alive(id) && get_user_team(id)==get_user_team(victim_id) && !is_user_alive(victim_id) && (get_user_team(victim_id) == CTS || get_user_team(victim_id) == TS)){
				p_data_b[id][PB_PHEONIXCASTER] = false
				new parm[2], name[32]
				parm[0]=victim_id
				p_data_b[victim_id][PB_SPAWNEDFROMITEM] = true
				set_task(0.7,"func_spawn",TASK_SPAWN+victim_id,parm,2)			// Spawns player
				set_hudmessage(200, 100, 0, -0.8, 0.1, 0, 1.0, 5.0, 0.1, 0.2, 2) 
				get_user_name(id,name,31)
				get_user_name(victim_id,name,31)
				show_hudmessage(victim_id,"%L",id,"HAS_REVIVED_YOU",name)
				client_print(victim_id,print_chat,"%L",id,"HAS_REVIVED_YOU2",g_MOD, name)	
				show_hudmessage(id,"%L",id,"YOU_HAVE_REVIVED",name)
				client_print(id,print_chat,"%L",id,"YOU_HAVE_REVIVED2",g_MOD,name)
				p_data_b[victim_id][PB_TOBEREVIVED]=true
				g_pheonixExistsT--
				break
			}
		}
	}
	else if(get_user_team(victim_id)==CTS && g_pheonixExistsCT>0){
		for (y = 0; y < numberofplayers; ++y){
			new id = players[y]
			if (p_data_b[id][PB_PHEONIXCASTER] && !p_data_b[victim_id][PB_TOBEREVIVED] && !endround && id!=victim_id && is_user_alive(id) && get_user_team(id)==get_user_team(victim_id) && !is_user_alive(victim_id) && (get_user_team(victim_id) == CTS || get_user_team(victim_id) == TS)){
				p_data_b[id][PB_PHEONIXCASTER] = false
				new parm[2], name[32]
				parm[0]=victim_id
				p_data_b[victim_id][PB_SPAWNEDFROMITEM] = true
				set_task(0.7,"func_spawn",TASK_SPAWN+victim_id,parm,2)			// Spawns player
				set_hudmessage(200, 100, 0, -1.6, 0.1, 0, 1.0, 5.0, 0.1, 0.2, 2)
				get_user_name(id,name,31)
				get_user_name(victim_id,name,31)
				show_hudmessage(victim_id,"%L",id,"HAS_REVIVED_YOU",name)
				client_print(victim_id,print_chat,"%L",id,"HAS_REVIVED_YOU2",g_MOD, name)	
				show_hudmessage(id,"%L",id,"YOU_HAVE_REVIVED",name)
				client_print(id,print_chat,"%L",id,"YOU_HAVE_REVIVED2",g_MOD,name)
				p_data_b[victim_id][PB_TOBEREVIVED]=true
				g_pheonixExistsCT--
				break
			}
		}
	}

	new parameter[1]
	parameter[0]=victim_id
	set_task(1.0,"getuserinput",TASK_GETINPUT+victim_id,parameter,1)

	return PLUGIN_CONTINUE
}

public WAR3_death(victim_id, killer_id, weapon, headshot) {
	#if ADVANCED_DEBUG == 1
		writeDebugInfo("WAR3_death",victim_id)
	#endif

	if (warcraft3==false)
		return PLUGIN_CONTINUE

	new weaponname[32]
	
	clear_all_icons(victim_id)
	
 	WAR3_death_victim(victim_id, killer_id)

	XP_onDeath(victim_id, killer_id, weapon, headshot)

	// Award $300 for a Kill
	if (get_user_team(killer_id)!=get_user_team(victim_id))
		set_user_money(killer_id,get_user_money(killer_id)+300,0)


	if(get_user_team(killer_id) == get_user_team(victim_id) && killer_id != victim_id){		// Team Kill
        new iKillerFrags = get_user_frags(killer_id) - 1

        set_user_frags(killer_id, iKillerFrags)

        // Update frags ( realtime )
	#if MOD == 0
        new iKillerDeaths = get_user_deaths(killer_id)
        Create_ScoreInfo(killer_id, iKillerFrags, iKillerDeaths, 0, get_user_team(killer_id))
	#endif
	}
	else{
        new iKillerFrags = get_user_frags(killer_id) + 1

        set_user_frags(killer_id, iKillerFrags)

        // Update frags ( realtime )
	#if MOD == 0
        new iKillerDeaths = get_user_deaths(killer_id)
        Create_ScoreInfo(killer_id, iKillerFrags, iKillerDeaths, 0, get_user_team(killer_id))
	#endif
	}

    // Create Death Message
	if(is_user_alive(victim_id)){

        // Kill Victim
		set_msg_block(gmsgDeathMsg,BLOCK_ONCE)
		user_kill(victim_id)

        // Update frags ( realtime )
	#if MOD == 0
		new iVictimDeaths = get_user_deaths(victim_id)
		new iVictimFrags = get_user_frags(victim_id) + 1

		set_user_frags(victim_id, iVictimFrags)

		Create_ScoreInfo(victim_id, iVictimFrags, iVictimDeaths, 0, get_user_team(victim_id))
	#endif
	switch (weapon){

	case CSW_KNIFE:			copy(weaponname, 31, "knife")

	case CSW_USP:           copy(weaponname, 31, "usp")
	case CSW_GLOCK18:       copy(weaponname, 31, "glock18")
	case CSW_DEAGLE:        copy(weaponname, 31, "deagle")
	case CSW_P228:          copy(weaponname, 31, "p228")
	case CSW_ELITE:         copy(weaponname, 31, "elite")
	case CSW_FIVESEVEN:     copy(weaponname, 31, "fiveseven")

	case CSW_M3:            copy(weaponname, 31, "m3")
	case CSW_XM1014:        copy(weaponname, 31, "xm1014")

	case CSW_MP5NAVY:       copy(weaponname, 31, "mp5navy")
	case CSW_TMP:           copy(weaponname, 31, "tmp")
	case CSW_P90:           copy(weaponname, 31, "p90")
	case CSW_MAC10:         copy(weaponname, 31, "mac10")
	case CSW_UMP45:         copy(weaponname, 31, "ump45")

	case CSW_AK47:          copy(weaponname, 31, "ak47")
	case CSW_SG552:         copy(weaponname, 31, "sg552")
	case CSW_M4A1:          copy(weaponname, 31, "m4a1")
	case CSW_AUG:           copy(weaponname, 31, "aug")
	case CSW_SCOUT:         copy(weaponname, 31, "scout")
	case CSW_AWP:           copy(weaponname, 31, "awp")
	case CSW_SG550:         copy(weaponname, 31, "sg550")
	case CSW_G3SG1:         copy(weaponname, 31, "g3sg1")

	case CSW_GALI:          copy(weaponname, 31, "galil")
	case CSW_FAMAS:         copy(weaponname, 31, "famas")

	case CSW_M249:          copy(weaponname, 31, "m249")

	case CSW_HEGRENADE:     copy(weaponname, 31, "grenade")

	case CSW_WORLDSPAWN:    copy(weaponname, 31, "worldspawn")

	case CSW_LIGHTNING:     raceskill(3,4,LANG_SERVER,weaponname,31)
	case CSW_SUICIDE:		raceskill(1,4,LANG_SERVER,weaponname,31)
	case CSW_FLAME:			raceskill(5,4,LANG_SERVER,weaponname,31)
	case CSW_LOCUSTS:		raceskill(8,4,LANG_SERVER,weaponname,31)
	case CSW_SERPENTWARD:   raceskill(6,3,LANG_SERVER,weaponname,31)
	case CSW_SHADOW:		raceskill(7,3,LANG_SERVER,weaponname,31)
	case CSW_THORNS:		raceskill(4,2,LANG_SERVER,weaponname,31)
	case CSW_CARAPACE:		raceskill(8,2,LANG_SERVER,weaponname,31)
	case CSW_CARRION:		raceskill(8,3,LANG_SERVER,weaponname,31)
		}
	#if MOD == 0
		Create_DeathMsg_CS(killer_id, victim_id, headshot, weaponname)
	#endif
	#if MOD == 1
		Create_DeathMsg_DOD(killer_id, victim_id, weapon)
	#endif
	}

	// Log Death
	new szKillerName[32], szVictimName[32]
	new szKillerTeam[32], szVictimTeam[32]
	new szKillerAuth[32], szVictimAuth[32]

	get_user_name(killer_id, szKillerName, 31)
	get_user_name(victim_id, szVictimName, 31)

	get_user_team(killer_id, szKillerTeam, 31)
	get_user_team(victim_id, szVictimTeam, 31)

	get_user_authid(killer_id, szKillerAuth, 31)
	get_user_authid(victim_id, szVictimAuth, 31)

	log_message("^"%s<%d><%s><%s>^" killed ^"%s<%d><%s><%s>^" with ^"%s^"", szKillerName, get_user_userid(killer_id), szKillerAuth, szKillerTeam, szVictimName, get_user_userid(victim_id), szVictimAuth, szVictimTeam, weaponname)
	
	return PLUGIN_CONTINUE
}

public _WAR3_Ultimate_Delay(parm[]){
	#if ADVANCED_DEBUG == 1
		writeDebugInfo("_WAR3_Ultimate_Delay",p_data[parm[0]][P_ULTIMATEDELAY])
	#endif

	
	new id = parm[0]

	p_data[id][P_ULTIMATEDELAY]--

	if (p_data[id][P_ULTIMATEDELAY] > 0)
		set_task(1.0,"_WAR3_Ultimate_Delay",TASK_UDELAY+id, parm, 1)
	else{
		WAR3_Ultimate_Ready(id)
	}

	return PLUGIN_CONTINUE
}

public WAR3_Ultimate_Ready(id){

	new szCommand[32]
	format(szCommand, 31, "speak %s", SOUND_ULTIMATEREADY)


	if(is_user_alive(id) && is_user_connected(id) && p_data[id][P_ULTIMATE]){

		p_data_b[id][PB_ULTIMATEUSED] = false

		client_cmd(id, szCommand)

		new szMessage[128]
		format(szMessage, 127, "%L", id, "ULTIMATE_READY")

		WAR3_status_text(id, szMessage, 2.0)

		icon_controller(id, ICON_SHOW)
	}
}

// From war3x (war3x.net)
public WAR3_status_text(id, szMessage[], Float:fDuration){
	#if ADVANCED_DEBUG == 1
		writeDebugInfo("WAR3_status_text",0)
	#endif

    set_hudmessage(255, 208, 0, HUDMESSAGE_POS_CENTER, HUDMESSAGE_POS_STATUS, 0, 6.0, fDuration, 0.1, 0.5, HUDMESSAGE_CHAN_STATUS)
    show_hudmessage(id, szMessage)

    // Print important messages to console
    if ( fDuration >= 3.0 ){
        client_print( id, print_console, "[%s] %s", g_MOD, szMessage )
    }

    return PLUGIN_HANDLED
}

public WAR3_select_race(id, racexp[9]){
	#if ADVANCED_DEBUG == 1
		writeDebugInfo("WAR3_select_race",0)
	#endif

	new race_name[10][RACE_NAME_LENGTH], i, pos, menu_msg[512], selectrace[128]
	new keys
	format(selectrace, 127, "%L",id ,"MENU_SELECT_RACE")

	for(i=1;i<(NUM_RACES+1);i++){
		racename(i,id,race_name[i],RACE_NAME_LENGTH_F)
	}

	if(MP_SAVEXP){
		pos += format(menu_msg[pos], 512-pos, "%L",id,"SELECT_RACE_TITLE", selectrace)

		for(i=1; i<(NUM_RACES+1);i++){
			if(i==5){
				new selecthero[128]
				format(selecthero, 127, "%L",id ,"SELECT_HERO")
				pos += format(menu_msg[pos], 512-pos, "%s", selecthero)
			}

			if(i==p_data[id][P_RACE])
				pos += format(menu_msg[pos], 512-pos, "\d%d. %s\d\R%d^n", i, race_name[i], racexp[i-1])
			else if(i==p_data[id][P_CHANGERACE])
				pos += format(menu_msg[pos], 512-pos, "\r%d. %s\r\R%d^n", i, race_name[i], racexp[i-1])
			else
				pos += format(menu_msg[pos], 512-pos, "\w%d. %s\y\R%d^n", i, race_name[i], racexp[i-1])

			keys |= (1<<(i-1))
		}
	}
	else{
		pos += format(menu_msg[pos], 512-pos, "%s^n^n", selectrace)

		for(i=1; i<(NUM_RACES+1);i++){
			if(i==5){
				new selecthero[128]
				format(selecthero, 127, "%L",id ,"SELECT_HERO")
				pos += format(menu_msg[pos], 512-pos, "%s", selecthero)
			}

			if(i==p_data[id][P_RACE])
				pos += format(menu_msg[pos], 512-pos, "\d%d. %s\d\R%d^n", i, race_name[i], racexp[i-1])
			else if(i==p_data[id][P_CHANGERACE])
				pos += format(menu_msg[pos], 512-pos, "\r%d. %s\r\R%d^n", i, race_name[i], racexp[i-1])
			else
				pos += format(menu_msg[pos], 512-pos, "\w%d. %s\y\R%d^n", i, race_name[i], racexp[i-1])

			keys |= (1<<(i-1))
		}
	}


	keys |= (1<<(i-1))

	if(NUM_RACES == 9)
		i = 0

	pos += format(menu_msg[pos], 512-pos, "%L",id,"SELECT_RACE_FOOTER", i)

	show_menu(id, keys, menu_msg, -1)

	return PLUGIN_HANDLED
}

public WAR3_set_race(id,race){
	#if ADVANCED_DEBUG == 1
		writeDebugInfo("WAR3_set_race",0)
	#endif

	clear_all_icons(id)

	emit_sound(id,CHAN_STATIC, SOUND_LEVELUP, 1.0, ATTN_NORM, 0, PITCH_NORM)

	p_data[id][P_RACE] = race

	p_data[id][P_SKILL1] = 0
	p_data[id][P_SKILL2] = 0
	p_data[id][P_SKILL3] = 0
	p_data[id][P_ULTIMATE] = 0
	p_data_b[id][PB_PHEONIXCASTER] = false
	p_data[id][P_CHANGERACE] = 0

	if (get_user_health(id)>100)
		set_user_health(id,100)

	#if MOD == 1
		dod_set_fuse(id,FUSE_RESET)
	#endif

	new parm[1]
	parm[0]=id

	if (MP_SAVEXP){
		p_data[id][P_XP] = 0
		p_data[id][P_LEVEL] = 0
		get_xp_from_file(id,0)
	}

	check_skills(id)
	#if MOD == 0
		if(!p_data_b[id][PB_BLINKDELAYED] && !p_data_b[id][PB_ULTIMATEUSED])
	#else
		if(!p_data_b[id][PB_BLINKDELAYED] && !p_data_b[id][PB_ULTIMATEUSED])
	#endif
		icon_controller(id,ICON_SHOW)

	if (get_user_team(id) == CTS || get_user_team(id) == TS) {
		new skillsused = p_data[id][P_SKILL1]+p_data[id][P_SKILL2]+p_data[id][P_SKILL3]
		if (skillsused < p_data[id][P_LEVEL])
			select_skill(id,0)
	}

	if(((p_data[id][P_RACE] == 9 && race9Options[2] == 2) || p_data[id][P_RACE] == 2) && p_data[id][P_SKILL2] && get_user_health(id) <= 100){	// set_health
		set_user_health(id,p_devotion[p_data[id][P_SKILL2]-1])
	}

	WAR3_Display_Level(id, DISPLAYLEVEL_SHOWRACE)
}

public _WAR3_Impale(parm[2]){

	new id = parm[0]

	if(parm[1]<4){
		new Float:vec_angle[3], Float:vec_v_angle[3]
		new i

		entity_get_vector(id, EV_VEC_angles, vec_angle)
		entity_get_vector(id, EV_VEC_v_angle, vec_v_angle)

		for(i=0;i<2;i++){ // Don't modify z axis (causes a roll)
			vec_angle[i] = vec_angle[i] + random_float(-10.0,10.0)
			vec_v_angle[i] = vec_v_angle[i] + random_float(-10.0,10.0)
		}

		entity_set_int(id, EV_INT_fixangle, 1)
		entity_set_vector(id, EV_VEC_angles, vec_angle)
		entity_set_vector(id, EV_VEC_v_angle, vec_v_angle)
		parm[1]++
		set_task(0.1, "_WAR3_Impale", 0, parm, 2)
	}
	else{
		entity_set_int(id, EV_INT_fixangle, 1)
	}
}

#if MOD == 0
public _WAR3_set_buytime(){
	g_buyTime=false
}
#endif

public _WAR3_Drop_Items(id){
	new origin[3]
	new iweapons[32] = 0, wpname[32] = 0, inum = 0
	get_user_weapons(id,iweapons,inum)

	// Disarm and Isolate Player Before Re-Incarnation
	get_user_origin(id,origin)
	origin[2] -= 2000
	set_user_origin(id,origin)
	for(new a=0;a<inum;++a){
		if(iweapons[a] != CSW_C4 && iweapons[a] != CSW_KNIFE){
			get_weaponname(iweapons[a],wpname,31)
			engclient_cmd(id,"drop",wpname)
		}
	}
	client_cmd(id,"weapon_knife")
}

#if MOD == 0
	public _WAR3_Give_Items(id){

		new origin[3]
		new weaponname[20] = 0, ammoname[20] = 0

		get_user_origin(id,origin)
		origin[2] += 2005

		if (p_data[id][P_ARMORONDEATH]){
			if (p_data_b[id][PB_HELMET])
				give_item(id,"item_assaultsuit")
			else
				give_item(id,"item_kevlar")

			set_user_armor(id,p_data[id][P_ARMORONDEATH])
		}

		if (p_data_b[id][PB_DEFUSE])
			give_item(id,"item_thighpack")

		if (p_data_b[id][PB_NIGHTVISION])
			cs_set_user_nvg(id,1)

		if(p_data_b[id][PB_SHIELD])
			give_item(id,"weapon_shield")

		new weaponid = 0, j
		for (j=0; (j < p_data[id][P_SAVEDNUMBER]) && (j < 32); ++j){
			weaponid=savedweapons[id][j]

			if(weaponid==CSW_USP){
				weaponname="weapon_usp"
				ammoname="ammo_45acp"
			}
			else if(weaponid==CSW_ELITE){
				weaponname="weapon_elite"
				ammoname="ammo_9mm"
			}
			else if(weaponid==CSW_FIVESEVEN){
				weaponname="weapon_fiveseven"
				ammoname="ammo_57mm"
			}
			else if(weaponid==CSW_GLOCK18){
				weaponname="weapon_glock18"
				ammoname="ammo_9mm"
			}
			else if(weaponid==CSW_DEAGLE){
				weaponname="weapon_deagle"
				ammoname="ammo_50ae"
			}
			else if(weaponid==CSW_P228){
				weaponname="weapon_p228"
				ammoname="ammo_357sig"
			}
			else if (weaponid==3){
				weaponname="weapon_scout"
				ammoname="ammo_762nato"
			}
			else if (weaponid==4){
				give_item(id,"weapon_hegrenade")
			}
			else if (weaponid==5){
				weaponname="weapon_xm1014"
				ammoname="ammo_buckshot"
			}
			else if (weaponid==7){
				weaponname="weapon_mac10"
				ammoname="ammo_45acp"
			}
			else if (weaponid==8){
				weaponname="weapon_aug"
				ammoname="ammo_556nato"
			}
			else if (weaponid==9){
				give_item(id,"weapon_smokegrenade")	
			}
			else if (weaponid==12){
				weaponname="weapon_ump45"
				ammoname="ammo_45acp"
			}
			else if (weaponid==13){
				weaponname="weapon_sg550"
				ammoname="ammo_556nato"
			}
			else if (weaponid==14){
				weaponname="weapon_galil"
				ammoname="ammo_556nato"
			}
			else if (weaponid==15){
				weaponname="weapon_famas"
				ammoname="ammo_556nato"
			}
			else if (weaponid==18){
				weaponname="weapon_awp"
				ammoname="ammo_338magnum"
			}
			else if (weaponid==19){
				weaponname="weapon_mp5navy"
				ammoname="ammo_9mm"				
			}
			else if (weaponid==20){
				weaponname="weapon_m249"
				ammoname="ammo_556natobox"
			}
			else if (weaponid==21){
				weaponname="weapon_m3"
				ammoname="ammo_buckshot"
			}
			else if (weaponid==22){
				weaponname="weapon_m4a1"
				ammoname="ammo_556nato"
			}
			else if (weaponid==23){
				weaponname="weapon_tmp"
				ammoname="ammo_9mm"
			}
			else if (weaponid==24){
				weaponname="weapon_g3sg1"
				ammoname="ammo_762nato"
			}
			else if (weaponid==25){
				if(p_data[id][P_FLASHCOUNT]==1)
					give_item(id,"weapon_flashbang")
				else{
					give_item(id,"weapon_flashbang")
					give_item(id,"weapon_flashbang")
				}
			}
			else if (weaponid==27){
				weaponname="weapon_sg552"
				ammoname="ammo_556nato"
			}
			else if (weaponid==28){
				weaponname="weapon_ak47"
				ammoname="ammo_762nato"
			}
			else if (weaponid==30){
				weaponname="weapon_p90"
				ammoname="ammo_57mm"
			}
			else{
				weaponname=""
				ammoname=""
			}
			if (contain(weaponname,"weapon_")==0){	//  if no match found, 0 if match
				give_item(id,weaponname)
				give_item(id,ammoname)
				give_item(id,ammoname)
				give_item(id,ammoname)
				give_item(id,ammoname)
			}
		}

		// Restore Re-Incarnated Player to the map
		if(FT_STEAM){
			set_user_origin(id,origin)
		}
		else{
			new parm2[4]
			parm2[0]=id
			parm2[1]=origin[0]
			parm2[2]=origin[1]
			parm2[3]=origin[2]
			set_task(0.1,"reset_position",TASK_RESETPOS+id,parm2,4)
		}

		// This will make the player have the new reincarnated weapon selected
		// instead of the player's knife being selected
		new iweapons[32] = 0, wpname[32] = 0, inum = 0
		new bool:foundPrim = false
		//new bool:foundSec = false
		get_user_weapons(id,iweapons,inum)

		for(new a=0;a<inum;++a){
			if(isPrimary(iweapons[a])){
				get_weaponname(iweapons[a],wpname,31)
				client_cmd(id,wpname)
				foundPrim = true
				break
			}
		}

		if(!foundPrim){
			for(new a=0;a<inum;++a){
				if(isSecondary(iweapons[a])){
					get_weaponname(iweapons[a],wpname,31)
					client_cmd(id,wpname)
					//foundSec = true
					break
				}
			}
		}	
	}
#endif

public WAR3_Display_Level(id, flag){
	#if ADVANCED_DEBUG == 1
		writeDebugInfo("WAR3_Display_Level",id)
	#endif

	if (get_cvar_num("FT_CD")) {
		if (!WAR3_CD_installed(id)){
			return PLUGIN_CONTINUE
		}
	}

#if MOD == 0
	if(FT_ITEMS_IN_HUD){
		new parm2[2]
		parm2[0] = id
		if(!task_exists(TASK_ITEMS+id)){
			_WAR3_showHUDItems(parm2)
		}
	}
#endif

	new oldlevel = p_data[id][P_LEVEL]

	if (p_data[id][P_XP]<0)
		p_data[id][P_XP]=0

	for (new i=0; i<=10; ++i){
		if (p_data[id][P_XP]>=xplevel[i])
			p_data[id][P_LEVEL]=i
		else
			break
	}
		
	new race_name[RACE_NAME_LENGTH]
	racename(p_data[id][P_RACE],id,race_name,RACE_NAME_LENGTH_F)

	#if MOD == 0
		new xpstring[512]
		new short_race_name[SHORT_RACE_NAME_LENGTH]
		shortracename(p_data[id][P_RACE],id,short_race_name,SHORT_RACE_NAME_LENGTH_F)

		if(get_cvar_num("FT_items_in_hud")){
			if(p_data[id][P_ITEM2]==0){
				if (p_data[id][P_LEVEL]==0)
					format(xpstring,511,"%s   XP: %d/%d ",race_name,p_data[id][P_XP],xplevel[p_data[id][P_LEVEL]+1])
				else if (p_data[id][P_LEVEL]<10)
					format(xpstring,511,"%L",id,"LEVEL",race_name,p_data[id][P_LEVEL],p_data[id][P_XP],xplevel[p_data[id][P_LEVEL]+1])
				else
					format(xpstring,511,"%L",id,"LEVEL10",race_name,p_data[id][P_LEVEL],xplevel[10],xplevel[10])
			}
			else{
				if (p_data[id][P_LEVEL]==0)
					format(xpstring,511,"%s   XP: %d/%d ",race_name,p_data[id][P_XP],xplevel[p_data[id][P_LEVEL]+1])
				else if (p_data[id][P_LEVEL]<10)
					format(xpstring,511,"%L",id,"LEVEL",race_name,p_data[id][P_LEVEL],p_data[id][P_XP],xplevel[p_data[id][P_LEVEL]+1])
				else
					format(xpstring,511,"%L",id,"LEVEL10",race_name,p_data[id][P_LEVEL],p_data[id][P_XP])
			}
		}else{
			new temp2[128]

			if (p_data[id][P_ITEM]!=0 && p_data[id][P_ITEM2]!=0){
				new short_item_name[SHORT_ITEM_NAME_LENGTH], short_item_name2[SHORT_ITEM_NAME_LENGTH]
				shortitemname(p_data[id][P_ITEM],id,short_item_name,SHORT_ITEM_NAME_LENGTH_F)
				shortitemname2(p_data[id][P_ITEM2],id,short_item_name2,SHORT_ITEM_NAME_LENGTH_F)

				if (p_data[id][P_ITEM2]==ITEM_RING && p_data[id][P_RINGS]>1)
					format(temp2,127,"%L",id,"PLAYERITEM_AND_REGEN",short_item_name,short_item_name2,p_data[id][P_RINGS])
				else
					format(temp2,127,"%L",id,"PLAYERITEM_AND",short_item_name,short_item_name2)
			}
			else if (p_data[id][P_ITEM]==0 && p_data[id][P_ITEM2]!=0){
				new short_item_name2[SHORT_ITEM_NAME_LENGTH]
				shortitemname2(p_data[id][P_ITEM2],id,short_item_name2,SHORT_ITEM_NAME_LENGTH_F)

				if (p_data[id][P_ITEM2]==ITEM_RING && p_data[id][P_RINGS]>1)
					format(temp2,127,"%s x%d ",short_item_name2,p_data[id][P_RINGS])
				else
					format(temp2,127,"%s",short_item_name2)
			}
			else if (p_data[id][P_ITEM]!=0 && p_data[id][P_ITEM2]==0){
				new short_item_name[SHORT_ITEM_NAME_LENGTH]
				shortitemname(p_data[id][P_ITEM],id,short_item_name,SHORT_ITEM_NAME_LENGTH_F)

				format(temp2,127,"%s",short_item_name)
			}

			if (p_data[id][P_LEVEL]==0)
				format(xpstring,511,"%s  XP: %d/%d %s",race_name,p_data[id][P_XP],xplevel[p_data[id][P_LEVEL]+1],temp2)
			else if(p_data[id][P_LEVEL]<10)
				format(xpstring,511,"%L",id,"LEVEL_SHORT",short_race_name,p_data[id][P_LEVEL],p_data[id][P_XP], xplevel[p_data[id][P_LEVEL]+1],temp2)
			else
				format(xpstring,511,"%L",id,"LEVEL10_SHORT",short_race_name,p_data[id][P_LEVEL],p_data[id][P_XP],temp2)			
		}

		if(get_user_team(id) == CTS || get_user_team(id) == TS)
			Create_StatusText(id, 0,xpstring)
	#endif

	if (p_data[id][P_LEVEL] > oldlevel && (flag==DISPLAYLEVEL_SHOWGAINED || flag==DISPLAYLEVEL_SHOWBOTH)){			// Level Gained
		new message[128]
		format(message,127,"%L",id,"YOU_GAINED_A_LEVEL")
		#if MOD == 0
			set_hudmessage(200, 100, 0, -1.0, 0.25, 0, 1.0, 2.0, 0.1, 0.2, HUDMESSAGE_CHAN_INFO)
			show_hudmessage(id, message)
		#endif
		#if MOD == 1
			Create_HudText(id, message, 1)
		#endif

		emit_sound(id,CHAN_STATIC, SOUND_LEVELUP, 1.0, ATTN_NORM, 0, PITCH_NORM)
	}

	new skillsused = p_data[id][P_SKILL1]+p_data[id][P_SKILL2]+p_data[id][P_SKILL3]+p_data[id][P_ULTIMATE]
	while (skillsused>p_data[id][P_LEVEL]){
		if (p_data[id][P_ULTIMATE]==1 && p_data[id][P_LEVEL]<6)
			p_data[id][P_ULTIMATE]=0
		else if (p_data[id][P_SKILL1]>=p_data[id][P_SKILL2] && p_data[id][P_SKILL1]>=p_data[id][P_SKILL3])
			--p_data[id][P_SKILL1]
		else if (p_data[id][P_SKILL2]>=p_data[id][P_SKILL1] && p_data[id][P_SKILL2]>=p_data[id][P_SKILL3])
			--p_data[id][P_SKILL2]
		else if (p_data[id][P_SKILL3]>=p_data[id][P_SKILL1] && p_data[id][P_SKILL3]>=p_data[id][P_SKILL2])
			--p_data[id][P_SKILL3]
		skillsused = p_data[id][P_SKILL1]+p_data[id][P_SKILL2]+p_data[id][P_SKILL3]+p_data[id][P_ULTIMATE]
	}


	if ((flag==DISPLAYLEVEL_SHOWRACE || flag==DISPLAYLEVEL_SHOWBOTH) && p_data[id][P_RACE]!=0){
		new temp[128]
		new message[256]
		format(message,255,"%s",race_name)
		format(temp,127,"%L",id,"LEVEL_BY_ITSELF",p_data[id][P_LEVEL])
		add(message,255,temp)

		new race_skill[4][RACE_SKILL_LENGTH]
		new i=0
		for(i=0;i<4;i++){
			raceskill(p_data[id][P_RACE],i+1,id,race_skill[i],RACE_SKILL_LENGTH_F)
		}

		if (p_data[id][P_SKILL1]){
			format(temp,127,"%L",id,"LEVEL2",race_skill[0],p_data[id][P_SKILL1])
			add(message,255,temp)
		}
		if (p_data[id][P_SKILL2]){
			format(temp,127,"%L",id,"LEVEL2",race_skill[1],p_data[id][P_SKILL2])
			add(message,255,temp)
		}
		if (p_data[id][P_SKILL3]){
			format(temp,127,"%L",id,"LEVEL2",race_skill[2],p_data[id][P_SKILL3])
			add(message,255,temp)
		}
		if (p_data[id][P_ULTIMATE]){
			format(temp,127,"%L",id,"ULTIMATE",race_skill[3])
			add(message,255,temp)
		}

		set_hudmessage(255, 255, 255, -1.0, 0.3, 0, 3.0, 5.0, 0.1, 0.2, HUDMESSAGE_CHAN_LEVEL)
		show_hudmessage(id,message)
	}

	if(get_cvar_num("sv_gravity")>650){
		if (((p_data[id][P_RACE] == 9 && race9Options[3] == 1) || p_data[id][P_RACE] == 1) && p_data[id][P_SKILL3]){		// Levitation
			if (get_user_gravity(id)!=p_levitation[p_data[id][P_SKILL3]-1])
				set_user_gravity(id,p_levitation[p_data[id][P_SKILL3]-1])
		}
		else if (get_user_gravity(id)!=1.0)
			set_user_gravity(id,1.0)
	}
	else
		set_user_gravity(id,1.0)

	if (((p_data[id][P_RACE] == 9 && race9Options[1] == 2) || p_data[id][P_RACE] == 2) && p_data[id][P_SKILL1]){		// Invisibility
		if (p_data_b[id][PB_KNIFESELECTED]){
			new invisibility = p_invisibility[p_data[id][P_SKILL1]-1]/2
			set_user_rendering(id,kRenderFxNone, 0,0,0, kRenderTransTexture,invisibility)
		}
		else
			set_user_rendering(id,kRenderFxNone, 0,0,0, kRenderTransTexture,p_invisibility[p_data[id][P_SKILL1]-1])
	}
	else if (p_data[id][P_ITEM]==ITEM_CLOAK){
		if (p_data_b[id][PB_KNIFESELECTED]){
			new invisibility = FT_CLOAK/2
			set_user_rendering(id,kRenderFxNone, 0,0,0, kRenderTransTexture,invisibility)
		}
		else
			set_user_rendering(id,kRenderFxNone, 0,0,0, kRenderTransTexture,FT_CLOAK)
	}
	else
		set_user_rendering(id)

	if (((p_data[id][P_RACE] == 9 && race9Options[1] != 4) || p_data[id][P_RACE] != 4 || !p_data[id][P_SKILL1])){	// Evasion
		if (get_user_health(id)>=500)
			set_user_health(id,get_user_health(id)-1024)
	}

	new parm4[1]
	parm4[0]=id
	unholyspeed(parm4)

	return PLUGIN_CONTINUE
}

WAR3_Immunity_Found_Near(id, origin[3]){
	new players[32], numplayers, targetid, targetorigin[3]

	if(get_user_team(id) == CTS)
		get_players(players, numplayers, "ae", "TERRORIST")
	else
		get_players(players, numplayers, "ae", "CT")

	for (new i=0; i<numplayers; ++i){
		targetid=players[i]

		if(p_data[targetid][P_ITEM] == ITEM_NECKLACE || p_data_b[targetid][PB_WARDENBLINK]){
			get_user_origin(targetid, targetorigin)

			if (get_distance(origin, targetorigin) <= FT_BLINK_RADIUS)
				return true
		}
	}

	return false
}