/*	global.c
 *
 *	raiselevel()		subroutine to raise the player one level
 *	loselevel()		subroutine to lower the player by one level
 *	raiseexperience(x)	subroutine to increase experience points
 *	loseexperience(x)	subroutine to lose experience points
 *	losehp(x)		subroutine to remove hit points from the player
 *	losemhp(x)		subroutine to remove max # hit points from 
 *				the player
 *	raisehp(x)		subroutine to gain hit points
 *	raisemhp(x)		subroutine to gain maximum hit points
 *	losespells(x)		subroutine to lose spells
 *	losemspells(x)		subroutine to lose maximum spells
 *	raisespells(x)		subroutine to gain spells
 *	raisemspells(x)		subroutine to gain maximum spells
 *	recalc()		function to recalculate the armor class of 
 *				the player
 *	makemonst(lev)		function to return monster number for a randomly
 *				selected monster
 *	positionplayer()	function to be sure player is not in a wall
 *	quit()			subroutine to ask if the player really wants 
 *				to quit
 *      has_object(object)      returns 0 or 1+index in iven[]
 *      nr_object(object)       returns number of objects of type object
 *      nr_obj_lst(n, liste)    returns number of objects of type objects in liste
 *      nr_obj_not(n, liste)    returns number of objects of type objects NOT in liste
 */

#include "header.h"
extern int score[],srcount,dropflag;
extern int random;/*	the random number seed			*/
extern short playerx,playery,lastnum;
extern char cheat,level,monstnamelist[];
extern char lastmonst[],*what[],*who[]; 
extern char winner[];
extern char logname[],monstlevel[];
extern char sciv[SCORESIZE+1][26][2],*potionname[],*scrollname[];
/*
	***********
	RAISE LEVEL
	***********
	raiselevel()

	subroutine to raise the player one level
	uses the skill[] array to find level boundarys
	uses c[EXPERIENCE]  c[LEVEL]
 */
raiselevel()
{
	if (c[LEVEL] < MAXPLEVEL) 
		raiseexperience((long)(skill[c[LEVEL]]-c[EXPERIENCE]));
}

/*
	***********
	LOOSE LEVEL
	***********
    loselevel()

	subroutine to lower the players character level by one
 */
loselevel()
{
	if (c[LEVEL] > 1) loseexperience((long)(c[EXPERIENCE] - skill[c[LEVEL]-1] + 1));
}

/*
 ****************
 RAISE EXPERIENCE
 ****************
 raiseexperience(x)
 
 subroutine to increase experience points
 */
raiseexperience(x)
     register long x;
{
  register int i,j;
  
  DEB1("Araiseexperience");
  i=c[LEVEL];	
  c[EXPERIENCE]+=x;
  while (c[EXPERIENCE] >= skill[c[LEVEL]] && (c[LEVEL] < MAXPLEVEL)) {
    j = (c[CONSTITUTION]-c[HARDGAME])>>1;
    c[LEVEL]++;	
    raisemhp((int)(rnd(3)+rnd((j>0)?j:1)));
    raisemspells((int)rund(3));
    if (c[LEVEL] < 7-c[HARDGAME]) 
      raisemhp((int)(c[CONSTITUTION]>>2));
  }
  ;DEB1("2raiseexperience");
  if (c[LEVEL] != i) {
    cursors();
    beep(); 
    lprintf("\nWelcome to level %d",(long)c[LEVEL]);	
    /* if we changed levels	*/
    switch (c[LEVEL]) {
    case 94:	/* earth guardian */
      c[WTW] = 99999L;
      break;
    case 95: 	/* air guardian */
      c[INVISIBILITY] = 99999L;
      break;
    case 96:	/* fire guardian */
      c[FIRERESISTANCE] = 99999L;
      break;
    case 97: 	/* water guardian */
      c[CANCELLATION] = 99999L;
      break;
    case 98: 	/* time guardian */
      c[HASTESELF] = 99999L;
      break;
    case 99:	/* ethereal guardian */
      c[STEALTH] = 99999L;
      c[SPIRITPRO] = 99999L;
      break;
    case 100:
      lprcat("\nYou are now The Creator ");
      DEB1("6araiseexp");
      for (i=0; i<MAXY; i++)
	for (j=0; j<MAXX; j++)  
	  know[j][i]=1;
      DEB1("6braiseexp");
      for (i=0; i<SPNUM; i++)	
	spelknow[i]=1;
      DEB1("6craiseexp");
      for (i=0; i<MAXSCROLL; i++)  {
	DEB1(scrollname[i]+1);
	scrollname[i][0]=' ';
      };
      DEB1("6draiseexp");
      for (i=0; i<MAXPOTION; i++) {
	DEB1(potionname[i]+1);  
	potionname[i][0]=' ';
      };
      DEB1("7raiseexperience");
      c[STEALTH] = 99999L;
      c[UNDEADPRO] = 99999L;
      c[SPIRITPRO] = 99999L;
      c[CHARMCOUNT] = 99999L;
      c[GIANTSTR] = 99999L;
      c[FIRERESISTANCE] = 99999L;
      c[DEXCOUNT] = 99999L;
      c[STRCOUNT] = 99999L;
      c[SCAREMONST] = 99999L;
      c[HASTESELF] = 99999L;
      c[CANCELLATION] = 99999L;
      c[INVISIBILITY] = 99999L;
      c[ALTPRO] = 99999L;
      c[WTW] = 99999L;
      c[AWARENESS] = 99999L;
      break;
    }
  }
  ;DEB1("Eraiseexperience");
}

