/* borg-frits.c
   "Parsival" borg spellcasting routines and spell-gaining routines
   Copyright (c) Frits Daalmans, 1995
   Read the file README.parsival for more info
*/
#include "angband.h"

static char rcsid[] = "$Id: borg-frits.c,v 1.7 1995/06/18 01:46:14 frits Exp frits $";

#ifdef AUTO_PLAY
#ifdef FRITS

/* this is not the main routine */
#include "borg.h"
#define EXTERN			/* main_enough */


/* global symbols */
bool do_gain_spells = TRUE;
bool do_browse_books = TRUE;


int protevil;
int drained_stat;

/* used to parse the screen when browsing */
int current_book;
int nrbooks = 0;
int known_spells = 0;
bool spells_known[9][9];

extern bool borg_cast_spell_target (char book, char spell);

/* this static data is from tables.c, spell_type.
   ordering there is struct {slevel,smana,sfail,sxtra,sexp} [class][book']['spell]
*/
/* now both manacost and splevel are in frits-dumpspells.c */


/* first spell level according to class */
int firstsplevel[6] =
{99,				/* warrior (never) */
 1,				/* mage */
 1,				/* priest */
 5,				/* rogue */
 3,				/* ranger */
 1				/* paladin */
};

/* extern symbols are in borg-frits.h */

/*
extern bool do_inven;
extern bool do_equip;
extern bool do_panel;
*/

int books[9];


/* this routine is re-entrant; comes back once, after the books have been checked. */
EXTERN bool
borg_can_gain_spell ()
{
  int spellstat = 0;
  int i, j;
  bool go_ahead;
  auto_item *item;
  char buf[20];

  borg_note ("Entered borg_can_gain_spell()");
  borg_note (format ("auto_sclass= %d\tWIS=%d\tINT=%d", auto_sclass, auto_stat_wis, auto_stat_int));

  /* don't spend too much time here for warriors, they need it elsewhere */
  if (auto_sclass == SCLASS_NONE)
    {
      do_gain_spells = FALSE;
      do_browse_books = FALSE;
      return (FALSE);		/* continue old goal */
    }

  do_browse_books = TRUE;

  if (auto_sclass == SCLASS_PRIEST)
    spellstat = auto_stat_wis;
  if (auto_sclass == SCLASS_MAGE)
    spellstat = auto_stat_int;

  /* need the study capacity, the books and the levels */
  if (known_spells != 0)
    {
      borg_note ("borg survived known_spells test");
      borg_note (format ("known_spells = %d, INT/WIS= %d", known_spells, spellstat));
      borg_note (format ("max. learnable spells = %d", maxknownspells (spellstat, auto_level)));

      if (maxknownspells (spellstat, auto_level) <= known_spells)
	{
	  do_gain_spells = FALSE;
	  do_browse_books = FALSE;
	  borg_note ("No spells to be gained right now");
	  return (FALSE);	/* continue old goal */
	}
      else
	{

	  /* check spellbooks */
	  for (i = 0; i < 9; i++)
	    books[i] = -1;

	  for (i = 0; i < 9; i++)
	    {
	      item = &auto_items[i];
	      if (auto_sclass == SCLASS_MAGE)
		{
		  for (j = 0; j < 9; j++)
		    {
		      if (kind_magic_books[j] == item->kind)
			{
			  books[j] = 1;
			}
		    }
		}
	      if (auto_sclass == SCLASS_PRIEST)
		{
		  for (j = 0; j < 9; j++)
		    {
		      if (kind_prayer_books[j] == item->kind)
			{
			  books[j] = 1;
			}
		    }
		}
	    }

	  sprintf (buf, "- - - - - - - - - ");
	  for (i = 0; i < 9; i++)
	    if (books[i] == 1)
	      buf[i * 2] = 'a' + i;
	  borg_note (format ("books available: %s", buf));

	  /* test for spell level */
	  go_ahead = FALSE;
	  for (i = 0; i < 9; i++)
	    {
	      if (books[i] == -1)
		continue;
	      for (j = 0; j < 9; j++)
		{
		  if ((splevel[auto_pclass][i][j] <= auto_level) && (spells_known[i][j] == FALSE))
		    {
		      borg_note (format ("I could gain book %c, spell %c (level %d)", 'a' + i, 'a' + j, splevel[auto_pclass][i][j]));
		      go_ahead = TRUE;
		    }
		}
	    }
	  if (go_ahead == FALSE)
	    {
	      borg_note ("Pity.. either gain some levels or get more books.");
	      do_gain_spells = FALSE;
	      do_browse_books = FALSE;
	      return (FALSE);	/* new goal */
	    }

	  /* actual gaining */
	  borg_note ("Whoopie! Gaining a new spell/prayer!");
	  if (auto_sclass == SCLASS_MAGE)
	    {
	      borg_keypress ('G');
	      borg_keypress ('a');
	      borg_keypress (ESCAPE);
	    }
	  else
	    {			/* priest */
	      borg_keypress ('G');
	    }
	  /* restart the process of gaining spells and fit in the new one */
	  do_gain_spells = TRUE;
	  do_browse_books = TRUE;
	  current_book = 0;
	  known_spells = 0;
	  return (TRUE);
	}
    }

  /* known_spells = 0; test further */

  /* still need the books and the levels */
  j = 0;
  for (i = 0; i < 9; i++)
    {
      if ((auto_sclass == SCLASS_MAGE) && (kind_have[kind_magic_books[i]] != 0))
	j++;
      if ((auto_sclass == SCLASS_PRIEST) && (kind_have[kind_prayer_books[i]] != 0))
	j++;
    }
  if (j == 0)
    {
      borg_oops ("OOPS! Borg can't find *any* spellbooks!");
      do_browse_books = FALSE;
      do_gain_spells = FALSE;
      nrbooks = 0;
      known_spells = 0;
      return (FALSE);
    }
  nrbooks = j;

  /* test: gain first spell */
  if (auto_level >= firstsplevel[auto_pclass])
    {
      borg_note ("*** Gaining my first spell :-) ***");
      /* copy gain code */
      if (auto_sclass == SCLASS_MAGE)
	{
	  borg_keypress ('G');
	  borg_keypress ('a');
	}
      else
	{			/* priest */
	  borg_keypress ('G');
	}
      /* restart the process of gaining spells and fit in the new one */
      do_gain_spells = TRUE;
      do_browse_books = TRUE;
      current_book = 0;
      known_spells = 0;
    }



  borg_note (format ("Have %d books", nrbooks));
  /* activate the routine to check 1st spellbook */

  borg_note ("Activating borg_think_browse()");
  current_book = 0;
  do_gain_spells = TRUE;
  do_browse_books = TRUE;
  return (FALSE);
}


