/*----------------------------------------------------------------
POXbot spawning routines

These started getting long so I threw them in a seperate file.
----------------------------------------------------------------*/
//
// standing
//
$frame stand1 stand2 stand3 stand4 stand5

$frame axstnd1 axstnd2 axstnd3 axstnd4 axstnd5 axstnd6
$frame axstnd7 axstnd8 axstnd9 axstnd10 axstnd11 axstnd12


//POX - New naming routine (doesn't allow duplicate names)
//Modified version of  name code from Doombot Skeleton v0.23 by Roscoe A. Sincero    
float (string st) check_bot_name =
{

// checks to see if the name is already used.

   local entity	  botname;
   botname = find(world, classname, "bot");
   while (botname != world)
   {
      if (botname.netname == st)
      {
	 // name already used
	 return TRUE;
      }
      botname = find(botname, classname, "bot");
   }

};

string() bot_name =
{
   local float r;
   local string st = "Mozilla";

      do
      {
	 r = random ();

	 if (r < 0.07)
	    st = "BadMan";
	 else if (r < 0.10)
	    st = "koRnewt";
	 else if (r < 0.13)
	    st = "FreakFace";
	 else if (r < 0.17)
	    st = "Udie!";
	 else if (r < 0.25)
	    st = "kILLer";
	 else if (r < 0.32)
	    st = "Sunshine";
	 else if (r < 0.36)
	    st = "Happy";
	 else if (r < 0.46)
	    st = "sICKO";
	 else if (r < 0.48)
	    st = "choke";
	 else if (r < 0.53)
	    st = "TrasH";
	 else if (r < 0.55)
	    st = "Johny5";
	 else if (r < 0.59)
	    st = "who?";
	 else if (r <0.62)
	    st = "BOO!";
	 else if (r < 0.68)
	    st = "Radley";
	 else if (r <0.72)
	    st = "Homer";
	 else if (r < 0.74)
	    st = "ScoRCh";
	 else if (r < 0.78)
	    st = "The Wind";
	 else if (r < 0.80)
	    st = "Reap-err";
	 else if (r < 0.82)
	    st = "LameO";
	 else if (r < 0.84)
	    st = "BOB";
	 else if (r < 0.86)
	    st = "gUMp";
	 else if (r < 0.89)
	    st = "C64";
	 else if (r < 0.92)
	    st = "Arse";
	 else if (r < 0.94)
	    st = "BIGhead";
	 else if ( r < 0.97)
	    st = "Santa";
	 else if (r < 1)
	    st = "Dung";
      
	 }
	 
   while (check_bot_name (st));

   return st;

};