/*
 ****************
 LOOSE EXPERIENCE
 ****************
 loseexperience(x)
 
 subroutine to lose experience points
 */
loseexperience(x)
     register long x;
{
  register int i,tmp;
  
  i=c[LEVEL];		
  c[EXPERIENCE]-=x;
  if (c[EXPERIENCE] < 0) c[EXPERIENCE]=0;
  while (c[EXPERIENCE] < skill[c[LEVEL]-1])
  {
    if (--c[LEVEL] <= 1) 
      c[LEVEL]=1;	/*	down one level		*/
    tmp = (c[CONSTITUTION]-c[HARDGAME])>>1;	/* lose hpoints */
    losemhp((int)rnd((tmp>0)?tmp:1));	/* lose hpoints */
    if (c[LEVEL] < 7-c[HARDGAME]) 
      losemhp((int)(c[CONSTITUTION]>>2));
    losemspells((int)rund(3));	/*	lose spells */
  }
  if (i!=c[LEVEL])
  {
    cursors();
    beep(); 
    lprintf("\nYou went down to level %d!",(long)c[LEVEL]);
  }
  bottomline();
}

/*
 ********
 LOOSE HP
 ********
 losehp(x)
 losemhp(x)
 
 subroutine to remove hit points from the player
 warning -- will kill player if hp goes to zero
 */
losehp(x)
     register int x;
{
  if ((c[HP] -= x) <= 0)
  {
    beep(); 
    lprcat("\n");  
    nap(3000);  
    died(lastnum);
  }
}

losemhp(x)
     register int x;
{
  c[HP] -= x;		
  if (c[HP] < 1)		
    c[HP]=1;
  c[HPMAX] -= x;	
  if (c[HPMAX] < 1)	
    c[HPMAX]=1;
}

/*
 ********
 RAISE HP
 ********
 raisehp(x)
 raisemhp(x)
 
 subroutine to gain maximum hit points
 */
raisehp(x)
     register int x;
{
  if ((c[HP] += x) > c[HPMAX]) c[HP] = c[HPMAX];
}

raisemhp(x)
     register int x;
{
  c[HPMAX] += x;	
  c[HP] += x;
}

/*
 ************
 RAISE SPELLS
 ************
 raisespells(x)
 raisemspells(x)
 
 subroutine to gain maximum spells
 */
raisespells(x)
     register int x;
{
  if ((c[SPELLS] += x) > c[SPELLMAX])	c[SPELLS] = c[SPELLMAX];
}

raisemspells(x)
     register int x;
{
  c[SPELLMAX]+=x; 
  c[SPELLS]+=x;
}

/*
 ************
 LOSE SPELLS
 ************
 losespells(x)
 losemspells(x)
 
 subroutine to lose maximum spells
 */
losespells(x)
     register int x;
{
  if ((c[SPELLS] -= x) < 0) c[SPELLS]=0;
}

