#include "bot.h"
#include "q_shared.h"
#include "m_player.h"

//======================================================================
//aim決定
//ent	entity
//aim	aimスキル
//yaw	dist
//wep	weapon
void Get_AimAngle(edict_t *ent,float aim,float dist,int weapon)
{
	edict_t *target;
	vec3_t	targaim,v;
	trace_t	rs_trace;

	target = ent->client->zc.first_target;

	switch(weapon)
	{
		//即判定
		case WEAP_SHOTGUN:
		case WEAP_SUPERSHOTGUN:
		case WEAP_RAILGUN:
			if(target != ent->client->zc.last_target)
			{
				if(target->svflags & SVF_MONSTER)
				{
					VectorSubtract(target->s.old_origin,target->s.origin,targaim);
				}
				else 
				{
					VectorCopy(target->velocity,targaim);
					VectorInverse (targaim);
				}
				VectorNormalize(targaim);
				VectorMA(target->s.origin,random() * aim * AIMING_POSGAP * random(),targaim,targaim);
			}
			else
			{
				VectorSubtract(ent->client->zc.last_pos,target->s.origin,targaim);
//				VectorScale (targaim, vec_t scale, vec3_t out)
				VectorMA(target->s.origin,aim * /*VectorLength(targaim)**/ random(),targaim,targaim);
			}
			VectorSubtract(targaim,ent->s.origin,targaim);
			
			ent->s.angles[YAW] = Get_yaw(targaim);
			ent->s.angles[PITCH] = Get_pitch(targaim);

			ent->s.angles[YAW] += aim * AIMING_ANGLEGAP_S * (random() - 0.5) *2;
			if(ent->s.angles[YAW] > 180) ent->s.angles[YAW] -= 360;
			else if(ent->s.angles[YAW] < -180) ent->s.angles[YAW] += 360;

			ent->s.angles[PITCH] += (aim * AIMING_ANGLEGAP_S * (random() - 0.5) * 2);
			if(ent->s.angles[PITCH] > 90) ent->s.angles[PITCH] = 90;
			else if(ent->s.angles[PITCH] < -90) ent->s.angles[PITCH] = -90;
			break;

		case WEAP_MACHINEGUN:
		case WEAP_CHAINGUN:
			if(target != ent->client->zc.last_target)
			{
				if(target->svflags & SVF_MONSTER)
				{
					VectorSubtract(target->s.old_origin,target->s.origin,targaim);
				}
				else 
				{
					VectorCopy(target->velocity,targaim);
					VectorInverse (targaim);
				}
				VectorNormalize(targaim);
				VectorMA(target->s.origin,random() * aim * AIMING_POSGAP,targaim,targaim);
			}
			else
			{
				VectorSubtract(ent->client->zc.last_pos,target->s.origin,targaim);
				VectorMA(target->s.origin,random() * aim /** VectorLength(targaim)*/,targaim,targaim);				
			}
			VectorSubtract(targaim,ent->s.origin,targaim);

			ent->s.angles[YAW] = Get_yaw(targaim);
			ent->s.angles[PITCH] = Get_pitch(targaim);

			ent->s.angles[YAW] += aim * AIMING_ANGLEGAP_M * (random() - 0.5) *2;
			if(ent->s.angles[YAW] > 180) ent->s.angles[YAW] -= 360;
			else if(ent->s.angles[YAW] < -180) ent->s.angles[YAW] += 360;

			ent->s.angles[PITCH] += (aim * AIMING_ANGLEGAP_M * (random() - 0.5) * 2);
			if(ent->s.angles[PITCH] > 90) ent->s.angles[PITCH] = 90;
			else if(ent->s.angles[PITCH] < -90) ent->s.angles[PITCH] = -90;
			break;

		case WEAP_BLASTER:			
		case WEAP_GRENADES:
		case WEAP_GRENADELAUNCHER:
		case WEAP_ROCKETLAUNCHER:
		case WEAP_PHALANX:
		case WEAP_BOOMER:	
			if(target != ent->client->zc.last_target)
			{
				if(target->svflags & SVF_MONSTER)
				{
					VectorSubtract(target->s.origin,target->s.old_origin,targaim);
				}
				else 
				{
					VectorCopy(target->velocity,targaim);
					targaim[0] *= 32;
					targaim[1] *= 32;
					targaim[2] *= 32;
				}
				VectorNormalize(targaim);
				VectorMA(target->s.origin,(11 - aim) * dist/25,targaim,targaim);
			}
			else
			{
				VectorSubtract(target->s.origin,ent->client->zc.last_pos,targaim);
				targaim[2] /= 2;
				VectorMA(target->s.origin,- aim * random() + dist/75,targaim,targaim);				
			}
			rs_trace = gi.trace(target->s.origin,NULL,NULL,targaim,target,MASK_SHOT);
			VectorCopy(rs_trace.endpos,targaim);

			if(weapon == WEAP_GRENADELAUNCHER
				|| weapon == WEAP_ROCKETLAUNCHER
				|| weapon == WEAP_PHALANX)
			{
				if(targaim[2] < (ent->s.origin[2] + JumpMax))
				{
					targaim[2] -= 24;

					VectorCopy(ent->s.origin,v);
					v[2] += ent->viewheight - 8;
					rs_trace = gi.trace(v,NULL,NULL,targaim,ent,MASK_SHOT);
					if(rs_trace.fraction != 1.0) targaim[2] += 24;
				}
				else if(targaim[2] > (ent->s.origin[2] + JumpMax)) targaim[2] += 5;
			}

			VectorSubtract(targaim,ent->s.origin,targaim);

			ent->s.angles[YAW] = Get_yaw(targaim);
			ent->s.angles[PITCH] = Get_pitch(targaim);

			ent->s.angles[YAW] += aim * AIMING_ANGLEGAP_M * (random() - 0.5) *2;
			if(ent->s.angles[YAW] > 180) ent->s.angles[YAW] -= 360;
			else if(ent->s.angles[YAW] < -180) ent->s.angles[YAW] += 360;

			ent->s.angles[PITCH] += (aim * AIMING_ANGLEGAP_M * (random() - 0.5) * 2);
			if(ent->s.angles[PITCH] > 90) ent->s.angles[PITCH] = 90;
			else if(ent->s.angles[PITCH] < -90) ent->s.angles[PITCH] = -90;
			break;

		case WEAP_HYPERBLASTER:
			if(target != ent->client->zc.last_target)
			{
				if(target->svflags & SVF_MONSTER)
				{
					VectorSubtract(target->s.origin,target->s.old_origin,targaim);
				}
				else 
				{
					VectorCopy(target->velocity,targaim);
					targaim[0] *= 32;
					targaim[1] *= 32;
					targaim[2] *= 32;
				}
				VectorNormalize(targaim);
				VectorMA(target->s.origin,(11 - aim) * dist/100,targaim,targaim);
			}
			else
			{
				VectorSubtract(target->s.origin,ent->client->zc.last_pos,targaim);
				targaim[2] /= 2;
				VectorMA(target->s.origin,- aim + dist/115,targaim,targaim);				
			}
			rs_trace = gi.trace(target->s.origin,NULL,NULL,targaim,target,MASK_SHOT);
			VectorCopy(rs_trace.endpos,targaim);

			VectorSubtract(targaim,ent->s.origin,targaim);

			ent->s.angles[YAW] = Get_yaw(targaim);
			ent->s.angles[PITCH] = Get_pitch(targaim);

			ent->s.angles[YAW] += aim * AIMING_ANGLEGAP_M * (random() - 0.5) *2;
			if(ent->s.angles[YAW] > 180) ent->s.angles[YAW] -= 360;
			else if(ent->s.angles[YAW] < -180) ent->s.angles[YAW] += 360;

			ent->s.angles[PITCH] += (aim * AIMING_ANGLEGAP_M * (random() - 0.5) * 2);
			if(ent->s.angles[PITCH] > 90) ent->s.angles[PITCH] = 90;
			else if(ent->s.angles[PITCH] < -90) ent->s.angles[PITCH] = -90;
			break;

		case WEAP_BFG:
			VectorCopy(ent->client->zc.vtemp,targaim);
			VectorSubtract(targaim,ent->s.origin,targaim);

			ent->s.angles[YAW] = Get_yaw(targaim);
			ent->s.angles[PITCH] = Get_pitch(targaim);
			break;
		default:
			break;
	}
}



