//------------------------------------------------------------------------------------
// Crossbow
//------------------------------------------------------------------------------------

void() T_Arrowtouch =
{
  local float rand;
  local float r, zone;

  if ((other.classname == "player") &&
     (self.velocity == '0 0 0'))
  {
    if (other.ammo_shells >= MAXAMMO_ARROWS)
      return;
    other.ammo_shells = other.ammo_shells + 1;
    sound(other, CHAN_ITEM, "weapons/lock4.wav", 0.6, ATTN_NORM);
    sprint(other, "You got the Arrow\n");
    remove(self);
    return;
  }
  if (other == self.owner)
    return;
  if (pointcontents(self.origin) == CONTENT_SKY)
  {
    remove(self);
    return;
  }
  if (other.takedamage) 
  {
    spawn_touchblood(20);
    sound(self, CHAN_AUTO, "weapons/arr2flsh.wav", 1, ATTN_NORM);
    zone = DetermineZone(self, other.origin);
    T_Damage(other, self, self.owner, ARROW_DAMAGE + (random()*ARROW_DAMAGE_ADDRANDOM), zone, "arrow", "");
    remove(self);
  }
  else if ((other.classname == "worldspawn") || (other.classname == "bomb"))
  {
    if (self.waterlevel > 2) 
      sound(self, CHAN_AUTO, "weapons/arr2wood.wav", 0.4, ATTN_NORM);
    else 
      sound(self, CHAN_AUTO, "weapons/arr2wood.wav", 1, ATTN_NORM);
    WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
    WriteByte(MSG_BROADCAST, TE_SPIKE);
    WriteCoord(MSG_BROADCAST, self.origin_x);
    WriteCoord(MSG_BROADCAST, self.origin_y);
    WriteCoord(MSG_BROADCAST, self.origin_z);
    self.velocity = '0 0 0';
    self.movetype = MOVETYPE_NONE;
  }
  else
    remove(self);
};

void() T_BArrowtouch =
{
  local float rand;
  local float r, zone;

  if (other == self.owner)
    return;
  if (pointcontents(self.origin) == CONTENT_SKY)
  {
    remove(self);
    return;
  }
  if ((other.classname == "bomb") && (other.solid != SOLID_NOT))
  {
	other.solid = SOLID_NOT;
	if(other.ninja)	//is an explodebox
	{
		T_Damage(other, self, self.owner, BARROW_DAMAGE + (random()*BARROW_DAMAGE_ADDRANDOM), zone, "burnarrow", "");
		remove(self);
		return;
	}
	else
		SpawnExplosion(other.origin, self.owner, BOMB_SCRAPS, "bombarrow", 1);
	if(other.flags & FL_ITEM)
	{
		other.model = string_null;
		other.solid = SOLID_NOT;
		if (deathmatch == 1)
			other.nextthink = time + 30;
		other.think = SUB_regen;
	}
	else
		remove(other);
  }
  if (other.takedamage) 
  {
	if(other.classname == "player")
		other.oldvel = self.velocity;
    spawn_touchblood(20);
    sound(self, CHAN_VOICE, "weapons/arr2flsh.wav", 1, ATTN_NORM);
    zone = DetermineZone(self, other.origin);
    T_Damage(other, self, self.owner, BARROW_DAMAGE + (random()*BARROW_DAMAGE_ADDRANDOM), zone, "burnarrow", "");
	if(other.items & IT_SUPER_NAILGUN)
	{
		other.items = other.items - (other.items & IT_SUPER_NAILGUN);
		SpawnExplosion(other.origin, self.owner, BOMB_SCRAPS, "bombplayerarrow", 1);
	}
	if(random() > BARROW_BURNCHANCE)
		Burn(other, NUM_FLAMES, self.owner);
	if((random() > 0.85) && (other.health) && ((other.classname == "player") || (other.flags & FL_MONSTER))) 
		SpawnBloodFountain(other, 1.5, (self.angles * -1), self.origin - other.origin);
	if(!self.count)	//this time, count is set in t_damage; whooO, another hack!
		remove(self);
	else		//fly away with head!!!
	{
		self.touch = SUB_Remove;
		self.nextthink = self.ltime;
		self.think = SUB_Remove;
	}
  }
  else if ((other.solid == SOLID_BSP) && (other.movetype == MOVETYPE_PUSH))
  {
    sound(self, CHAN_VOICE, "weapons/arr2wood.wav", 1, ATTN_NORM);
    WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
    WriteByte(MSG_BROADCAST, TE_SPIKE);
    WriteCoord(MSG_BROADCAST, self.origin_x);
    WriteCoord(MSG_BROADCAST, self.origin_y);
    WriteCoord(MSG_BROADCAST, self.origin_z);
    self.velocity = '0 0 0';
    self.movetype = MOVETYPE_NONE;
    self.touch = T_Arrowtouch;
    setmodel(self, "progs/arrow.mdl");
    self.nextthink = self.ltime;
    self.think = SUB_Remove;
  }
  else
    remove(self);
};

