/*
+-------+
|PickUps|
+-------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=+
| Scratch                                      Http://www.admdev.com/scratch |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| Items that are able to be picked up such as ammo, weapons, special         |
| items and so on.			                       			     |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
*/

.string mdl;
.float		aflag;
void() bound_other_ammo;
void() SpawnGrenade;

/*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
prints a warning message when spawned
*/

void() SUB_regen =
{
	if (self.netname == "pistol") // throw grenade pickup from pistol item
		SpawnGrenade();
	self.model = self.mdl;		// restore original model
	self.solid = SOLID_TRIGGER;	// allow it to be touched again
	sound (self, CHAN_VOICE, "items/itemres.wav", 1, ATTN_NORM);	// play respawn sound
	setorigin (self, self.origin);
};

void() noclass =
{
	dprint ("noclass spawned at");
	dprint (vtos(self.origin));
	dprint ("\n");
	remove (self);
};



/*
============
PlaceItem

plants the object on the floor
============
*/
void() PlaceItem =
{
	local float	oldz;

	self.mdl = self.model;		// so it can be restored on respawn
	self.flags = FL_ITEM;		// make extra wide
	self.solid = SOLID_TRIGGER;
	self.movetype = MOVETYPE_TOSS;
	self.velocity = '0 0 0';
	self.origin_z = self.origin_z + 6;
	oldz = self.origin_z;
	if (!droptofloor(0,0))
	{
		dprint ("Item fell out of level at ");
		dprint (vtos(self.origin));
		dprint ("\n");
		remove(self);
		return;
	}
};

void() grenade_touch =
{
	if (other.classname != "player" || other.health <= 0)
		return;
	if (other.ammo_rockets >= 3)
		return;
	other.ammo_rockets = other.ammo_rockets + 1;
	sound (self, CHAN_VOICE, "items/pk_gren.wav", 1, ATTN_NORM); // item sound

	bound_other_ammo ();
	
	sprint (other, "You picked up a grenade.\n");
	SUB_UseTargets();				// fire all targets / killtargets
	remove(self);
};


void() SpawnGrenade =
{
	local	entity new;

	new = spawn();

	new.origin = self.origin + v_up*16;
	setmodel (new, "progs/pk_gren.mdl");
	setsize (new, '0 0 0', '0 0 0');
	new.velocity_x = random()*125 + 50 * crandom();
	new.velocity_y = random()*125 + 50 * crandom();
	new.velocity_z = 145;
	new.flags = FL_ITEM;
	new.movetype = MOVETYPE_TOSS;
	new.solid = SOLID_TRIGGER;
	new.touch = grenade_touch;
	new.think = SUB_Remove; // change me?
	new.nextthink = time + 24;
	new.classname = "item_grenade";
};

/*
============
StartItem

Sets the clipping size and plants the object on the floor
============
*/
void() StartItem =
{
	if (self.netname == "pistol") // throw grenade pickup from pistol item
		SpawnGrenade();
	self.nextthink = time + 0.2;	// items start after other solids
	self.think = PlaceItem;
};

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

WEAPONS

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

void() bound_other_ammo =
{
	if (other.ammo_shells > 32) // Shotgun Shells
		other.ammo_shells = 32;
	if (other.ammo_nails > 150) // Pistols & SubMach
		other.ammo_nails = 150;	
	if (other.ammo_rockets > 3) // Grenades
		other.ammo_rockets = 3;
};


float(float w) RankForWeapon =
{
	if (w == W_SUBMACHINE)
		return 1;
	if (w == W_SHOTGUN)
		return 2;
	if (w == W_DOUBLEPISTOL)
		return 3;
	if (w == W_PISTOL)
		return 4;
	return 5;
};

/*
=============
Deathmatch_Weapon

Deathmatch weapon change rules for picking up a weapon
=============
*/
void(float old, float new) RankChange_Weapon =
{
	local float or, nr;

	// change self.weapon if desired
	or = RankForWeapon (self.weapon);
	nr = RankForWeapon (new);
	if (nr < or)
	{
		self.weapon = new;
		// Grab weapon animation
		other.checkwepstop_finished = time + 0.4;
		other.think = player_grabwep1;
		other.nextthink = time + 0.1;
	}
};

/*
=============
weapon_touch
=============
*/
float() W_BestWeapon;

