/***************************************************************************
 *  combat.c added by Charles Marchant
 *  Jan 12 1995 to replace old combat
 */


#include "mstruct.h"
#include "mextern.h"

#ifdef DMALLOC
  #include "/usr/local/include/dmalloc.h"
#endif

int update_combat(crt_ptr)
creature *crt_ptr;
{
   creature *att_ptr;
   room     *rom_ptr;
   etag     *ep;
   ctag     *cp;
   char     *enemy;
   int      n = 0,rtn = 0,p = 0,fd,t = 0;
   


   rom_ptr = crt_ptr->parent_rom;
   ep = crt_ptr->first_enm;
   while(1)
     {
       enemy = ep->enemy;
       if(!enemy)
	  ep = ep->next_tag;
       if(!ep)
	  return 0;
       if(enemy)
	  break;
     }
    
   att_ptr = find_crt(crt_ptr, rom_ptr->first_ply,enemy, 1);
   if(!att_ptr)
      att_ptr = find_crt(crt_ptr, rom_ptr->first_mon,enemy, 1);
   if(!att_ptr)
   {
     if(!find_who(enemy))
       del_enm_crt(enemy, crt_ptr);
     else
       end_enm_crt(enemy, crt_ptr);
     return 0;
   }
   
   if(is_charm_crt(crt_ptr->name, att_ptr)&& F_ISSET(crt_ptr, MCHARM))
      p = 1;
   crt_ptr->NUMHITS++;
   n=20;
   if(F_ISSET(crt_ptr, MMAGIO))
      n=crt_ptr->proficiency[0];
	         
   if(F_ISSET(crt_ptr, MMAGIC) && mrand(1, 100) <= n && !p) 
   {
     rtn = crt_spell(crt_ptr, att_ptr);
     if(rtn == 2) 
        return 1; 
     else if(rtn == 1)
        n = 21;
     else 
      	n = crt_ptr->thaco - att_ptr->armor/10;
   }
   else 
   {
     n = crt_ptr->thaco - att_ptr->armor/10;
     n = MAX(n, 1);
   }
   
   
   if(mrand(1,20) >= n && !p) 
    {
      fd = att_ptr->fd;
      ANSI(fd, RED); 
      if(F_ISSET(crt_ptr, MBRETH) && mrand(1,30)<5)
      {
       if (F_ISSET(crt_ptr, MBRWP1) && !F_ISSET(crt_ptr, MBRWP2))
         n = bw_spit_acid(crt_ptr,att_ptr);
       else if (F_ISSET(crt_ptr, MBRWP1) && F_ISSET(crt_ptr, MBRWP2))
         n = bw_poison(crt_ptr,att_ptr);
       else if (!F_ISSET(crt_ptr, MBRWP1) && F_ISSET(crt_ptr, MBRWP2))
         n = bw_cone_frost(crt_ptr,att_ptr);
       else
         n = bw_cone_fire(crt_ptr,att_ptr);
      }
      else if(F_ISSET(crt_ptr, MENEDR) && mrand(1,100)< 25) 
        n = power_energy_drain(crt_ptr,att_ptr);
      else
        n = mdice(crt_ptr);		     
    
        att_ptr->hpcur -= n;
                
	print(fd, "%M hit you for %d damage.\n",crt_ptr, n);
	/* Output only when monster v. monster */
	 if (att_ptr->type == MONSTER && crt_ptr->type == MONSTER) { 
        	broadcast_rom2(fd,crt_ptr->fd,att_ptr->rom_num,"%M hits %m.", 
		       crt_ptr, att_ptr);
		add_enm_crt(crt_ptr->name, att_ptr);
	}
	add_enm_dmg(att_ptr->name, crt_ptr,n);

        if(F_ISSET(crt_ptr, MPOISS) && mrand(1,100) <= 15) 
	{
          print(fd, "%M poisoned you.\n",crt_ptr);
          F_SET(att_ptr, PPOISN);
        }

        if(F_ISSET(crt_ptr, MDISEA) && mrand(1,100) <= 15) 
	{
          print(fd, "%M infects you.\n",crt_ptr);
          F_SET(att_ptr, PDISEA);
        }
		
	if(F_ISSET(crt_ptr, MBLNDR) && mrand(1,100) <= 15) 
	{
          print(fd, "%M  blinds your eyes.\n",crt_ptr);
          F_SET(att_ptr, PBLIND);
	}
  
        if(F_ISSET(crt_ptr, MDISIT) && mrand(1,100) <= 15) 
           dissolve_item(att_ptr,crt_ptr);
                
        ANSI(fd, WHITE);

        n = choose_item(att_ptr);

        if(n) 
	{
          if(--att_ptr->ready[n-1]->shotscur<1) 
	  {
            print(fd,"Your %s fell apart.\n",att_ptr->ready[n-1]->name);
            broadcast_rom(fd,att_ptr->rom_num,"%M's %s fell apart.",
                          att_ptr,att_ptr->ready[n-1]->name);
            add_obj_crt(att_ptr->ready[n-1],att_ptr);
            att_ptr->ready[n-1] = 0;
            compute_ac(att_ptr);
          }
	}
        
        if(att_ptr->type == PLAYER && !F_ISSET(att_ptr, PNOAAT) && !p)
	{      
             rtn = attack_crt(att_ptr, crt_ptr);
             if(rtn) 
		return 1;
	}
	else 
	{      
          if(LT(att_ptr,LT_ATTCK) < t)
	  {				   
	    rtn = attack_crt(att_ptr, crt_ptr);
            att_ptr->lasttime[LT_ATTCK].ltime = t;
	    if(rtn) 
	      return 1;
	  }
	}
                
	if(att_ptr->hpcur < 1) 
	{
           ANSI(fd, MAGENTA);
           print(fd, "%M killed you.\n", crt_ptr);
           ANSI(fd, WHITE);
           if(att_ptr->type == MONSTER && crt_ptr->type == MONSTER) {
		broadcast_rom2(att_ptr->fd,crt_ptr->fd,att_ptr->rom_num,"%M killed %m.",
                       crt_ptr, att_ptr);
	   }
	   die(att_ptr, crt_ptr);
           return 1;
	}
        else if(F_ISSET(att_ptr, PWIMPY)) 
        {
          if(att_ptr->hpcur <= att_ptr->WIMPYVALUE) 
	  {
            flee(att_ptr);
            return 1;
	  }
	}
        else if(F_ISSET(att_ptr, PFEARS)) 
	{
	  int ff;
	  ff = 40 + (1- (att_ptr->hpcur/att_ptr->hpmax))*40 +
	       bonus[att_ptr->constitution]*3 + 
	       (att_ptr->class == PALADIN) ? -10 : 0;
          if(ff < mrand(1,100)) 
	  {
            flee(att_ptr);
                     
	  }
	}
       
   }
   else if(n <= 20 && !p) 
   {
     ANSI(att_ptr->fd, CYAN);
     print(att_ptr->fd, "%M missed you.\n", crt_ptr);
    /* Output only when monster v. monster */
     if (att_ptr->type == MONSTER && crt_ptr->type == MONSTER) { 
	     broadcast_rom2(att_ptr->fd,crt_ptr->fd, 
       		att_ptr->rom_num,"%M misses %m.", crt_ptr, att_ptr);
	     add_enm_crt(crt_ptr->name, att_ptr);
     }
     ANSI(att_ptr->fd, WHITE);
     if(att_ptr->type == PLAYER && !F_ISSET(att_ptr, PNOAAT))
     {      
         rtn = attack_crt(att_ptr, crt_ptr);
         if(rtn) 
	    return 1;
     }
     else 
     {      
       if(LT(att_ptr,LT_ATTCK) < t)
       {			
	 rtn = attack_crt(att_ptr, crt_ptr);
         att_ptr->lasttime[LT_ATTCK].ltime = t;
	 if(rtn) 
	    return 1;
       }
     }
   }
  return 0;
}