/* fills known_spells; has to give keypresses, and read info. */
/* this routine parses the info from cmd5.c 's print_spells() */
/* the other half of this routine resides in borg_think() in borg-{ben,ew}.c */
EXTERN bool
borg_think_browse ()
{
  int spell;
  int i, j;
  char buf[128];
  byte t_a;
  int priestmage;
  static int trouble = 0;
  int letter;
  int thisbook, nextbook;

  /*
  static s32b timeout_browse;

  if (c_t - timeout_browse < 100*auto_level) {
     borg_note("Warning: too much spell browsing");
     do_browse_books=FALSE;
     return(FALSE);
  }
*/

  priestmage = ((auto_sclass == SCLASS_PRIEST) ? 0 : 1);
  nrbooks = 0;
  if (auto_sclass == SCLASS_MAGE)
    {
      for (j = 0; j < 9; j++)
	if (kind_have[kind_magic_books[j]] != 0)
	  nrbooks++;
    }
  else
    {
      for (j = 0; j < 9; j++)
	if (kind_have[kind_prayer_books[j]] != 0)
	  nrbooks++;
    }

  borg_note (format ("Entering borg_prepare_spells, current book=%d,nrbooks=%d", current_book, nrbooks));

  thisbook = -1;
  if (auto_sclass == SCLASS_MAGE)
    {
      for (i = 0; i < 9; i++)
	if (kind_magic_books[i] == auto_items[current_book].kind)
	  thisbook = i;
    }
  else
    {
      for (i = 0; i < 9; i++)
	if (kind_prayer_books[i] == auto_items[current_book].kind)
	  thisbook = i;
    }


  borg_note (format ("Checking all known spells from book %d ('%c')...", thisbook + 1, current_book + 'a'));
  /* do this only once; we need the books array info */
  for (spell = 0; spell < 9; spell++)
    {
      /* zero out buf */
      bzero (buf, 127);
      borg_what_text (COL_SPELLWIN, ROW_SPELLBOOK + spell + 1, 55, &t_a, buf);
      borg_note (format ("line %02d=[%s]", spell, buf));
      letter = buf[2];
      /* ( keep vi happy */
      if (buf[3] != ')')
	continue;
      if (letter - 'a' != spell)
	borg_note (format ("Hm. spell # is %d but letter '%c'", spell + 1, letter));
      /* 36 ev = level */
      if (strstr (buf, "unknown") == NULL)
	{
	  /* untried or known */
	  spells_known[thisbook][letter - 'a'] = TRUE;
	  known_spells++;
	  /*
	  if (strstr (buf, "untried") != NULL)
	    borg_note (format ("Untried: book %d ('%c') spell '%c'", thisbook + 1, current_book + 'a', letter));
	  borg_note (format ("Known: book %c spell '%c'", current_book + 'a', letter));
*/
	}

    }
  /* everything went OK */
  trouble = 0;
  current_book++;
  nextbook = -1;
  if (auto_sclass == SCLASS_MAGE)
    {
      for (i = 0; i < 9; i++)
	if (kind_magic_books[i] == auto_items[current_book].kind)
	  nextbook = i;
    }
  else
    {
      for (i = 0; i < 9; i++)
	if (kind_prayer_books[i] == auto_items[current_book].kind)
	  nextbook = i;
    }
  /* bail out here if next book unavailable */
  if (nextbook == -1)
    {
      borg_note ("*** all books checked ***");
      borg_keypress (ESCAPE);
      borg_keypress (' ');
      borg_keypress ('\n');
      do_browse_books = FALSE;
      current_book = 0;
      /*
      timeout_browse=c_t;
*/

      /* show us what you've learned */
      borg_note ("book avail?   spells");
      for (i = 0; i < 9; i++)
	{
	  sprintf (buf, " %1d  %c         . . . . . . . . . .", i + 1, ((books[i] == -1) ? 'n' : 'y'));
	  for (j = 0; j < 9; j++)
	    buf[14 + j * 2] = (spells_known[i][j] ? j + 'a' : ' ');
	  borg_note (format ("%s", buf));
	}
      /* goto kapermee; */
      return (FALSE);
    }
  else
    {
      do_browse_books = TRUE;
      borg_keypress (ESCAPE);

      /* check the next book */
      borg_note (format ("prepare_spells pressing ' b%c'", 'a' + current_book));
      return (TRUE);

    }
}



