/*
+------+
|Player|
+------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Scratch                                      Http://www.admdev.com/scratch |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Player animation, functions, and related things dealing with the           |
| upperhalf of Corporal and his weapons.			                       |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
*/

$frame death1 death2 death3 death4 death5 death6
$frame grabwep1 grabwep2 grabwep3 grabwep4 grabwep5 grabwep6 grabwep7
$frame ohstand1
$frame thstand1
$frame bgstand1
$frame ohrun1 ohrun2 ohrun3 ohrun4 ohrun5 ohrun6
$frame thrun1 thrun2 thrun3 thrun4 thrun5 thrun6
$frame bgrun1 bgrun2 bgrun3 bgrun4 bgrun5 bgrun6
$frame stab1 stab2 stab3 stab4
$frame slash1 slash2 slash3 slash4 
$frame ohfire1 ohfire2 ohfire3 ohfire4 ohfire5
$frame ohfires1 ohfires2 ohfires3 ohfires4 ohfires5
$frame thfire1 thfire2
$frame bgfire1 bgfire2 bgfire3 bgfire4 bgfire5 bgfire6 bgfire7 bgfire8 bgfire9 bgfire10 bgfire11 bgfire12 bgfire13 bgfire14 bgfire15 bgfire16 bgfire17 bgfire18 bgfire19
$frame throw1 throw2 throw3 throw4 throw5  //74-78

float() crandom;
void(float u, float r, float f) GunFlare;
void(float u, float r, float f) MuzzleFlash;
void() player_stand;
void() player_run;
void() W_Pistol; 
void() W_Pistol2;
void() W_Shotgun;
void() W_MachineGun;
void() ThrowCasing;
void() player_death1;
void() W_FireKnife;

void()  player_stand =[        $ohstand1,       player_stand		]
{
	if (self.velocity_x || self.velocity_y)
	{
		self.walkframe=0;
		player_run();
		return;
	}
	if (self.walkframe != 0)
		self.walkframe = 0;

	if (self.weapon == W_KNIFE || self.weapon == W_PISTOL)
		self.frame = $ohstand1;
	if (self.weapon == W_DOUBLEPISTOL)
		self.frame = $thstand1;
	if (self.weapon == W_SHOTGUN || self.weapon == W_SUBMACHINE)
		self.frame = $bgstand1;
};

void()  player_run =[   $thrun1,      player_run      ]
{
	if (!self.velocity_x && !self.velocity_y)
	{
		self.walkframe=0;
		player_stand();
		return;
	}
	if (self.weapon == W_KNIFE || self.weapon == W_PISTOL)
	{
		if (self.walkframe >= 6)
			self.walkframe = 0;
		self.frame = $ohrun1 + self.walkframe;
	}
	if (self.weapon == W_DOUBLEPISTOL)
	{
		if (self.walkframe >= 6)
			self.walkframe = 0;
		self.frame = self.frame + self.walkframe;
	}
	if (self.weapon == W_SHOTGUN || self.weapon == W_SUBMACHINE)
	{
		if (self.walkframe >= 6)
			self.walkframe = 0;
		self.frame = $bgrun1 + self.walkframe;
	}
	if (!self.flags & FL_ONGROUND)
		return;
	self.walkframe = self.walkframe + 1;
};

void() player_grabwep1	=[	$grabwep1,	player_grabwep2	] {self.attack_finished = time + 0.7;};
void() player_grabwep2	=[	$grabwep2,	player_grabwep3	] {};
void() player_grabwep3	=[	$grabwep3,	player_grabwep4	] {};
void() player_grabwep4	=[	$grabwep4,	player_grabwep5	] {sound (self, CHAN_BODY, "weapons/change.wav", 1, ATTN_NORM);};
void() player_grabwep5	=[	$grabwep5,	player_grabwep6	] {};
void() player_grabwep6	=[	$grabwep6,	player_grabwep7	] {};
void() player_grabwep7	=[	$grabwep7,	player_stand	] {};

void() player_stab1	=[	$stab1,	player_stab2	] {sound (self, CHAN_WEAPON, "weapons/knife1.wav", 1, ATTN_NORM);};
void() player_stab2	=[	$stab2,	player_stab3	] {};
void() player_stab3	=[	$stab3,	player_stab4	] {W_FireKnife();};
void() player_stab4	=[	$stab4,	player_stand	] {};

