.float iterations; 
void () moss_precache = {

   precache_sound2 ("weapons/cock1.wav");
   precache_sound2 ("weapons/cock2.wav");
   precache_sound2 ("weapons/shotfire.wav");
   precache_model2 ("progs/v_nshot.mdl");
   precache_model2 ("progs/blood.mdl");
//   precache_model2 ("progs/v_moss.mdl");
//   precache_model2 ("progs/sshell.mdl");

};
/*

void (vector position, vector direction) Shoot_Blood = {

   local entity blood;

   blood = spawn ();
   blood.owner = self;
   blood.movetype = MOVETYPE_FLYMISSILE;
   blood.solid = SOLID_NOT;
   makevectors (self.angles);
   blood.velocity = direction;
   blood.nextthink = (time + 0.250);
   blood.think = SUB_Remove;
   blood.touch = SUB_Remove;
   setmodel (blood,"progs/blood.mdl");
   setsize (blood,VEC_ORIGIN,VEC_ORIGIN);
   setorigin (blood,position);

};

float (entity hit, float damage) MossbergAddMultiDamage = {

   if ( !hit ) {

      return ;

   }
   if ( (hit != multi_ent) ) {

      ApplyMultiDamage ();
      multi_damage = damage;
      multi_ent = hit;

   } else {

      multi_damage = (multi_damage + damage);

   }
   return ( multi_damage );

};
*/
/*
//==========================================================================
//  SHOTGUN MOD -- by Patrick Martin
//--------------------------------------------------------------------------
//  Below is some code that recreates the Doom-style shotgun.
//==========================================================================
*/
float() crandom;
void(vector org, vector vel, float damage) SpawnBlood;

//-------------------------------------------------------- New Code --------
//  This inflicts damage to the entity struck.
//--------------------------------------------------------------------------
void(float damage, vector dir, entity attacker) PM_TracePellet =
{
	local	vector	vel, org;
        local float rand;

// Don't injure attacker.
        if (trace_ent == attacker)
                return;

// Find the velocity of flying blood.

	vel = normalize(dir + v_up*crandom() + v_right*crandom());
	vel = vel + 2*trace_plane_normal;
	vel = vel * 200;


// Spot where the pellet(s) hit.
	org = trace_endpos - dir*4;

// Show blood or sparks.
	if (trace_ent.takedamage)
        {
        if (trace_ent.classname != "player")
	        SpawnAlienBlood (org, vel*0.2, damage);
        else
	        SpawnBlood (org, vel*0.2, damage);
	        
                vel_x = ((random () * 300.000) + dir_x);
                vel_y = ((random () * 300.000) + dir_y);
                vel_z = ((random () * 300.000) + dir_z);

				//damage = damage * 2;
                T_Damage (trace_ent, self, self, damage);
	}
	else
	{
                WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
		WriteByte (MSG_BROADCAST, TE_GUNSHOT);
		WriteCoord (MSG_BROADCAST, org_x);
		WriteCoord (MSG_BROADCAST, org_y);
		WriteCoord (MSG_BROADCAST, org_z);
                rand = random ();

      particle (org,'20.000 22.000 27.000',192.000,TE_WIZSPIKE);
      particle (org,'27.000 26.000 28.000',192.000,TE_WIZSPIKE);
      particle (org,'29.000 28.000 24.000',192.000,TE_WIZSPIKE);
      particle (org,'17.000 8.000 10.000',192.000,TE_WIZSPIKE);

                //if (rand < 0.5)
                  //      spawnspark(org,dir);  
	}
};

//-------------------------------------------------------- New Code --------
//  This stops the traceline (shotgun pellet) from going any further.
//--------------------------------------------------------------------------
float(entity head) PM_StopPellet =
{
        if (head.deadflag)
        {
                T_Damage(trace_ent,self, self, 5);
                return FALSE;
        }

        if (head.takedamage)    return TRUE;
//        if (head.classname == "monster_boss")    return TRUE;
        return FALSE;
};

