[comp.sources.games] v07i035: omega3 - rogue like dungeon exploration

billr@saab.CNA.TEK.COM (Bill Randle) (07/14/89)

Submitted-by: "Laurence R. Brothers"   <brothers@paul.rutgers.edu>
Posting-number: Volume 7, Issue 35
Archive-name: omega3/Part16
Supersedes: omega2: Volume 5, Issue 12-29,38-40



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 16 (of 20)."
# Contents:  ochar.c omaze3.dat ommelee.c opriest.c outil.c
# Wrapped by billr@saab on Thu Jun 29 08:14:12 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'ochar.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ochar.c'\"
else
echo shar: Extracting \"'ochar.c'\" \(13968 characters\)
sed "s/^X//" >'ochar.c' <<'END_OF_FILE'
X/* omega copyright (C) by Laurence Raphael Brothers, 1987,1988,1989 */
X/* ochar.c */
X/* Player generation */
X
X#include "oglob.h"
X
X
X/* set player to begin with */
Xvoid initplayer()
X{
X   int i;
X   int oldchar=FALSE;
X   FILE *fd;
X
X   strcpy(Player.name,getlogin());
X   Player.itemweight = 0;
X   Player.food = 36; 
X   Player.packptr = 0;
X   Player.options = 0;
X   for (i=0;i<MAXITEMS;i++)
X     Player.possessions[i] = NULL;
X   for (i=0;i<MAXPACK;i++)
X     Player.pack[i] = NULL;
X   for (i=0;i<NUMIMMUNITIES;i++) Player.immunity[i] = 0;
X   for (i=0;i<NUMSTATI;i++) Player.status[i] = 0;
X   for (i=0;i<NUMRANKS;i++) {
X     Player.rank[i] = 0;
X     Player.guildxp[i] = 0;
X   }
X   Player.alignment = 0;
X   Player.cash = 250;
X   if ((fd=omegarc_check())!=NULL) {
X     fread((char *)&i,sizeof(int),1,fd);
X     if (i != VERSION) {
X#ifndef MSDOS
X       print1("Out of date .omegarc! Make another!");
X#else
X       print1("Out of date omega.rc! Make another!");
X#endif
X       morewait();
X     }
X     else {
X       oldchar = TRUE;
X       fread((char *)&Player,sizeof(Player),1,fd);
X       fread((char *)&Searchnum,sizeof(int),1,fd);
X       fread((char *)&Verbosity,sizeof(char),1,fd);
X       strcpy(Player.name,getlogin());
X     }
X     fclose(fd);
X   }
X   if (! oldchar) {
X     initstats();
X     optionset(RUNSTOP);
X     optionset(CONFIRM);
X   }
X   Searchnum = max(1,min(9,Searchnum));
X   Player.hp = Player.maxhp = Player.maxcon;
X   calc_melee();
X   Player.mana = Player.maxmana = calcmana();
X   Player.click = 1;
X   strcpy(Player.meleestr,"CCBC");
X   dataprint();
X }
X
X
XFILE *omegarc_check()
X{
X  FILE *fd;
X#ifndef MSDOS
X  strcpy(Str3,".omegarc");
X#else
X  strcpy(Str3,"omega.rc");
X#endif
X  if ((fd = fopen(Str3,"r")) != NULL) {
X#ifndef MSDOS
X    print2("Use .omegarc in wd? [yn] ");
X#else
X    print2("Use omega.rc in wd? [yn] ");
X#endif
X    if (ynq2()!='y') fd = NULL;
X  }
X  clearmsg();
X  return(fd);
X}
X
Xvoid initstats()
X{
X  char response;
X  print1("Do you want to run a character [c] or play yourself [p]?");
X  do response = mcigetc(); while ((response!='c')&&(response != 'p'));
X  if (response == 'c') omegan_character_stats();
X  else {
X    user_character_stats();
X    user_intro();
X#ifndef MSDOS
X    print1("Do you want to save this set-up to .omegarc in this wd? [yn] ");
X#else
X    print1("Do you want to save this set-up to omega.rc in this wd? [yn] ");
X#endif
X    if (ynq1()=='y')
X      save_omegarc();
X  }
X  xredraw();
X}
X
Xvoid save_omegarc()
X{
X#ifndef MSDOS
X  FILE *fd = fopen(".omegarc","w");
X#else
X  FILE *fd = fopen("omega.rc","w");
X#endif
X  int i=VERSION;
X  if (fd == NULL)
X#ifndef MSDOS
X    print1("Sorry, couldn't save .omegarc for some reason.");
X#else
X    print1("Sorry, couldn't save omega.rc for some reason.");
X#endif
X  else {
X    fwrite((char *)&i,sizeof(int),1,fd);
X    print1("First, set options.");
X    setoptions();
X    fwrite((char *)&Player,sizeof(Player),1,fd);
X    fwrite((char *)&Searchnum,sizeof(int),1,fd);
X    fwrite((char *)&Verbosity,sizeof(char),1,fd);
X    fclose(fd);
X  }
X}
X
X
X
X#ifndef MSDOS
Xint calcmana()
X#else
Xlong calcmana()
X#endif
X{
X#ifndef MSDOS
X  return(Player.pow * (Player.level+1));
X#else
X  return(Player.pow * (long)(Player.level+1));
X#endif
X}
X
X
X/*  npcbehavior digits 1234
X
X4 : alignment (LAWFUL,CHAOTIC, or NEUTRAL)
X3 : primary combat action (melee,missile,spell,thief,flight,1..5)
X2 : competence at 4 (0..9, 0 = incompetent, 9 = masterful)
X1 : conversation mode
X
Xstatus : 1 = dead, 2 = saved, 3 = retired
X*/
Xint fixnpc(status)
Xint status;
X{
X  int npcbehavior=0;
X  char response;
X  if (status == 1) { /* player is dead, all undead are chaotic */
X    npcbehavior+=CHAOTIC;
X    npcbehavior+=10; /* melee */
X    npcbehavior+=100*min(9,((int) (Player.level/3)));
X    npcbehavior+=3000; /* evil */
X  }
X  else {
X    clearmsg();
X    print1("NPC Behavior Determination Module");
X    menuclear();
X    menuprint("Your overall NPC behavior is:");
X    if (Player.alignment < -10) {
X      npcbehavior += CHAOTIC;
X      menuprint("\n\n CHAOTIC");
X    }
X    else if (Player.alignment > 10) {
X      npcbehavior += LAWFUL;
X      menuprint("\n\n LAWFUL");
X    }
X    else {
X      npcbehavior += NEUTRAL;
X      menuprint("\n\n NEUTRAL");
X    }
X    menuprint("\n\n1: hand-to-hand combat");
X    menuprint("\n2: missile combat");
X    menuprint("\n3: spellcasting");
X    menuprint("\n4: thieving");
X    menuprint("\n5: escape");
X    menuprint("\n\nEnter NPC response to combat: ");
X    response = '0';
X    while ((response != '1') && 
X	   (response != '2') &&
X	   (response != '3') &&
X	   (response != '4') &&
X	   (response != '5'))
X      response = menugetc();
X    menuaddch(response);
X    npcbehavior+=10*(response - '0');
X    npcbehavior+=100*competence_check(response-'0');
X    response = '0';
X    menuclear();
X    menuprint("1: threaten");
X    menuprint("\n2: greet");
X    menuprint("\n3: aid");
X    menuprint("\n4: beg");
X    menuprint("\n5: silence");
X    menuprint("\n\nEnter NPC response to conversation: ");
X    while ((response != '1') && 
X	   (response != '2') &&
X	   (response != '3') &&
X	   (response != '4') &&
X	   (response != '5'))
X      response = menugetc();
X    menuaddch(response);
X    npcbehavior+=1000*(response - '0');
X    xredraw();
X  }
X    return(npcbehavior);
X}
X
X
X/* estimates on a 0..9 scale how good a player is at something */
Xint competence_check(attack)
Xint attack;  
X{
X  int ability = 0;
X  switch(attack) {
X  case 1: /* melee */
X    ability += statmod(Player.str);
X  case 2: /* missle */
X    ability += statmod(Player.dex);
X    ability += Player.rank[LEGION];
X    ability += ((int) (Player.dmg / 10) - 1);
X    break;
X  case 3: /* spellcasting */
X    ability += statmod(Player.iq);
X    ability += statmod(Player.pow);
X    ability += Player.rank[CIRCLE];
X    ability += Player.rank[COLLEGE];
X    ability += Player.rank[PRIEST];
X    break;
X  case 4: /* thieving */
X    ability += statmod(Player.dex);
X    ability += statmod(Player.agi);
X    ability += Player.rank[THIEVES];
X    break;
X  case 5: /* escape */
X    ability += 2 * statmod(Player.agi);
X    break;
X  }
X  ability += ((int) (Player.level / 5));
X  if (ability < 0) ability = 0;
X  if (ability > 9) ability = 9;
X  return(ability);
X}
X
Xvoid user_character_stats()
X{
X  int num,iqpts=0,numints=0,ok,agipts=0,dexpts=0,powpts=0,conpts=0;
X  print1("OK, now try to answer honestly the following questions:");
X  morewait();
X  print1("How many pounds can you bench press? ");
X  num = parsenum();
X  if (num < 30) Player.str = Player.maxstr = 3;
X  else if (num < 90) Player.str = Player.maxstr = num/10;
X  else Player.str = Player.maxstr = 9+((num-120)/30);
X  if (Player.str > 18) {
X    print2("Even if it's true, I don't believe it.");
X    morewait();
X    clearmsg();
X    Player.str = Player.maxstr = 18;
X  }
X  
X  print1("Took an official IQ test? [yn] ");
X  if (ynq1()=='y') {
X    print1("So, whadja get? ");
X    num = parsenum()/10;
X    if (num > 18) {
X      print2("Even if it's true, I don't believe it.");
X      morewait();
X      clearmsg();
X      num = 18;
X    }
X    iqpts+=num;
X    numints++;
X  }
X
X  print1("Took Undergraduate entrance exams? [yn] ");
X  if (ynq1()=='y') {
X    do {
X      print1("So, what percentile? ");
X      num = parsenum();
X      ok = (num < 100);
X      if (! ok) {
X	print2("That's impossible!");
X	morewait();
X	clearmsg();
X      }
X    } while (! ok);
X    iqpts += (int) ((((num - 49)/50.0)*9)+9);
X    numints++;
X  }
X  print1("Took Graduate entrance exams? [yn] ");
X  if (ynq1()=='y') {
X    do {
X      print1("So, what percentile? ");
X      num = parsenum();
X      ok = (num < 100);
X      if (! ok) {
X	print2("That's impossible!");
X	morewait();
X	clearmsg();
X      }
X    } while (! ok);
X    iqpts += (int) ((((num - 49)/50.0)*9)+9);
X    numints++;
X  }
X
X  if (numints == 0) {
X    print1("Pretty dumb, aren't you? [yn] ");
X    if (ynq1()=='y') {
X      Player.iq = random_range(3)+3;      
X      print2("I thought so....");
X    }
X    else {
X      Player.iq = random_range(6)+8;
X      print2("Well, not *that* dumb.");
X    }
X    morewait();
X    clearmsg();
X  }
X  else Player.iq = iqpts/numints;
X  Player.maxiq = Player.iq;
X  agipts = 0;
X  print1("Can you dance? [yn] ");
X  if (ynq1()=='y') {
X    agipts++;
X    nprint1(" Well? [yn] ");
X    if (ynq1()=='y') agipts+=2;
X  }
X  print1("Do you have training in a martial art or gymnastics? [yn] ");
X  if (ynq1()=='y') {
X    agipts+=2;
X    print2("Do you have dan rank or equivalent? [yn] ");
X    if (ynq2()=='y') agipts+=4;
X  }
X  clearmsg();
X  print1("Do you play some field sport? [yn] ");
X  if (ynq1()=='y') {
X    agipts++;
X    nprint1(" Are you good? [yn] ");
X    if (ynq1()=='y') agipts++;
X  }
X  print1("Do you cave, mountaineer, etc.? [yn] ");
X  if (ynq1()=='y')
X    agipts+=3;
X  print1("Do you skate or ski? [yn] ");
X  if (ynq1()=='y') {
X    agipts+=2;
X    nprint1(" Well? [yn] ");
X    if (ynq1()=='y') agipts+=2;
X  }
X  print1("Are you physically handicapped? [yn] ");
X  if (ynq1()=='y')
X    agipts-=4;
X  print1("Are you accident prone? [yn] ");
X  if (ynq1()=='y')
X    agipts-=4;
X  print1("Can you use a bicycle? [yn] ");
X  if (ynq1()!='y')
X    agipts-=4;
X  Player.agi = Player.maxagi = 9 + agipts/2;
X  print1("Do you play video games? [yn] ");
X  if (ynq1()=='y') {
X    dexpts+=2;
X    print2("Do you get high scores? [yn] ");
X    if (ynq2()=='y') dexpts+=4;
X  }
X  clearmsg();
X  print1("Are you an archer, fencer, or marksman? [yn] ");
X  if (ynq1()=='y') {
X    dexpts+=2;
X    print2("A good one? [yn] ");
X    if (ynq2()=='y') dexpts+=4;
X  }
X  clearmsg();
X  print1("Have you ever picked a lock? [yn] ");
X  if (ynq1()=='y') {
X    dexpts+=2;
X    print2("Really. Well, the police are being notified.");
X  }
X  morewait();
X  clearmsg();
X  print1("What's your typing speed (words per minute) ");
X  num = parsenum();
X  if (num > 125) {
X    print2("Tell me another one....");
X    morewait();
X    clearmsg();
X    num = 125;
X  }
X  dexpts += num/25;
X  print1("Hold your arm out. Tense your fist. Hand shaking? [yn] ");
X  if (ynq1()=='y')
X    dexpts-=3;
X  print1("Ambidextrous, are you? [yn] ");
X  if (ynq1()=='y')
X    dexpts+=4;
X  print1("Can you cut a deck of cards with one hand? [yn] ");
X  if (ynq1()=='y')
X    dexpts+=2;
X  print1("Can you tie your shoes blindfolded? [yn] ");
X  if (ynq1()!='y')
X    dexpts-=3;
X  Player.dex = Player.maxdex = 6 + dexpts/2;
X  print1("Do you ever get colds? [yn] ");
X  if (ynq1()!='y') 
X    conpts+=4;
X  else {
X    nprint1(" Frequently? [yn] ");
X    if (ynq1() == 'y') conpts -=4;
X  }
X  print1("Had any serious accident or illness this year? [yn] ");
X  if (ynq1()=='y') conpts -=4;
X  else conpts +=4;
X  print1("Have a chronic disease? [yn] ");
X  if (ynq1() =='y') conpts -=4;
X  print1("Overweight or underweight by more than 20 percent? [yn] ");
X  if (ynq1() =='y') conpts -=2;
X  print1("High Blood Pressure? [yn] ");
X  if (ynq1() =='y') conpts -=2;
X  print1("Smoke? [yn] ");
X  if (ynq1() =='y') conpts -=3;
X  print1("Take aerobics classes? [yn] ");
X  if (ynq1() =='y') conpts +=2;
X  print1("How many miles can you run? ");
X  num = parsenum();
X  if (num > 25) {
X    print2("Right. Sure. Give me a break.");
X    morewait();
X    clearmsg();
X    conpts += 8;
X  }
X  else if (num < 1) conpts -= 3;
X  else if (num < 5) conpts += 2;
X  else if (num < 10) conpts += 4;
X  else conpts += 8;
X  Player.con = Player.maxcon = 12 + conpts/3;
X  print1("Do animals react oddly to your presence? [yn] ");
X  if (ynq1()=='y') {
X    print2("How curious that must be.");
X    morewait();
X    clearmsg();
X    powpts += 2;
X  }
X  print1("Can you see auras? [yn] ");
X  if (ynq1()=='y') {
X    nprint1(" How strange.");
X    morewait();
X    powpts += 3;
X  }
X  print1("Ever have an out-of-body experience? [yn] ");
X  if (ynq1()=='y') {
X    print2("Wow, man. Fly the friendly skies....");
X    morewait();
X    clearmsg();
X    powpts += 3;
X  }
X  print1("Did you ever cast a spell? [yn] ");
X  if (ynq1()=='y') {
X    powpts += 3;
X    nprint1(" Did it work? [yn] ");
X    if (ynq1()=='y') {
X      powpts+=7;
X      print2("Sure it did.");
X      morewait();
X      clearmsg();
X    }
X  }
X  print1("Do you have ESP? [yn] ");
X  if (ynq1()=='y') {
X    powpts += 3;
X    print2("Yeah, tell me more.");
X    morewait();
X    clearmsg();
X  }
X  print1("Do you have PK? [yn] ");
X  if (ynq1()=='y') {
X    powpts+= 6;
X    print2("I can't tell you how much that moves me.");
X    morewait();
X    clearmsg();
X  }
X  print1("Do you believe in ghosts? [yn] ");
X  if (ynq1()=='y') {
X    powpts+=2;
X    print2("I do! I do! I do believe in ghosts!");
X    morewait();
X    clearmsg();
X  }
X  print1("Are you Irish? [yn] ");
X  if (ynq1()=='y') {
X    powpts+=2;
X    nprint1(" Is that blarney or what?");
X    morewait();
X  }
X  Player.pow = Player.maxpow = 3 + powpts/2;
X  print1("What is your sexual preference? [mf] ");
X  do Player.preference = mcigetc();
X  while ((Player.preference != 'm') && (Player.preference != 'f'));
X}
X
X
X
Xvoid omegan_character_stats()
X{
X  int share1,share2,i=0;
X  print1("To reroll hit ESCAPE; hit any other key to accept these stats.");
X  print2("You have only 10 chances to reroll....");
X  do {
X    i++;
X    Player.iq = Player.maxiq = 4 + random_range(5)+
X      (share1 = random_range(6)) + (share2 = random_range(6));
X    Player.pow = Player.maxpow = 4 + random_range(5) + share1 +share2;
X    Player.dex = Player.maxdex = 4 + random_range(5)+
X      (share1 = random_range(6)) + (share2 = random_range(6));
X    Player.agi = Player.maxagi = 4 + random_range(5) + share1 +share2;
X    Player.str = Player.maxstr = 4 + random_range(5)+
X      (share1 = random_range(6)) + (share2 = random_range(6));
X    Player.con = Player.maxcon = 4 + random_range(5) + share1 +share2;
X    Player.cash = random_range(100)+random_range(100)+
X      random_range(100)+random_range(100)+random_range(100);
X    calc_melee();
X    dataprint();
X  } while ((i < 11) && (mgetc() == ESCAPE));
X  clearmsg();
X  print1("Please enter your character's name: ");
X  strcpy(Player.name,msgscanstring());
X  print1("What is your character's sexual preference? [mf] ");
X  do Player.preference = mcigetc();
X  while ((Player.preference != 'm') && (Player.preference != 'f'));
X
X}
X
END_OF_FILE
if test 13968 -ne `wc -c <'ochar.c'`; then
    echo shar: \"'ochar.c'\" unpacked with wrong size!