void() player_slash1	=[	$slash1,	player_slash2	] {sound (self, CHAN_WEAPON, "weapons/knife2.wav", 1, ATTN_NORM);};
void() player_slash2	=[	$slash2,	player_slash3	] {W_FireKnife();};
void() player_slash3	=[	$slash3,	player_slash4	] {W_FireKnife();};
void() player_slash4	=[	$slash4,	player_stand	] {};

void() player_pistol1	=[	$ohfire1,	player_pistol2	] 
{
	if (random() < 0.30)
		sound (self, CHAN_WEAPON, "weapons/pistol.wav", 1, ATTN_NORM);
	else if (random() < 0.60)
		sound (self, CHAN_WEAPON, "weapons/pistol2.wav", 1, ATTN_NORM);
	else
		sound (self, CHAN_WEAPON, "weapons/pistol3.wav", 1, ATTN_NORM);	
	MuzzleFlash(16, 8, 18);self.effects = EF_MUZZLEFLASH;ThrowCasing();
};
void() player_pistol2	=[	$ohfire2,	player_pistol3	] {};
void() player_pistol3	=[	$ohfire3,	player_pistol4	] {};
void() player_pistol4	=[	$ohfire4,	player_pistol5	] {};
void() player_pistol5	=[	$ohfire5,	player_stand	] {};

void() player_pistols1	=[	$ohfires1,	player_pistols2	] {sound (self, CHAN_WEAPON, "weapons/pistol.wav", 1, ATTN_NORM);MuzzleFlash(16, 8, 18);self.effects = EF_MUZZLEFLASH;ThrowCasing();};
void() player_pistols2	=[	$ohfires2,	player_pistols3	] {};
void() player_pistols3	=[	$ohfires3,	player_pistols4	] {};
void() player_pistols4	=[	$ohfires4,	player_pistols5	] {};
void() player_pistols5	=[	$ohfires5,	player_stand	] {};


void() player_doublepistol1	=[	$thfire1,	player_doublepistol2	] 
{
	ThrowCasing();
	MuzzleFlash(12, 8, 24);
	W_Pistol();
	sound (self, CHAN_WEAPON, "weapons/pistol.wav", 1, ATTN_NORM);
	self.effects = EF_MUZZLEFLASH;
	self.currentammo = self.ammo_nails = self.ammo_nails - 1;
	if (self.currentammo < 1) player_stand();
};
void() player_doublepistol2	=[	$thfire1,	player_stand	] {};
void() player_doublepistol3	=[	$thfire2,	player_doublepistol4	] 
{
	ThrowCasing();
	MuzzleFlash(12, -8, 24);
	W_Pistol2();
	sound (self, CHAN_WEAPON, "weapons/pistol.wav", 1, ATTN_NORM);
	self.effects = EF_MUZZLEFLASH;
	self.currentammo = self.ammo_nails = self.ammo_nails - 1;
};
void() player_doublepistol4	=[	$thfire2,	player_stand	] {};