// ------------------------------------------------
void() respawn_bot =
// ------------------------------------------------
{

local entity spot;

// putting him back in game

	CopyToBodyQue (self);//POX - dead bodies remain
	
	spot = SelectSpawnPoint();
	self.origin = spot.origin + '0 0 1';
	self.angles = spot.angles;
	self.fixangle = TRUE;	
	spawn_tfog (self.origin);
	spawn_tdeath (self.origin, self);
	self.solid = SOLID_SLIDEBOX;
	self.movetype = MOVETYPE_STEP;
	self.flags &= ~FL_ONGROUND;
	makevectors(self.angles);
	self.velocity = self.velocity + v_forward*20;

//POX - Reset PowerUps
	self.super_damage_finished = 0;
	self.radsuit_finished = 0;
	self.invisible_finished = 0;
	self.invincible_finished = 0;
	self.invincible_time = 0;
	
	
	//POX v1.2 - missed this - dead bots with powerups could respawn 'glowing'
	self.effects = 0;

	
// making him normal again
//	setmodel(self, self.mdl);

//Predator Mode
	if (deathmatch & DM_PREDATOR)
	{
		//self.skin = 0;
		//setmodel(self, "progs/eyes.mdl");
					
		self.invisible_time = 1;
		self.invisible_finished = time + 9999999999;

	}
	else
		self.skin = self.skinsave;
	
	setmodel(self, self.mdl);

//POX - DarkMode
	if (deathmatch & DM_DARK)
		flash_on(self);
		
//Lastman Standing (Although bots are counted out at death, they don't go away till respawn - same for players)
	if (self.frags <= 0 && (deathmatch & DM_LMS))
	{
		self.think = SUB_Remove;
		self.nextthink = time + 0.1;
		return;
	}
		
	setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
	self.deadflag = DEAD_NO;
	self.takedamage = DAMAGE_AIM;
	self.ideal_yaw = self.angles * '0 1 0';
	self.yaw_speed = 120;
	self.view_ofs = '0 0 22';
	self.frame = $stand1;
	self.button1 = 90;

// finishing his characteristics

//POX - reset ammo
	self.ammo_shells = 0;
	self.ammo_nails = 0;
	self.ammo_rockets = 0;
	self.ammo_cells = 0;
	
	self.items = IT_TSHOT;
	self.currentammo = self.ammo_shells = self.ammo_shells + 25;
	self.weapon = IT_TSHOT;
	self.health = 100;
	self.max_health = 100;
	self.classname = "bot";
	self.enemy = world;
	self.goalentity = world;
	self.search_time = 0;
	
	// POX v1.1 - spawn with 50 armour points
	self.items &= ~(IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3);
	self.items |= IT_ARMOR1;
	self.armorvalue = 50;
	self.armortype = 0.9;

	//FFA Mode
	if (deathmatch & DM_FFA)
	{
		self.invincible_finished = time + 3;
		self.invincible_time = 1;
		self.items = IT_BONESAW | IT_TSHOT | IT_COMBOGUN | IT_PLASMAGUN | IT_SUPER_NAILGUN | IT_GRENADE_LAUNCHER | IT_ROCKET_LAUNCHER | IT_INVULNERABILITY | IT_ARMOR3;
		self.health = 200;
		self.max_health = 200;
		self.armorvalue = 250;
		self.ammo_shells = 100;
		self.ammo_nails = 200;
		self.ammo_rockets = 100;
		self.ammo_cells = 200;	
		self.armortype = 0.9;
		
		sound (self, CHAN_VOICE, "items/protect.wav", 1, ATTN_NORM);
	}

// making him stand for a bit
	self.pausetime = time + 5;
	self.nextthink = time + 0.1;
	self.think = self.th_stand;
	
	self.bot_needs_item = FALSE; //POX - clear any needed items


//POX v1.11 - spawn bots AFTER all players are in
/*
	msgUpdateNameToAll (self.fClientNo, self.netname);
	msgUpdateColorsToAll (self.fClientNo, self.fShirt, self.fPants);
	msgUpdateFragsToAll (self.fClientNo, self.frags);
*/
};