fi
# end of 'ochar.c'
fi
if test -f 'omaze3.dat' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'omaze3.dat'\"
else
echo shar: Extracting \"'omaze3.dat'\" \(287 characters\)
sed "s/^X//" >'omaze3.dat' <<'END_OF_FILE'
X"z"""""""""""""""""""""...................."""."""-""".""""-"""."""...".?."..."........""".""""""".""""""""""""........"..........."""-"""".""""""-""""."""...."..."......"....""-""-"-"-""-"""-""-""-"?"..?.".".."..."..."?""""""""."""""."""."""">?-?-?-.-."?-.?"O.-??""""""""""""""""""""""
END_OF_FILE
if test 287 -ne `wc -c <'omaze3.dat'`; then
    echo shar: \"'omaze3.dat'\" unpacked with wrong size!
fi
# end of 'omaze3.dat'
fi
if test -f 'ommelee.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ommelee.c'\"
else
echo shar: Extracting \"'ommelee.c'\" \(7666 characters\)
sed "s/^X//" >'ommelee.c' <<'END_OF_FILE'
X/* omega copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
X/* ommelee */
X/* various functions to do with monster melee */
X
X#include "oglob.h"
X
X
Xvoid m_hit(m,dtype)
Xstruct monster *m;
Xint dtype;
X{
X  if (m->uniqueness == COMMON) {
X    strcpy(Str3,"a ");
X    strcat(Str3,m->monstring);
X  }
X  else strcpy(Str3,m->monstring);
X  if ((Player.status[DISPLACED] > 0) && (random_range(2) == 1))
X    mprint("The attack was displaced!");
X  else  p_damage(random_range(m->dmg),dtype,Str3);
X}
X
X
X
X/* execute monster attacks versus player */
Xvoid tacmonster(m)
Xstruct monster *m;
X{
X  int i=0;
X  drawvision(Player.x,Player.y);
X  transcribe_monster_actions(m);
X  while ((i < strlen(m->meleestr)) && (m->hp > 0)) {
X    if (m->uniqueness == COMMON) {
X      strcpy(Str4,"The ");
X      strcat(Str4,m->monstring);
X    }
X    else strcpy(Str4,m->monstring);
X    if (m->meleestr[i] == 'A') {
X      strcat(Str4," attacks ");
X      strcat(Str4,actionlocstr(m->meleestr[i+1]));
X      if (Verbosity == VERBOSE) mprint(Str4);
X      monster_melee(m,m->meleestr[i+1],0);
X    }
X    else if (m->meleestr[i] == 'L') {
X      strcat(Str4," lunges ");
X      strcat(Str4,actionlocstr(m->meleestr[i+1]));
X      if (Verbosity == VERBOSE) mprint(Str4);
X      monster_melee(m,m->meleestr[i+1],m->level);
X    }
X    i+=2;
X  }
X}
X
X
X
Xvoid monster_melee(m,hitloc,bonus)
Xstruct monster *m;
Xchar hitloc;
Xint bonus;
X{
X  if (player_on_sanctuary())
X    print1("The aegis of your deity protects you!");
X  else {
X    /* It's lawful to wait to be attacked */
X    if (m->attacked==0) Player.alignment++;
X    m->attacked++;
X    if (m->uniqueness == COMMON) {
X      strcpy(Str2,"The ");
X      strcat(Str2,m->monstring);
X    }
X    else strcpy(Str2,m->monstring);
X    if (monster_hit(m,hitloc,bonus))
X      switch(m->meleef) {
X      case M_NO_OP: 
X	strcat(Str2," touches you.");
X	mprint(Str2);
X	break;
X      case M_MELEE_NORMAL:
X	strcat(Str2," hits you.");
X	mprint(Str2);
X	m_hit(m,NORMAL_DAMAGE);
X	break;
X      case M_MELEE_NG:
X	strcat(Str2," hits you.");
X	mprint(Str2);
X	m_hit(m,NORMAL_DAMAGE);
X	if (random_range(5)==3) m_sp_ng(m);
X	break;
X      case M_MELEE_FIRE:
X	strcat(Str2," blasts you with fire.");
X	mprint(Str2);
X	m_hit(m,FLAME);
X	break;
X      case M_MELEE_DRAGON:
X	strcat(Str2," hits you and blasts you with fire.");
X	mprint(Str2);
X	m_hit(m,NORMAL_DAMAGE);
X	m_hit(m,FLAME);
X	break;
X      case M_MELEE_ELEC:
X	strcat(Str2," lashes you with electricity.");
X	mprint(Str2);
X	m_hit(m,ELECTRICITY);
X	break;
X      case M_MELEE_COLD:
X	strcat(Str2," freezes you with cold.");
X	mprint(Str2);
X	m_hit(m,ELECTRICITY);
X	break;
X      case M_MELEE_POISON:
X	strcat(Str2," hits you.");
X	mprint(Str2);
X	m_hit(m,NORMAL_DAMAGE);
X	if (random_range(10) < m->level) {
X	  mprint("You've been poisoned!");
X	  p_poison(m->dmg);
X	}
X	break;
X      case M_MELEE_GRAPPLE:
X	strcat(Str2," grabs you.");
X	mprint(Str2);
X	m_hit(m,NORMAL_DAMAGE);
X	Player.status[IMMOBILE]++;
X	break;
X      case M_MELEE_SPIRIT:
X	strcat(Str2," touches you.");
X	mprint(Str2);
X	m_hit(m,NORMAL_DAMAGE);
X	drain_life(m->level);
X	break;
X      case M_MELEE_DISEASE:
X	strcat(Str2," hits you.");
X	mprint(Str2);
X	m_hit(m,NORMAL_DAMAGE);
X	if (random_range(10) < m->level) {
X	  mprint("You've been infected!");
X	  disease(m->level);
X	}
X	break;
X      case M_MELEE_SLEEP:
X	strcat(Str2," hit you.");
X	mprint(Str2);
X	m_hit(m,NORMAL_DAMAGE);
X	if (random_range(10) < m->level) {
X	  mprint("You feel drowsy");
X	  sleep_player(m->level);
X	}
X	break;
X      }
X    else {
X      if (random_range(10)) strcat(Str2," missed you.");
X      else switch(random_range(10)) {
X      case 0: strcat(Str2," flailed stupidly at you."); break;
X      case 1: strcat(Str2," made you laugh."); break;
X      case 2: strcat(Str2," blundered severely.");
X	m_damage(m,m->dmg,UNSTOPPABLE); break;
X      case 3: strcat(Str2," tripped while attacking.");m_dropstuff(m);break;
X      case 4: strcat(Str2," seems seriously confused.");
X	m->speed = min(30,m->speed*2); break;
X      case 5: strcat(Str2," is seriously ashamed."); break;
X      case 6: strcat(Str2," made a boo-boo."); break;
X      case 7: strcat(Str2," blundered."); break;
X      case 8: strcat(Str2," cries out in anger and frustration."); break;
X      case 9: strcat(Str2," curses your ancestry."); break;
X      }
X      mprint(Str2);
X    }
X  }
X}
X
X
X
X/* checks to see if player hits with hitmod vs. monster m at location hitloc */
Xint monster_hit(m,hitloc,bonus)
Xstruct monster *m;
Xchar hitloc;
Xint bonus;
X{
X  int i=0,blocks=FALSE,goodblocks=0,hit,riposte=FALSE;
X  while (i<strlen(Player.meleestr)) {
X    if ((Player.meleestr[i] == 'B') || (Player.meleestr[i] == 'R')) {
X      blocks = TRUE;
X      if (hitloc == Player.meleestr[i+1]) {
X	goodblocks++;
X	if (Player.meleestr[i] == 'R') riposte = TRUE;
X      }
X    }
X    i+=2;
X  }
X  if (! blocks) goodblocks = -1;
X  hit = hitp(m->hit+bonus,Player.defense+goodblocks*10);
X  if ((! hit) && (goodblocks > 0)) {
X    if (Verbosity == VERBOSE) mprint("You blocked it!");
X    if (riposte) {
X      if (Verbosity != TERSE) mprint("You got a riposte!");
X      if (hitp(Player.hit,m->ac)) {
X	mprint("You hit!");
X	weapon_use(0,Player.possessions[O_WEAPON_HAND],m);
X      }
X      else mprint("You missed.");
X    }
X  }
X  return(hit);
X}
X
X
X
X/* decide monster actions in tactical combat mode */
X/* if monster is skilled, it can try see the player's attacks coming and
X   try to block appropriately. */
X
Xvoid transcribe_monster_actions(m)
Xstruct monster *m;
X{
X  int i;
X  char attack_loc,block_loc;
X  static char mmstr[80];
X  
X  int p_blocks[3];
X  int p_attacks[3];
X
X  for(i=0;i<3;i++)p_blocks[i] = p_attacks[i] = 0;
X
X  /* Find which area player blocks and attacks least in */
X  i = 0;
X  while (i<strlen(Player.meleestr)) {
X    if ((Player.meleestr[i] == 'B') ||
X	(Player.meleestr[i] == 'R')) {
X      if (Player.meleestr[i+1] == 'H') p_blocks[0]++;
X      if (Player.meleestr[i+1] == 'C') p_blocks[1]++;
X      if (Player.meleestr[i+1] == 'L') p_blocks[2]++;
X    }
X    else if ((Player.meleestr[i] == 'A') ||
X	     (Player.meleestr[i] == 'L')) {
X      if (Player.meleestr[i+1] == 'H') p_attacks[0]++;
X      if (Player.meleestr[i+1] == 'C') p_attacks[1]++;
X      if (Player.meleestr[i+1] == 'L') p_attacks[2]++;
X    }
X    i+=2;
X  }
X
X  if ((p_blocks[2] <= p_blocks[1]) &&
X      (p_blocks[2] <= p_blocks[0]))
X    attack_loc = 'L';
X  else if ((p_blocks[1] <= p_blocks[2]) &&
X	   (p_blocks[1] <= p_blocks[0]))
X    block_loc = 'C';
X  else attack_loc = 'H';
X  if ((p_attacks[2] <= p_attacks[1]) &&
X      (p_attacks[2] <= p_attacks[0]))
X    block_loc = 'L';
X  else if ((p_attacks[1] <= p_attacks[2]) &&
X	   (p_attacks[1] <= p_attacks[0]))
X    block_loc = 'C';
X  else block_loc = 'H';
X
X  m->meleestr = mmstr;
X
X  if (m->id != NPC)
X    strcpy(m->meleestr,Monsters[m->id].meleestr);
X  else {
X    strcpy(m->meleestr,"");
X    for(i=0;i<m->level;i+=2) 
X      strcat(m->meleestr,"L?R?");
X  }
X
X  i = 0;
X  while (i<strlen(m->meleestr)) {
X    if ((m->meleestr[i] == 'A') || (m->meleestr[i] == 'L')) {
X      if (m->meleestr[i+1] == '?') {
X	if (m->level+random_range(30) > Player.level+random_range(20))
X	  m->meleestr[i+1] = attack_loc;
X	else m->meleestr[i+1] = random_loc();
X      }
X      else if (m->meleestr[i+1] == 'X') m->meleestr[i+1] = random_loc();
X    }
X    else if ((m->meleestr[i] == 'B') || (m->meleestr[i] == 'R')) {
X      if (m->meleestr[i+1] == '?') { 
X	if (m->level+random_range(30) > Player.level+random_range(20))
X	  m->meleestr[i+1] = block_loc;
X	else m->meleestr[i+1] = random_loc();
X      }
X      else if (m->meleestr[i+1] == 'X') m->meleestr[i+1] = random_loc();
X    }
X    i+=2;
X  }
X}
X
Xchar random_loc()
X{
X  switch(random_range(3)) {
X  case 0:return('H'); break;
X  case 1:return('C'); break;
X  case 2:return('L'); break;
X  }
X}
END_OF_FILE
if test 7666 -ne `wc -c <'ommelee.c'`; then
    echo shar: \"'ommelee.c'\" unpacked with wrong size!