void() BArrowthink =
{
  local float pc;
  pc = pointcontents(self.origin);
  if(self.ltime < time)
  {
     remove(self);
     return;
  }
  if(self.jumptime < time)
  {
    sound (self, CHAN_VOICE, "misc/fireamb1.wav", 1, ATTN_NORM);
    self.jumptime = time + 2;
  }
  if((pc == CONTENT_WATER) || (pc == CONTENT_SLIME))
  {
    DeathBubbles(1);
    sound (self, CHAN_VOICE, "misc/flamend.wav", 1, ATTN_NORM);
    setmodel(self, "progs/arrow.mdl");
    self.touch = T_Arrowtouch;
    self.nextthink = self.ltime;
    self.think = SUB_Remove;
    return;
  }
  else if (pc == CONTENT_LAVA)
  {
    particle(self.origin, '0 0 200', 4, 10);
    sound (self, CHAN_VOICE, "misc/flamend.wav", 1, ATTN_NORM);
    remove(self);
    return;
  }
  self.frame = self.frame + 1;
  if(self.frame > 2)
    self.frame = 0;
  self.nextthink = time + 0.1;
};

void(float burning) W_FireCrossbow =
{
  local entity missile;

  self.currentammo = self.ammo_shells = self.ammo_shells - 1;
  self.punchangle_x = -4;
  missile = spawn();
  missile.owner = self;
  if (self.waterlevel >= 2)
  {
    if(burning)
    {
      DeathBubbles(1);
      sound (self, CHAN_VOICE, "misc/flamend.wav", 1, ATTN_NORM);
      burning = FALSE;
    }
    missile.movetype = MOVETYPE_BOUNCE;
  }
  else
    missile.movetype = MOVETYPE_FLYMISSILE;
  missile.flags = FL_ITEM;
  missile.solid = SOLID_TRIGGER;
  makevectors(self.v_angle);
  missile.velocity = aim(self, 1000);
  missile.velocity = missile.velocity * 1100 + crandom() * v_right * ARROW_RANDOM + crandom() * v_up * ARROW_RANDOM;
  missile.angles = vectoangles(missile.velocity);
  if(burning)
  {
    setmodel(missile, "progs/b_arrow.mdl");
    missile.touch = T_BArrowtouch;
    missile.ltime = time + ARROW_TIME;
    missile.nextthink = time + 0.1;
    missile.think = BArrowthink;
    missile.classname = "barrow";
  }
  else
  {
    setmodel(missile, "progs/arrow.mdl");
    missile.touch = T_Arrowtouch;
    missile.nextthink = time + ARROW_TIME;
    missile.think = SUB_Remove;
  }
  setsize(missile, VEC_ORIGIN, VEC_ORIGIN);
  setorigin(missile, self.origin + v_forward * 8 + '0 0 16');
};