/* see cmd5.c for table in calc_spells() */
EXTERN int
maxknownspells (intwis, level)
     int intwis;
     int level;
{
  int spelllevs;
  /*  from tables.c, class_info[].
    mind that the ordering is a bit different here. */
  static int spellfirst[6] =
  {99, 1, 1, 5, 3, 1};

  spelllevs = level + 1 - spellfirst[auto_pclass];

  /* from stat_adj() in misc.c */
  if (intwis <= 7)
    return (0);			/* stat_adj = 0 */
  if (intwis <= 67)
    return (spelllevs);		/* stat_adj = 1,2,3 */
  if (intwis <= 107)
    return (3 * spelllevs / 2);	/* stat_adj = 4,5 */
  if (intwis <= 117)
    return (2 * spelllevs);	/* stat_adj = 6 */
  return (5 * spelllevs / 2);	/* stat_adj > 6 */
}



EXTERN bool
borg_cast_spell (book, spell)
     char book;
     char spell;
{
  int invbook = -1;
  int book_kind = -1;
  int i;

#ifdef FRITSDEBUG
  borg_note (format ("In routine borg_cast_spell({sclass %d},%c,%c)", auto_sclass, book, spell));
#endif /* FRITSDEBUG */

  /* check mana cost, prayer/spellbook available, etc.
	      return FALSE if not possible, TRUE if possible */
  /* no way to check if spell worked though */
  if (!borg_can_cast (book, spell))
    return (FALSE);

  if (auto_sclass == SCLASS_MAGE)
    book_kind = kind_magic_books[book - 'a'];
  if (auto_sclass == SCLASS_PRIEST)
    book_kind = kind_prayer_books[book - 'a'];
  for (i = 0; i < 9; i++)
    if (auto_items[i].kind == book_kind)
      invbook = i;

  /* not in town, in case of stores */
  /* HAAAAAAAAAAAAAAAAAAACK
  if ((do_inven) || (do_equip) || (do_panel) || (do_browse_books))
  {
      borg_note ("borg spellcast in illegal state");
      return (FALSE);
  }
*/
  /* HAAACK
  if (auto_depth == 0)
    {
      borg_note ("borg doesn't cast spells in town!");
      return (FALSE);
    }
*/

  if (auto_sclass == SCLASS_PRIEST)
    {
      borg_note (format ("Borg casting prayer '%c' from book '%c'", spell, book));
      borg_keypress ('p');
      borg_keypress ('a' + invbook);
      borg_keypress (spell);
      return (TRUE);
    }
  else
    {
      if (auto_sclass == SCLASS_MAGE)
	{
	  borg_note (format ("Borg casting spell '%c' from book '%c'", spell, book));
	  borg_keypress ('m');
	  borg_keypress ('a' + invbook);
	  borg_keypress (spell);
	  return (TRUE);
	}
    }

  return (FALSE);
}