//-------------------------------------------------------- New Code --------
//  This traces the path of each shotgun pellet fired.
//--------------------------------------------------------------------------
void(float shotcount, vector dir, vector spread) FireMossberg =
{
        local   vector  direction;
	local	vector	src;

        local   float   hitwall;
        local   float   hitentity;
        local   float   leftover;
        local   float   damage;
        local   float   dist;
        local   float   travel;

	makevectors(self.v_angle);

	src = self.origin + v_forward*10;
	src_z = self.absmin_z + self.size_z * 0.7;

// Make an attack for each pellet.
	while (shotcount > 0)
	{
        // Spot where shotgun pellets originate.
            src = self.origin + v_forward*10;
            src_z = self.absmin_z + self.size_z * 0.7;

        // Each pellet is given a slight, random course change.
            direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;

        // Trace a line to the wall, if any.
            traceline (src, src + direction*2048, TRUE, self);
            dist = 2048 * trace_fraction;
            if (trace_fraction < 1)
                hitwall = TRUE;
            else
                hitwall = FALSE;

        // Now check for targets that cross the line.
            hitentity = FALSE;
            traceline (src, src + direction*(dist+4), FALSE, self);
            if (trace_fraction < 1)
            {   if (!PM_StopPellet(trace_ent))
                {   leftover = dist - (dist * trace_fraction);
                    src = trace_endpos;

                    while (leftover > 1)
                    {   traceline (src, src + direction*leftover, FALSE, trace_ent);
                        travel = leftover * trace_fraction;
                        if (travel < 1)
                            leftover = 0;
                        else
                        {   leftover = leftover - travel;
                            src = trace_endpos;
                            if (PM_StopPellet(trace_ent))
                            {   leftover = 0;
                                hitentity = TRUE;
                            }
                        }
                    }

                }
                else
                    hitentity = TRUE;
            }
            else
                traceline (src, src + direction*dist, FALSE, self);

        // If the pellet hit something, show the damage.
            if (hitwall || hitentity)
            {   damage = (ceil(random() * 5) + 10) *2;    // 22-30 damage per shot
                PM_TracePellet(damage, direction, self);
            }
            shotcount = shotcount - 1;
        }
};