losemspells(x)
     register int x;
{
  if ((c[SPELLMAX] -= x) < 0) c[SPELLMAX]=0;
  if ((c[SPELLS] -= x) < 0) c[SPELLS]=0;
}

/*
  makemonst(lev)
  int lev;
  
  function to return monster number for a randomly selected monster
  for the given cave level	
  */
makemonst(lev)
     register int lev;
{
  register int tmp,x;
  
  
  if (lev < 1)	
    lev = 1;
  if (lev > 12)	
    lev = 12;
  
  tmp=WATERLORD;
  
  if (lev < 5) 
    while (tmp==WATERLORD) 
      tmp=rnd(((x=monstlevel[lev-1])!=0)?x:1);
  
  else while (tmp==WATERLORD)
    tmp=rnd(((x=monstlevel[lev-1]-monstlevel[lev-4])!=0)?x:1)
      +monstlevel[lev-4];
  
  while (monster[tmp].genocided && tmp<MAXMONST) tmp++; /* genocided? */
  
  if (level < 16)
    if (rnd(100)<10) tmp=LEMMING;
  
  return(tmp);
}

/*
  positionplayer()
  
  function to be sure player is not in an object (wall etc.)
  */
positionplayer()
{
  int try;
  try = 2;
  
  while ( try && ( item[playerx][playery] || mitem[playerx][playery] ) )
    if (++playerx >= MAXX-1)
    {
      playerx = 1;
      if (++playery >= MAXY-1)
      {	
	playery = 1;	
	--try;	
      }
    }
  if (try==0)	 lprcat("Failure in positionplayer\n");
}

/*
  recalc()	function to recalculate the armor class of the player etc.
  */
recalc()
{
  register int i;
  
  DEB1("Arecalc");
  c[AC] = c[MOREDEFENSES];
  if (c[WEAR] >= 0)
    switch(iven[c[WEAR]]) {
    case OSHIELD:		
      c[AC] += 2 + ivenarg[c[WEAR]]; 
      break;
    case OLEATHER:		
      c[AC] += 2 + ivenarg[c[WEAR]]; 
      break;
    case OSTUDLEATHER:	
      c[AC] += 3 + ivenarg[c[WEAR]]; 
      break;
    case ORING:			
      c[AC] += 5 + ivenarg[c[WEAR]]; 
      break;
    case OCHAIN:		
      c[AC] += 6 + ivenarg[c[WEAR]]; 
      break;
    case OSPLINT:		
      c[AC] += 7 + ivenarg[c[WEAR]]; 
      break;
    case OPLATE:		
      c[AC] += 9 + ivenarg[c[WEAR]]; 
      break;
    case OPLATEARMOR:	
      c[AC] += 10 + ivenarg[c[WEAR]]; 
      break;
    case OSSPLATE:		
      c[AC] += 12 + ivenarg[c[WEAR]]; 
      break;
    case OELVENCHAIN:
      c[AC] += 15 + ivenarg[c[WEAR]]; 
      break;
    }
  ;DEB1("5recalc");
  if (c[SHIELD] >= 0) if (iven[c[SHIELD]] == OSHIELD) c[AC] += 2 + ivenarg[c[SHIELD]];
  if (c[WIELD] < 0)  c[WCLASS] = 0;  
  else {
    i = ivenarg[c[WIELD]];
    switch(iven[c[WIELD]]) {
    case ODAGGER:    
      c[WCLASS] =  3 + i;  
      break;
    case OBELT:
      c[WCLASS] =  7 + i;  
      break;
    case OSHIELD:	 
      c[WCLASS] =  8 + i;  
      break;
    case OPSTAFF:
    case OSPEAR:     
      c[WCLASS] = 10 + i;  
      break;
    case OFLAIL:     
      c[WCLASS] = 14 + i;  
      break;
    case OBATTLEAXE: 
      c[WCLASS] = 17 + i;  
      break;
    case OLANCE:	 
      c[WCLASS] = 20 + i;  
      break;
    case OLONGSWORD: 
      c[WCLASS] = 22 + i;  
      break;
    case O2SWORD:    
      c[WCLASS] = 26 + i;  
      break;
    case OSWORDofSLASHING: 
      c[WCLASS] = 30 + i; 
      break;
    case OSLAYER:	 
      c[WCLASS] = 30 + i; 
      break;
    case OSWORD:     
      c[WCLASS] = 32 + i;  
      break;
    case OHAMMER:    
      c[WCLASS] = 35 + i;  
      break;
    default:	     
      c[WCLASS] = 0;
    }
  }
  c[WCLASS] += c[MOREDAM];
  DEB1("7recalc");
  /*	now for abilities based on rings	*/
  c[REGEN]=1;		
  c[ENERGY]=0;
  ;DEB1("8recalc");
  for (i=0; i < NINVT; i++) {
    switch(iven[i]) {
    case OPROTRING: 
      c[AC]     += ivenarg[i] + 1;	
      break;
    case ODAMRING:  
      c[WCLASS] += ivenarg[i] + 1;	
      break;
    case OBELT:     
      c[WCLASS] += ((ivenarg[i]<<1)) + 2;	
      break;
      
    case OREGENRING:	
      c[REGEN]  += ivenarg[i] + 1;	
      break;
    case ORINGOFEXTRA:	
      c[REGEN]  += 5 * (ivenarg[i]+1); 
      break;
    case OENERGYRING:	
      c[ENERGY] += ivenarg[i] + 1;	
      break;
    }
  }
  ;DEB1("Erecalc");
}