/* This code is derived from Ben Harrison's borg_play_fire() routine */
EXTERN bool
borg_cast_spell_at (book, spell, x2, y2)
     char book;
     char spell;
     int x2, y2;
{
  int x1 = c_x, y1 = c_y;

  auto_grid *ag;

  /* not in town, in case of stores */
  if (auto_depth == 0)
    {
      borg_note ("borg doesn't cast spells in town!");
      return (FALSE);
    }

  /* Only a two in five chance */
  if (rand_int (5) > 1)
    return (FALSE);

  /* Paranoia -- Must be "on screen" */
  if (!panel_contains (y2, x2))
    return (FALSE);

  /* Must not be adjacent */
  if (distance (y1, x1, y2, x2) <= 1)
    return (FALSE);

  /* Must not be too far away */
  if (distance (y1, x1, y2, x2) > 10)
    return (FALSE);

  /* Must have "missile line of sight" */
  if (!borg_projectable (y1, x1, y2, x2))
    return (FALSE);


  /* XXX Hack -- do not "fire" at mushrooms/skeletons */
  ag = grid (x2, y2);
  if (ag->o_c == ',')
    return (FALSE);
  if (ag->o_c == 's')
    return (FALSE);

  if (borg_can_cast (book, spell) == FALSE)
    return (FALSE);

  borg_note (format ("Casting spell from (%d,%d) at (%d,%d)", c_x, c_y, x2, y2));

  /* Use that spellbook/prayerbook! */
  if (auto_sclass == SCLASS_PRIEST)
    borg_keypress ('p');
  else if (auto_sclass == SCLASS_MAGE)
    borg_keypress ('m');
  borg_keypress ('a' + current_book);
  borg_keypress (spell);

  /* Target the location */
  borg_keypress ('*');
  borg_keypress ('p');

  /* Start at the player */
  x1 = c_x;
  y1 = c_y;

  /* Move to the location */
  for (; y1 < y2; y1++)
    borg_keypress ('2');
  for (; y1 > y2; y1--)
    borg_keypress ('8');
  for (; x1 < x2; x1++)
    borg_keypress ('6');
  for (; x1 > x2; x1--)
    borg_keypress ('4');

  /* Select the target */
  borg_keypress ('t');

  /* Success */
  return (TRUE);
}


EXTERN bool
borg_cast_spell_oninv (book, spell, invitem)
     char book;
     char spell;
     int invitem;
{

#ifdef FRITSDEBUG
  borg_note (format ("In routine borg_cast_spell_oninv({sclass %d},%c,%c)", auto_sclass, book, spell));
#endif /* FRITSDEBUG */

  /* check mana cost, prayer/spellbook available, etc.
	      return FALSE if not possible, TRUE if possible */
  /* no way to check if spell worked though */
  if (borg_can_cast (book, spell) == FALSE)
    return (FALSE);

  /* not in town, in case of stores */
  if (auto_depth == 0)
    {
      borg_note ("borg doesn't cast spells in town!");
      return (FALSE);
    }

  if (auto_sclass == SCLASS_PRIEST)
    {
      borg_note (format ("Borg casting prayer '%c' from book '%c' on inv. item '%c'", spell, book, invitem));
      borg_keypress ('p');
      borg_keypress ('a' + current_book);
      borg_keypress (spell);
      borg_keypress (invitem);
      return (TRUE);
    }
  else
    {
      if (auto_sclass == SCLASS_MAGE)
	{
	  borg_note (format ("Borg casting spell '%c' from book '%c' on inv. item '%c'", spell, book, invitem));
	  borg_keypress ('m');
	  borg_keypress ('a' + current_book);
	  borg_keypress (spell);
	  borg_keypress (invitem);
	  return (TRUE);
	}
    }

  return (FALSE);
}