/*
void (float damage, vector dir) MossbergTraceAttack = {

   local vector vel;
   local vector org;
   local vector meatdir;
   local float rand;

   vel = normalize (((dir + (v_up * crandom ())) + (v_right * crandom ())));
   vel = (vel + (FL_SWIM * trace_plane_normal));
   vel = (vel * 200.000);
   org = (trace_endpos - (dir * MOVETYPE_STEP));
   meatdir_x = ((random () * 300.000) + dir_x);
   meatdir_y = ((random () * 300.000) + dir_y);
   meatdir_z = ((random () * 300.000) + dir_z);
   makevectors (self.v_angle);
   if ( trace_ent.takedamage ) {

      if ( (rand < 0.500) ) {

         Shoot_Blood (org,meatdir);

      }
        if (trace_ent.classname == "monster_shambler") damage = floor(damage / 2);
      rand = MossbergAddMultiDamage (trace_ent,damage);
//
      if ( (trace_ent.movetype != MOVETYPE_PUSH) ) {

         if ( (((((rand >= 24.000) && (rand < 42.000)) && (rand < trace_ent.health)) && (self.flycheck == AS_STRAIGHT)) && (self.targetflyonce1 == MSG_BROADCAST)) && (trace_ent.classname != "monster_oldone")) {

            self.targetflyonce1 = AS_STRAIGHT;
            trace_ent.flags = (trace_ent.flags - FL_ONGROUND);
            trace_ent.velocity = (v_forward * 140.000);
            trace_ent.velocity_z = (trace_ent.velocity_z + ((random () + 0.500) * 80.000));

         }
         if ( ((((rand >= 24.000) && (rand < 42.000)) && (rand >= trace_ent.health)) && (self.flycheck == AS_STRAIGHT)&&(trace_ent.classname != "monster_oldone")) ) {

//if (trace_ent.classname != "player") trace_ent.movetype = MOVETYPE_BOUNCE;
            trace_ent.flags = (trace_ent.flags - FL_ONGROUND);
            trace_ent.velocity = (v_forward * 220.000);
            trace_ent.velocity_z = (trace_ent.velocity_z + ((random () + 0.500) * 200.000));

         }
         if ( (((((rand >= 42.000) && (rand < 60.000)) && (rand < trace_ent.health)) && (self.flycheck == AS_STRAIGHT)) && (self.targetflyonce2 == MSG_BROADCAST))&& (trace_ent.classname != "monster_oldone") ) {

            self.targetflyonce2 = AS_STRAIGHT;
            trace_ent.flags = (trace_ent.flags - FL_ONGROUND);
            trace_ent.velocity = (v_forward * 180.000);
            trace_ent.velocity_z = (trace_ent.velocity_z + ((random () + 0.500) * 120.000));

         }
         if ( ((((rand >= 42.000) && (rand < 60.000)) && (rand >= trace_ent.health)) && (self.flycheck == AS_STRAIGHT))&& (trace_ent.classname != "monster_oldone") ) {

//if (trace_ent.classname != "player")            trace_ent.movetype = MOVETYPE_BOUNCE;
            trace_ent.flags = (trace_ent.flags - FL_ONGROUND);
            trace_ent.velocity = (v_forward * 240.000);
            trace_ent.velocity_z = (trace_ent.velocity_z + ((random () + 0.500) * 220.000));

         }
         if ( ((((rand >= 66.000) && (rand < trace_ent.health)) && (self.flycheck == AS_STRAIGHT)) && (self.targetflyonce3 == MSG_BROADCAST))&& (trace_ent.classname != "monster_oldone") ) {

            self.targetflyonce3 = AS_STRAIGHT;
            trace_ent.flags = (trace_ent.flags - FL_ONGROUND);
            trace_ent.velocity = (v_forward * 220.000);
            trace_ent.velocity_z = (trace_ent.velocity_z + ((random () + 0.500) * 160.000));

         }
         if ( (((rand >= 66.000) && (rand >= trace_ent.health)) && (self.flycheck == AS_STRAIGHT)) && (trace_ent.classname != "monster_oldone")) {

//if (trace_ent.classname != "player")            trace_ent.movetype = MOVETYPE_BOUNCE;
            trace_ent.flags = (trace_ent.flags - FL_ONGROUND);
            trace_ent.velocity = (v_forward * 280.000);
            trace_ent.velocity_z = (trace_ent.velocity_z + ((random () + 0.500) * 230.000));

         }

      }

   } else {

      WriteByte (MSG_BROADCAST,SVC_TEMPENTITY);
      WriteByte (MSG_BROADCAST,TE_GUNSHOT);
      WriteCoord (MSG_BROADCAST,org_x);
      WriteCoord (MSG_BROADCAST,org_y);
      WriteCoord (MSG_BROADCAST,org_z);
      rand = random ();

//      if (rand < 0.5)
  //         spawnspark(org,dir);  
           particle (org,'0 0 0',236,TE_WIZSPIKE);
   }

};

void (float shotcount, vector dir, vector spread) FireMossberg = {

   local vector direction;
   local vector src;
   local float damage;

   makevectors (self.v_angle);
//   self.targetflyonce1 = MSG_BROADCAST;
//   self.targetflyonce2 = MSG_BROADCAST;
//   self.targetflyonce3 = MSG_BROADCAST;
//   self.flycheck = MSG_BROADCAST;
   src = (self.origin + (v_forward * TE_LAVASPLASH));
   src_z = (self.absmin_z + (self.size_z * 0.700));
   ClearMultiDamage ();
   while ( (shotcount > MSG_BROADCAST) ) {

      if ( (shotcount == AS_STRAIGHT) ) {

         self.flycheck = AS_STRAIGHT;

      }

      direction = ((dir + ((crandom () * spread_x) * v_right)) + ((crandom () * spread_y) * v_up));
      traceline (src,(((src + (direction * IT_CELLS)) - (v_right * 100.000)) + (v_up * 50.000)),FALSE,self);
      if ( (trace_fraction != AS_STRAIGHT) ) {

//         MossbergTraceAttack (TE_LIGHTNING2,direction);
        damage = ceil(random() * 10) * 5;    // 5-15 damage         
         MossbergTraceAttack (damage,direction);

      }
      shotcount = (shotcount - AS_STRAIGHT);

   }
   ApplyMultiDamage ();

};
*/