/*
  quit()
  
  subroutine to ask if the player really wants to quit
  */
quit()
{
  register int i;
  
  cursors();
  strcpy(lastmonst,"");
  lprcat("\n\nDo you really want to quit? (y)es, (n)o, (s)ave");
  while (1) {
    i=getcharacter();
    if ( (i == 'y') || (i == 'Y') )	{ 
      died(300); 
      return; 
    } else if ( (i == 'n') || (i == 'N') || (i == '\33') )	{ 
      lprcat(" no"); 
      lflush(); 
      return; 
    } else if ( (i == 's') || (i == 'S') ) {
      lprcat(" save");
      lflush();
      clear();  
      lprcat("Saving . . ."); 
      lflush();  
      savegame(savefilename); 
      wizard=1; 
      died(-257);
    } else {
      lprcat("\n");  
      if (boldon) setbold();  
      lprcat("Yes");  
      if (boldon) resetbold();  
      lprcat(" ");
      if (boldon) setbold();  
      lprcat("Save");
      if (boldon) resetbold();  
      lprcat(" or ");
      if (boldon) setbold();  
      lprcat("No");  
      if (boldon) resetbold();  
      lprcat(" please?   Do you want to quit? ");
    };
  }
}

/*
  function to ask --more-- then the user must enter a space
  */
more()
{
  lprcat("\n  --- press ");  
  standout("space");  
  lprcat(" to continue --- ");
  while (getcharacter() != 0x20);
}

/*
  function to ask --more-- no checks
  */
morex(select)
{
  int res;
  
  if ( select ) {
    lprintf("\n  --- select one, press ");
    standout("Esc");
    lprcat(" to escape or ");  
    standout("space");  
    lprcat(" to continue --- ");
    res = getcharacter();
  }else{
    more();
    res = 0x20;
  };
  return ( res );
}

/*
  function to put something in the players inventory
  returns 0 if success, 1 if a failure
  */