/* current_book is the inventory item; book is the spellbook type */
EXTERN bool
borg_can_cast (book, spell)
     char book;
     char spell;
{
  int cost;

  /* check confused/blind */
  if (do_confused | do_blind)
    {
      borg_note (format ("borg can't cast book '%c' spell '%c': blind/confused",
			 book, spell));
      return (FALSE);
    }

  /* not in town, in case of stores; but this code moved to actual spell procs */

  /* check mana */
  cost = manacost[auto_pclass][book - 'a'][spell - 'a'];
  if (auto_curmana < cost)
    {
      /* generates LOADS of unnecessary messages */
      /*
      borg_note (format ("borg can't cast book '%c' spell '%c': cost %d, mana %d",
			 book, spell, cost, auto_curmana));
*/
      return (FALSE);
    }

  /* check spellbook -- in actual routine, current_book is reused. */
  if (((auto_sclass == SCLASS_MAGE) && (kind_have[kind_magic_books[book - 'a']] == 0)) ||
    ((auto_sclass == SCLASS_PRIEST) && (kind_have[kind_prayer_books[book - 'a']] == 0)))
    return (FALSE);

  /* check spell known */
  return (spells_known[book - 'a'][spell - 'a']);

}

/* try cast an aggressive spell at a monster */
/* make sure that:
   1) you have some mana left to flee etc.
   2) don't cast spells too often that have a destructive effect on 
      nice items lying around (acid ball, etc.)

   Actually, this routine is *crap*.
   should take care of the victim's:
  - number; ball spells, dispel spells
  - elemental resistances
*/
EXTERN bool
borg_cast_aggressive_spell ()
{

  switch (auto_pclass)
    {
    case PCLASS_WARRIOR:
      return (FALSE);
      break;

    case PCLASS_MAGE:
      if ((auto_curmana > 51) && (borg_can_cast('i','f')))
	return (borg_cast_spell_target ('i', 'f'));	/* Mana Storm! */
      if ((auto_curmana > 41) && (borg_can_cast('i','e')))
	return (borg_cast_spell_target ('i', 'e'));	/* Meteor Swarm */
      if ((auto_curmana > 31) && (borg_can_cast('i','d')) && (rand_int(5)==0))
	return (borg_cast_spell_target ('i', 'd'));	/* Ice Storm */
      if ((auto_curmana > 21) && (borg_can_cast('i','c')) && (rand_int(20)==0))
	return (borg_cast_spell_target ('i', 'c'));	/* Acid Ball */
      if ((auto_curmana > 15) && (borg_can_cast('i','b')))
	return (borg_cast_spell_target ('i', 'b'));	/* Cloud Kill */
      if ((auto_curmana > 12) && (borg_can_cast('i','a')) && (rand_int(4)==0))
	return (borg_cast_spell_target ('i', 'a'));	/* Acid Bolt */
      if ((auto_curmana > 24) && (borg_can_cast('d','e')) && (rand_int(10)==0))
	return (borg_cast_spell_target ('d', 'e'));	/* Fire Ball */
      if ((auto_curmana > 18) && (borg_can_cast('d','a')) && (rand_int(5)==0))
	return (borg_cast_spell_target ('d', 'a'));	/* Frost Ball */
      if ((auto_curmana > 15) && (borg_can_cast('c','g')))
	return (borg_cast_spell_target ('c', 'g'));	/* Fire Bolt */
      if ((auto_curmana > 12) && (borg_can_cast('b','h')))
	return (borg_cast_spell_target ('b', 'h'));	/* Frost Bolt */
      if ((auto_curmana > 12) && (borg_can_cast('b','g')) && (rand_int(10)==0))
	return (borg_cast_spell_target ('b', 'g'));	/* Spear of Light */
      if ((auto_curmana > 10) && (borg_can_cast('b','b')))
	return (borg_cast_spell_target ('b', 'b'));	/* Lightning Bolt */
      if ((auto_curmana > 9) && (borg_can_cast('a','i')))
	return (borg_cast_spell_target ('a', 'i'));	/* Stinking Cloud */
      return (borg_cast_spell_target ('a', 'a'));	/* Magic Missile */
      break;

    case PCLASS_ROGUE:
      if ((auto_curmana > 29) && (borg_can_cast('i','b')))	/* Cloud Kill */
      return (borg_cast_spell('i','b'));
      if ((auto_curmana > 25) && (borg_can_cast('i','a')))	/* Acid Bolt */
      return (borg_cast_spell('i','a'));
      if ((auto_curmana > 19) && (borg_can_cast('b','g')) && (rand_int(10)==0))
	return (borg_cast_spell_target ('b', 'g'));	/* Spear of Light */
      break;

    case PCLASS_PRIEST:
      if ((auto_curmana > 70) && (rand_int (6) == 0))
	if ((borg_cast_spell_target ('i', 'e')) == TRUE)
	  return (TRUE);	/* Annihilation! */
      if ((auto_curmana > 14) && (rand_int (3) == 0))
	if ((borg_cast_spell_target ('i', 'b')) == TRUE)
	  return (TRUE);	/* *Dispel Evil* */
      if (auto_curmana > 10)
	return (borg_cast_spell_target ('c', 'b'));	/* Orb of Draining */
      /* hey, not much of an aggressive spell, but what the heck */
      return (borg_cast_spell_target ('b', 'a'));	/* Blind Creature */
      break;

    case PCLASS_RANGER:
      if ((auto_curmana > 60) && (borg_can_cast('i','e')))
	return (borg_cast_spell_target ('i', 'e'));	/* Meteor Swarm */
      if ((auto_curmana > 45) && (borg_can_cast('i','d')))
	return (borg_cast_spell_target ('i', 'd'));	/* Ice Storm */
      if ((auto_curmana > 35) && (borg_can_cast('i','c')) && (rand_int(20)==0))
	return (borg_cast_spell_target ('i', 'c'));	/* Acid Ball */
      if ((auto_curmana > 29) && (borg_can_cast('i','b')))
	return (borg_cast_spell_target ('i', 'b'));	/* Cloud Kill */
      if ((auto_curmana > 26) && (borg_can_cast('i','a')) && (rand_int(4)==0))
	return (borg_cast_spell_target ('i', 'a'));	/* Acid Bolt */
      if ((auto_curmana > 35) && (borg_can_cast('d','e')) && (rand_int(10)==0))
	return (borg_cast_spell_target ('d', 'e'));	/* Fire Ball */
      if ((auto_curmana > 31) && (borg_can_cast('d','a')) && (rand_int(5)==0))
	return (borg_cast_spell_target ('d', 'a'));	/* Frost Ball */
      if ((auto_curmana > 30) && (borg_can_cast('c','g')))
	return (borg_cast_spell_target ('c', 'g'));	/* Fire Bolt */
      if ((auto_curmana > 22) && (borg_can_cast('b','h')))
	return (borg_cast_spell_target ('b', 'h'));	/* Frost Bolt */
      if ((auto_curmana > 21) && (borg_can_cast('b','g')) && (rand_int(10)==0))
	return (borg_cast_spell_target ('b', 'g'));	/* Spear of Light */
      if ((auto_curmana > 17) && (borg_can_cast('b','b')))
	return (borg_cast_spell_target ('b', 'b'));	/* Lightning Bolt */
      if ((auto_curmana > 15) && (borg_can_cast('a','i')))
	return (borg_cast_spell_target ('a', 'i'));	/* Stinking Cloud */
      return (borg_cast_spell_target ('a', 'a'));	/* Magic Missile */
      break;

    case PCLASS_PALADIN:
      if ((auto_curmana > 90) && (rand_int (6) == 0))
	if ((borg_cast_spell_target ('i', 'e')) == TRUE)
	  return (TRUE);	/* Annihilation! */
      if ((auto_curmana > 40) && (rand_int (3) == 0))
	if ((borg_cast_spell_target ('i', 'b')) == TRUE)
	  return (TRUE);	/* *Dispel Evil* */
      if (auto_curmana > 22)
	return (borg_cast_spell_target ('c', 'b'));	/* Orb of Draining */
      /* else */
      return (borg_cast_spell_target ('b', 'a'));	/* Blind Creature */
      break;
    }

  return (FALSE);
}

