/*-------------------------------------------------------------------
Filename : cbnmods.qc
Author   : Cameron Newham
Version  : 1.1
Date     : 96/08/17

Description
-----------
Provides routines specific to my patches.  See the description
file that came with the archive for further details.

Public Entry Points
-------------------
CN_Missile_Bubbles
CN_Missile_Think
CN_Ditch_Rockets
--------------------------------------------------------------------*/

void() bubble_bob;
void() GrenadeExplode; //Needed for CN_Missile_Think
void(float num_bubbles) DeathBubbles;

/*-------------------------------------------------------------------
Slightly modified version of Id's DeathBubblesSpawn
--------------------------------------------------------------------*/
void() MissileBubblesSpawn =
{
local entity    bubble;
        bubble = spawn();
        setmodel (bubble, "progs/s_bubble.spr");
        setorigin (bubble, self.owner.origin);
        bubble.movetype = MOVETYPE_NOCLIP;
        bubble.solid = SOLID_NOT;
        bubble.velocity = '0 0 15';
        bubble.nextthink = time + 0.5;
        bubble.think = bubble_bob;
        bubble.classname = "bubble";
        bubble.frame = 0;
        bubble.cnt = 0;
        setsize (bubble, '-8 -8 -8', '8 8 8');
        self.nextthink = time + 0.1;
        self.think = MissileBubblesSpawn;
        self.air_finished = self.air_finished + 1;
        if (self.air_finished >= self.bubble_count)
                remove(self);
};

/*---------------------CN_Missile_Bubbles----------------------------
Makes an underwater entity look like a real underwater entity by
spraying out bubbles.  This is designed for use with rockets.
--------------------------------------------------------------------*/
void(float num_bubbles) CN_Missile_Bubbles =
{
  local vector  rocket_origin;
  local entity  bubble_spawner;
        
        //rocket_origin = self.origin + ('0 -50 -50');
        bubble_spawner = spawn();
        setorigin (bubble_spawner, self.origin + '0 0 -60');
        bubble_spawner.movetype = MOVETYPE_NONE;
        bubble_spawner.solid = SOLID_NOT;
        bubble_spawner.nextthink = time + 0.1;
        bubble_spawner.think = MissileBubblesSpawn;
        bubble_spawner.air_finished = 0;
        bubble_spawner.owner = self;
        bubble_spawner.bubble_count = num_bubbles;
        return;
};


/*----------------------CN_Missile_Think-----------------------------
Missile Velocity Correction.
Correct the velocity of spikes, rockets and grenades underwater.  
Simulates water resistance.  Also calls CN_Missile_Bubbles for rockets
underwater.  Rockets are slowed in water and speed up again in air,
while grenades are slowed by each passage through water.
--------------------------------------------------------------------*/
void() CN_Missile_Think =
{
  local vector v1;
  local vector v2;

  // if it's a grenade then we must make it explode after
  // it's duration expires

  if ((self.classname == "grenade") && (time > self.duration))
  {
    // this is a grenade and it's past its use-by date
    self.think = GrenadeExplode;
    self.nextthink = time + 0.1;
  }
  else
  if (self.duration < time)
    self.think = SUB_Remove;
  else
  {
    self.nextthink = time + 0.1;

    v1 = self.origin;
    v2 = v1;
    traceline (v1, v2, TRUE, self);

    if (trace_inwater == TRUE) 
    {
      if ((random() > 0.72) && (self.classname == "rocket"))
        CN_Missile_Bubbles(1);

      if (self.jump_flag == FALSE)
      {
        // correct velocity underwater if not underwater
        // (jump_flag) already.
        self.jump_flag = TRUE;  // now in water
        self.swim_flag = TRUE;  // water->air transition not done
        self.velocity = self.velocity * 0.4292;
        self.angles = vectoangles(self.velocity);
      }
    }
    else
    {
      // make sure we only do this for 1 water/surf transition
      if (self.swim_flag == TRUE) 
      {
        if (self.classname == "rocket")
        {
          // correct velocity out of water for rockets
          self.velocity = self.velocity * 2.33;
        }
        self.jump_flag = FALSE;  //out of water
        self.swim_flag = FALSE;  //water->air transition finished
      }
    }
  }
  
};

/*------------------------CN_Ditch_Rockets---------------------------
Removes half your rockets, places them in a backpack and ejects
it to the world.  You'll need this for when you get too many rockets
and get weighed down.
--------------------------------------------------------------------*/
void() CN_Ditch_Rockets =
{
        local entity back_pack;
        local float  num_to_ditch;  

        // if we have none or one then return!
        if (self.ammo_rockets < 2)
          return;

        // spawn a backpack
        back_pack = spawn();

        // calculate number to ditch and set appropriate amounts
        // for entity and backpack
        num_to_ditch = self.ammo_rockets / 2;
        num_to_ditch = floor(num_to_ditch);
        back_pack.ammo_rockets = num_to_ditch;
        self.ammo_rockets = self.ammo_rockets - num_to_ditch;


        back_pack.owner = self;
        makevectors(self.v_angle);
        setorigin(back_pack, self.origin + '0 0 45');
        back_pack.velocity = aim(self, 1000);
        back_pack.velocity_x = back_pack.velocity_x * -340;
        back_pack.velocity_y = back_pack.velocity_y * -340;
        back_pack.velocity_z = back_pack.velocity_z * 380;
        back_pack.angles = vectoangles(back_pack.velocity);
        back_pack.flags = FL_ITEM;
        back_pack.solid = SOLID_TRIGGER;
        back_pack.movetype = MOVETYPE_TOSS;
        back_pack.nextthink = time + 0.2;

        setmodel (back_pack, "progs/backpack.mdl");
        setsize(back_pack, '-16 -16 0', '16 16 56');
        back_pack.touch = BackpackTouch;
        back_pack.nextthink = time + 120;    // remove pack after 120 secs
        back_pack.think = SUB_Remove;

        sprint(self, "Dumped Rockets\n");

        W_SetCurrentAmmo();
};