//======================================================================
//武器使用可能？
int CanUsewep(edict_t *ent,int weapon)
{
	gitem_t *item;
	gclient_t	*client;
	int mywep,ammoindex;

	client = ent->client;

	mywep = Get_KindWeapon(client->pers.weapon);

	switch(weapon)
	{
		case WEAP_BLASTER:
			item = Fdi_BLASTER;//FindItem("Blaster");
			if(client->pers.inventory[ITEM_INDEX(item)])
			{
				if(mywep == WEAP_BLASTER || client->weaponstate == WEAPON_READY)
				{
					item->use(ent,item);
					if(client->weaponstate == WEAPON_READY) return true;
					else return 2;
				}
			}
			break;
	
		case WEAP_SHOTGUN:
			item = Fdi_SHOTGUN;//FindItem("Shotgun");
			ammoindex = ITEM_INDEX(Fdi_SHELLS/*FindItem("Shells")*/);
			if(client->pers.inventory[ITEM_INDEX(item)]
				&& client->pers.inventory[ammoindex] > 0)
			{
				if(mywep == WEAP_SHOTGUN || client->weaponstate == WEAPON_READY)
				{
					item->use(ent,item);
					if(client->weaponstate == WEAPON_READY) return true;
					else return 2;
				}
			}
			break;

		case WEAP_SUPERSHOTGUN:
			item = Fdi_SUPERSHOTGUN;//FindItem("Super Shotgun");
			ammoindex = ITEM_INDEX(Fdi_SHELLS/*FindItem("Shells")*/);

			if(	client->pers.inventory[ITEM_INDEX(item)]
				&& client->pers.inventory[ammoindex] > 1)
			{
				if(mywep == WEAP_SUPERSHOTGUN || client->weaponstate == WEAPON_READY)
				{
					item->use(ent,item);
					if(client->weaponstate == WEAPON_READY) return true;
					else return 2;
				}
			}
			break;

		case WEAP_MACHINEGUN:
			item = Fdi_MACHINEGUN;//FindItem("Machinegun");
			ammoindex = ITEM_INDEX(Fdi_BULLETS/*FindItem("Bullets")*/);

			if(	client->pers.inventory[ITEM_INDEX(item)]
				&& client->pers.inventory[ammoindex] > 0)
			{
				if(client->pers.weapon != item) item->use(ent,item);
				
				if(mywep == WEAP_MACHINEGUN || client->weaponstate == WEAPON_READY
					|| client->weaponstate == WEAPON_FIRING)
				{
//					if(client->pers.weapon == item) return true;
//					else {item->use(ent,item); return 2;}
					if(client->weaponstate == WEAPON_READY || client->weaponstate == WEAPON_FIRING) return true;
					else return 2;
				}
			}
			break;

		case WEAP_CHAINGUN:
			item = FindItem("Chaingun");
			ammoindex = ITEM_INDEX(Fdi_BULLETS/*FindItem("Bullets")*/);

			if(	client->pers.inventory[ITEM_INDEX(item)]
				&& client->pers.inventory[ammoindex] > 0)
			{
				if(mywep == WEAP_CHAINGUN || client->weaponstate == WEAPON_READY)
				{
					item->use(ent,item);
					if(client->weaponstate == WEAPON_READY || client->weaponstate == WEAPON_FIRING) return true;
					else return 2;
				}
			}
			break;

		case WEAP_GRENADES:
			item = Fdi_GRENADES;//FindItem("Grenades");
			ammoindex = ITEM_INDEX(Fdi_GRENADES/*FindItem("Grenades")*/);

			if(client->pers.inventory[ammoindex] > 0)
			{
				if(mywep == WEAP_GRENADES || client->weaponstate == WEAPON_READY)
				{
					item->use(ent,item);
					if(client->weaponstate == WEAPON_READY) return true;
					else return 2;
				}
			}
			break;

		case WEAP_TRAP:
			item = Fdi_TRAP;//FindItem("Trap");
			ammoindex = ITEM_INDEX(Fdi_TRAP/*FindItem("Trap")*/);

			if(client->pers.inventory[ammoindex] > 0)
			{
				if(mywep == WEAP_GRENADES || client->weaponstate == WEAPON_READY)
				{
					item->use(ent,item);
					if(client->weaponstate == WEAPON_READY) return true;
					else return 2;
				}
			}
			break;

		case WEAP_GRENADELAUNCHER:
			item = Fdi_GRENADELAUNCHER;//FindItem("Grenade Launcher");
			ammoindex = ITEM_INDEX(Fdi_GRENADES/*FindItem("Grenades")*/);

			if(	client->pers.inventory[ITEM_INDEX(item)]
				&& client->pers.inventory[ammoindex] > 0)
			{
				if(mywep == WEAP_GRENADELAUNCHER || client->weaponstate == WEAPON_READY)
				{
					item->use(ent,item);
					if(client->weaponstate == WEAPON_READY) return true;
					else return 2;
				}
			}
			break;

		case WEAP_ROCKETLAUNCHER:
			item = Fdi_ROCKETLAUNCHER;//FindItem("Rocket Launcher");
			ammoindex = ITEM_INDEX(Fdi_ROCKETS/*FindItem("Rockets")*/);

			if(	client->pers.inventory[ITEM_INDEX(item)]
				&& client->pers.inventory[ammoindex] > 0)
			{
				if(mywep == WEAP_ROCKETLAUNCHER || client->weaponstate == WEAPON_READY)
				{
					item->use(ent,item);
					if(client->weaponstate == WEAPON_READY) return true;
					else return 2;
				}
			}
			break;

		case WEAP_HYPERBLASTER:
			item = Fdi_HYPERBLASTER;//FindItem("HyperBlaster");
			ammoindex = ITEM_INDEX(Fdi_CELLS/*FindItem("Cells")*/);

			if(	client->pers.inventory[ITEM_INDEX(item)]
				&& client->pers.inventory[ammoindex] > 0)
			{
				if(mywep == WEAP_HYPERBLASTER || client->weaponstate == WEAPON_READY)
				{
					item->use(ent,item);
					if(client->weaponstate == WEAPON_READY || client->weaponstate == WEAPON_FIRING) return true;
					else return 2;
				}
			}
			break;

		case WEAP_BOOMER:
			item = Fdi_BOOMER;//FindItem("Ionripper");
			ammoindex = ITEM_INDEX(Fdi_CELLS/*FindItem("Cells")*/);

			if(	client->pers.inventory[ITEM_INDEX(item)]
				&& client->pers.inventory[ammoindex] > 0)
			{
				if(mywep == WEAP_BOOMER || client->weaponstate == WEAPON_READY)
				{
					item->use(ent,item);
					if(client->weaponstate == WEAPON_READY || client->weaponstate == WEAPON_FIRING) return true;
					else return 2;
				}
			}
			break;

		case WEAP_RAILGUN:
			item = Fdi_RAILGUN;//FindItem("Railgun");
			ammoindex = ITEM_INDEX(Fdi_SLUGS/*FindItem("Slugs")*/);

			if(	client->pers.inventory[ITEM_INDEX(item)]
				&& client->pers.inventory[ammoindex] > 0)
			{
				if(mywep == WEAP_RAILGUN || client->weaponstate == WEAPON_READY)
				{
					item->use(ent,item);
					if(client->weaponstate == WEAPON_READY) return true;
					else return 2;
				}
			}
			break;

		case WEAP_PHALANX:
			item = Fdi_PHALANX;//FindItem("Phalanx");
			ammoindex = ITEM_INDEX(Fdi_MAGSLUGS/*FindItem("Mag Slug")*/);

			if(	client->pers.inventory[ITEM_INDEX(item)]
				&& client->pers.inventory[ammoindex] > 0)
			{
				if(mywep == WEAP_PHALANX || client->weaponstate == WEAPON_READY)
				{
					item->use(ent,item);
					if(client->weaponstate == WEAPON_READY) return true;
					else return 2;
				}
			}
			break;

		case WEAP_BFG:
			item = Fdi_BFG;//FindItem("BFG10K");
			ammoindex = ITEM_INDEX(Fdi_CELLS/*FindItem("Cells")*/);

			if( client->pers.inventory[ITEM_INDEX(item)]
				&& client->pers.inventory[ammoindex] >= 50)
			{
				if(mywep == WEAP_BFG || client->weaponstate == WEAPON_READY)
				{
					item->use(ent,item);
					if(client->weaponstate == WEAPON_READY) return true;
					else return 2;
				}
			}
			break;
		default:	//case WEAP_BLASTER:
			item = Fdi_BLASTER;//FindItem("Blaster");
			if(client->pers.inventory[ITEM_INDEX(item)])
			{
				if(mywep == WEAP_BLASTER || client->weaponstate == WEAPON_READY)
				{
					item->use(ent,item);
					if(client->weaponstate == WEAPON_READY) return true;
					else return 2;
				}
			}
			break;
	}
	return false;
}