/* find out more about the surroundings */
EXTERN bool
borg_cast_detection_spell ()
{

  switch (auto_pclass)
    {
    case PCLASS_WARRIOR:
      return (FALSE);
      break;

    case PCLASS_MAGE:
    case PCLASS_RANGER:
      return (borg_cast_spell ('a', 'h'));	/* Detect Traps/Doors */
      break;

    case PCLASS_ROGUE:
      switch (rand_int (10))
	{
	case 0:
	case 1:
	case 2:
	case 3:
	case 4:
	  return (borg_cast_spell ('a', 'h'));	/* Detect Traps/Doors */
	  break;
	case 5:
	case 6:
	  return (borg_cast_spell ('a', 'g'));	/* Object Detection */
	  break;
	case 7:
	case 8:
	  return (borg_cast_spell ('a', 'e'));	/* Treasure Detection */
	  break;
	default:
	  return (FALSE);
	  break;
	}
      break;

    case PCLASS_PRIEST:
    case PCLASS_PALADIN:
      if ((rand_int (100) == 0) && (auto_curmana > 100) && (borg_can_cast ('f','e')))
	return (borg_cast_spell ('f', 'e'));	/* Clairvoyance */
      if ((rand_int (50) == 0) && (auto_curmana > 40) && (borg_can_cast ('c','g')))
	return (borg_cast_spell ('c', 'g'));	/* Sense Surroundings */
      if ((rand_int (30) == 0) && (auto_curmana > 40) && (borg_can_cast ('c','d')))
	return (borg_cast_spell ('c', 'd'));	/* Sense Invisible */
      if (rand_int (3) == 0)
	return (borg_cast_spell ('a', 'f'));	/* Find Traps */
      else
	return (borg_cast_spell ('a', 'g'));	/* Detect Doors/stairs */
      break;
    }

  return (FALSE);
}