void() player_shotgun1	=[	$bgfire1,	player_shotgun2	] 
{
	if (random() < 0.30)
		sound (self, CHAN_WEAPON, "weapons/shotgnb1.wav", 1, ATTN_NORM);
	else if (random() < 0.60)
		sound (self, CHAN_WEAPON, "weapons/shotgnb2.wav", 1, ATTN_NORM);
	else
		sound (self, CHAN_WEAPON, "weapons/shotgnb3.wav", 1, ATTN_NORM);
	ThrowCasing();
	W_Shotgun();W_Shotgun();W_Shotgun();W_Shotgun();W_Shotgun();W_Shotgun();W_Shotgun();GunFlare(16, 0, 40);self.effects = EF_MUZZLEFLASH;
};
void() player_shotgun2	=[	$bgfire2,	player_shotgun3	] {};
void() player_shotgun3	=[	$bgfire3,	player_shotgun4	] {self.nextthink = time + 0.05;};
void() player_shotgun4	=[	$bgfire4,	player_shotgun5	] {self.nextthink = time + 0.05;};
void() player_shotgun5	=[	$bgfire5,	player_shotgun6	] {self.nextthink = time + 0.05;};
void() player_shotgun6	=[	$bgfire6,	player_shotgun7	] {self.nextthink = time + 0.05;sound (self, CHAN_WEAPON, "weapons/shotgun2.wav", 1, ATTN_NORM);};
void() player_shotgun7	=[	$bgfire7,	player_shotgun8	] {self.nextthink = time + 0.05;};
void() player_shotgun8	=[	$bgfire8,	player_shotgun9	] {self.nextthink = time + 0.05;};
void() player_shotgun9	=[	$bgfire9,	player_shotgun10	] {self.nextthink = time + 0.05;};
void() player_shotgun10	=[	$bgfire10,	player_shotgun11	] {self.nextthink = time + 0.05;};
void() player_shotgun11	=[	$bgfire11,	player_shotgun12	] {self.nextthink = time + 0.05;};
void() player_shotgun12	=[	$bgfire12,	player_shotgun13	] {self.nextthink = time + 0.05;};
void() player_shotgun13	=[	$bgfire13,	player_shotgun14	] {self.nextthink = time + 0.05;sound (self, CHAN_WEAPON, "weapons/shotgun3.wav", 1, ATTN_NORM);};
void() player_shotgun14	=[	$bgfire14,	player_shotgun15	] {self.nextthink = time + 0.05;};
void() player_shotgun15	=[	$bgfire15,	player_shotgun16	] {self.nextthink = time + 0.05;};
void() player_shotgun16	=[	$bgfire16,	player_shotgun17	] {self.nextthink = time + 0.05;};
void() player_shotgun17	=[	$bgfire17,	player_shotgun18	] {self.nextthink = time + 0.05;};
void() player_shotgun18	=[	$bgfire18,	player_shotgun19	] {self.nextthink = time + 0.05;};
void() player_shotgun19	=[	$bgfire19,	player_stand	] {self.nextthink = time + 0.05;};

void() player_machinegun1	=[	$bgfire1,	player_machinegun2	] {self.nextthink = time + 0.05;W_MachineGun();self.effects = EF_MUZZLEFLASH;
	// different pitches
	if (random() < 0.25)
		sound (self, CHAN_WEAPON, "weapons/submach.wav", 1, ATTN_NORM);
	else if (random() < 0.50)
		sound (self, CHAN_WEAPON, "weapons/submach2.wav", 1, ATTN_NORM);
	else if (random() < 0.75)
		sound (self, CHAN_WEAPON, "weapons/submach3.wav", 1, ATTN_NORM);
	else
		sound (self, CHAN_WEAPON, "weapons/submach4.wav", 1, ATTN_NORM);
	ThrowCasing();
};
void() player_machinegun2	=[	$bgfire4,	player_stand	] {self.nextthink = time + 0.05;MuzzleFlash(16, 0, 24);};

void() DropWeapon_Think =
{
	if (self.attack_finished < time)
		remove(self);

	if (self.flags & FL_ONGROUND && self.cnt == 0)
	{
		self.cnt = 1;
		self.avelocity = '0 0 0';
		self.angles_x = self.angles_z = 0;
		self.origin_z = self.origin_z + 10; // prevent sinking
	}
	self.nextthink = time + 0.1;
};

void() DropWeapon =
{
	local	entity new;

	new = spawn();

	makevectors(self.angles);
	new.origin = self.origin + v_up*16;
	if (self.weapon == W_KNIFE)
		setmodel (new, "progs/dr_knife.mdl");
	else if (self.weapon == W_PISTOL || self.weapon == W_DOUBLEPISTOL)
		setmodel (new, "progs/dr_pist.mdl");
	else if (self.weapon == W_SHOTGUN)
		setmodel (new, "progs/dr_shotg.mdl");
	else if (self.weapon == W_SUBMACHINE)
		setmodel (new, "progs/dr_subm.mdl");

	setsize (new, '0 0 0', '0 0 0');

	new.angles_y = random() * 360;
	makevectors (new.angles);
	new.velocity = v_forward * 120;
	new.velocity_z = random()*100;

	new.movetype = MOVETYPE_TOSS;
	new.solid = SOLID_NOT;
	new.avelocity_x = random()*600;
	new.avelocity_y = random()*600;
	new.avelocity_z = random()*600;
	new.attack_finished = time + 6 + random()*10; // time till removal
	new.think = DropWeapon_Think;
	new.nextthink = time + 0.1;
};

// dropwep
// FALSE = Keeps his weapon held after death
// TRUE = Drops weapon

// dethtype
// NOTE: dethtype 1 and over auto-switches to corpdeth.mdl, it's not VWEP compatible and never will be
// which is why DropWeapon was created.
// 0 = regular death (vwep compatible)
// 1 = grabs neck while falling
// 2 = Spins arounds and falls
// 3 = Blown backwards, can stick on wall
// 4 = Drops to knees then falls on side
// 5 = Air Ragdoll
// 6 = Died in air, similar to air ragdoll
// 7 = Shrink and turn to particle

