/*
==============================================================================

BOT

==============================================================================
*/

// Prototypes

void	()		Bot_Precache;
void	()		BotActivate;
void	()		BotDeActivate;
void	()		BotToggle;
void	()		BotAutoToggle;
void	()		BotMoveToggle;
void	()		BotTurnRight;
void	()		BotTurnLeft;
void	()		BotFireToggle;
void	()		BotFire;
void	()		BotTeleportHome;

void (vector org, vector vec) LaunchLaser;
void (vector org) spawn_tfog;


//=============================================================
// Bot_Precache - called by Worldspawn
//=============================================================
void () Bot_Precache =
{
	precache_model2 ("progs/enforcer.mdl");
	precache_model2 ("progs/h_mega.mdl");
	precache_model2 ("progs/laser.mdl");

	precache_sound2 ("enforcer/death1.wav");
	precache_sound2 ("enforcer/enfire.wav");
	precache_sound2 ("enforcer/enfstop.wav");
	precache_sound2 ("enforcer/idle1.wav");
	precache_sound2 ("enforcer/pain1.wav");
	precache_sound2 ("enforcer/pain2.wav");
	precache_sound2 ("enforcer/sight1.wav");
	precache_sound2 ("enforcer/sight2.wav");
	precache_sound2 ("enforcer/sight3.wav");
	precache_sound2 ("enforcer/sight4.wav");
};


//=============================================================
// BotActivate - Activates the bot
//=============================================================
void () BotActivate =
{
// sounds and models precached in the world.qc file

	local entity	newbot;

	newbot = spawn();
	newbot.solid = SOLID_SLIDEBOX;
	newbot.movetype = MOVETYPE_STEP;

	newbot.angles = self.angles;
	newbot.classname = "bot";
	newbot.owner=self;
	self.bot=newbot;
	self.bot_flag = TRUE;
	self.bot_auto = TRUE;
	self.bot.auto_fire = TRUE;
	newbot.health = 100;
	newbot.takedamage = DAMAGE_AIM;
        newbot.goalentity = self;
	newbot.movetarget = self;
	newbot.pausetime = time + 2;
	newbot.ideal_yaw = newbot.angles * '0 1 0';
	newbot.yaw_speed = 30;
	newbot.view_ofs = '0 0 25';

// Set to automatic mode sequences at startup
	newbot.th_stand = bot_stand1;
	newbot.th_walk = bot_walk1;
	newbot.th_run = bot_run1;
	newbot.th_pain = bot_pain;
	newbot.th_die = bot_die;
	newbot.th_missile = bot_atk1;
        newbot.team = self.team;        // DM BOT
	setmodel (newbot, "progs/enforcer.mdl");
	setsize (newbot, '-16 -16 -24', '16 16 40');
	setorigin(newbot, self.origin);

	spawn_tfog (newbot.origin);

	centerprint(self, "bot activated\n");
	
	newbot.nextthink = time + 0.1;
	newbot.think = newbot.th_stand;
};


//=============================================================
// BotDeActivate - Deactivates the bot
//=============================================================
void () BotDeActivate =
{
	spawn_tfog (self.bot.origin);
	self.bot.nextthink = time + 0.1;
	self.bot.think = SUB_Remove;
	self.bot_flag = FALSE;
	centerprint(self, "bot deactivated\n");
};


//=============================================================
// BotToggle - Toggle bot on and off
//=============================================================
void () BotToggle =
{
	if (!(self.bot_flag))
		BotActivate();
	else
		BotDeActivate();
};


//=============================================================
// BotAutoToggle - Toggle the bot between automatic and manual
//=============================================================
void () BotAutoToggle =
{
	if (!(self.bot_flag))
	{
		sprint (self, "sorry, bot is not activated\n");
		return;
	}

	if (self.bot_auto)
	{
		self.bot_auto = FALSE;

	// Set to manual mode sequences
		self.bot.th_stand = man_bot_stand1;
		self.bot.th_walk = man_bot_walk1;
		self.bot.th_run = man_bot_run1;
		self.bot.th_pain = bot_pain;		// These don't need to be
                self.bot.th_die = bot_die;              // set to a special manual
		self.bot.th_missile = bot_atk1;		// version.

		self.bot.nextthink = time + 0.1;
		self.bot.think = self.bot.th_stand;
		self.bot.move_flag = STAND;
	}
	else
	{
		self.bot_auto = TRUE;

		// Set to automatic mode sequences
		self.bot.th_stand = bot_stand1;
		self.bot.th_walk = bot_walk1;
		self.bot.th_run = bot_run1;
		self.bot.th_pain = bot_pain;
		self.bot.th_die = bot_die;
		self.bot.th_missile = bot_atk1;

		self.bot.movetarget = self.owner;
		self.bot.nextthink = time + 0.1;
		self.bot.think = self.bot.th_stand;
	}
};