fi
# end of 'ommelee.c'
fi
if test -f 'opriest.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'opriest.c'\"
else
echo shar: Extracting \"'opriest.c'\" \(14337 characters\)
sed "s/^X//" >'opriest.c' <<'END_OF_FILE'
X/* omega copyright (C) by Laurence Raphael Brothers, 1987,1988,1989 */
X/* opriest.c */
X/* functions for clerics. */
X
X#include "oglob.h"
X
X/* prayer occurs at altars, hence name of function */
Xvoid l_altar()
X{
X  int i,deity;
X  char response;
X
X  if (Current_Environment == E_COUNTRYSIDE) deity = DRUID;
X  else deity = Level->site[Player.x][Player.y].aux;
X
X  switch(deity) {
X    default:
X      print1("This rude altar has no markings.");
X      break;
X    case ODIN:
X      print1("This granite altar is graven with a gallows.");
X      break;
X    case SET:
X      print1("This sandstone altar has a black hand drawn on it.");
X      break;
X    case HECATE:
X      print1("This silver altar is inlaid with a black crescent moon.");
X      break;
X    case ATHENA:
X      print1("This golden altar is inscribed with an owl.");
X      break;
X    case DESTINY:
X      print1("This crystal altar is in the form of an omega.");
X      break;
X    case DRUID:
X      print1("This oaken altar is ornately engraved with leaves.");
X      break;
X  }
X  print2("Worship at this altar? [yn] ");
X  if (ynq2() == 'y') {
X    if (Player.rank[PRIESTHOOD] == 0) increase_priest_rank(deity);
X    else if (! check_sacrilege(deity)) {
X      if (Blessing) print1("You have a sense of immanence.");
X      print2("Request a Blessing, Sacrifice an item, or just Pray [b,s,p] ");
X      do response = mcigetc();
X      while ((response != 'b') && 
X	     (response != 's') && 
X	     (response != 'p') && 
X	     (response != ESCAPE));
X      if (response == 'b') {
X	print1("You beg a heavenly benefice.");
X	print2("You hear a gong resonating throughout eternity....");
X	morewait();
X	if (Blessing) {
X	  print1("A shaft of lucent radiance lances down from the heavens!");
X	  print2("You feel uplifted....");
X	  morewait();
X	  gain_experience(Player.rank[PRIESTHOOD]*Player.rank[PRIESTHOOD]*50);
X	  cleanse(1);
X	  heal(10);
X	  bless(1);
X	  Blessing = FALSE;
X	  increase_priest_rank(deity);
X	}
X	else {
X	  print1("Your ardent plea is ignored.");
X	  print2("You feel ashamed.");
X	  Player.xp -= (Player.xp/4);
X	}
X	calc_melee();
X      }
X      else if (response == 's') {
X	print1("Which item to Sacrifice?");
X	i = getitem(NULL);
X	if (i==ABORT) i = 0;
X	if (Player.possessions[i] == NULL) {
X	  print1("You have insulted your deity!");
X	  print2("Not a good idea, as it turns out...");
X	  dispel(-1);
X	  p_damage(Player.hp-1,UNSTOPPABLE,"a god's pique");
X	}
X	else if (true_item_value(Player.possessions[i]) >
X		 (Player.rank[PRIESTHOOD] *
X		  Player.rank[PRIESTHOOD] *
X		  Player.rank[PRIESTHOOD] * 50)) {
X	  print1("With a burst of blue flame, your offering vanishes!");
X	  dispose_lost_objects(1,Player.possessions[i]);
X	  print2("A violet nimbus settles around your head and slowly fades.");
X	  morewait();
X	  Blessing = TRUE;
X	}
X	else {
X	  print1("A darkling glow envelopes your offering!");
X	  print2("The glow slowly fades....");
X	  morewait();
X	  setgamestatus(SUPPRESS_PRINTING);
X	  if (Player.possessions[i]->used) {
X	    Player.possessions[i]->used = FALSE;
X	    item_use(Player.possessions[i]);
X	    Player.possessions[i]->blessing =
X	      -1 - abs(Player.possessions[i]->blessing);
X	    Player.possessions[i]->used = TRUE;
X	    item_use(Player.possessions[i]);
X	  }
X	  else Player.possessions[i]->blessing =
X	    -1 - abs(Player.possessions[i]->blessing);
X	  resetgamestatus(SUPPRESS_PRINTING);
X	}
X      }
X      else if (response == 'p') {
X	if (deity != Player.patron) 
X	  print1("Nothing seems to happen.");
X	else increase_priest_rank(deity);
X      }
X    }
X  }
X}
X
X
X
X
Xint check_sacrilege(deity)
Xint deity;
X{
X  int i,sacrilege=FALSE;
X  if ((Player.patron != deity) && (Player.patron > 0)) {
X    sacrilege=TRUE;
X    Player.pow--;
X    Player.maxpow--;
X    switch(Player.patron) {
X    case ODIN:
X      print1("Odin notices your lack of faith! ");
X      morewait();
X      if (deity == ATHENA) {
X	print2("However, Athena intercedes on your behalf.");
X	sacrilege = FALSE;
X      }
X      else {
X	print2("You are struck by a thunderbolt!");
X	p_damage(Player.level*5,UNSTOPPABLE,"Odin's wrath");
X	if (Player.hp > 0) {
X	  morewait();
X	  print2("The bolt warps your feeble frame....");
X	  Player.maxcon = Player.maxcon/2;
X	  Player.con = min(Player.con,Player.maxcon);
X	  Player.maxstr = Player.maxstr/2;
X	  Player.con = min(Player.str,Player.maxstr);
X	}
X      }
X      morewait();
X      break;
X    case SET:
X      print1("Set notices your lack of faith! ");
X      morewait();
X      if (deity == HECATE) {
X	print1("But since you pray to a friendly deity,");
X	print2("Set decides not to punish you.");
X	sacrilege = FALSE;
X      }
X      else {
X	print2("You are blasted by a shaft of black fire!");
X	p_damage(Player.level*5,UNSTOPPABLE,"Set's anger");
X	if (Player.hp > 0) {
X	  morewait();
X	  print1("You are wreathed in clouds of smoke.");
X	  for(i=0;i<MAXITEMS;i++) 
X	    if ((Player.possessions[i] != NULL) &&
X		(Player.possessions[i]->blessing > -1))
X	      conform_lost_object(Player.possessions[i]);
X	  morewait();
X	  print2("You feel Set's Black Hand on your heart....");
X	  Player.con = Player.maxcon = Player.maxcon / 4;
X	}
X      }
X      morewait();
X      break;
X    case HECATE:
X      print1("Hecate notices your lack of faith! ");
X      morewait();
X      if (deity == SET) {
X	print1("But ignores the affront since she likes Set.");
X	sacrilege = FALSE;
X      }
X      else {
X	print1("You are zapped by dark moonbeams!");
X	p_damage(Player.level*5,UNSTOPPABLE,"Hecate's malice");
X	if (Player.hp > 0) {
X	  print2("The beams leach you of magical power!");
X	  Player.maxpow = Player.maxpow/5;
X	  Player.pow = min(Player.pow,Player.maxpow);
X	  for(i=0;i<NUMSPELLS;i++) 
X	    Spells[i].known = FALSE;
X	}
X      }
X      morewait();
X      break;
X    case ATHENA:
X      print1("Athena notices your lack of faith! ");
X      morewait();
X      if (deity == ODIN) {
X	print2("But lets you off this time since Odin is also Lawful.");
X	sacrilege = FALSE;
X      }
X      else {
X	print2("You are zorched by godsfire!");
X	if (Player.hp > 0) {
X	  morewait();
X	  print1("The fire burns away your worldly experience!");
X		Player.level = 0;
X	  Player.xp = 0;
X	  Player.maxhp = Player.hp = Player.con;
X	  print2("Your power is reduced by the blast!!!");
X	  Player.pow = Player.maxpow = Player.maxpow/3;
X	  Player.mana = min(Player.mana,calcmana());
X	}
X      }
X      morewait();
X      break;
X    case DESTINY:
X      print2("The Lords of Destiny ignore your lack of faith.");
X      sacrilege = FALSE;
X      morewait();
X      break;
X    case DRUID:
X      print2("Your treachery to the ArchDruid has been noted.");
X      if (random_range(2) == 1)
X	Player.alignment += 40;
X      else Player.alignment -= 40;
X      morewait();
X      break;
X    }
X    if (sacrilege) {
X      Player.patron = 0;
X      Player.rank[PRIESTHOOD] = 0;
X    }
X  }
X  return(sacrilege);
X}
X
Xvoid increase_priest_rank(deity)
Xint deity;
X{
X  if (Player.rank[PRIESTHOOD] == 0) switch(deity) {
X  default:
X    print2("Some nameless god blesses you....");
X    Player.hp = Player.maxhp;
X    morewait();
X    print2("The altar crumbles to dust and blows away.");
X    Level->site[Player.x][Player.y].locchar = FLOOR;
X    Level->site[Player.x][Player.y].p_locf = L_NO_OP;
X    break;
X  case ODIN:
X    if (Player.alignment > 0) {
X      print1("Odin hears your prayer!");
X      print2(Priest[ODIN]);
X      nprint2(" personally blesses you.");
X      nprint2(" You are now a lay devotee of Odin.");
X      Player.patron = ODIN;
X      Player.rank[PRIESTHOOD] = LAY;
X      Player.guildxp[PRIESTHOOD] = 1;
X      morewait();
X      learnclericalspells(ODIN,LAY);
X    }
X    else print1("Odin ignores you.");
X    break;
X  case SET:
X    if (Player.alignment < 0) {
X      print1("Set hears your prayer!");
X      print2(Priest[SET]);
X      nprint2(" personally blesses you. ");
X      nprint2(" You are now a lay devotee of Set.");
X      Player.patron = SET;
X      Player.rank[PRIESTHOOD] = LAY;
X      Player.guildxp[PRIESTHOOD] = 1;
X      morewait();
X      learnclericalspells(SET,LAY);
X    }
X    else print1("Set ignores you.");
X    break;
X  case ATHENA:
X    if (Player.alignment > 0) {
X      print1("Athena hears your prayer!");
X      print2(Priest[ATHENA]);
X      nprint2(" personally blesses you.");
X      nprint2(" You are now a lay devotee of Athena.");
X      Player.patron = ATHENA;
X      Player.rank[PRIESTHOOD] = LAY;
X      Player.guildxp[PRIESTHOOD] = 1;
X      morewait();
X      learnclericalspells(ATHENA,LAY);
X    }
X    else print1("Athena ignores you.");
X    break;
X  case HECATE:
X    if (Player.alignment < 0) {
X      print1("Hecate hears your prayer!");
X      print2(Priest[HECATE]);
X      nprint2(" personally blesses you.");
X      nprint2(" You are now a lay devotee of Hecate.");
X      Player.patron = HECATE;
X      Player.rank[PRIESTHOOD] = LAY;
X      Player.guildxp[PRIESTHOOD] = 1;
X      morewait();
X      learnclericalspells(HECATE,LAY);
X    }
X    else print1("Hecate ignores you.");
X    break;
X  case DRUID:
X    if (abs(Player.alignment) < 10) {
X      print1(Priest[DRUID]);
X      nprint1(" personally blesses you.");
X      print2("You are now a lay devotee of the Druids.");
X      Player.patron = DRUID;
X      Player.rank[PRIESTHOOD] = LAY;
X      Player.guildxp[PRIESTHOOD] = 1;
X      morewait();
X      learnclericalspells(DRUID,LAY);
X    }
X    else {
X      print1("You hear a voice....");
X      morewait();
X      print2("'Only those who embody the Balance may become Druids.'");
X    }
X    break;
X  case DESTINY:
X    print1("The Lords of Destiny could hardly care less.");
X    print2("But you can consider yourself now to be a lay devotee.");
X    Player.patron = DESTINY;
X    Player.rank[PRIESTHOOD] = LAY;
X      Player.guildxp[PRIESTHOOD] = 1;
X    break;
X  }
X  else if (deity == Player.patron) {
X    if ((((deity == ODIN) || (deity == ATHENA)) && 
X	 (Player.alignment < 1)) ||
X	(((deity == SET) || (deity == HECATE)) && 
X	 (Player.alignment > 1)) ||
X	((deity == DRUID) && (abs(Player.alignment) > 10))) {
X      print1("You have swerved from the One True Path!");
X      print2("Your deity is greatly displeased...");
X      Player.xp -= Player.level*Player.level;
X      Player.xp = max(0,Player.xp);
X    }
X    else if (Player.rank[PRIESTHOOD]== HIGHPRIEST) answer_prayer();
X    else if (Player.rank[PRIESTHOOD]== SPRIEST) {
X      if (Player.level > Priestlevel[deity])
X	hp_req_test();
X      else answer_prayer();
X    }
X    else if (Player.rank[PRIESTHOOD]==PRIEST) {
X      if (Player.guildxp[PRIESTHOOD] >= 4000) {
X	print1("An heavenly fanfare surrounds you!");
X	print2("Your deity raises you to the post of Senior Priest.");
X	hp_req_print();
X	Player.rank[PRIESTHOOD] = SPRIEST;
X      }
X      else answer_prayer();
X    }
X    else if (Player.rank[PRIESTHOOD]==ACOLYTE) {
X      if (Player.guildxp[PRIESTHOOD] >= 1500) {
X	print1("A trumpet sounds in the distance.");
X	print2("Your deity raises you to the post of Priest.");
X	Player.rank[PRIESTHOOD] = PRIEST;
X	morewait();
X	learnclericalspells(deity,PRIEST);
X      }
X      else answer_prayer();
X    }
X    else if (Player.rank[PRIESTHOOD]==LAY) {
X      if (Player.guildxp[PRIESTHOOD] >= 400) {
X	print1("A mellifluous chime sounds from above the altar.");
X	print2("Your deity raises you to the post of Acolyte.");
X	Player.rank[PRIESTHOOD] = ACOLYTE;
X	morewait();
X	learnclericalspells(deity,ACOLYTE);
X      }
X      else answer_prayer();
X    }
X  }
X}
X
X
Xvoid answer_prayer()
X{
X  clearmsg();
X  switch(random_range(12)) {
X  case 0: print1("You have a revelation!"); break;
X  case 1: print1("You feel pious."); break;
X  case 2: print1("A feeling of sanctity comes over you."); break;
X  default: print1("Nothing unusual seems to happen."); break;
X  }
X}
X
X
Xvoid hp_req_test()
X{
X  pob o;
X  switch  (Player.patron) {
X  case ODIN:
X    if (find_item(&o,ARTIFACTID+17,-1))
X      make_hp(o);
X    else hp_req_print();
X    break;
X  case SET:
X    if (find_item(&o,ARTIFACTID+14,-1))
X      make_hp(o);
X    else hp_req_print();
X    break;
X  case ATHENA:
X    if (find_item(&o,ARTIFACTID+15,-1))
X      make_hp(o);
X    else hp_req_print();
X    break;
X  case HECATE:
X    if (find_item(&o,ARTIFACTID+16,-1))
X      make_hp(o);
X    else hp_req_print();
X    break;
X  case DRUID:
X    if (find_item(&o,ARTIFACTID+14,-1))
X      make_hp(o);
X    else if (find_item(&o,ARTIFACTID+15,-1))
X      make_hp(o);
X    else if (find_item(&o,ARTIFACTID+16,-1))
X      make_hp(o);
X    else if (find_item(&o,ARTIFACTID+17,-1))
X      make_hp(o);
X    else hp_req_print();
X    break;
X  case DESTINY:
X    if (find_item(&o,ARTIFACTID+19,-1))
X      make_hp(o);
X    else hp_req_print();
X    break;
X  }
X}
X
X
Xvoid hp_req_print()
X{
X  morewait();
X  print1("To advance further, you must obtain the Holy Symbol of ");
X  switch(Player.patron) {
X  case ODIN:
X    nprint1(Priest[SET]);
X    print2("who may be found in the main Temple of Set.");
X    break;
X  case SET:
X    nprint1(Priest[ODIN]);
X    print2("who may be found in the main Temple of Odin.");
X    break;
X  case ATHENA:
X    nprint1(Priest[HECATE]);
X    print2("who may be found in the main Temple of Hecate.");
X    break;
X  case HECATE:
X    nprint1(Priest[ATHENA]);
X    print2("who may be found in the main Temple of Athena.");
X    break;
X  case DRUID:
X    print2("any of the aligned priests");
X    nprint2(" who may be found in their main temples.");
X    break;
X  case DESTINY:
X    nprint1(Priest[DESTINY]);
X    print2("who may be found in the main Temple of Destiny.");
X    break;
X  }
X}
X
Xvoid make_hp(o)
Xpob o;
X{
X  print1("A full-scale heavenly choir chants 'Hallelujah' all around you!");
X  print2("You notice a change in the symbol you carry....");
X  switch(Player.patron) {
X  case ODIN:
X    *o = Objects[ARTIFACTID+14];
X    break;
X  case SET:
X    *o = Objects[ARTIFACTID+17];
X    break;
X  case ATHENA:
X    *o = Objects[ARTIFACTID+16];
X    break;
X  case HECATE:
X    *o = Objects[ARTIFACTID+15];
X    break;
X  case DRUID:
X    *o = Objects[ARTIFACTID+18];
X    break;
X  case DESTINY:
X    *o = Objects[ARTIFACTID+19];
X    break;
X  }
X  o->known = 2;
X  o->charge = 17; /* random hack to convey bit that symbol is functional */
X  morewait();
X  if (Player.patron == DRUID)
X    print1("Your deity raises you to the post of ArchDruid!");
X  else print1("Your deity raises you to the post of High Priest!");
X  print2("You feel holy.");
X  strcpy(Priest[Player.patron],Player.name);
X  Priestlevel[Player.patron] = Player.level;
X  Player.rank[PRIESTHOOD] = HIGHPRIEST;
X  morewait();
X  learnclericalspells(Player.patron,HIGHPRIEST);
X}
END_OF_FILE
if test 14337 -ne `wc -c <'opriest.c'`; then
    echo shar: \"'opriest.c'\" unpacked with wrong size!