// ------------------------------------------------
void(float teem) create_bot =
// ------------------------------------------------
{
local entity bot, spot;
local float r, cno, sn, pn;

//POX - NoBots option
if (deathmatch & DM_NOBOTS)
	{
		bprint ("No bots allowed in this game.\n");
		return;
	}


//POX - added for bot ranking support
if (botcounter == 8)
   {
      // already reached maximum number of bots.
      bprint ("Maximum number of bots has been\n");
      bprint ("reached. Only 8 bots are allowed.\n");
      return;
   }

   cno = clientNextAvailable ();

	if (cno == -1)
	{
	bprint ("Server is full.  Unable to spawn bot.\n");
	return;
	}

// initializing the entity
	bot = spawn();

//POX - added for bot ranking support
	botcounter = botcounter + 1;
	
	spot = SelectSpawnPoint();
	bot.origin = spot.origin + '0 0 1';
	bot.angles = spot.angles;
	bot.fixangle = TRUE;	
	spawn_tfog (bot.origin);
	spawn_tdeath (bot.origin, bot);
	bot.solid = SOLID_SLIDEBOX;
	bot.movetype = MOVETYPE_STEP;

// defining his animation
//POX - added a couple new skins for bots

	bot.mdl = "progs/player.mdl";
	
//POX1.01b - FIX for friendly team bot skin (use base skin)
	if (teamplay && teem == 2)
		bot.skin = 0;
	else
	{
		if (random() < 0.5)
			bot.skin = 1;
		else
			bot.skin = 2;
	}
		
	bot.skinsave = bot.skin;

	bot.frame = $stand1;
	bot.th_stand = bot_stand1;
	bot.th_walk = bot_walk1;
	bot.th_run = bot_run1;
	bot.th_pain = bot_pain;
	bot.th_die = bot_die;
	bot.th_missile = bot_attack;

// arming and naming him
	bot.items |= IT_TSHOT;
	bot.currentammo = bot.ammo_shells = bot.ammo_shells + 25;
	bot.weapon = IT_TSHOT;
	bot.health = 100;
	bot.max_health = 100;
	bot.classname = "bot";

//POX - Added for Powerup Support
	bot.super_damage_finished = 0;
	bot.radsuit_finished = 0;
	bot.invisible_finished = 0;
	bot.invincible_finished = 0;
	bot.effects = 0;
	bot.invincible_time = 0;

// POX v1.1 - spawn with 50 armour points
	self.items &= ~(IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3);
	self.items |= IT_ARMOR1;
	self.armorvalue = 50;
	self.armortype = 0.9;
	
//POX - Added for Ranking Support
   clientSetUsed (cno);

	bot.fClientNo = cno;
	bot.colormap = cno + 1;

	if (!teamplay)
	{	
		bot.fShirt = floor (random() * 13);
		bot.fPants = floor (random() * 13);
	}

/*	
POX - I've changed tutor bot team rules to support multiple clients (in theory).
Only one all bot team is allowed, but you can mix bots and clients on other teams.
This is kind of a hack since every client can create a team bot and/or an all bot team bot.
I should implement a user config that limits the number of team members,
currently only the server limit will do this, and real clients will always boot a bot when
they join if there isn't any space.
*/
sn = -1;
pn = -1;
	//POX - Create a Friendly Team Bot
	if (teamplay && teem == 2)
	{
		bot.team = self.team;
		
	//POX - This is a hack to get the proper colours to show in the rankings (colormap didn't work(?))
	//POX - It tests every combination of colours (plus a few more for good luck) until the right one is found
			while (sn < 15)
			{
				while (pn < 15)
				{
					//POX - FIX ME - cvars always refer to the server (maybe force teams to wear solid colours)
					if (cvar("_cl_color") == (sn*16) + pn)
					{
						
						//bot.colormap = self.colormap;						
						bot.fShirt = sn;
						bot.fPants = pn;
						
						sn = 15;
						pn = 15;
					}
		
					pn = pn + 1;
				}
	
			sn = sn + 1;
			pn = 0;
			}			
		}
		
	//POX - Create an all Bot Team Bot (bad guys)
	if (teamplay && teem == 1)
		{
			bot.team = 16; //POX - I figured team 17 would never exist so I used it for the all bot team	
			//POX - all bot team is always white on white
			bot.fShirt = 0;
			bot.fPants = 0;
		}

	
	//Predator Mode
	if (deathmatch & DM_PREDATOR)
	{
		//setmodel(bot, "progs/eyes.mdl");
		//bot.skin = 0;
		
		bot.invisible_time = 1;
		bot.invisible_finished = time + 9999999999;
		
	}
	
	setmodel(bot, bot.mdl);
	
	//Dark Mode
	if (deathmatch & DM_DARK)
		flash_on(bot);

		
	//Last Man Standing
	if (deathmatch & DM_LMS)
	{
		lms_plrcount = lms_plrcount + 1;
		
		if (fraglimit_LMS == 0)
			bot.frags = 5;
		else
			bot.frags = fraglimit_LMS;
	}

	//FFA Mode
	if (deathmatch & DM_FFA)
	{
		bot.invincible_finished = time + 5;
		bot.invincible_time = 1;
		bot.items = IT_BONESAW | IT_TSHOT | IT_COMBOGUN | IT_PLASMAGUN | IT_SUPER_NAILGUN | IT_GRENADE_LAUNCHER | IT_ROCKET_LAUNCHER | IT_INVULNERABILITY | IT_ARMOR3;
		bot.health = 200;
		bot.max_health = 200;
		bot.armorvalue = 250;
		bot.ammo_shells = 100;
		bot.ammo_nails = 200;
		bot.ammo_rockets = 100;
		bot.ammo_cells = 200;	
		bot.armortype = 0.9;
		
		sound (bot, CHAN_VOICE, "items/protect.wav", 1, ATTN_NORM);
	}
	
	bot.netname = bot_name();			

//POX - Added for Ranking Support
   msgUpdateNameToAll( bot.fClientNo, bot.netname );
   msgUpdateColorsToAll( bot.fClientNo, bot.fShirt, bot.fPants );
   msgUpdateFragsToAll( bot.fClientNo, bot.frags );
	
	bprint(bot.netname);
	bprint(" entered the game\n");

// polishing him up
	setsize (bot, VEC_HULL_MIN, VEC_HULL_MAX);	
	bot.ideal_yaw = bot.angles * '0 1 0';
	bot.yaw_speed = 120;
	bot.view_ofs = '0 0 22';
	bot.takedamage = DAMAGE_AIM;
	bot.attack_state = 0;
	bot.button1 = 90;
	bot.nextthink = time + 0.1 + random();
	bot.think = bot.th_walk;

/*POX v1.11 - Cloak is back to eyes (bot powerup check is less accurate now, but good enough)
//POX - This part is a hack - it allows the Player who spawned the bot to check it's powerups
//POX - This was necessary for the new cloak effect to work with bots
//POX - The down side is, when a player disconnects, his bots must go with him

	self.total_spawned_bots = self.total_spawned_bots + 1;
	
	if (self.total_spawned_bots == 1)
		self.bot_a = bot;
	if (self.total_spawned_bots == 2)
		self.bot_b = bot;
	if (self.total_spawned_bots == 3)
		self.bot_c = bot;
	if (self.total_spawned_bots == 4)
		self.bot_d = bot;
	if (self.total_spawned_bots == 5)
		self.bot_e = bot;
	if (self.total_spawned_bots == 6)
		self.bot_f = bot;
	if (self.total_spawned_bots == 7)
		self.bot_g = bot;
	if (self.total_spawned_bots == 8)
		self.bot_h = bot;
*/

//POX - Define BotPrefs - semi-random based on skill level setting
//Skill 1 (default) will spawn randomized bots (but no extremely bad or good ones)

//POX - speed
	if (skill == 0)
		bot.botpref_speed	= 0.1;
	
	if (skill == 1)
	{
		r = random() - 0.5;
		if (r < 0.06)
			r = 0.06;
		if (r > 0.09)
			r = 0.09;
			
		bot.botpref_speed = r;
	}
	
	if (skill == 2)
		bot.botpref_speed	= 0.07;
	
	if (skill > 2)
		bot.botpref_speed	= 0.05;

//POX - health awarness
	r = floor(random() * 30 + (10*skill) + 20);
	
	if (r < 60)
		r = 60;
	
	bot.botpref_health = r;

//POX - aim
	if (skill == 0)
		bot.botpref_aim = 0.25;
	
	if (skill == 1)
	{
		r = random();
		if (r < 0.05)
			r = 0.05;
		if (r > 0.2)
			r = 0.2;
			
		bot.botpref_aim = r;
	}
	
	if (skill == 2)
		bot.botpref_aim = 0.1;
	
	if (skill > 2)
		bot.botpref_aim = 0;

//POX - Client Awareness
	if (skill == 0)
		bot.botpref_aware = FALSE;
	else if (skill == 1 || skill == 2)
	{
		r = random();
		if (r < skill*0.4)
			bot.botpref_aware = TRUE;
		else
			bot.botpref_aware = FALSE;
	}
	else
		bot.botpref_aware = TRUE;
		
//POX - Attack Styles
		r = floor(random() * 3);
		
		if (r == 1 && random() > 0.5)
			bot.botpref_attack = AS_RUSH;
		else if (r == 2)
			bot.botpref_attack = AS_RETREAT;
		else
			bot.botpref_attack = AS_SMART;
		
		if (skill == 2 && random() >0.2)
			bot.botpref_attack = AS_SMART;
		
		if (skill > 2)
			bot.botpref_attack = AS_SMART;

//POX - Best Weapon Pref
		r = random();
		
		if (r > 0.5)
			bot.botpref_weapon = IT_PLASMAGUN;
		else
			bot.botpref_weapon = IT_ROCKET_LAUNCHER;


//POX - Reaction Time	
		if (skill == 0)
			bot.botpref_react = 0.1;
		
		if (skill == 1 || skill == 2)
		{
			r = random ();
			if (r > 0.1)
				r = 0.1;
			else if (r < 0.09)
				r = 0.09;
			
			bot.botpref_react = r;
		}
		
		if (skill > 2)
			bot.botpref_react = 0.01;

	
};