void() PainSkinCheck = // called from different functions
{
	if (self.skin == 5) // Ranger has no pain skins
		return;

	if (self.dethtype > 0)
	{
		self.skin = 4; // skin 4 is death skin
		return;
	}

	// Pain Skins
	if (self.health >= 80)
		self.skin = 0;
	else if (self.health >= 60 && self.health < 80)
		self.skin = 1;
	else if (self.health >= 30 && self.health < 60)
		self.skin = 2;
	else
		self.skin = 3;
};

void() PlayerDie =
{
	self.effects = 0;
	self.view_ofs = '0 0 -8';
	self.deadflag = DEAD_DYING;
	self.movetype = MOVETYPE_TOSS;
	self.angles_x = self.angles_z = 0;

	if (random() > 0.5 && self.dethtype != 5)
		sound (self, CHAN_VOICE, "player/death.wav", 1, ATTN_NORM);
	else
		sound (self, CHAN_VOICE, "player/death2.wav", 1, ATTN_NORM);


	if (self.opponent.weapon == W_KNIFE)
		self.dethtype = 0;
	else if (self.opponent.weapon == W_PISTOL)
		self.dethtype = 1;
	else if (self.opponent.weapon == W_DOUBLEPISTOL)
		self.dethtype = 2;
	else if (self.opponent.weapon == W_SHOTGUN)
		self.dethtype = 3;
	else if (self.opponent.weapon == W_SUBMACHINE)
		self.dethtype = 4;
	if (self.exploded == TRUE) // grenade
		self.dethtype = 5;
	if (!self.flags & FL_ONGROUND && self.dethtype != 7) // in air death and not telefragged..
		self.dethtype = 6;
	// dethtype 7 is called from triggers because it's a telefrag
	if (self.dethtype != 4) // uzi death
		self.solid = SOLID_NOT;

	if (self.dethtype > 0)
	{
		setmodel (self, "progs/corpdeth.mdl");
		if (self.skin == 5) // ranger
			self.skin = 1; // death skin set
		else
			self.skin = 0;
		setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
	}

	if (self.dethtype == 5)
	{
		if (random() > 0.5)
			sound (self, CHAN_VOICE, "player/scream.wav", 1, ATTN_NORM);
		else
			sound (self, CHAN_VOICE, "player/scream2.wav", 1, ATTN_NORM);

		self.dropwep = TRUE;
		DropWeapon();
		self.flags = self.flags - (self.flags & FL_ONGROUND);
		self.velocity_z = self.velocity_z + 165 * random() + 235;
		player_airdeth1();
		return;
	}

	if (self.dethtype == 7) // goes before 6 since teledeath can happen in air
	{
		player_teledeth1();
		self.dropwep = TRUE;
		DropWeapon();
		return;
	}

	if (self.dethtype == 6)
	{
		player_airdeth1();
		self.dropwep = TRUE;
		DropWeapon();
		return;
	}

	if (self.opponent.weapon == W_KNIFE)
	{
		self.dropwep = FALSE;
		player_death1 ();
	}
	else if (self.opponent.weapon == W_PISTOL)
	{
		self.dropwep = TRUE;
		DropWeapon();
		player_deatha1 (); //corpdeth.qc
	}
	else if (self.opponent.weapon == W_DOUBLEPISTOL)
	{
		self.dropwep = TRUE;
		DropWeapon();
		if (self.weapon == W_DOUBLEPISTOL)
			DropWeapon();
		player_deathb1 (); //corpdeth.qc
	}
	else if (self.opponent.weapon == W_SHOTGUN)
	{
		local vector view;

		makevectors (self.angles);
		view = vectoangles(self.opponent.origin - self.origin);
		self.angles_y = view_y;
		self.fixangle = TRUE;
		self.dropwep = TRUE;
		DropWeapon();
		self.velocity = self.velocity - v_forward * 200;
		self.flags = self.flags - (self.flags & FL_ONGROUND);
		self.velocity_z = random()*110 + 200;
		player_deathc1 (); // corpdeth.qc
	}
	else if (self.opponent.weapon == W_SUBMACHINE)
	{
		self.dropwep = TRUE;
		DropWeapon();
		player_deathd1();
	}
};