/* Protection from Evil, Haste Self */
/* the one argument is c_t, for we want to know how many ticks have passed */
EXTERN bool
borg_cast_preventive_spell ()
{
  static long last_time_protevil;
  long timeout_protevil;
  static long last_time_resist_h_c;
  long timeout_resist_h_c;

  static long last_time_haste;
  long timeout_haste;

  switch (auto_sclass)
    {
    case SCLASS_NONE:
      return (FALSE);
      break;

    case SCLASS_MAGE:
      timeout_haste = c_t - last_time_haste;
      if (timeout_haste < 100)
	return (FALSE);

      if (borg_can_cast ('d', 'd') && (auto_curmana > 30))
	{
	  last_time_haste = c_t;
	  return (borg_cast_spell ('d', 'd'));	/* Haste Self */
	}
      break;

    case SCLASS_PRIEST:
      timeout_protevil = c_t - last_time_protevil;
      if (timeout_protevil < 100)
	return (FALSE);

      if (borg_can_cast ('c', 'e') && (auto_curmana > 30))
	{
	  last_time_protevil = c_t;
	  return (borg_cast_spell ('c', 'e'));	/* Protection from Evil */
	}

      timeout_resist_h_c = c_t - last_time_resist_h_c;
      if (timeout_resist_h_c < 100)
	return (FALSE);
      if (borg_can_cast ('b', 'h') && (auto_curmana > 30))
	{
	  last_time_resist_h_c = c_t;
	  return (borg_cast_spell ('b', 'h'));	/* Resist heat/cold */
	}
      break;

    }

  return (FALSE);
}

/* KLUDGE for aggressive spells */
EXTERN bool
borg_cast_spell_target (book, spell)
     char book;
     char spell;
{
  bool worked;

  worked = borg_cast_spell (book, spell);
  if (worked == TRUE)
    borg_keypress ('5');
  return (worked);
}

/* these spells only cast in case of great need, so always do 'em */
EXTERN bool
borg_cast_teleport_spell ()
{

  switch (auto_sclass)
    {
    case SCLASS_NONE:
      return (FALSE);
      break;

    case SCLASS_MAGE:
      if (borg_can_cast ('b', 'f'))	/* Teleport */
	return (borg_cast_spell ('b', 'f'));
      else
	return (borg_cast_spell ('a', 'c'));	/* Phase Door */
      break;

    case SCLASS_PRIEST:
      if ((auto_curmana > 30) && (borg_can_cast ('e', 'b')))
	return (borg_cast_spell ('e', 'b'));	/* Teleport */
      return (borg_cast_spell ('b', 'b'));	/* Portal */
      break;

    }

  return (FALSE);
}