//=============================================================
// BotMoveToggle - Toggle moving (walk, run, stand) in man mode
//=============================================================
void () BotMoveToggle =
{
// The bot.move_flag is set in the first frame of the
// stand, walk, and run manual frame sequences

	if (!(self.bot_flag))
	{
		sprint (self, "sorry, bot is not activated\n");
		return;
	}

	if (self.bot_auto)
	{
		sprint (self, "sorry, bot in automatic mode\n");
		return;
	}
	else
	{
		if (self.bot.move_flag == STAND)
		{
			self.bot.move_flag = WALK;
			self.bot.nextthink = time + 0.1;
			self.bot.think = self.bot.th_walk;
			return;
		}
		if (self.bot.move_flag == WALK)
		{
			self.bot.move_flag = RUN;
			self.bot.nextthink = time + 0.1;
			self.bot.think = self.bot.th_run;
			return;
		}
		else
		{
			self.bot.move_flag = STAND;
			self.bot.nextthink = time + 0.1;
			self.bot.think = self.bot.th_stand;
			return;
		}
	}
};

//=============================================================
// BotTurnRight - Turn bot 22.5 degrees to right in man mode
//=============================================================
void () BotTurnRight =
{
	if (!(self.bot_flag))
	{
		sprint (self, "sorry, bot is not activated\n");
		return;
	}

	if (self.bot_auto)
	{
		sprint (self, "sorry, bot is in automatic mode\n");
		return;
	}

	self.bot.ideal_yaw = self.bot.ideal_yaw - 22.5;
	return;
};


//=============================================================
// BotTurnLeft - Turn bot 22.5 degrees to left in man mode
//=============================================================
void () BotTurnLeft =
{
	if (!(self.bot_flag))
	{
		sprint (self, "sorry, bot is not activated\n");
		return;
	}

	if (self.bot_auto)
	{
		sprint (self, "sorry, bot is in automatic mode\n");
		return;
	}

	self.bot.ideal_yaw = self.bot.ideal_yaw + 22.5;
};


//=============================================================
// BotFireToggle - Toggle auto-fire in automatic mode
//=============================================================
void () BotFireToggle =
{
	if (!(self.bot_flag))
	{
		sprint (self, "sorry, bot is not activated\n");
		return;
	}

	if (!(self.bot_auto))
	{
		sprint (self, "sorry, bot is in manual mode\n");
		return;
	}
    
	if (self.bot.auto_fire == TRUE)
		self.bot.auto_fire = FALSE;
	else
		self.bot.auto_fire = TRUE;

	return;
};


//=============================================================
// BotFire - Have bot fire at its current target
//=============================================================
void () BotFire =
{
	local entity oldself;
	local vector org;

	if (!(self.bot_flag))
	{
		sprint (self, "sorry, bot is not activated\n");
		return;
	}
	
	oldself = self;
	self = self.bot;

	if (self.owner.bot_auto && self.enemy != world && self.enemy.health > 1
		&& !(self.enemy.items & IT_INVISIBILITY) && visible(self.enemy))
	{
		sound (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
		enforcer_fire();
	}
	else
	{
		sound (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
		self.effects = self.effects | EF_MUZZLEFLASH;
		makevectors (self.angles);
		org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
		LaunchLaser(org, v_forward);
	}

	self = oldself;
	return;
};


//=============================================================
// BotTeleportHome - Teleports bot back to its owner
//=============================================================
void () BotTeleportHome =
{
	if (!(self.bot_flag))
	{
		sprint (self, "sorry, bot is not activated\n");
		return;
	}
	
	spawn_tfog (self.bot.origin);
	self.bot.ideal_yaw = self.angles * '0 1 0';
	self.bot.pausetime = time + 2;
	self.bot.nextthink = time + 0.1;
	self.bot.think = self.bot.th_stand;
	setorigin(self.bot, self.origin);
	spawn_tfog (self.bot.origin);
	self.bot.nextthink = time + 0.1;
	self.bot.think = self.bot.th_stand;
	return;
};