//------------------------------------------------------------

//	Use BFG

//------------------------------------------------------------
qboolean B_UseBfg(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
	int k,mywep;
	zgcl_t		*zc;
	gclient_t	*client;

	client = ent->client;
	zc = &client->zc;

	if((k = CanUsewep(ent,WEAP_BFG)))
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
		if((k = Bot_traceS(ent,target))) VectorCopy(target->s.origin,zc->vtemp);

		if(FFlg[skill] & FIRE_STAYFIRE)
		{
			if(k /*&& random() < 0.8*/)
			{
				client->buttons |= BUTTON_ATTACK;
				zc->battlemode |= FIRE_STAYFIRE;			//モード遷移
				zc->battlecount = 8 + (int)(10 * random());
				trace_priority = TRP_ALLKEEP;
				return true;
			}
		}
		//爆発回避
		else if((FFlg[skill] & FIRE_EXPAVOID)
		&& distance < 300 /*&& random() < 0.5 */
		&& Bot_traceS(ent,target))
		{
			if(ent->groundentity || zc->waterstate)
			{
				zc->battlemode |= FIRE_EXPAVOID;
				zc->battlecount = 6 + (int)(6 * random());
				trace_priority = TRP_ALLKEEP;
				return true;
			}
		}
		//普通
		else if(!(FFlg[skill] &(FIRE_STAYFIRE | FIRE_EXPAVOID)))
		{
			if(k /*&& random() < 0.8*/)
			{
				zc->battlemode |= FIRE_BFG;
				zc->battlecount = 6 + (int)(6 * random());
				trace_priority = TRP_ANGLEKEEP;
				return true;
			}
		}
		else if((FFlg[skill] & FIRE_EXPAVOID)
			&& Bot_traceS(ent,target))
		{
			if(k /*&& random() < 0.8*/)
			{
				zc->battlemode |= FIRE_BFG;
				zc->battlecount = 6 + (int)(6 * random());
				trace_priority = TRP_ANGLEKEEP;
				return true;
			}
		}
	}
	return false;
}

//------------------------------------------------------------

//	Use Hyper Blaster

//------------------------------------------------------------
qboolean B_UseHyperBlaster(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
	int k,mywep;
	zgcl_t		*zc;
	gclient_t	*client;

	client = ent->client;
	zc = &client->zc;

	if((k = CanUsewep(ent,WEAP_HYPERBLASTER)))
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		client->buttons |= BUTTON_ATTACK;
		if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
		return true;
	}
	return false;
}

//------------------------------------------------------------

//	Use Phalanx