void () W_FireMossberg = {

   local vector dir;

   self.punchangle_x = CONTENT_SOLID;
   
   self.currentammo = self.ammo_shells = (self.ammo_shells - 2);
//   self.currentammo = self.mossclip = self.mossclip - 1;
   dir = aim (self,100000.000);
//   FireMossberg (10,dir,'0.080 0.060 0.000');
   FireMossberg (6,dir,'0.04 0.04 0');

};

void () player_mossberg = [ 1.000, mossberg2 ] {

	self.effects = (self.effects | EF_MUZZLEFLASH);
	self.weaponframe = WEAPON_SHOTGUN;
	self.nextthink = (time + 0.030);
	self.punchangle_x = CONTENT_SOLID;
	self.punchangle_z = WEAPON_ROCKET;
	sound (self,CHAN_WEAPON,"weapons/shotfire.wav",TRUE,ATTN_NORM);
	W_FireMossberg ();
	self.iterations = 0;
//   self.fire = WEAPON_SHOTGUN;

};



void () mossberg2 = [ 2.000, mossberg3 ] {

	self.weaponframe = WEAPON_ROCKET;
	self.nextthink = (time + 0.030);

};

void () mossberg3 = [ 3.000, mossberg4 ] {

	self.weaponframe = AS_MELEE;
	self.nextthink = (time + 0.030);

};

void () mossberg4 = [ 4.000, mossberg5 ] {

	self.weaponframe = WEAPON_SPIKES;
	self.nextthink = (time + 0.050);

};

void () mossberg5 = [ 5.000, mossberg6 ] {

	self.weaponframe = TE_LIGHTNING1;
	self.nextthink = (time + 0.055);
	self.iterations = 0;
//	self.reload = 1;
};
void() mossberg12;
void() mossberg6 = [ 103, mossberg6 ]
{
		  self.weaponframe = 6 + self.iterations;
		  if (self.weaponframe == 8) 
					 sound (self,CHAN_AUTO,"weapons/cock1.wav",TRUE,ATTN_NORM);
		  else if (self.weaponframe == 11) self.think = mossberg12;
		  self.iterations = self.iterations + 1;
		  self.nextthink = time + 0.06;
};
void () mossberg12 = [ 2.000, mossberg13 ] {

	local vector dir;


	self.weaponframe = 12.000;
	self.nextthink = (time + 0.060);
	sound (self,CHAN_AUTO,"weapons/cock2.wav",TRUE,ATTN_NORM);
	makevectors (self.v_angle);
	dir = v_right * 150 + v_up * 100;

//	eject_shell ((self.origin + v_forward * 25.000 + v_up * 13 - v_right * 10),dir);

};

void () mossberg13 = [ 3.000, mossberg14 ] {

	self.weaponframe = 13.000;
	self.nextthink = (time + 0.060);

};

void () mossberg14 = [ 9.000, mossberg15 ] {

	self.weaponframe = 14.000;
	self.nextthink = (time + 0.065);

};

void () mossberg15 = [ 10.000, mossberg16 ] {

	self.weaponframe = 15.000;
	self.nextthink = (time + 0.070);

};