fi
# end of 'opriest.c'
fi
if test -f 'outil.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'outil.c'\"
else
echo shar: Extracting \"'outil.c'\" \(14444 characters\)
sed "s/^X//" >'outil.c' <<'END_OF_FILE'
X/* copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
X/* outils.c */
X
X/* Random utility functions called from all over */
X
X#include "oglob.h"
X
X/* x and y on level? */
Xint inbounds(x,y)
Xint x,y;
X{
X  return((x>=0)&&(y>=0)&&(x<WIDTH)&&(y<LENGTH));
X}
X
X/* RANDFUNCTION is defined in odefs.h */
Xint random_range(k)
Xint k;
X{
X  return( k==0 ? 0 : (int) RANDFUNCTION % k ) ;
X}
X
X
X/* modify absolute y coord relative to which part of level we are on */
Xint screenmod(y)
Xint y;
X{
X  return(y-ScreenOffset);
X}
X
X
Xint offscreen(y)
Xint y;
X{
X  return((y<0)||
X	 (y<ScreenOffset) ||
X	 (y>ScreenOffset+ScreenLength-1) ||
X	 (y>LENGTH));
X}
X
X
X/* always hit on a natural 0; never hit on a natural 19 */
Xint hitp(hit,ac)
Xint hit,ac;
X{
X  int roll = random_range(20);
X  if (roll == 0) return(TRUE);
X  else if (roll == 19) return(FALSE);
X  else return((roll < (hit - ac)) ? TRUE : FALSE );
X}
X
X
X
X#ifndef MSDOS
X/* this function doesnt seem to exist by itself... */
Xint sign(n)
Xint n;
X{
X  if (n == 0) return(0);
X  else return((n < 0) ? -1 : 1);
X}
X
X
X/* why load the math library.... */
Xint max(a,b)
Xint a,b;
X{
X  return((a>b) ? a : b);
X}
X
X/* why load the math library.... */
Xint min(a,b)
Xint a,b;
X{
X  return((a<b) ? a : b);
X}
X#endif
X
X
X/* number of moves from x1,y1 to x2,y2 */
Xint distance(x1,y1,x2,y2)
Xint x1,y1,x2,y2;
X{
X  return(max(abs(x2-x1),abs(y2-y1)));
X}
X
X
X/* can you shoot, or move monsters through a spot? */
Xint unblocked(x,y)
Xint x,y;
X{
X  if ((! inbounds(x,y)) ||
X      (Level->site[x][y].creature != NULL) ||
X      (Level->site[x][y].locchar == WALL) ||
X      (Level->site[x][y].locchar == PORTCULLIS) ||
X      (Level->site[x][y].locchar == STATUE) ||
X      (Level->site[x][y].locchar == HEDGE) ||
X      (Level->site[x][y].locchar == CLOSED_DOOR) ||
X      loc_statusp(x,y,SECRET) ||
X      ((x==Player.x) && (y==Player.y)))
X    return(FALSE);
X  else 
X    return(TRUE);
X}
X
X
X/* do monsters want to move through a spot */
Xint m_unblocked(m,x,y)
Xstruct monster *m;
Xint x,y;
X{
X  if ((! inbounds(x,y)) || ((x==Player.x) && (y==Player.y)))
X    return(FALSE);
X  else if ((Level->site[x][y].creature != NULL) ||
X	   (Level->site[x][y].locchar == SPACE)) return(FALSE);
X  else if (m_statusp(m,ONLYSWIM)) 
X    return(Level->site[x][y].locchar == WATER);
X  else if ((Level->site[x][y].locchar == FLOOR) ||
X	   (Level->site[x][y].locchar == OPEN_DOOR))
X    return(TRUE);
X  else if ((Level->site[x][y].locchar == PORTCULLIS) ||
X	   (Level->site[x][y].locchar == WALL) ||
X	   (Level->site[x][y].locchar == STATUE) ||
X	   loc_statusp(x,y,SECRET))
X    return(m_statusp(m,INTANGIBLE));
X  else if (Level->site[x][y].locchar==WATER)
X    return(m_statusp(m,SWIMMING) || 
X	   m_statusp(m,ONLYSWIM) ||
X	   m_statusp(m,FLYING));
X  else if (Level->site[x][y].locchar == CLOSED_DOOR) {
X    if (m->movef==M_MOVE_SMART) {
X      mprint("You hear a door creak open.");
X      Level->site[x][y].locchar = OPEN_DOOR;
X      return(TRUE);
X    }
X    else if (random_range(m->dmg) > random_range(100)) {
X      mprint("You hear a door shattering.");
X      Level->site[x][y].locchar = RUBBLE;
X      return(TRUE);
X    }
X    else return(m_statusp(m,INTANGIBLE));
X  }
X  else if (Level->site[x][y].locchar == LAVA)
X    return((m_immunityp(m,FLAME) && 
X	    m_statusp(m,SWIMMING)) ||
X	   m_statusp(m,FLYING));
X  else if (Level->site[x][y].locchar == FIRE)
X    return(m_immunityp(m,FLAME));
X  else if ((Level->site[x][y].locchar == TRAP) ||
X	   (Level->site[x][y].locchar == HEDGE) ||
X	   (Level->site[x][y].locchar == ABYSS))
X    return((m->movef == M_MOVE_CONFUSED) ||
X	   m_statusp(m,FLYING));
X  else return(TRUE);
X}
X
X
X
X/* can you see through a spot? */
Xint view_unblocked(x,y)
Xint x,y;
X{
X  if (! inbounds(x,y)) return(FALSE);
X  else if ((Level->site[x][y].locchar == WALL) ||
X	   (Level->site[x][y].locchar == STATUE) ||
X	   (Level->site[x][y].locchar == HEDGE) ||
X	   (Level->site[x][y].locchar == FIRE) ||
X	   (Level->site[x][y].locchar == CLOSED_DOOR) ||
X	   loc_statusp(x,y,SECRET))
X    return(FALSE);
X  else 
X    return(TRUE);
X}
X
X
X#ifndef MSDOS
X/* 8 moves in Dirs */
Xvoid initdirs()
X{
X  Dirs[0][0] = 1;
X  Dirs[0][1] = 1;
X  Dirs[0][2] = -1;
X  Dirs[0][3] = -1;
X  Dirs[0][4] = 1;
X  Dirs[0][5] = -1;
X  Dirs[0][6] = 0;
X  Dirs[0][7] = 0;
X  Dirs[0][8] = 0;
X  Dirs[1][0] = 1;
X  Dirs[1][1] = -1;
X  Dirs[1][2] = 1;
X  Dirs[1][3] = -1;
X  Dirs[1][4] = 0;
X  Dirs[1][5] = 0;
X  Dirs[1][6] = 1;
X  Dirs[1][7] = -1;
X  Dirs[1][8] = 0;
X}
X#endif
X
X
X
X
X
X/* do_los moves pyx along a lineofsight from x1 to x2 */
X/* x1 and x2 are pointers because as a side effect they are changed */
X/* to the final location of the pyx */
Xvoid do_los(pyx,x1,y1,x2,y2)
Xchar pyx;
Xint *x1,*y1,x2,y2;
X{
X  int ox,oy,sx,sy,v;
X
X  do {
X    ox = *x1;
X    oy = *y1;
X    sx=sign(x2-*x1);
X    sy=sign(y2-*y1);
X    if (abs(x2-*x1) > abs(y2-*y1))
X      *x1 += sx;
X    else if (abs(x2-*x1) < abs(y2-*y1))
X      *y1 += sy;
X    else {
X      *x1 += sx;
X      *y1 += sy;
X    }
X    Level->site[*x1][*y1].showchar = pyx;
X    /* delay enough to make pyx visible */
X    for(v=1;v<10;v++) plotchar(pyx,*x1,*y1);
X    plotspot(ox,oy,FALSE);
X  } while(unblocked(*x1,*y1) && ((*x1 != x2) || (*y1 != y2)));
X  
X  plotspot(*x1,*y1,FALSE);
X  levelrefresh();
X}
X
X
X/* This is the same as do_los, except we stop before hitting nonliving
Xobstructions */
Xvoid do_object_los(pyx,x1,y1,x2,y2)
Xchar pyx;
Xint *x1,*y1,x2,y2;
X{
X  int ox,oy,sx,sy,v;
X
X  do {
X    ox = *x1;
X    oy = *y1;
X    sx=sign(x2-*x1);
X    sy=sign(y2-*y1);
X    if (abs(x2-*x1) > abs(y2-*y1))
X      *x1 += sx;
X    else if (abs(x2-*x1) < abs(y2-*y1))
X      *y1 += sy;
X    else {
X      *x1 += sx;
X      *y1 += sy;
X    }
X    if (unblocked(*x1,*y1)) {
X      for(v=1;v<10;v++) plotchar(pyx,*x1,*y1);
X      Level->site[*x1][*y1].showchar = pyx;
X    }
X    plotspot(ox,oy,TRUE);
X  } while(unblocked(*x1,*y1) && ((*x1 != x2) || (*y1 != y2)));
X  
X  if ((! unblocked(*x1,*y1)) && (Level->site[*x1][*y1].creature == NULL)) {
X    *x1 = ox;
X    *y1 = oy;
X  }
X  plotspot(*x1,*y1,TRUE);
X  levelrefresh();
X}
X      
X    
X
X
X/* los_p checks to see whether there is an unblocked los from x1,y1 to x2,y2 */
Xint los_p(x1,y1,x2,y2)
Xint x1,y1,x2,y2;
X{
X  int sx,sy;
X  do {
X    sx=sign(x2-x1);
X    sy=sign(y2-y1);
X    if (abs(x2-x1) > abs(y2-y1))
X      x1 += sx;
X    else if (abs(x2-x1) < abs(y2-y1))
X      y1 += sy;
X    else {
X      x1 += sx;
X      y1 += sy;
X    }
X  } while (unblocked(x1,y1) && ((x1 != x2) || (y1 != y2)));
X  return((x1==x2) && (y1==y2));
X}
X
X
X/* view_los_p sees through monsters */
Xint view_los_p(x1,y1,x2,y2)
Xint x1,y1,x2,y2;
X{
X  int sx,sy;
X  do {
X    sx=sign(x2-x1);
X    sy=sign(y2-y1);
X    if (abs(x2-x1) > abs(y2-y1))
X      x1 += sx;
X    else if (abs(x2-x1) < abs(y2-y1))
X      y1 += sy;
X    else {
X      x1 += sx;
X      y1 += sy;
X    }
X  } while (view_unblocked(x1,y1) && ((x1 != x2) || (y1 != y2)));
X  return((x1==x2) && (y1==y2));
X}
X
X
X
X#ifndef MSDOS
Xint gamestatusp(flag)
X#else
Xlong gamestatusp(flag)
X#endif
Xlong flag;
X{
X  return(GameStatus&flag);
X}
X
Xvoid setgamestatus(flag)
Xlong flag;
X{
X  GameStatus |= flag;
X}
X
Xvoid resetgamestatus(flag)
Xlong flag;
X{
X  GameStatus &= ~flag;
X}
X
X
X#ifndef MSDOS
X/* returns the command direction from the index into Dirs */
Xchar inversedir(dirindex)
Xint dirindex;	  
X{
X  switch (dirindex) {
X    case 0:return('n');break;
X    case 1:return('u');break;
X    case 2:return('b');break;
X    case 3:return('y');break;
X    case 4:return('l');break;
X    case 5:return('h');break;
X    case 6:return('j');break;
X    case 7:return('k');break;
X  }
X}
X#endif
X
X
X#ifndef MSDOS
Xint calc_points()
X#else
Xlong calc_points()
X#endif
X{
X#ifndef MSDOS
X  int i,points=0;
X#else
X  int i;
X  long points=0;
X#endif
X  
X  if (gamestatusp(SPOKE_TO_DRUID)) points += 50;
X  if (gamestatusp(COMPLETED_CAVES)) points += 100;
X  if (gamestatusp(COMPLETED_SEWERS)) points += 200;
X  if (gamestatusp(COMPLETED_CASTLE)) points += 300;
X  if (gamestatusp(COMPLETED_ASTRAL)) points += 400;
X  if (gamestatusp(COMPLETED_VOLCANO)) points += 500;
X  if (gamestatusp(KILLED_DRAGONLORD)) points += 100;
X  if (gamestatusp(KILLED_EATER)) points += 100;
X  if (gamestatusp(KILLED_LAWBRINGER)) points += 100;
X
X  points += Player.xp/50;
X
X  points += Player.cash/500;
X
X  for (i=0;i<MAXITEMS;i++) 
X    if (Player.possessions[i] != NULL)
X      points += Player.possessions[i]->level*(Player.possessions[i]->known+1);
X
X  for (i=0;i<MAXPACK;i++) 
X    if (Player.pack[i] != NULL)
X      points += Player.pack[i]->level*(Player.pack[i]->known+1);
X
X  for (i=0;i<NUMRANKS;i++) {
X    if (Player.rank[i] == 5) points += 500;
X    else points += 20*Player.rank[i];
X  }
X  
X  if (Player.hp < 1)
X    points = (points / 2);
X  
X  else if (Player.rank[ADEPT])
X    points *= 10;
X  
X  return(points);
X}
X
X
X/* returns the 24 hour clock hour */
Xint hour()
X{
X#ifndef MSDOS
X  return(((Time+720) / 60) % 24);
X#else
X  return((int)(((Time+720) / 60) % 24));
X#endif
X}
X
X/* returns 0, 10, 20, 30, 40, or 50 */
Xint showminute()
X{
X#ifndef MSDOS
X  return(((Time % 60)/10)*10);
X#else
X  return((int)((Time % 60)/10)*10);
X#endif
X}
X
X/* returns the 12 hour clock hour */
Xint showhour()
X{
X  int showtime;
X  if ((hour() == 0) || (hour() == 12)) showtime = 12;
X  else showtime = (hour() % 12);
X  return(showtime);
X}
X
X/* nighttime is defined from 9 PM to 6AM */
Xint nighttime()
X{
X  return((hour() > 20) || (hour() < 7));
X}
X
Xchar *getarticle(str)
Xchar *str;
X{
X  if ((str[0]=='a') || (str[0]=='A') ||
X      (str[0]=='e') || (str[0]=='E') ||
X      (str[0]=='i') || (str[0]=='I') ||
X      (str[0]=='o') || (str[0]=='O') ||
X      (str[0]=='u') || (str[0]=='U') ||
X      (((str[0]=='h') || (str[0]=='H')) && 
X       ((str[1]=='i') || (str[1]=='e'))))
X    return("an ");
X  else return("a ");
X}
X
Xint day()
X{
X  return ((Date % 30) + 1);
X}
X
Xchar *ordinal(number)
Xint number;
X{
X  if ((number == 11) || (number == 12) || (number == 13)) return("th");
X  else  switch(number % 10) {
X    case 1:return("st");break;
X    case 2:return("nd");break;
X    case 3:return("rd");break;
X    default: return("th");break;
X  }
X}
X	   
Xchar *month()
X{
X  switch((Date % 360) / 30) {
X    case 0: return("Freeze"); break;
X    case 1: return("Ice"); break;
X    case 2: return("Mud"); break;
X    case 3: return("Storm"); break;
X    case 4: return("Breeze"); break;
X    case 5: return("Light"); break;
X    case 6: return("Flame"); break;
X    case 7: return("Broil"); break;
X    case 8: return("Cool"); break;
X    case 9: return("Haunt"); break;
X    case 10: return("Chill"); break;
X    case 11: return("Dark"); break;
X    case 12: return("Twixt"); break;
X  }
X}
X
X
X/* finds floor space on level with buildaux not equal to baux, 
Xsets x,y there. There must *be* floor space somewhere on level.... */
X
Xvoid findspace(x,y,baux)
Xint *x,*y;
X{
X  int i,j,k,l,done=FALSE;
X  i = k = random_range(WIDTH);
X  j = l = random_range(LENGTH);
X  do {
X    i++;
X    if (i >= WIDTH) {
X      i = 0;
X      j++;
X      if (j > LENGTH)
X	j = 0;
X      done = ((i == k) && (j == l));
X    }
X    done = done || 
X      ((Level->site[i][j].locchar == FLOOR) &&
X       (Level->site[i][j].creature == NULL) &&
X       (Level->site[i][j].buildaux != baux));
X  } while (! done);
X  *x = i;
X  *y = j;
X}
X
X/* is prefix a prefix of s? */
Xint strprefix(prefix,s)
Xchar *prefix,*s;
X{
X  int i=0,matched=TRUE;
X  if (strlen(prefix) > strlen(s)) return(FALSE);
X  else {
X    while (matched && (i<strlen(prefix))) {
X      matched = (prefix[i] == s[i]);
X      i++;
X    }
X    return(matched);
X  }
X}
X
Xint confirmation()
X{
X  switch(random_range(4)) {
X  case 0:  mprint("Are you sure? [yn] "); break;
X  case 1:  mprint("Certain about that? [yn] "); break;
X  case 2:  mprint("Do you really mean it? [yn] "); break;
X  case 3:  mprint("Confirm that, would you? [yn] "); break;
X  }
X  return(ynq()=='y');
X}
X
X
X/* is character c a member of string s */
Xint strmem(c,s)
Xchar c;
Xchar *s;
X{
X  int i,found=FALSE;
X  for(i=0;((i<strlen(s)) && (! found));i++)
X    found = (s[i] == c);
X  return(found);
X}
X
X
X/* returns true if its ok to get rid of a level */
Xint ok_to_free(level)
Xplv level;
X{
X  if (level == NULL) return(FALSE);
X  else return((level->environment != E_CITY) &&
X	      (level->environment != E_VILLAGE) &&
X	      (level->environment != Current_Dungeon));
X}
X
X
Xvoid calc_weight()
X{
X  int i,weight=0;
X
X  for(i=1;i<MAXITEMS;i++) 
X    if (Player.possessions[i] != NULL)
X      weight += Player.possessions[i]->weight *
X	Player.possessions[i]->number;
X
X  if ((Player.possessions[O_WEAPON_HAND] != NULL) &&
X      (Player.possessions[O_READY_HAND] == Player.possessions[O_WEAPON_HAND]))
X    weight -= Player.possessions[O_READY_HAND]->weight *
X      Player.possessions[O_READY_HAND]->number;
X      
X  for(i=1;i<MAXPACK;i++) 
X    if (Player.pack[i] != NULL)
X      weight += Player.pack[i]->weight *
X	Player.pack[i]->number;
X
X  Player.itemweight = weight;
X
X  dataprint();
X}
X	  
X/* alloc just enough string space for str, strcpy, and return pointer */
Xchar *salloc(str)
Xchar *str;
X{
X  char *s=calloc((unsigned)(strlen(str)+1),sizeof(char));
X  strcpy(s,str);
X  return(s);
X}
X
X#ifdef MSDOS
X/* ****Moved here from another file**** */
X/* reads a string from a file. If it is a line with more than 80 char's,
X   then remainder of line to \n is consumed */
Xvoid filescanstring(fd,fstr)
XFILE *fd;
Xchar *fstr;
X{
X  int i= -1;
X  int byte='x';
X  while ((i<80) && (byte != '\n') && (byte != EOF)) {
X    i++;
X    byte=fgetc(fd);
X    fstr[i] = byte;
X  } 
X  if (byte != '\n')
X    while((byte!='\n') && (byte != EOF))
X      byte=fgetc(fd);
X  fstr[i]=0;
X}
X#endif
X
X#ifdef MSDOS
X/* ****Moved here from another file**** */
X/* returns a "level of difficulty" based on current environment
X   and depth in dungeon. Is somewhat arbitrary. value between 1 and 10.
X   May not actually represent real difficulty, but instead level
X   of items, monsters encountered.    */
Xint difficulty()
X{
X  int depth = 1;
X  if (Level != NULL) depth = Level->depth;
X  switch(Current_Environment) {
X  case E_COUNTRYSIDE: return(7); break;
X  case E_CITY: return(3); break;
X  case E_VILLAGE: return(1); break;
X  case E_TACTICAL_MAP: return(7); break;
X  case E_SEWERS: return(depth/6)+3;break;
X  case E_CASTLE: return(depth/4)+4;break;
X  case E_CAVES: return(depth/3)+1;break;
X  case E_VOLCANO: return(depth/4)+5;break;
X  case E_ASTRAL: return(8);break;
X  case E_ARENA: return(5);break;
X  case E_HOVEL: return(3);break;
X  case E_MANSION: return(7);break;
X  case E_HOUSE: return(5);break;
X  case E_DLAIR: return(9);break;
X  case E_ABYSS: return(10);break;
X  case E_STARPEAK: return(9);break;
X  case E_CIRCLE: return(8);break;
X  case E_MAGIC_ISLE: return(8);break;
X  case E_TEMPLE: return(8);break;
X  default: return(3); break;
X  }
X}
X#endif
END_OF_FILE
if test 14444 -ne `wc -c <'outil.c'`; then
    echo shar: \"'outil.c'\" unpacked with wrong size!
fi
# end of 'outil.c'
fi
echo shar: End of archive 16 \(of 20\).
cp /dev/null ark16isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 20 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0