/***************************************************************************
 *  breath weapons 
 */

int bw_spit_acid(crt_ptr,vic_ptr)
creature *crt_ptr;
creature *vic_ptr;
{
  int fd;
  int n;
  fd = vic_ptr->fd;
  print(fd, "%M spits acid on you!\n", crt_ptr);
  broadcast_rom(fd,vic_ptr->rom_num,"%M spits acid on %m!",crt_ptr,vic_ptr);
  n = dice(crt_ptr->level, 3, 0);
  return n;
}

int bw_poison(crt_ptr,vic_ptr)
creature *crt_ptr;
creature *vic_ptr;
{
   int fd;
   int n;
   fd = vic_ptr->fd;
   print(fd, "%M breathes poisonous gas on you!\n", crt_ptr);
   broadcast_rom(fd, vic_ptr->rom_num,
                 "%M breathes poisonous gas on %m!", crt_ptr, vic_ptr);
   n = dice(crt_ptr->level, 2, 1);
   print(fd, "%M poisoned you.\n", crt_ptr);
   F_SET(vic_ptr, PPOISN);
   return n;
}

int bw_cone_frost(crt_ptr,vic_ptr)
creature *crt_ptr;
creature *vic_ptr;
{
   int fd;
   int n;
   fd = vic_ptr->fd;
   print(fd, "%M breathes frost on you!\n", crt_ptr);
   broadcast_rom(fd,vic_ptr->rom_num,"%M breathes frost on %m!",
		 crt_ptr,vic_ptr);
   if(F_ISSET(vic_ptr, PRCOLD))
     n = dice(crt_ptr->level, 2, 0);
   else
     n = dice(crt_ptr->level, 4, 0);
   return n;
}

int bw_cone_fire(crt_ptr,vic_ptr)
creature *crt_ptr;
creature *vic_ptr;
{
   int fd;
   int n;
   fd = vic_ptr->fd;
   print(fd, "%M breathes fire on you!\n", crt_ptr);
   broadcast_rom(fd, vic_ptr->rom_num,"%M breathes fire on %m!", 
		 crt_ptr, vic_ptr);
   if(F_ISSET(vic_ptr, PRFIRE))
      n = dice(crt_ptr->level, 2, 0);
   else
      n = dice(crt_ptr->level, 4, 0);
   return n;
}
   
int power_energy_drain(crt_ptr,vic_ptr)
creature *crt_ptr;
creature *vic_ptr;
{
  int n;
  int fd;
  fd = vic_ptr->fd;
  n = dice(crt_ptr->level, 5, (crt_ptr->level)*5);
  n = MAX(0,MIN(n,vic_ptr->experience));
  print(fd, "%M drains your experience!\n", crt_ptr);
  broadcast_rom2(crt_ptr->fd,vic_ptr->fd, vic_ptr->rom_num,
		 "%M energy drains %m!", crt_ptr, vic_ptr);
  vic_ptr->experience -= n;
  lower_prof(vic_ptr,n);
  print(fd, "%M drains you for %d experience.\n",crt_ptr,n);
  return 0;
}