void() weapon_touch =
{
	local	float	hadammo, best, new, old, leave;
	local	entity stemp;

	if (other.classname != "player") return;
	if (other.health <= 0) return;

	if (deathmatch == 2) leave = 1;
	else leave = 0;
	
	if (self.netname == "pistol")
	{
		if (leave && (other.items & W_PISTOL)) return;

		hadammo = other.ammo_nails;
		other.ammo_nails = other.ammo_nails + 15;
		if (other.items & W_PISTOL && !other.items & W_DOUBLEPISTOL)
		{
			new = W_DOUBLEPISTOL;
			sprint (other, "Akimbo Pistols earned!\n");
		}
		else
		{
			sprint (other, "You picked up a Pistol.\n");
			new = W_PISTOL;
		}
	}
	if (self.netname == "akimbo pistols")
	{
		if (leave && (other.items & W_DOUBLEPISTOL)) return;
		hadammo = other.ammo_nails;
		new = W_DOUBLEPISTOL | W_PISTOL;
		other.ammo_nails = other.ammo_nails + 30;
		sprint (other, "You picked up the Akimbo Pistols.\n");
	}
	if (self.netname == "shotgun")
	{
		if (leave && (other.items & W_SHOTGUN)) return;
		hadammo = other.ammo_shells;
		new = W_SHOTGUN;
		other.ammo_shells = other.ammo_shells + 8;
		sprint (other, "You picked up the Shotgun.\n");
	}
	if (self.netname == "sub-machinegun")
	{
		if (leave && (other.items & W_SUBMACHINE)) return;
		hadammo = other.ammo_nails;
		new = W_SUBMACHINE;
		other.ammo_nails = other.ammo_nails + 24;
		sprint (other, "You picked up the Sub-Machinegun.\n");
	}
	sound (self, CHAN_VOICE, "items/pk_wep.wav", 1, ATTN_NORM); // item sound		

	bound_other_ammo ();

	// change to the weapon
	old = other.items;
	other.items = other.items | new;
	
	stemp = self;
	self = other;

	if (!self.ishuman) // Frikbots bust out the weapons only
		RankChange_Weapon (old, new);

	W_SetCurrentAmmo();

	self = stemp;

	if (leave) return;

	// remove it in single player, or setup for respawning in deathmatch
	self.model = string_null;
	self.solid = SOLID_NOT;
	if (deathmatch == 1) self.nextthink = time + 15;
	self.think = SUB_regen;
	
	activator = other;
	SUB_UseTargets();				// fire all targets / killtargets
};

void() item_pistol =
{
	precache_model ("progs/pk_pist.mdl");
	setmodel (self, "progs/pk_pist.mdl");
	self.weapon = W_PISTOL;
	self.netname = "pistol";
	self.touch = weapon_touch;
	setsize (self, '-16 -16 0', '16 16 56');
	StartItem ();
};

void() item_pistols =
{
	precache_model ("progs/pk_2pist.mdl");
	setmodel (self, "progs/pk_2pist.mdl");
	self.weapon = W_DOUBLEPISTOL;
	self.netname = "akimbo pistols";
	self.touch = weapon_touch;
	setsize (self, '-16 -16 0', '16 16 56');
	StartItem ();
};

void() item_shotgun =
{
	precache_model ("progs/pk_shotg.mdl");
	setmodel (self, "progs/pk_shotg.mdl");
	self.weapon = W_SHOTGUN;
	self.netname = "shotgun";
	self.classname = "4"; // weapon number
	self.touch = weapon_touch;
	setsize (self, '-16 -16 0', '16 16 56');
	StartItem ();
};

void() item_submachine =
{
	precache_model ("progs/pk_subm.mdl");
	setmodel (self, "progs/pk_subm.mdl");
	self.weapon = W_SUBMACHINE;
	self.netname = "sub-machinegun";
	self.classname = "5"; // weapon number
	self.touch = weapon_touch;
	setsize (self, '-16 -16 0', '16 16 56');
	StartItem ();
};

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

AMMO

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

void() ammo_touch =
{
local entity	stemp;
local float		best;

	if (other.classname != "player") return;
	if (other.health <= 0) return;


	// pistol/submachinegun/doublepistol
	if (self.weapon == 1)
	{
		if (other.ammo_nails >= 200)
			return;
		other.ammo_nails = other.ammo_nails + self.aflag;
		sound (self, CHAN_VOICE, "items/pk_bullt.wav", 1, ATTN_NORM); // item sound				
	}

	// shotgun
	if (self.weapon == 2)
	{
		if (other.ammo_shells >= 32)
			return;
		other.ammo_shells = other.ammo_shells + self.aflag;
		sound (self, CHAN_VOICE, "items/pk_shell.wav", 1, ATTN_NORM); // item sound
	}

	bound_other_ammo ();
	
	sprint (other, "You got some ");
	sprint (other, self.netname);
	sprint (other, ".\n");


	// if changed current ammo, update it
	stemp = self;
	self = other;
	W_SetCurrentAmmo();
	self = stemp;

	// remove it in single player, or setup for respawning in deathmatch
	self.model = string_null;
	self.solid = SOLID_NOT;
	if (deathmatch == 1) self.nextthink = time + 10;
	self.think = SUB_regen;

	activator = other;
	SUB_UseTargets();				// fire all targets / killtargets
};