EXTERN bool
borg_cast_dinner_spell (void)
{

  switch (auto_sclass)
    {
    case SCLASS_MAGE:
      return (borg_cast_spell ('c', 'a'));	/* Satisfy Hunger */
      break;

    case SCLASS_PRIEST:
      return (borg_cast_spell ('b', 'f'));	/* Satisfy Hunger */
      break;
    }


  return (FALSE);
}

EXTERN bool borg_can_cast_dinner_spell(void)
{
if (borg_dont_need_food==TRUE) return(TRUE);
switch(auto_sclass) {
case SCLASS_MAGE:
if(borg_can_cast('c','a'))		/* Satisfy Hunger */
{
borg_dont_need_food=TRUE;
borg_note("The borg will from now on not need any food anymore");
return(TRUE);
}
break;

case SCLASS_PRIEST:
if(borg_can_cast('b','f'))		/* Satisfy Hunger */
{
borg_dont_need_food=TRUE;
borg_note("The borg will from now on not need any food anymore");
return(TRUE);
}
break;

default:
return(FALSE); /* warrior */
break;
}
return(FALSE);
}


/* WARNING: this spell takes another argument (the inventory item) */
EXTERN bool
borg_cast_identify_spell (item)
     char item;
{

  switch (auto_sclass)
    {
    case SCLASS_MAGE:
      if (borg_can_cast ('c', 'e'))
	{
	  borg_cast_spell ('c', 'e');	/* Identify */
	  borg_keypress (item);
	  return (TRUE);
	}
      break;

    case SCLASS_PRIEST:
      if (borg_can_cast ('f', 'c'))
	{
	  borg_cast_spell ('f', 'c');	/* Perception */
	  borg_keypress (item);
	  return (TRUE);
	}
    }

  return (FALSE);
}

EXTERN bool borg_can_cast_identify_spell(void)
{
if (borg_dont_need_identify==TRUE) return(TRUE);

switch(auto_sclass) {
case SCLASS_MAGE:
if(borg_can_cast('c','e'))	/* Identify */
{
borg_dont_need_identify=TRUE;
borg_note("The borg will from now on not need any scrolls of identify anymore");
return(TRUE);
}
break;

case SCLASS_PRIEST:
if(borg_can_cast('f','c'))	/* Perception */
{
borg_dont_need_identify=TRUE;
borg_note("The borg will from now on not need any scrolls of identify anymore");
return(TRUE);
}
break;

default:	/* warrior */
return(FALSE);
break;
}

return(FALSE);
}

/* better not cast these spells in combat with the causer of the grief
   or you'll run out of mana swiftly.. */
EXTERN bool 
borg_cast_healing_spell ()
{
  if (auto_sclass == SCLASS_NONE)	/* warriors don't cast any */
    return (FALSE);

  /* Fear */
  if ((do_afraid) && (auto_sclass == SCLASS_PRIEST) && (borg_can_cast ('a', 'd')))
    return (borg_cast_spell ('a', 'd'));	/* Remove Fear */

  /* Poison */
  if (do_poisoned)
    {
      if (auto_sclass == SCLASS_MAGE)
	{
	  return (borg_cast_spell ('b', 'e'));	/* Cure Poison */
	}
      if (auto_sclass == SCLASS_PRIEST)
	{
	  /* cure it ... */
	  if (borg_can_cast ('c', 'a'))
	    return (borg_cast_spell ('c', 'a'));	/* Neutralize Poison */
	  /* or else, slow it */
	  else
	    return (borg_cast_spell ('a', 'h'));	/* Slow Poison */
	}
    }

  /* Next ones are only for priests in possession of 'Purifications and Healing' */
  /* Since my borg-variant just found one I'll add them here :-) */

  /* Stat drain */
  if ((auto_sclass == SCLASS_PRIEST) && (borg_can_cast ('g', 'd')) &&
      ((do_fix_str) || (do_fix_int) || (do_fix_wis) || (do_fix_dex) || (do_fix_con) || (do_fix_chr)))
    return (borg_cast_spell ('g', 'd'));	/* Restoration */

  /* Exp drain */
  if ((auto_sclass == SCLASS_PRIEST) && (borg_can_cast ('g', 'e')) && (do_fix_exp) )
    return (borg_cast_spell ('g', 'e'));	/* Remembrance */


  /* nothing applicable */
  return (FALSE);
}

#endif /* FRITS */
#endif /* AUTO_PLAY */