//------------------------------------------------------------
qboolean B_UsePhalanx(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
	int k,mywep;
	zgcl_t		*zc;
	gclient_t	*client;

	client = ent->client;
	zc = &client->zc;

	if((k = CanUsewep(ent,WEAP_PHALANX)))
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
		if((FFlg[skill] & FIRE_PRESTAYFIRE)
			&& ((distance > 500 && random() < 0.1) || fabs(ent->s.angles[PITCH]) > 45 ) 
			&& Bot_traceS(ent,target)
			&& (enewep <= WEAP_MACHINEGUN || enewep == WEAP_GRENADES))
		{
			if(ent->groundentity || zc->waterstate)
			{
				zc->battlemode |= FIRE_PRESTAYFIRE;
				zc->battlecount = 2 + (int)(6 * random());
				trace_priority = TRP_ALLKEEP;
				return true;
			}
		}
		if((FFlg[skill] & FIRE_JUMPROC) && random() < 0.3 
			&& (target->s.origin[2] - ent->s.origin[2]) < JumpMax
			&& !(client->ps.pmove.pm_flags && PMF_DUCKED)) 
		{
			if(ent->groundentity && !ent->waterlevel <= 1)
			{
				if(zc->route_trace)
				{
					if(Bot_Fall(ent,ent->s.origin,0))
					{
						trace_priority = TRP_ALLKEEP;
						if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
						return true;
					}
				}
				else
				{
					ent->moveinfo.speed = 0;
					ent->velocity[2] += VEL_BOT_JUMP;
					gi.sound(ent, CHAN_VOICE, gi.soundindex("*jump1.wav"), 1, ATTN_NORM, 0);
					PlayerNoise(ent, ent->s.origin, PNOISE_SELF);	//pon
					Set_BotAnim(ent,ANIM_JUMP,FRAME_jump1-1,FRAME_jump6);
					trace_priority = TRP_ALLKEEP;
					if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
					return true;
				}
			}
		}
		else if((FFlg[skill] & FIRE_EXPAVOID)
		&& distance < 300 && random() < 0.5 
		&& Bot_traceS(ent,target))
		{
			if(ent->groundentity || zc->waterstate)
			{
				zc->battlemode |= FIRE_EXPAVOID;
				zc->battlecount = 4 + (int)(6 * random());
				trace_priority = TRP_ALLKEEP;
				return true;
			}
		}
		if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
		return true;
	}
	return false;
}


//------------------------------------------------------------

//	Use Rocket

//------------------------------------------------------------
qboolean B_UseRocket(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
	int k,mywep;
	zgcl_t		*zc;
	gclient_t	*client;

	client = ent->client;
	zc = &client->zc;

	if((k = CanUsewep(ent,WEAP_ROCKETLAUNCHER)))
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
		if((FFlg[skill] & FIRE_PRESTAYFIRE)
			&& ((distance > 500 && random() < 0.1) || fabs(ent->s.angles[PITCH]) > 45 ) 
			&& Bot_traceS(ent,target)
			&& (enewep <= WEAP_MACHINEGUN || enewep == WEAP_GRENADES))
		{
			if(ent->groundentity || zc->waterstate)
			{
				zc->battlemode |= FIRE_PRESTAYFIRE;
				zc->battlecount = 2 + (int)(6 * random());
				trace_priority = TRP_ALLKEEP;
				return true;
			}
		}
		if((FFlg[skill] & FIRE_JUMPROC) && random() < 0.3 
			&& (target->s.origin[2] - ent->s.origin[2]) < JumpMax
			&& !(client->ps.pmove.pm_flags && PMF_DUCKED)) 
		{
			if(ent->groundentity && !ent->waterlevel <= 1)
			{
				if(zc->route_trace)
				{
					if(Bot_Fall(ent,ent->s.origin,0))
					{
						trace_priority = TRP_ALLKEEP;
						if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
						return true;
					}
				}
				else
				{
					ent->moveinfo.speed = 0;

					ent->velocity[2] += VEL_BOT_JUMP;
					gi.sound(ent, CHAN_VOICE, gi.soundindex("*jump1.wav"), 1, ATTN_NORM, 0);
					PlayerNoise(ent, ent->s.origin, PNOISE_SELF);	//pon
					Set_BotAnim(ent,ANIM_JUMP,FRAME_jump1-1,FRAME_jump6);
					trace_priority = TRP_ALLKEEP;
					if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
					return true;
				}
			}
		}
		else if((FFlg[skill] & FIRE_EXPAVOID)
		&& distance < 300 && random() < 0.5 
		&& Bot_traceS(ent,target))
		{
			if(ent->groundentity || zc->waterstate)
			{
				zc->battlemode |= FIRE_EXPAVOID;
				zc->battlecount = 4 + (int)(6 * random());
				trace_priority = TRP_ALLKEEP;
				return true;
			}
		}
		if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
		return true;
	}
	return false;
}



//------------------------------------------------------------

//	Use Boomer

//------------------------------------------------------------
qboolean B_UseBoomer(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
	int k,mywep;
	zgcl_t		*zc;
	gclient_t	*client;

	client = ent->client;
	zc = &client->zc;

	if((k = CanUsewep(ent,WEAP_BOOMER)))
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		client->buttons |= BUTTON_ATTACK;
		if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
		return true;
	}
	return false;
}

//------------------------------------------------------------

//	Use Railgun

//------------------------------------------------------------
qboolean B_UseRailgun(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
	int k,mywep;
	zgcl_t		*zc;
	gclient_t	*client;

	client = ent->client;
	zc = &client->zc;

	if((k = CanUsewep(ent,WEAP_RAILGUN)))
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		client->buttons |= BUTTON_ATTACK;
		if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
		return true;
	}
	return false;
}

//------------------------------------------------------------

//	Use Grenade Launcher

//------------------------------------------------------------
qboolean B_UseGrenadeLauncher(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
	int k,mywep;
	zgcl_t		*zc;
	gclient_t	*client;

	client = ent->client;
	zc = &client->zc;

	if((k = CanUsewep(ent,WEAP_GRENADELAUNCHER)))
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		if((FFlg[skill] & FIRE_STAYFIRE)
			&& random() < 0.3 && target->s.origin[2] < ent->s.origin[2])
		{
			if(ent->groundentity || zc->waterstate)
			{
				if(Bot_traceS(ent,target))
				{
					zc->battlemode |= FIRE_STAYFIRE;
					zc->battlecount = 5 + (int)(10 * random());
					trace_priority = TRP_ALLKEEP;
					client->buttons |= BUTTON_ATTACK;
					return true;
				}
			}
		}
		else if((FFlg[skill] & FIRE_EXPAVOID)
		&& distance < 300 && random() < 0.5 
		&& Bot_traceS(ent,target))
		{
			if(ent->groundentity || zc->waterstate)
			{
				zc->battlemode |= FIRE_EXPAVOID;
				zc->battlecount = 2 + (int)(6 * random());
				trace_priority = TRP_ALLKEEP;
				return true;
			}
		}
		client->buttons |= BUTTON_ATTACK;
		if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
		return true;
	}
	return false;

}

//------------------------------------------------------------

//	Use Chain Gun

//------------------------------------------------------------
qboolean B_UseChainGun(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
	int k,mywep;
	zgcl_t		*zc;
	gclient_t	*client;

	client = ent->client;
	zc = &client->zc;

	if((k = CanUsewep(ent,WEAP_CHAINGUN)))
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		client->buttons |= BUTTON_ATTACK;
		if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
		return true;
	}
	return false;
}


//------------------------------------------------------------

//	Use Machine Gun

//------------------------------------------------------------
qboolean B_UseMachineGun(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
	int k,mywep;
	zgcl_t		*zc;
	gclient_t	*client;

	client = ent->client;
	zc = &client->zc;

	if((k = CanUsewep(ent,WEAP_MACHINEGUN)))
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		if(k == true) client->buttons |= BUTTON_ATTACK;
		if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
		return true;
	}
	return false;
}

//------------------------------------------------------------

//	Use S-Shotgun