take(itm,arg)
     int itm,arg;
{
  register int i,limit;
  
  /*	cursors(); */
  if ((limit = 15+(c[LEVEL]>>1)) > NINVT)  limit=NINVT;
  for (i=0; i<limit; i++)
    if (iven[i]==0) {
      iven[i] = itm;  
      ivenarg[i] = arg;  
      limit=0;
      switch(itm) {
      case OPROTRING:	
      case ODAMRING: 
      case OBELT: 	
	limit=1;  
	break;
      case ODEXRING:	
	c[DEXTERITY] += ivenarg[i]+1; 
	limit=1;	
	break;
      case OSTRRING:	
	c[STREXTRA]  += ivenarg[i]+1;
	limit=1; 
	break;
      case OCLEVERRING:
	c[INTELLIGENCE] += ivenarg[i]+1;
	limit=1; 
	break;
      case OHAMMER:	
	c[DEXTERITY] += 10;	
	c[STREXTRA]+=10;
	c[INTELLIGENCE]-=10;	
	limit=1;	 
	break;
      case OORB:	
	c[ORB]++;
	c[AWARENESS]++;
	break;
      case OORBOFDRAGON:
	c[SLAYING]++;		
	break;
      case OSPIRITSCARAB: 
	c[NEGATESPIRIT]++;	
	break;
      case OCUBEofUNDEAD: 
	c[CUBEofUNDEAD]++;	
	break;
      case ONOTHEFT:	
	c[NOTHEFT]++;		
	break;
      case OSWORDofSLASHING:	
	c[DEXTERITY] +=5;	
	limit=1; 
	break;
      case OSLAYER:
	c[INTELLIGENCE]+=10;
	break;
      case OPSTAFF:
	c[WISDOM]+=10;
	break;
      case  OLARNEYE:
	monstnamelist[DEMONLORD]   = '1';
	monstnamelist[DEMONLORD+1] = '2';
	monstnamelist[DEMONLORD+2] = '3';
	monstnamelist[DEMONLORD+3] = '4';
	monstnamelist[DEMONLORD+4] = '5';
	monstnamelist[DEMONLORD+5] = '6';
	monstnamelist[DEMONLORD+6] = '7';
	monstnamelist[DEMONPRINCE] = '9';
	monstnamelist[LUCIFER] = '0';
	break;
      };
      
      lprcat("\nYou pick up:"); 
      srcount=0;  
      (void) show3(i, 0);
      if (limit) bottomline();  
      return(0);
    }
  lprcat("\nYou can't carry anything else");  
  return(1);
}

/*
  subroutine to drop an object  returns 1 if something there already else 
  
  k is index into iven list of object to drop
  */

drop_object(k)
     int k;
{
  int itm;
  
  if ((k<0) || (k>=NINVT)) return(0);
  itm = iven[k];
  cursors();
  if (itm==0) { 
    lprintf("\nYou don't have item %c! ",k+'a'); 
    return(1); 
  }
  if (item[playerx][playery]) { 
    beep(); 
    lprcat("\nThere's something here already"); 
    return(1); 
  }
  if (playery==MAXY-1 && playerx==33) 
    return(1); /* not in entrance */
  
  item[playerx][playery] = itm;
  iarg[playerx][playery] = ivenarg[k];
  
  srcount=0; 
  lprcat("\n  You drop:"); 
  (void) show3(k, 0); /* show what item you dropped*/
  know[playerx][playery] = 0;  
  iven[k]=0;
  if (c[WIELD]==k) 
    c[WIELD]= -1;
  if (c[WEAR]==k)  
    c[WEAR] = -1;
  if (c[SHIELD]==k) 
    c[SHIELD]= -1;
  adjustcvalues(itm,ivenarg[k]);
  if (itm==OLANCE) recalc();
  /* say dropped an item so wont ask to pick it up right away */
  dropflag=1;
  return(0);
}

/*
  function to enchant armor player is currently wearing
  */
enchantarmor()
{
  register int tmp;
  if (c[WEAR]<0) { 
    if (c[SHIELD] < 0)
    { 
      cursors(); 
      beep(); 
      lprcat("\nYou feel a sense of loss"); 
      return; 
    }
    else { 
      tmp=iven[c[SHIELD]]; 
      if (tmp != OSCROLL) if (tmp != OPOTION) { 
	ivenarg[c[SHIELD]]++; 
	bottomline(); 
      } 
    } 
  }
  tmp = iven[c[WEAR]];
  if (tmp!=OSCROLL) if (tmp!=OPOTION)  { 
    ivenarg[c[WEAR]]++;  
    bottomline(); 
  }
}

/*
  function to enchant a weapon presently being wielded
  */
enchweapon()
{
  register int tmp;
  
  if (c[WIELD]<0) { 
    cursors(); 
    beep(); 
    lprcat("\nYou feel depressed"); 
    return; 
  }
  tmp = iven[c[WIELD]];
  if (tmp!=OSCROLL) if (tmp!=OPOTION) { 
    ivenarg[c[WIELD]]++;
    if (tmp==OCLEVERRING) c[INTELLIGENCE]++;  
    else
      if (tmp==OSTRRING)	c[STREXTRA]++;  
      else
	if (tmp==ODEXRING)    c[DEXTERITY]++;		  
    bottomline(); 
  }
}

/*
  routine to tell if player can carry one more thing
  returns 1 if pockets are full, else 0
  */