void () mossberg16 = [ 10.000, player_run ] {

	self.weaponframe = 16;
	self.nextthink = (time + 0.070);

};

//void () reload_mossberg29;

/*

void () player_reload_mossberg = [ 10.000, reload_mossberg2 ] {
	self.reload = 1;
	self.attack_finished = time + 3;
	self.weaponframe = 17.000;
	self.nextthink = (time + 0.020);
//   self.reload = WEAPON_SHOTGUN;
//	self.iterations = 0;
//	self.buttonpressed = 0;
};

void() reload_mossberg22;

void() reload_mossberg2 = [ 10, reload_mossberg2 ]
{
		  self.weaponframe = 17 + self.iterations;
		  if (self.weaponframe == 35) self.think = reload_mossberg22;

		  if (self.button0) self.buttonpressed = 1;
		  self.nextthink = time + 0.05;
		  self.iterations = self.iterations + 1;
};
void () reload_mossberg22 = [ 10, reload_mossberg23 ] {

	self.weaponframe = 37;
	self.nextthink = time + 0.05;
	self.currentammo = self.mossclip = self.mossclip + 1;
	self.ammo_shells = self.ammo_shells - 1;
	if ((self.ammo_shells < 1)||(self.buttonpressed)||(self.button0))
	{
		  self.attack_finished = time + 0.5;
		  self.think = reload_mossberg29;
	}
	self.iterations = 0;
};

void() reload_mossberg28;

void () reload_mossberg23 = [ 10.000, reload_mossberg23 ] {

	self.weaponframe = 38 + self.iterations;
	if (self.weaponframe  == 39)
			  sound (self,CHAN_AUTO,"weapons/mk23in.wav",TRUE,ATTN_NORM);
	else if (self.weaponframe == 42)
		  self.think = reload_mossberg28;

	if (self.button0)
		  self.buttonpressed = 1;

	self.nextthink = time + 0.05;
	self.iterations = self.iterations + 1;
};


void () reload_mossberg23 = [ 10.000, reload_mossberg24 ] {

	self.weaponframe = 38 + self.iterations;
	if (self.weaponframe == 42) self.think = 
	self.nextthink = time + 0.05;

};

void () reload_mossberg24 = [ 10.000, reload_mossberg25 ] {

	self.weaponframe = 39.000;
	self.nextthink = (time + 0.050);
	sound (self,CHAN_AUTO,"weapons/mk23in.wav",TRUE,ATTN_NORM);

};

void () reload_mossberg25 = [ 10.000, reload_mossberg26 ] {

	self.weaponframe = 40.000;
	self.nextthink = (time + 0.050);

};

void () reload_mossberg26 = [ 10.000, reload_mossberg27 ] {

	self.weaponframe = 41.000;
	self.nextthink = (time + 0.050);

};

void () reload_mossberg27 = [ 10.000, reload_mossberg28 ] {

	self.weaponframe = 42.000;
	self.nextthink = (time + 0.050);

};
void () reload_mossberg28 = [ 10.000, reload_mossberg23 ] {

	self.weaponframe = 43;
	self.nextthink = time + 0.05;
  
	self.currentammo = self.mossclip = self.mossclip + 1;
	self.ammo_shells = self.ammo_shells - 1;
	if ((self.mossclip >= 8)||(self.ammo_shells < 1)||(self.buttonpressed)||(self.button0))
		  self.think = reload_mossberg29;
	self.iterations = 0;
	self.attack_finished = time + 0.5;

};

void () reload_mossberg29 = [ 10.000, reload_mossberg29 ] {

	self.weaponframe = 44 + self.iterations;
	if (self.weaponframe == 45)
		  sound (self,CHAN_AUTO,"weapons/mk23in.wav",TRUE,ATTN_NORM);
	else if (self.weaponframe == 52)
		  self.think = player_run;
	self.nextthink = time + 0.05;
	self.iterations = self.iterations + 1;
};
*/