//------------------------------------------------------------
qboolean B_UseSuperShotgun(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
	int k,mywep;
	zgcl_t		*zc;
	gclient_t	*client;

	client = ent->client;
	zc = &client->zc;

	if((k = CanUsewep(ent,WEAP_SUPERSHOTGUN)))
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		client->buttons |= BUTTON_ATTACK;
		if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
		return true;
	}
	return false;
}

//------------------------------------------------------------

//	Use Shotgun

//------------------------------------------------------------
qboolean B_UseShotgun(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
	int k,mywep;
	zgcl_t		*zc;
	gclient_t	*client;

	client = ent->client;
	zc = &client->zc;

	if((k = CanUsewep(ent,WEAP_SHOTGUN)))
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		client->buttons |= BUTTON_ATTACK;
		if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
		return true;
	}
	return false;
}

//------------------------------------------------------------

//	Use Hand Grenade

//------------------------------------------------------------
qboolean B_UseHandGrenade(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
	int k,mywep;
	zgcl_t		*zc;
	gclient_t	*client;

	client = ent->client;
	zc = &client->zc;

	if((k = CanUsewep(ent,WEAP_GRENADES)))
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		if(ent->client->weaponstate == WEAPON_READY ) client->buttons |= BUTTON_ATTACK;
		if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
		return true;
	}
	return false;
}

//------------------------------------------------------------

//	Use Trap

//------------------------------------------------------------
qboolean B_UseTrap(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
	int k,mywep;
	zgcl_t		*zc;
	gclient_t	*client;

	client = ent->client;
	zc = &client->zc;

	if((k = CanUsewep(ent,WEAP_TRAP)))
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		if(ent->client->weaponstate == WEAPON_READY ) client->buttons |= BUTTON_ATTACK;
		if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
		return true;
	}
	return false;
}


//------------------------------------------------------------

//	Use Blaster

//------------------------------------------------------------
qboolean B_UseBlaster(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
	int k,mywep;
	zgcl_t		*zc;
	gclient_t	*client;

	client = ent->client;
	zc = &client->zc;

	if((k = CanUsewep(ent,WEAP_BLASTER)))
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		client->buttons |= BUTTON_ATTACK;
		if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
		return true;;
	}
	return false;
}

//return weapon
void Combat_LevelX(edict_t *ent,int foundedenemy,int enewep
				   ,float aim,float distance,int skill)
{
	gclient_t	*client;
	zgcl_t		*zc;
	edict_t		*target;
	int			mywep,k;
	vec3_t		v;
//	qboolean	mod = false;

	client = ent->client;
	zc = &client->zc;
	target = zc->first_target;

	//-----------------------------------------------------------------------
	//ステータスを反映
	//-----------------------------------------------------------------------
	k = false;
	//予測========================
	if(zc->battlemode & FIRE_ESTIMATE)
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		//Phalanx
		if(distance > 100 || mywep == WEAP_PHALANX)
		{
			if(B_UsePhalanx(ent,target,enewep,aim,distance,skill)) k = true;
		}

		//Rocket
		if(distance > 100 || mywep == WEAP_ROCKETLAUNCHER)
		{
			if(B_UseRocket(ent,target,enewep,aim,distance,skill)) k = true;
		}
	
		//Boomer
		if(distance < 1200)
		{
			if(B_UseBoomer(ent,target,enewep,aim,distance,skill)) k = true;
		}		
		//Grenade Launcher
		if(distance > 100 && distance < 400 && (target->s.origin[2] - ent->s.origin[2]) < 200)
		{
			if(B_UseGrenadeLauncher(ent,target,enewep,aim,distance,skill)) k = true;
		}
		//Hand Grenade
		if(distance < 1200)
		{
			if(B_UseHandGrenade(ent,target,enewep,aim,distance,skill)) k = true;
		}
		VectorSubtract(zc->vtemp,ent->s.origin,v);
		ent->s.angles[YAW] = Get_yaw(v);
		ent->s.angles[PITCH] = Get_pitch(v);
		if(k) trace_priority = TRP_ALLKEEP;
		else trace_priority = TRP_ANGLEKEEP;
		return;
	}
	VectorSubtract(target->s.origin,ent->s.origin,v);
	ent->s.angles[YAW] = Get_yaw(v);
	ent->s.angles[PITCH] = Get_pitch(v);
	trace_priority = TRP_ANGLEKEEP;
}