pocketfull()
{
  register int i,limit; 
  if ((limit = 15+(c[LEVEL]>>1)) > NINVT)  limit=NINVT;
  for (i=0; i<limit; i++) if (iven[i]==0) return(0);
  return(1);
}

/*
  function to return 1 if a monster is next to the player else returns 0
  */
nearbymonst()
{
  register int tmp,tmp2;
  for (tmp=playerx-1; tmp<playerx+2; tmp++)
    for (tmp2=playery-1; tmp2<playery+2; tmp2++)
      if (mitem[tmp][tmp2]) return(1); /* if monster nearby */
  return(0);
}

/*
  function to steal an item from the players pockets
  returns 1 if steals something else returns 0
  */
stealsomething()
{
  register int i,j;
  
  j=100;
  while (1) {
    i=rund(NINVT);
    if (iven[i]) if (c[WEAR]!=i) if (c[WIELD]!=i) if (c[SHIELD]!=i) {
      srcount=0; 
      (void) show3(i, 0);
      adjustcvalues(iven[i],ivenarg[i]);  
      iven[i]=0; 
      return(1);
    }
    if (--j <= 0) return(0);
  }
}

/*
  function to return 1 is player carrys nothing else return 0
  */
emptyhanded()
{
  register int i;
  
  for (i=0; i < NINVT; i++)
    if( (iven[i]) && (i!=c[WIELD]) && (i!=c[WEAR]) && (i!=c[SHIELD]) ) return(0);
  return(1);
}

/*
  function to create a gem on a square near the player
  */
creategem()
{
  register int i,j;
  switch(rnd(4))
  {
  case 1:	 
    i=ODIAMOND;	
    j=50;	
    break;
  case 2:	 
    i=ORUBY;		
    j=40;	
    break;
  case 3:	 
    i=OEMERALD;	
    j=30;	
    break;
  default: 
    i=OSAPPHIRE;	
    j=20;	
    break;
  };
  createitem(i,rnd(j)+j/10);
}

/*
  function to change character levels as needed when dropping an object
  that affects these characteristics
  */
adjustcvalues(itm,arg)
     int itm,arg;
{
  register int flag,i;
  
  flag=0;
  switch(itm) {
  case ODEXRING:	
    c[DEXTERITY] -= arg+1;  
    flag=1; 
    break;
  case OSTRRING:	
    c[STREXTRA]  -= arg+1;  
    flag=1; 
    break;
  case OCLEVERRING: 
    c[INTELLIGENCE] -= arg+1;  
    flag=1; 
    break;
  case OHAMMER:	
    c[DEXTERITY] -= 10;	
    c[STREXTRA] -= 10;
    c[INTELLIGENCE] += 10; 
    flag=1; 
    break;
  case OORB:	
    c[ORB]--;
    c[AWARENESS]--;
  case OSWORDofSLASHING:		
    c[DEXTERITY] -= 5;
    flag=1; 
    break;
  case OSLAYER:		
    c[INTELLIGENCE]-=10; 
    flag=1; 
    break;
  case OPSTAFF:		
    c[WISDOM]-=10; 
    flag=1;
    break;
  case OORBOFDRAGON:		
    --c[SLAYING];		
    return;
  case OSPIRITSCARAB:		
    --c[NEGATESPIRIT];	
    return;
  case OCUBEofUNDEAD:		
    --c[CUBEofUNDEAD];	
    return;
  case ONOTHEFT:			
    --c[NOTHEFT]; 		
    return;
  case OLANCE:			
    c[LANCEDEATH]=0;	
    return;
  case OLARNEYE: {
    char c = objnamelist[0];
    monstnamelist[DEMONLORD  ] = c;
    monstnamelist[DEMONLORD+1] = c;
    monstnamelist[DEMONLORD+2] = c;
    monstnamelist[DEMONLORD+3] = c;
    monstnamelist[DEMONLORD+4] = c;
    monstnamelist[DEMONLORD+5] = c;
    monstnamelist[DEMONLORD+6] = c;
    monstnamelist[DEMONPRINCE] = c;
    monstnamelist[LUCIFER]     = c;
    cursors();
    return;
  }
  case OPOTION:	
  case OSCROLL:	
    return;
    
  default:	
    flag=1;
  };
  if (flag) bottomline();
  
  for (i=0;i<6;i++)
    if (c[i] < 3)
      c[i] = 3;
}