void() item_bullets =
{
	self.touch = ammo_touch;

	precache_model ("progs/pk_bullt.bsp");
	setmodel (self, "progs/pk_bullt.bsp");
	self.aflag = 25;
	self.weapon = 1;
	self.netname = "bullets";
	setsize (self, '0 0 0', '32 32 56');
	StartItem ();
};

void() item_shells =
{
	self.touch = ammo_touch;

	precache_model ("progs/pk_shell.bsp");
	setmodel (self, "progs/pk_shell.bsp");
	self.aflag = 6;
	self.weapon = 2;
	self.netname = "shells";
	setsize (self, '0 0 0', '32 32 56');
	StartItem ();
};

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

ENERGY SHIELD

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

void() shield_touch;

void() shield_touch =
{
	local	float	type, value, bit;
	
	if (other.health <= 0) return;
	if (other.classname != "player") return;

	if (self.classname == "item_shield")
	{
		type = 0.3;
		value = 100;
		bit = IT_SHIELD;
	}
	if (other.armortype*other.armorvalue >= type*value) return;
		
	other.armortype = type;
	other.armorvalue = value;
	other.items = other.items - (other.items & (IT_SHIELD)) + bit;

	self.solid = SOLID_NOT;
	self.model = string_null;
	if (deathmatch == 1) self.nextthink = time + 20;
	self.think = SUB_regen;

	sound (self, CHAN_BODY, "items/pk_sheld.wav", 1, ATTN_NORM);
	sprint(other, "You picked up an energy shield.\n");	
	activator = other;
	SUB_UseTargets();				// fire all targets / killtargets
};

void() item_shield =
{
	precache_sound ("items/pk_sheld.wav");
	self.touch = shield_touch;
	precache_model ("progs/shield.mdl");
	setmodel (self, "progs/shield.mdl");
	setsize (self, '-16 -16 0', '16 16 56');
	StartItem ();
};

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

TIME DELAYER

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

void() timedelay_touch =
{
	if (other.classname != "player") return;
	if (other.health <= 0) return;

	sound(other, CHAN_ITEM, "items/pk_tdlay.wav", 1, ATTN_NONE);
	localcmd ("host_framerate 0.01\n");
	if (deathmatch == 0) timedelay_finished = time + 30;
	else timedelay_finished = time + 15;
	timedelay = TRUE; // on
	bprint(other.netname);
	bprint(" has set off an alien time delayer.\n");

	self.solid = SOLID_NOT;
	self.model = string_null;
	if (deathmatch == 1) self.nextthink = time + 200;
	self.think = SUB_regen;

	activator = other;
	SUB_UseTargets();				// fire all targets / killtargets
};

void() item_timedelay =
{
	self.touch = timedelay_touch;
	precache_model ("progs/pk_time.mdl");
	setmodel (self, "progs/pk_time.mdl");
	setsize (self, '-16 -16 0', '16 16 56');
	StartItem ();
};

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

HEALTH BOXES

=========================================================================
*/
//
// T_Heal: add health to an entity, limiting health to max_health
// "ignore" will ignore max_health limit
//
float (entity e, float healamount, float ignore) T_Heal =
{
	if (e.health <= 0) return 0;
	if ((!ignore) && (e.health >= other.max_health)) return 0;
	healamount = ceil(healamount);

	e.health = e.health + healamount;
	if ((!ignore) && (e.health >= other.max_health)) e.health = other.max_health;
		
	if (e.health > 100) e.health = 100;
	return 1;
};

.float	healamount, healtype;
void() health_touch;

void() item_health10 =
{	
	self.touch = health_touch;

	precache_model("progs/pk_hlh10.bsp");

//	precache_sound("items/r_item1.wav");
	setmodel(self, "progs/pk_hlh10.bsp");
//	self.noise = "items/r_item1.wav";
	self.healamount = 10;

	setsize (self, '0 0 0', '32 32 56');
	StartItem ();
};

void() item_health25 =
{	
	self.touch = health_touch;

	precache_model("progs/pk_hlh25.bsp");

//	precache_sound("items/r_item1.wav");
	setmodel(self, "progs/pk_hlh25.bsp");
//	self.noise = "items/r_item1.wav";
	self.healamount = 25;

	setsize (self, '0 0 0', '32 32 56');
	StartItem ();
};

void() health_touch =
{
	local	float amount;
	local entity oself;
	local	string	s;
	
	if (other.classname != "player")
		return;
	
	if (!T_Heal(other, self.healamount, 0))
		return;

	oself = self;
	self = other;
	PainSkinCheck();
	self = oself;
	
	sprint(other, "You receive ");
	s = ftos(self.healamount);
	sprint(other, s);
	sprint(other, " health\n");
	
	// health touch sound
	//	sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
	
	self.model = string_null;
	self.solid = SOLID_NOT;

	if (deathmatch)
		self.nextthink = time + 20;

	self.think = SUB_regen;

	activator = other;
	SUB_UseTargets();				// fire all targets / killtargets
};