//return weapon
void Combat_Level0(edict_t *ent,int foundedenemy,int enewep
				   ,float aim,float distance,int skill)
{
	float		f;
	gclient_t	*client;
	zgcl_t		*zc;

	edict_t		*target;
	int			mywep,i,j,k;
	vec3_t		v,vv,v1,v2;
//	qboolean	mod = false;

	trace_t		rs_trace;

	client = ent->client;
	zc = &client->zc;
	target = zc->first_target;


	//-----------------------------------------------------------------------
	//ステータスを反映
	//-----------------------------------------------------------------------
	//チキンは狙いがキツイ==============
	if(zc->battlemode == FIRE_CHIKEN) aim *= 0.7;
	//左右に回避========================
	if(zc->battlemode & FIRE_SHIFT)
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);

		if(--zc->battlesubcnt > 0)
		{
			if(ent->groundentity)
			{
				if(zc->battlemode & FIRE_SHIFT_R)
				{
					zc->moveyaw = ent->s.angles[YAW] + 90;
					if(zc->moveyaw > 180) zc->moveyaw -= 360;
				}
				else
				{
					zc->moveyaw = ent->s.angles[YAW] - 90;
					if(zc->moveyaw < -180) zc->moveyaw += 360;
				}
				trace_priority = TRP_MOVEKEEP;	//後退処理
			}
		}
		else
		{
			zc->battlemode &= ~FIRE_SHIFT;
		}
	}

	//dodge=============================
	if(Bot[ent->client->zc.botindex].param[BOP_DODGE]
		&& ent->groundentity && !ent->waterlevel)
	{
		AngleVectors (target->client->v_angle, v,NULL, NULL);
		VectorScale (v, 300, v);

		VectorSet(vv, 0, 0,  target->viewheight-8);
		VectorAdd(target->s.origin,vv,vv);
		VectorAdd(vv,v,v);

		VectorSet(v1, -4, -4,-4);
		VectorSet(v2, 4, 4, 4);
		rs_trace = gi.trace(vv,v1,v2,v,target,MASK_SHOT);

		if(rs_trace.ent == ent)
		{
			if(rs_trace.endpos[2] > (ent->s.origin[2] + 4) && random() < 0.4)
			{
				client->ps.pmove.pm_flags |= PMF_DUCKED;
				zc->battleduckcnt = 2 + 8 * random();
			}
			else if(rs_trace.endpos[2] < (ent->s.origin[2] + JumpMax - 24))
			{
				if(zc->route_trace)
				{
					if(Bot_Fall(ent,ent->s.origin,0)) trace_priority = TRP_MOVEKEEP;;
				}
				else
				{
					ent->moveinfo.speed = 0.5;
	
					ent->velocity[2] += VEL_BOT_JUMP;
					gi.sound(ent, CHAN_VOICE, gi.soundindex("*jump1.wav"), 1, ATTN_NORM, 0);
					PlayerNoise(ent, ent->s.origin, PNOISE_SELF);	//pon
					Set_BotAnim(ent,ANIM_JUMP,FRAME_jump1-1,FRAME_jump6);
				}					
			}
		}
	}
	//無視して走る========================
	if(zc->battlemode & FIRE_IGNORE)
	{
		if(--zc->battlecount > 0)
		{
			if(zc->first_target != zc->last_target)
			{
				zc->battlemode = 0;
			}
			else return;
		}
		zc->battlemode = 0;
	}

	//立ち止まって撃つ準備========================
	if(zc->battlemode & FIRE_PRESTAYFIRE)
	{
		if(--zc->battlecount > 0)
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			Get_AimAngle(ent,aim,distance,mywep);
			if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity) ent->client->ps.pmove.pm_flags |= PMF_DUCKED;
			trace_priority = TRP_ALLKEEP;	//動かない
			return;
		}
		if(!(zc->battlemode & FIRE_SHIFT)) zc->battlemode = FIRE_STAYFIRE;			//モード遷移
		zc->battlecount = 5 + (int)(20 * random());
	}

	//立ち止まって撃つ========================
	if(zc->battlemode & FIRE_STAYFIRE)
	{
		if(--zc->battlecount > 0)
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			if(1/*mywep == WEAP_BFG*/) CanUsewep(ent,WEAP_BFG);
			aim *= 0.95;
			Get_AimAngle(ent,aim,distance,mywep);
			if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity)
			{
				if(mywep == WEAP_BFG)
				{
					if(target->s.origin[2] > ent->s.origin[2]) client->ps.pmove.pm_flags |= PMF_DUCKED;
				}
				else client->ps.pmove.pm_flags |= PMF_DUCKED;
			}
			if(!(zc->battlemode & FIRE_SHIFT)) trace_priority = TRP_ALLKEEP;	//動かない
			if(Bot_traceS(ent,target) 
				|| mywep == WEAP_BFG 
				|| mywep == WEAP_GRENADELAUNCHER) client->buttons |= BUTTON_ATTACK;
			return;
		}
		zc->battlemode = 0;
	}

	//FIRE_RUSH	つっこむ========================
	if(zc->battlemode & FIRE_RUSH)
	{
		if(--zc->battlecount > 0)
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			if(1/*mywep == WEAP_BFG*/) CanUsewep(ent,WEAP_BFG);
			aim *= 0.95;
			Get_AimAngle(ent,aim,distance,mywep);
			if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity)
			{
				if(mywep == WEAP_BFG)
				{
					if(target->s.origin[2] > ent->s.origin[2]) client->ps.pmove.pm_flags |= PMF_DUCKED;
				}
				else client->ps.pmove.pm_flags |= PMF_DUCKED;
			}
			trace_priority = TRP_MOVEKEEP;	//後退処理
			zc->moveyaw = ent->s.angles[YAW];

			if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
			return;
		}
		zc->battlemode = 0;
	}

	//後退ファイア(爆発回避)========================
	if(zc->battlemode & FIRE_EXPAVOID)
	{
		if(--zc->battlecount > 0)
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			if(1/*mywep == WEAP_BFG*/) CanUsewep(ent,WEAP_BFG);
			aim *= 0.95;
			Get_AimAngle(ent,aim,distance,mywep);
			if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity)
			{
				if(mywep == WEAP_BFG)
				{
					if(target->s.origin[2] > ent->s.origin[2]) client->ps.pmove.pm_flags |= PMF_DUCKED;
				}
				else client->ps.pmove.pm_flags |= PMF_DUCKED;
			}
			trace_priority = TRP_MOVEKEEP;	//後退処理
			zc->moveyaw = ent->s.angles[YAW] + 180;
			if(zc->moveyaw > 180) zc->moveyaw -= 360;

			if(Bot_traceS(ent,target) 
				|| mywep == WEAP_BFG 
				|| mywep == WEAP_GRENADELAUNCHER) client->buttons |= BUTTON_ATTACK;
			return;
		}
		zc->battlemode = 0;
	}
	//ＢＦＧファイア(爆発回避)========================
	if(zc->battlemode & FIRE_BFG)
	{
		if(--zc->battlecount > 0)
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			if(1/*mywep == WEAP_BFG*/) CanUsewep(ent,WEAP_BFG);
			aim *= 0.95;
			Get_AimAngle(ent,aim,distance,mywep);
			if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity)
			{
				if(1/*mywep == WEAP_BFG*/)
				{
					if(target->s.origin[2] > ent->s.origin[2]) client->ps.pmove.pm_flags |= PMF_DUCKED;
				}
				else client->ps.pmove.pm_flags |= PMF_DUCKED;
			}
			trace_priority = TRP_ANGLEKEEP;	//後退処理

			if(Bot_traceS(ent,target) 
				|| mywep == WEAP_BFG 
				|| mywep == WEAP_GRENADELAUNCHER) client->buttons |= BUTTON_ATTACK;
			return;
		}
		zc->battlemode = 0;
	}

	//撃って避難========================
	if(zc->battlemode & FIRE_REFUGE)
	{
		if(--zc->battlecount > 0)
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			//CanUsewep(ent,WEAP_BFG);
			aim *= 0.95;
			Get_AimAngle(ent,aim,distance,mywep);
			if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity)
			{
				if(mywep == WEAP_BFG)
				{
					if(target->s.origin[2] > ent->s.origin[2]) client->ps.pmove.pm_flags |= PMF_DUCKED;
				}
				else client->ps.pmove.pm_flags |= PMF_DUCKED;
			}
			trace_priority = TRP_ANGLEKEEP;	//動かない