void() set_disconnect_frame =
{	// used by disconnect command
	droptofloor(0,0);
	self.frame = $death6;
	self.movetype = MOVETYPE_TOSS;
	self.deadflag = DEAD_DEAD;
};

void() blood;

void() PlayerDead =
{
	if (self.dethtype != 7) // not a telefrag
		blood();
	// allow respawn after a certain time
	self.respawn_finished = time + 5;
	sprint (self, "Òåóðá÷î éî  óåãïîäó ®®®\n");
	self.deadflag = DEAD_DEAD;
	self.think = DeadThink; //corpdeth.qc
	self.nextthink = time + 0.1;
};

void() PlayerPain =
{
	local	float v, r;
	local	string tmpstr;

	// Shield
	if (self.armorvalue > 0)
	{
		sound (self, CHAN_BODY, "player/shldsmk.wav", 1, ATTN_NORM);
		self.effects = self.effects | EF_BRIGHTFIELD | EF_DIMLIGHT;
		self.shield_finished = time + 0.1;
		self.shield = TRUE;
		return; // No pain sounds/skins with shield
	}
	PainSkinCheck();

	r = random();
	if (r > 0.3) return;

	v = random() * 4;
	if (v < 1)
		tmpstr = "player/pain1.wav";
	else if (v < 2)
		tmpstr = "player/pain2.wav";
	else if (v < 3)
		tmpstr = "player/pain3.wav";
	else
		tmpstr = "player/pain4.wav";

	sound (self, CHAN_VOICE, tmpstr, 1, ATTN_NORM);
};

void() player_death1	=[	$death1,	player_death2	] {};
void() player_death2	=[	$death2,	player_death3	] {};
void() player_death3	=[	$death3,	player_death4	] {};
void() player_death4	=[	$death4,	player_death5	] {};
void() player_death5	=[	$death5,	player_death6	] 
{
	if (self.flags & FL_ONGROUND)
		sound (self, CHAN_BODY, "misc/floorhit.wav", 1, ATTN_NORM);	
};
void() player_death6	=[	$death6,	player_death6	] 
{
	PlayerDead();
};

void() W_Grenade;
void() player_grenade1	=[	$throw1,	player_grenade2	] {};
void() player_grenade2	=[	$throw2,	player_grenade3	] {};
void() player_grenade3	=[	$throw3,	player_grenade4	] {W_Grenade();};
void() player_grenade4	=[	$throw4,	player_grenade5	] {};
void() player_grenade5	=[	$throw5,	player_stand	] {};

//
// laser targetter / ingame crosshair
//

void() target_update =
{
	if (!self.owner.netname)
		remove(self);
	if (intermission_running)
	{
		setmodel(self, string_null);
		self.frame = 0;
		self.think = SUB_Null;
		self.nextthink = -1;
	}

	makevectors (self.owner.v_angle);
	traceline (self.owner.origin, (self.owner.origin + (v_forward * 999999)), FALSE, self);
	setorigin (self, trace_endpos + (v_forward * -5));

	if (self.owner.deadflag == 0)
	{
		if (trace_ent.flags & FL_CLIENT)
		{
			if (self.frame < 1)
				self.frame = self.frame + 1;
			else
				self.frame = 0;
			setmodel (self, "progs/lockon.spr");
			if (self.cnt == FALSE) // make sure lock on sound isn't repeatedly played
			{
				self.cnt = TRUE;
				sound (self.owner, CHAN_BODY, "player/lockon.wav", 1, ATTN_NORM);
			}
		}
		else
		{
			self.cnt = FALSE;
			setmodel (self, "progs/target.mdl");
		}
	}
	else
	{
		self.frame = 0;
		setmodel (self, "progs/null.spr");
	}

	setsize (self, '0 0 0', '0 0 0');
	self.nextthink = time + 0.01;
};

void() targetter =
{
	local entity targa;

	targa = spawn ();
	targa.movetype = MOVETYPE_NONE;
	targa.solid = SOLID_NOT;
	setmodel (targa, "progs/target.mdl"); 
	setsize (targa, '0 0 0', '0 0 0');
	targa.classname = "target";
	targa.owner = self;
	makevectors (self.v_angle);
	traceline (self.origin, (self.origin + (v_forward * 999999)) ,FALSE ,self);
	setorigin (targa, trace_endpos);
	targa.think = target_update;
	targa.nextthink = time + 0.01;
};