/*
  function to read a string from token input "string"
  returns a pointer to the string
  */
gettokstr(str)
     register char *str;
{
  register int i,j;
  
  i=50;
  while ((getcharacter() != '"') && (--i > 0));
  i=36;
  while (--i > 0) {
    if ((j=getcharacter()) != '"') *str++ = j;  
    else i=0;
  }
  *str = 0;
  i=50;
  if (j != '"') while ((getcharacter() != '"') && (--i > 0)); /* if end due to too long, then find closing quote */
}

/*
  function to ask user for a password (no echo)
  returns 1 if entered correctly, 0 if not
  */
static char gpwbuf[33];

getpassword()
{
  register int i,j;
  register char *gpwp;
  extern char *password;
  
  scbr();	/*	system("stty -echo cbreak"); */
  gpwp = gpwbuf;	
  lprcat("\nEnter Password: "); 
  lflush();
  i = strlen(password);
  for (j=0; j<i; j++) read(0,gpwp++,1);	  
  gpwbuf[i]=0;
  sncbr(); /* system("stty echo -cbreak"); */
  if (strcmp(gpwbuf,password) != 0) {	
    lprcat("\nSorry\n");  
    lflush();
    return(0);
  }
  else  return(1);
}

/*
  subroutine to get a yes or no response from the user
  returns y or n
  */
getyn()
{
  register int i;
  
  i=0; 
  while (i!='y' && i!='n' && i!='\33') i=getcharacter();
  return(i);
}

/*
  function to calculate the pack weight of the player
  returns the number of pounds the player is carrying
  */
packweight()
{
  register int i,k;
  
  k=c[GOLD]/1000; 
  for (i=0; i < NINVT; i++)
    switch(iven[i]) {
    case OSSPLATE:   
    case OPLATEARMOR: 
      k += 40;
      break;
    case OPLATE:
      k += 35;	
      break;
    case OHAMMER:	
      k += 30;	
      break;
    case OSPLINT:	
      k += 26;	
      break;
      
    case OCHAIN:
    case OBATTLEAXE:   		
    case O2SWORD:		
      k += 23;	
      break;
      
    case OLONGSWORD:
    case OPSTAFF:
    case OSWORD:
    case ORING:
    case OFLAIL:		
      k += 20;	
      break;
      
    case OELVENCHAIN: 	
    case OSWORDofSLASHING:	
    case OLANCE:
    case OSLAYER:
    case OSTUDLEATHER:	
      k += 15;	
      break;
      
      
    case OLEATHER:
    case OSPEAR:		
      k += 8;		
      break;
      
    case OORBOFDRAGON:
    case OORB:
    case OBELT:		
      k += 4;		
      break;
      
    case OSHIELD:		
      k += 7;		
      break;
    case OCHEST:		
      k += 30 + ivenarg[i];	
      break;
    default:		
      k++;
    };
  return(k);
}


has_object(what)
     int    what;
{
  int i, res;
  
  res = -1;
  i = 0;
  while( !((i >= NINVT) || (res >= 0)) ){
    if( iven[i] == what ) res = i;
    i++;
  };
  return (res);
}


nr_object(what)
     int    what;
{
  int i, res;
  
  res = 0;
  for (i=0; i < NINVT; i++){
    if( ((what == ANYINVT) && (iven[i] != 0)) || (iven[i] == what) ) {
      res++;
    };
  };
  return (res);
}


nr_obj_lst(n, liste)
     int    n;
     int    liste[];
{
  int i, j, res;
  
  res = 0;
  for (i=0; i < NINVT; i++){
    for (j=0; j < n; j++){
      if( (iven[i] == liste[j]) ) {
	res++;
	j = n; /* terminate this loop */
      };
    };
  };
  return (res);
}



nr_obj_not(n, liste)
     int    n;
     int    liste[];
{
  int i, j, res, found;
  
  res = 0;
  for (i=0; i < NINVT; i++){
    if ( iven[i] != 0 ){
      found = 0;
      for (j=0; (j < n) && ! found; j++){
	found = (iven[i] == liste[j]);
      };
      if ( ! found ){
	res++;
      };
    };
  };
  return (res);
}