//			trace_priority = TRP_ALLKEEP;	//動かない
			if(Bot_traceS(ent,target) 
				|| mywep == WEAP_BFG 
				|| mywep == WEAP_GRENADELAUNCHER) client->buttons |= BUTTON_ATTACK;
			return;
		}
		zc->battlemode = 0;
		zc->routeindex -= 2;
	}

	if(!(client->zc.zccmbstt & CTS_ENEM_NSEE) 
		&& (zc->zcstate & STS_WAITSMASK2)
		&& (target->s.origin[2] - ent->s.origin[2]) < -300)
	{
		if((k = CanUsewep(ent,WEAP_GRENADELAUNCHER)))
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			Get_AimAngle(ent,aim,distance,mywep);
			if((target->client->weaponstate == WEAPON_FIRING && ent->groundentity) || (zc->zcstate & STS_WAITSMASK2)) ent->client->ps.pmove.pm_flags |= PMF_DUCKED;
			client->buttons |= BUTTON_ATTACK;
			trace_priority = TRP_ANGLEKEEP;
			return;
		}
		if((k = CanUsewep(ent,WEAP_GRENADES)))
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			Get_AimAngle(ent,aim,distance,mywep);
			if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity) ent->client->ps.pmove.pm_flags |= PMF_DUCKED;
			if(ent->client->weaponstate == WEAPON_READY ) client->buttons |= BUTTON_ATTACK;
			trace_priority = TRP_ANGLEKEEP;
			return;
		}
	}

	//-----------------------------------------------------------------------
	//特殊ファイアリング
	//-----------------------------------------------------------------------
	mywep = Get_KindWeapon(client->pers.weapon);

	//左右回避セット========================
	if(!(zc->battlemode & FIRE_SHIFT) && skill > (random() * skill) /*&& distance < 250*/
		&& (30 * random()) < Bot[zc->botindex].param[BOP_OFFENCE])
	{
		k = false;
		if(zc->route_trace && enewep != WEAP_RAILGUN)
		{
			for(i = zc->routeindex;i < (zc->routeindex + 10);i++)
			{
				if(i >= CurrentIndex) break;
				if(Route[i].state == GRS_ITEMS)
				{
					if(Route[i].ent->solid == SOLID_TRIGGER)
					{
						k = true;
						break;
					}
				}				
			}
		}
		if(!k)
		{
			Get_AimAngle(ent,aim,distance,mywep);
			f =target->s.angles[YAW] - ent->s.angles[YAW];

			if(f > 180)
			{
				f = -(360 - f);
			}
			if( f < -180)
			{
				f = -(f + 360);
			}
	
			//俺をみている！！
			if(f <= -160)
			{

				zc->battlemode |= FIRE_SHIFT_L;
				zc->battlesubcnt = 5 + (int)(16 * random());
			}
			else if(f >= 160)
			{
				zc->battlemode |= FIRE_SHIFT_R;
				zc->battlesubcnt = 5 + (int)(16 * random());
			}
		}
	}

	//敵がペンタをとっている========================
	if((FFlg[skill] & FIRE_AVOIDINV)
		&& target->client->invincible_framenum > level.framenum)
	{
//		mywep = Get_KindWeapon(client->pers.weapon);
		Get_AimAngle(ent,aim,distance,mywep);
		trace_priority = TRP_MOVEKEEP;	//後退処理
		zc->moveyaw = ent->s.angles[YAW] + 180;
		if(zc->moveyaw > 180) zc->moveyaw -= 360;
		return;
	}
	//Quad時の処理=================================
	if((FFlg[skill] & FIRE_QUADUSE) 
		&& (ent->client->quad_framenum > level.framenum)
		&& distance < 300)
	{
		j = false;
		if(enewep < WEAP_MACHINEGUN || enewep == WEAP_GRENADES) j = true;

		//Hyper Blaster
		if((k = CanUsewep(ent,WEAP_HYPERBLASTER)))
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			Get_AimAngle(ent,aim,distance,mywep);
			client->buttons |= BUTTON_ATTACK;
			trace_priority = TRP_ANGLEKEEP;
			if(j)
			{
				zc->battlemode |= FIRE_RUSH;
				zc->battlecount = 8 + (int)(10 * random());
			}
			return;
		}
		//Chain Gun
		if((k = CanUsewep(ent,WEAP_CHAINGUN)))
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			Get_AimAngle(ent,aim,distance,mywep);
			client->buttons |= BUTTON_ATTACK;
			trace_priority = TRP_ANGLEKEEP;
			if(j)
			{
				zc->battlemode |= FIRE_RUSH;
				zc->battlecount = 8 + (int)(10 * random());
			}
			return;
		}
		//Machine Gun
		if((k = CanUsewep(ent,WEAP_MACHINEGUN)))
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			Get_AimAngle(ent,aim,distance,mywep);
			client->buttons |= BUTTON_ATTACK;
			trace_priority = TRP_ANGLEKEEP;
			if(j)
			{
				zc->battlemode |= FIRE_RUSH;
				zc->battlecount = 8 + (int)(10 * random());
			}
			return;
		}
		//S-Shotgun
		if((k = CanUsewep(ent,WEAP_SUPERSHOTGUN)))
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			Get_AimAngle(ent,aim,distance,mywep);
			client->buttons |= BUTTON_ATTACK;
			trace_priority = TRP_ANGLEKEEP;
			if(j)
			{
				zc->battlemode |= FIRE_RUSH;
				zc->battlecount = 8 + (int)(10 * random());
			}
			return;
		}
	}
	//撃って逃げる処理=================================
	if((FFlg[skill] & FIRE_REFUGE)
		&& zc->battlemode == 0 && zc->route_trace && zc->routeindex > 1 )
	{
		j = false;
		if(enewep >= WEAP_CHAINGUN && enewep != WEAP_GRENADES) j = true;


		Get_RouteOrigin(zc->routeindex - 2,v);

		if(fabs(v[2] - ent->s.origin[2]) < JumpMax && j)
		{
			mywep = Get_KindWeapon(client->pers.weapon);
			if(mywep == WEAP_GRENADELAUNCHER
			|| mywep == WEAP_ROCKETLAUNCHER
			|| mywep == WEAP_PHALANX)
			{
				zc->battlemode |= FIRE_REFUGE;			//モード遷移
				zc->battlecount = 8 + (int)(10 * random());
				trace_priority = TRP_ALLKEEP;
				return;
			}
		}
	}
	//トレース中以外のときにグルグルを防ぐ=================================
	if(!zc->route_trace && distance < 100)
	{
		zc->battlemode |= FIRE_EXPAVOID;			//モード遷移
		zc->battlecount = 4 + (int)(8 * random());
		trace_priority = TRP_ALLKEEP;		
	}


	
	//-----------------------------------------------------------------------
	//プライオリティ
	//-----------------------------------------------------------------------	
	//BFG
	if(distance > 200)
	{
		if(B_UseBfg(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}
	
	for(i = 0;i < 3;i++)
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		
		if(i == 0 && zc->secwep_selected) continue;

		//try to select secondary weapon
		if(i == 0 && zc->secwep_selected) i = 1;
		else if(i == 0 && foundedenemy < 3 
			&& target->health < 50 && !zc->secwep_selected
			&& ent->health >= 50)
		{
			if((9 * random()) < Bot[zc->botindex].param[BOP_COMBATSKILL])
			{
				zc->secwep_selected = 2;
				i = 1;
			}
		}

		if(i == 2)
		{
			if(zc->secwep_selected)
			{
				zc->secwep_selected = 0;
				j = 0;
			}
			else break;
		}
		else j = i;

		if(distance > 100 && (mywep == WEAP_BFG || random() < 0.5))
		{
			if(B_UseBfg(ent,target,enewep,aim,distance,skill)) goto FIRED;
		}

		switch(Bot[zc->botindex].param[BOP_PRIWEP + j])
		{
			case WEAP_BFG:
				if(distance > 100)
				{
					if(B_UseBfg(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
				break;
			case WEAP_HYPERBLASTER:
				if(distance < 1200)
				{
					if(B_UseHyperBlaster(ent,target,enewep,aim,distance,skill)) goto FIRED;			
				}
				break;
			case WEAP_PHALANX:
				if(distance > 100 && distance < 1200/*|| mywep == WEAP_PHALANX*/)
				{
					if(B_UsePhalanx(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
				break;
			case WEAP_ROCKETLAUNCHER:
				if(distance > 100 && distance < 1200/*|| mywep == WEAP_ROCKETLAUNCHER*/)
				{
					if(B_UseRocket(ent,target,enewep,aim,distance,skill)) goto FIRED;			
				}
				break;
			case WEAP_BOOMER:
				if(distance < 1200)
				{
					if(B_UseBoomer(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
				break;
			case WEAP_RAILGUN:
				if(distance < 1200)
				{
					if(B_UseRailgun(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
				break;
			case WEAP_GRENADELAUNCHER:
				if(distance > 100 && distance < 400 && (target->s.origin[2] - ent->s.origin[2]) < 200)
				{
					if(B_UseGrenadeLauncher(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
				break;
			case WEAP_CHAINGUN:
			case WEAP_MACHINEGUN:
				if(distance < 1200)
				{
					if(B_UseChainGun(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
				if(distance < 1200)
				{
					if(B_UseMachineGun(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
				break;
			case WEAP_SUPERSHOTGUN:
			case WEAP_SHOTGUN:
				if(distance < 1200)
				{
					if(B_UseSuperShotgun(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
				if(distance < 1200)
				{
					if(B_UseShotgun(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
			case WEAP_GRENADES:
				if(distance < 1200)
				{
					if(B_UseHandGrenade(ent,target,enewep,aim,distance,skill)) goto FIRED;
				}
				break;
			default:
				break;
		}
	}

	
	//-----------------------------------------------------------------------
	//通常ファイアリング
	//-----------------------------------------------------------------------
	zc->secwep_selected = 0;
	//BFG
	if(distance > 200)
	{
		if(B_UseBfg(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}

	//Hyper Blaster
	if(distance < 1200)
	{
		if(B_UseHyperBlaster(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}

	//Phalanx
	if((distance > 100 && distance < 1200)/*|| mywep == WEAP_PHALANX*/)
	{
		if(B_UsePhalanx(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}

	//Rocket
	if((distance > 100 && distance < 1200)/*|| mywep == WEAP_ROCKETLAUNCHER*/)
	{
		if(B_UseRocket(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}
	
	//Boomer
	if(distance < 1200)
	{
		if(B_UseBoomer(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}

	//Railgun
	if(distance < 1200)
	{
		if(B_UseRailgun(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}
	
	//Grenade Launcher
	if(distance > 100 && distance < 400 && (target->s.origin[2] - ent->s.origin[2]) < 200)
	{
		if(B_UseGrenadeLauncher(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}
	//Chain Gun
	if(distance < 1200)
	{
		if(B_UseChainGun(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}
	//Machine Gun
	if(distance < 1200)
	{
		if(B_UseMachineGun(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}
	//S-Shotgun
	if(distance < 1200)
	{
		if(B_UseSuperShotgun(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}

	if((FFlg[skill] & FIRE_IGNORE)
		&& distance > 400 && ent->groundentity
		&& !(zc->zcstate & STS_WAITSMASK))
	{
		zc->battlemode = FIRE_IGNORE;
		zc->battlecount = 5 + (int)(10 * random());

	} 

	//Shotgun
	if(distance < 1200)
	{
		if(B_UseShotgun(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}
	//Hand Grenade
	if(distance < 400)
	{
		if(B_UseHandGrenade(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}
	//Trap
	if(distance < 400)
	{
		if(B_UseTrap(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}
	//Blaster
	if(distance < 1200)
	{
		if(B_UseBlaster(ent,target,enewep,aim,distance,skill)) goto FIRED;
	}

	VectorSubtract(zc->vtemp,ent->s.origin,v);
	ent->s.angles[YAW] = Get_yaw(v);
	ent->s.angles[PITCH] = Get_pitch(v);
	trace_priority = TRP_ANGLEKEEP;
	return;

FIRED:
	if(zc->secwep_selected == 2) zc->secwep_selected = 1;
	
	//チキンやろう========================
	if(zc->battlemode == FIRE_CHIKEN)
	{
		if(--zc->battlesubcnt > 0  && ent->groundentity && ent->waterlevel < 2)
		{
			f =target->s.angles[YAW] - ent->s.angles[YAW];

			if(f > 180)
			{
				f = -(360 - f);
			}
			if( f < -180)
			{
				f = -(f + 360);
			}
			if(fabs(f) >= 150) 
			{
				zc->battlemode = 0;
			}
			else 
			{
				if(client->weaponstate != WEAPON_READY
					&& target->s.origin[2] < ent->s.origin[2] )
				{
					if(mywep == WEAP_ROCKETLAUNCHER 
						|| mywep == WEAP_PHALANX
						|| mywep == WEAP_GRENADELAUNCHER
						|| mywep == WEAP_RAILGUN)
						client->ps.pmove.pm_flags |= PMF_DUCKED;
					else if(Bot[zc->botindex].param[BOP_COMBATSKILL] >= 7)
					{
						if(mywep == WEAP_SHOTGUN 
							|| mywep == WEAP_SUPERSHOTGUN
							|| mywep == WEAP_BLASTER)
							client->ps.pmove.pm_flags |= PMF_DUCKED;
					}
				}
				trace_priority = TRP_ALLKEEP;
			}
			return;
		}
		else zc->battlemode = 0;
	}
	else if(zc->battlemode == 0 && distance > 200 
		&& ent->groundentity && ent->waterlevel < 2
		&& (9 * random()) > Bot[zc->botindex].param[BOP_OFFENCE])
	{
		mywep = Get_KindWeapon(client->pers.weapon);
		if(mywep > WEAP_BLASTER && target->client->zc.first_target != ent)
		{
			f =target->s.angles[YAW] - ent->s.angles[YAW];

			if(f > 180)
			{
				f = -(360 - f);
			}
			if( f < -180)
			{
				f = -(f + 360);
			}
			if(fabs(f) < 150)
			{
				zc->battlemode = FIRE_CHIKEN;
				zc->battlesubcnt = 5 + (int)(random() * 8);
				trace_priority = TRP_ALLKEEP;
			}
		}
	}
}



void UsePrimaryWeapon(edict_t *ent)
{
//	int mywep = Get_KindWeapon(ent->client->pers.weapon);

	if(CanUsewep(ent,WEAP_BFG)) return;

	CanUsewep(ent,Bot[ent->client->zc.botindex].param[BOP_PRIWEP]);
}



/*------------------------------------------------------------------------------*/

void UpdateExplIndex(edict_t* ent)
{
	int	i;
	qboolean	mod = false;

	for(i = 0;i < MAX_EXPLINDEX;i++)
	{
		if(ExplIndex[i] != NULL) {if(ExplIndex[i]->inuse == false) ExplIndex[i] = NULL;}
		if(!mod && ExplIndex[i] == NULL) {ExplIndex[i] = ent;mod = true;}
	}
}

