[comp.sources.games] v07i032: 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 32
Archive-name: omega3/Part13
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 13 (of 20)."
# Contents:  oaux1.c ocity.c oenv.c
# Wrapped by billr@saab on Thu Jun 29 08:14:08 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'oaux1.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'oaux1.c'\"
else
echo shar: Extracting \"'oaux1.c'\" \(25805 characters\)
sed "s/^X//" >'oaux1.c' <<'END_OF_FILE'
X/* omega copyright (C) by Laurence Raphael Brothers, 1987,1988,1989 */
X
X/* oaux1.c */
X
X/* auxiliary functions for those in ocom.c, also see oaux2.c 
X   and oaux3.c */ 
X
X#include "oglob.h"
X
X
X
X/* check to see if too much tunneling has been done in this level */
Xvoid tunnelcheck()
X{
X  Level->tunnelled++;
X  if ((Level->tunnelled) > LENGTH/4)
X    mprint("Dust and stone fragments fall on you from overhead.");
X  if ((Level->tunnelled) > LENGTH/2)
X    mprint("You hear groaning and creaking noises.");
X  if ((Level->tunnelled) > 3*LENGTH/4) 
X    mprint("The floor trembles and you hear a loud grinding screech.");
X  if ((Level->tunnelled) > LENGTH) {
X    mprint("With a scream of tortured stone, the entire level caves in!!!");
X    gain_experience(5000);
X    mprint("You are flattened into an unpleasant jellylike substance.");
X    p_death("dungeon cave-in");
X  }
X}
X
X/* displays a room's name */
Xvoid showroom(i)
Xint i;
X{
X  strcpy(Str1,"");
X  strcpy(Str2,"");
X  switch(Current_Environment) {
X  case E_MANSION:
X    strcpy(Str2,"A luxurious mansion: ");
X    break;
X  case E_HOUSE:
X    strcpy(Str2,"A house:");
X    break;
X  case E_HOVEL:
X    strcpy(Str2,"A hovel:");
X    break;
X  case E_CITY:
X    strcpy(Str2,"The City of Rampart");
X    break;
X  case E_VILLAGE:
X    switch(Villagenum) {
X    case 1: strcpy(Str2,"The Village of Star View"); break;
X    case 2: strcpy(Str2,"The Village of Woodmere"); break;
X    case 3: strcpy(Str2,"The Village of Stormwatch"); break;
X    case 4: strcpy(Str2,"The Village of Thaumaris"); break;
X    case 5: strcpy(Str2,"The Village of Skorch"); break;
X    case 6: strcpy(Str2,"The Village of Whorfen"); break;
X    }
X    break;
X  case E_CAVES:
X    strcpy(Str2,"The Goblin Caves: ");
X    break;
X  case E_CASTLE:
X    strcpy(Str2,"The Archmage's Castle: ");
X    break;
X  case E_ASTRAL:
X    strcpy(Str2,"The Astral Plane: ");
X    break;
X  case E_VOLCANO:
X    strcpy(Str2,"The Volcano: ");
X    break;
X  case E_SEWERS:
X    strcpy(Str2,"The Sewers: ");
X    break;
X  case E_TACTICAL_MAP:
X    strcpy(Str2,"The Tactical Map ");
X    break;
X  }
X  if ((Current_Environment == E_MANSION) ||
X      (Current_Environment == E_HOUSE)) 
X    strcpy(Str1,roomname(i));
X  else if (Current_Environment == Current_Dungeon) {
X    strcpy(Str1,"Level ");
X    if (Level->depth < 10) {
X      Str1[6] = Level->depth + '0';
X      Str1[7] = 0;
X    }
X    else {
X      Str1[6] = (Level->depth / 10) + '0';
X      Str1[7] = (Level->depth % 10) + '0';
X      Str1[8] = 0;
X    }
X    strcat(Str1," (");
X    strcat(Str1,roomname(i));
X    strcat(Str1,")");
X  }
X  strcat(Str2,Str1);
X  locprint(Str2);
X}
X
X
Xint player_on_sanctuary()
X{
X  if ((Player.x==Player.sx) &&
X      (Player.y==Player.sy))
X    return(TRUE);
X  else {
X    if (Player.patron) {
X      if ((Level->site[Player.x][Player.y].locchar == ALTAR) &&
X	  (Level->site[Player.x][Player.y].aux == Player.patron))
X	return(TRUE);
X      else return(FALSE);
X    }
X    else return(FALSE);
X  }
X}
X
X
X/* check a move attempt, maybe attack something, return TRUE if ok to move. */
X/* x y is the proposed place to move to */
Xint p_moveable(x,y)
Xint x,y;
X{
X  setgamestatus(SKIP_MONSTERS);
X  if (! inbounds(x,y)) return (FALSE);
X  else if (Player.status[SHADOWFORM]) {
X    resetgamestatus(SKIP_MONSTERS);
X    return(TRUE);
X  }
X  else if (loc_statusp(x,y,SECRET)) {
X    if (!gamestatusp(FAST_MOVE)) print3("Ouch!");
X    return(FALSE);
X  }
X  else if (Level->site[x][y].creature != NULL) {
X    if (! gamestatusp(FAST_MOVE)) {
X      fight_monster(Level->site[x][y].creature);
X      resetgamestatus(SKIP_MONSTERS);
X      return(FALSE);
X    }
X    else return(FALSE);
X  }
X  else if ((Level->site[x][y].locchar == WALL) ||
X	   (Level->site[x][y].locchar == STATUE) ||
X	   (Level->site[x][y].locchar == PORTCULLIS) ||
X	   (Level->site[x][y].locchar == CLOSED_DOOR) ||
X	   (gamestatusp(FAST_MOVE) &&
X	    ((Level->site[x][y].locchar == HEDGE) ||
X	     (Level->site[x][y].locchar == LAVA) ||
X	     (Level->site[x][y].locchar == ABYSS) ||
X	     (Level->site[x][y].locchar == FIRE) ||
X	     (Level->site[x][y].locchar == WATER) ||
X	     (Level->site[x][y].locchar == LIFT) ||
X	     (Level->site[x][y].locchar == TRAP)))) {
X    if (! gamestatusp(FAST_MOVE)) print3("Ouch!");
X    return(FALSE);
X  }
X  else if (optionp(CONFIRM)) {
X    if ((Level->site[x][y].locchar == HEDGE) ||
X	(Level->site[x][y].locchar == LAVA) ||
X	(Level->site[x][y].locchar == FIRE) ||
X	(Level->site[x][y].locchar == ABYSS) ||
X	(Level->site[x][y].locchar == WATER) ||
X	(Level->site[x][y].locchar == RUBBLE) ||
X	(Level->site[x][y].locchar == LIFT) ||
X	(Level->site[x][y].locchar == TRAP)) {
X      /* horses WILL go into water... */
X      if (gamestatusp(MOUNTED)) {
X	if (Level->site[x][y].locchar != WATER) {
X	  print1("You can't convince your steed to continue.");
X	  setgamestatus(SKIP_MONSTERS);
X	  return(FALSE);
X	}
X	else return(TRUE);
X      }
X      else if (confirmation()) resetgamestatus(SKIP_MONSTERS);
X      else setgamestatus(SKIP_MONSTERS);
X      return(!gamestatusp(SKIP_MONSTERS));
X    }
X    else {
X      resetgamestatus(SKIP_MONSTERS);
X      return(TRUE);
X    }
X  }
X  else {
X    resetgamestatus(SKIP_MONSTERS);
X    return(TRUE);
X  }
X}
X
X
X
X/* check a move attempt in the countryside */
Xint p_country_moveable(x,y)
Xint x,y;
X{
X  if (! inbounds(x,y)) return (FALSE);
X  else if (optionp(CONFIRM)) {
X    if ((Country[x][y].current_terrain_type == CHAOS_SEA) ||
X	(Country[x][y].current_terrain_type == MOUNTAINS))
X      return(confirmation());
X    else return(TRUE);
X  }
X  else return(TRUE);
X}
X
X
X
X
X
X/* search once particular spot */
Xvoid searchat(x,y)
Xint x,y;
X{
X  int i;
X  if (inbounds(x,y) && (random_range(3) || Player.status[ALERT])) {
X    if (loc_statusp(x,y,SECRET)) {
X      lreset(x,y,SECRET);
X      if ((Level->site[x][y].locchar==OPEN_DOOR) ||
X	  (Level->site[x][y].locchar==CLOSED_DOOR))
X	mprint("You find a secret door!");
X      else mprint("You find a secret passage!");
X      for(i=0;i<8;i++)
X	lset(x+Dirs[0][i],y+Dirs[1][i],STOPS);
X      drawvision(Player.x,Player.y);
X    }
X    if ((Level->site[x][y].p_locf >= TRAP_BASE) &&
X	(Level->site[x][y].locchar != TRAP) &&
X	(Level->site[x][y].p_locf <= TRAP_BASE+NUMTRAPS)) {
X      Level->site[x][y].locchar = TRAP;
X      mprint("You find a trap!");
X      drawvision(Player.x,Player.y);
X      resetgamestatus(FAST_MOVE);
X    }
X  }
X}
X
X
X
X/* This is to be called whenever anything might change player performance in
X   melee, such as changing weapon, statistics, etc. */
Xvoid calc_melee()
X{
X  calc_weight();
X
X  Player.maxweight = (Player.str * Player.agi * 10);
X  Player.absorption = Player.status[PROTECTION];
X  Player.defense = 2 * statmod(Player.agi)+(Player.level/2);
X  Player.hit = Player.level + statmod(Player.dex)+1;
X  Player.dmg = statmod(Player.str)+3;
X  Player.speed = 5 - min(4,(statmod(Player.agi)/2));
X  if (Player.status[HASTED] > 0) Player.speed = Player.speed / 2;
X  if (Player.status[SLOWED] > 0) Player.speed = Player.speed * 2;
X  if (Player.itemweight > 0)
X    switch(Player.maxweight / Player.itemweight) {
X    case 0: Player.speed+=6; break;
X    case 1: Player.speed+=3; break;
X    case 2: Player.speed+=2; break;
X    case 3: Player.speed+=1; break;
X    }
X  
X  if (Player.status[ACCURATE]) Player.hit+=20;
X  if (Player.status[HERO]) Player.hit+=Player.dex;
X  if (Player.status[HERO]) Player.dmg+=Player.str;
X  if (Player.status[HERO]) Player.defense+=Player.agi;
X  if (Player.status[HERO]) Player.speed=Player.speed / 2;
X
X  Player.speed = max(1,min(25,Player.speed));
X
X  if (gamestatusp(MOUNTED)) {
X    Player.speed = 3;
X    Player.hit += 10;
X    Player.dmg += 10;
X  }
X
X  /* weapon */
X  /* have to check for used since it could be a 2h weapon just carried
X     in one hand */
X  if (Player.possessions[O_WEAPON_HAND] != NULL) 
X    if (Player.possessions[O_WEAPON_HAND]->used &&
X	((Player.possessions[O_WEAPON_HAND]->objchar==WEAPON)||
X	 (Player.possessions[O_WEAPON_HAND]->objchar==MISSILEWEAPON))) {
X      Player.hit += 
X	Player.possessions[O_WEAPON_HAND]->hit + 
X	  Player.possessions[O_WEAPON_HAND]->plus;
X      Player.dmg += 
X	Player.possessions[O_WEAPON_HAND]->dmg + 
X	  Player.possessions[O_WEAPON_HAND]->plus;
X    }
X  
X  /* shield or defensive weapon */
X  if (Player.possessions[O_SHIELD] != NULL) {
X    Player.defense += 
X      Player.possessions[O_SHIELD]->aux + 
X	Player.possessions[O_SHIELD]->plus;
X  }
X  
X  /* armor */
X  if (Player.possessions[O_ARMOR] != NULL) {
X    Player.absorption += Player.possessions[O_ARMOR]->dmg;
X    Player.defense += 
X      Player.possessions[O_ARMOR]->plus - 
X	Player.possessions[O_ARMOR]->aux;
X  }
X
X  if (strlen(Player.meleestr) > 2*maneuvers())
X    default_maneuvers();
X  comwinprint();
X  showflags();
X  dataprint();
X}
X
X
X/* player attacks monster m */
Xvoid fight_monster(m)
Xstruct monster *m;
X{
X  int hitmod = 0;
X  int reallyfight = TRUE;
X
X  if (Player.status[AFRAID]) {
X    print3("You are much too afraid to fight!");
X    reallyfight = FALSE;
X  }
X  else if (player_on_sanctuary()) {
X    print3("You restrain yourself from desecrating this holy place.");
X    reallyfight = FALSE;
X  }
X  else if (Player.status[SHADOWFORM]) {
X    print3("Your attack has no effect in your shadowy state.");
X    reallyfight = FALSE;
X  }
X  else if ((Player.status[BERSERK]<1) && (! m_statusp(m,HOSTILE))) {
X    if (optionp(BELLICOSE)) reallyfight = TRUE;
X    else reallyfight = confirmation();
X  }
X  else reallyfight = TRUE;
X  
X  if (reallyfight) {
X
X    if (Lunarity == 1) hitmod += Player.level;
X    else if (Lunarity == -1) hitmod -= (Player.level / 2);
X
X    if (! m->attacked) Player.alignment -= 2; /* chaotic action */
X    m_status_set(m,AWAKE);
X    m_status_set(m,HOSTILE);
X    m->attacked = TRUE;
X    Player.hit += hitmod;
X    tacplayer(m);
X    Player.hit -= hitmod;
X  }
X}
X
X
X
X
X/* Attempt to break an object o */
Xvoid damage_item(o)
Xpob o;     
X{
X  int i;
X  /* special case -- break star gem */
X  if (o->id == ARTIFACTID+21) {
X    print1("The Star Gem shatters into a million glistening shards....");
X    if (Current_Environment == E_STARPEAK) {
X      if (! gamestatusp(KILLED_LAWBRINGER))
X	print2("You hear an agonizing scream of anguish and despair.");
X      morewait();
X      print1("A raging torrent of energy escapes in an explosion of magic!");
X      print2("The energy flows to the apex of Star Peak where there is");
X      morewait();
X      clearmsg();
X      print1("an enormous explosion!");
X      morewait();
X      annihilate(1);
X      print3("You seem to gain strength in the chaotic glare of magic!");
X      Player.str = Player.maxstr + 5;
X      Player.pow = Player.maxpow + 5;
X      Player.alignment -= 200;
X      dispose_lost_objects(1,o);
X    }
X    else {
X      morewait();
X      print1("The shards coalesce back together again, and vanish");
X      print2("with a muted giggle.");
X      dispose_lost_objects(1,o);
X    }
X  }
X  else {
X    if (o->fragility < random_range(30)) {
X      if (o->objchar == STICK) {
X	strcpy(Str1,"Your ");
X	strcat(Str1,(o->blessing >= 0 ? o->truename : o->cursestr));
X	strcat(Str1," explodes!");
X	print1(Str1);
X	morewait();
X	if (o->charge < 1)
X	  nprint1(" Fzzz... Out of Power... Oh well...");
X	else {
X	  nprint1(" Ka-Blamm!!!");
X	  /* general case. Some sticks will eventually do special things */
X	  morewait();
X	for(i=0;i<9;i++)
X	  manastorm(Player.x+Dirs[0][i],
X		    Player.y+Dirs[1][i],
X		    o->charge*o->level*10);
X	  dispose_lost_objects(1,o);
X	}
X      }
X      else if ((o->blessing > 0) && (o->level >= random_range(10))) {
X	strcpy(Str1,"Your ");
X	strcat(Str1,itemid(o));
X	strcat(Str1," glows strongly.");
X	print1(Str1);
X      }
X      else if ((o->blessing < -1) && (o->level >= random_range(10))) {
X	strcpy(Str1,"You hear an evil giggle from your ");
X	strcat(Str1,itemid(o));
X	print1(Str1);
X      }
X      else if (o->plus > 0) {
X	strcpy(Str1,"Your ");
X	strcat(Str1,itemid(o));
X	strcat(Str1," glows and then fades.");
X	print1(Str1);
X	o->plus--;
X      }
X      else {
X	if (o->blessing > 0) print1("You hear a faint despairing cry!");
X	else if (o->blessing < 0) print1("You hear an agonized scream!");
X	strcpy(Str1,"Your ");
X	strcat(Str1,itemid(o));
X	strcat(Str1," shatters in a thousand lost fragments!");
X	print2(Str1);
X	dispose_lost_objects(1,o);
X      }
X    }
X  }
X}
X      
X      
X
X
X
X
X
X/* do dmg points of damage of type dtype, from source fromstring */
Xvoid p_damage(dmg,dtype,fromstring)
Xint dmg,dtype;
Xchar *fromstring;
X{
X  if (! p_immune(dtype)) {
X    if (gamestatusp(FAST_MOVE)) {
X      drawvision(Player.x,Player.y);
X      resetgamestatus(FAST_MOVE);
X    }
X    if (dtype == NORMAL_DAMAGE) Player.hp -= max(1,(dmg-Player.absorption));
X    else Player.hp -= dmg;
X    if (Player.hp < 1) p_death(fromstring);
X  }
X  else mprint("You resist the effects!");
X  dataprint();
X}
X
X/* game over, you lose! */
Xvoid p_death(fromstring)
Xchar *fromstring;
X{
X  Player.hp = -1;
X  print3("You died!");
X  morewait();
X  display_death(fromstring);
X#ifdef MSDOS
X  kill_all_levels();
X#endif
X  endgraf();
X  exit(0);
X}
X
X
X/* move the cursor around, like for firing a wand, sets x and y to target */
Xvoid setspot(x,y)
Xint *x,*y;
X{
X  char c = ' ';
X  mprint("Targeting.... ? for help");
X  showcursor(*x,*y);
X  while ((c != '.') && (c != ESCAPE)) {
X    c = lgetc();
X    switch(c) {
X      case 'h':case '4': movecursor(x,y,-1,0);  break;
X      case 'j':case '2': movecursor(x,y,0,1);  break;
X      case 'k':case '8': movecursor(x,y,0,-1);  break;
X      case 'l':case '6': movecursor(x,y,1,0);  break;
X      case 'b':case '1': movecursor(x,y,-1,1);  break;
X      case 'n':case '3': movecursor(x,y,1,1);  break;
X      case 'y':case '7': movecursor(x,y,-1,-1);  break;
X      case 'u':case '9': movecursor(x,y,1,-1);  break;
X      case '?':
X	clearmsg();
X	mprint("Use vi keys or numeric keypad to move cursor to target.");
X	mprint("Hit the '.' key when done, or ESCAPE to abort.");
X	break;
X    }
X  }
X  if (c==ESCAPE) *x = *y= ABORT;
X  screencheck(Player.y);
X}
X
X
X/* get a direction: return index into Dirs array corresponding to direction */
Xint getdir()
X{
X  int ok = TRUE;
X  do {
X    mprint("Select direction [hjklyubn, ESCAPE to quit]: ");
X    switch (mgetc()) {
X    case '4':
X    case 'h':
X    case 'H': return(5); break;
X    case '2':
X    case 'j':
X    case 'J': return(6); break;
X    case '8':
X    case 'k':
X    case 'K': return(7); break;
X    case '6':
X    case 'l':
X    case 'L': return(4); break;
X    case '7':
X    case 'y':
X    case 'Y': return(3); break;
X    case '9':
X    case 'u':
X    case 'U': return(1); break;
X    case '1':
X    case 'b':
X    case 'B': return(2); break;
X    case '3':
X    case 'n':
X    case 'N': return(0); break;
X    case ESCAPE: return(ABORT); break;
X    default: print3("That's not a direction! "); ok = FALSE; break;
X    }
X  } while (! ok);
X}
X
X
X
X
X/* bitwise access functions to Player.options */
X
Xint optionp(o)
Xint o;
X{
X  return(Player.options&o);
X}
X
Xvoid optionset(o)
Xint o;
X{
X  Player.options |= o;
X}
X
Xvoid optionreset(o)
Xint o;
X{
X  Player.options &= ~o;
X}
X
X
X
X/* functions describes monster m's state for examine function */      
Xchar *mstatus_string(m)
Xstruct monster *m;
X{
X  if (m->uniqueness == COMMON) {
X    if (m->hp < Monsters[m->id].hp / 3)
X      strcpy(Str2,"a grievously injured ");
X    else if (m->hp < Monsters[m->id].hp / 2)
X      strcpy(Str2,"a severely injured ");
X    else if (m->hp < Monsters[m->id].hp)
X      strcpy(Str2,"an injured ");
X    else strcpy(Str2,getarticle(m->monstring));
X    if (m->level > Monsters[m->id].level) {
X      strcat(Str2," (level ");
X      strcat(Str2,wordnum(m->level+1-Monsters[m->id].level));
X      strcat(Str2,") ");
X    }
X    strcat(Str2,m->monstring);
X  }
X  else {
X    strcpy(Str2,m->monstring);
X    if (m->hp < Monsters[m->id].hp / 3)
X      strcat(Str2," who is grievously injured ");
X    else if (m->hp < Monsters[m->id].hp / 2)
X      strcat(Str2," who is severely injured ");
X    else if (m->hp < Monsters[m->id].hp)
X      strcat(Str2," who is injured ");
X  }
X  return(Str2);
X}
X
X
X
X
X/* for the examine function */
Xvoid describe_player()
X{
X  if (Player.hp < (Player.maxhp /5))
X    print1("A grievously injured ");
X  else if (Player.hp < (Player.maxhp /2))
X    print1("A seriously wounded ");
X  else if (Player.hp < Player.maxhp)
X    print1("A somewhat bruised ");
X  else print1("A fit ");
X
X  nprint1(levelname(Player.level));
X  nprint1(" named ");
X  nprint1(Player.name);
X}
X
X
X/* access to player experience... */
X/* share out experience among guild memberships */
X#ifndef MSDOS
Xvoid gain_experience(amount)
Xint amount;
X{
X  int i,count=0,share;
X  Player.xp += amount;
X  gain_level(); /* actually, check to see if should gain level */
X  for(i=0;i<NUMRANKS;i++)
X    if (Player.guildxp[i] > 0) count++;
X  share = amount/(max(count,1));
X  for(i=0;i<NUMRANKS;i++)
X    if (Player.guildxp[i] > 0) Player.guildxp[i]+=share;
X}
X#else
Xvoid gain_lexperience(amount)
Xlong amount;
X{
X  int i,count=0;
X  long share;
X  Player.xp += amount;
X  gain_level(); /* actually, check to see if should gain level */
X  for(i=0;i<NUMRANKS;i++)
X    if (Player.guildxp[i] > 0) count++;
X  share = amount/(max(count,1));
X  for(i=0;i<NUMRANKS;i++)
X    if (Player.guildxp[i] > 0) Player.guildxp[i]+=share;
X}
X#endif
X
X
X/* try to hit a monster in an adjacent space. If there are none
X   return FALSE. Note if you're berserk you get to attack ALL
X   adjacent monsters! */
Xint goberserk()
X{
X  int wentberserk=FALSE,i;
X  char meleestr[80];
X  strcpy(meleestr,Player.meleestr);
X  strcpy(Player.meleestr,"ALACAH");
X  for(i=0;i<8;i++)
X    if (Level->site
X	[Player.x+Dirs[0][i]]
X	[Player.y+Dirs[1][i]]
X	.creature
X	!= NULL) {
X      wentberserk=TRUE;
X      fight_monster(Level->site
X		    [Player.x+Dirs[0][i]]
X		    [Player.y+Dirs[1][i]]
X		    .creature);
X      morewait();
X    }
X  strcpy(Player.meleestr,meleestr);
X  return(wentberserk);
X}
X
X/* identifies a trap for examine() by its aux value */
Xchar *trapid(trapno)
Xint trapno;
X{
X  switch (trapno) {
X  case L_TRAP_SIREN:return("A siren trap");break;
X  case L_TRAP_DART:return("A dart trap");break;
X  case L_TRAP_PIT:return("A pit");break;
X  case L_TRAP_SNARE:return("A snare");break;
X  case L_TRAP_BLADE:return("A blade trap");break;
X  case L_TRAP_FIRE:return("A fire trap");break;
X  case L_TRAP_TELEPORT:return("A teleport trap");break;
X  case L_TRAP_DISINTEGRATE:return("A disintegration trap");break;
X  case L_TRAP_DOOR:return("A trap door");break;
X  case L_TRAP_MANADRAIN:return("A manadrain trap");break;
X  case L_TRAP_ACID:return("An acid shower trap");break;
X  case L_TRAP_SLEEP_GAS:return("A sleep gas trap");break;
X  case L_TRAP_ABYSS:return("A concealed entrance to the abyss");break;
X  default: return("A completely inoperative trap.");break;
X  }
X}
X
X
X/* checks current food status of player, every hour, and when food is eaten */
Xvoid foodcheck()
X{
X  if (Player.food > 48) {
X    print3("You vomit up your huge meal.");
X    Player.food = 12;
X  }
X  else if (Player.food == 30) 
X    print3("Time for a smackerel of something.");
X  else if (Player.food == 20) 
X    print3("You feel hungry.");
X  else if (Player.food == 12) 
X    print3("You are ravenously hungry.");
X  else if (Player.food == 3) {
X    print3("You feel weak.");
X    if (gamestatusp(FAST_MOVE)) {
X      drawvision(Player.x,Player.y);
X      resetgamestatus(FAST_MOVE);
X    }
X  }
X  else if (Player.food < 0) {
X    if (gamestatusp(FAST_MOVE)) {
X      drawvision(Player.x,Player.y);
X      resetgamestatus(FAST_MOVE);
X    }
X    print3("You're starving!");
X    p_damage(-5*Player.food,UNSTOPPABLE,"starvation");
X  }
X  showflags();
X}
X
X
X
X
X/* see whether room should be illuminated */
Xvoid roomcheck()
X{
X  static int oldroomno = -1;
X  static plv oldlevel = NULL;
X  int roomno = Level->site[Player.x][Player.y].roomnumber;
X
X  if ((roomno == RS_CAVERN) ||
X      (roomno == RS_SEWER_DUCT) || 
X      (roomno == RS_KITCHEN) ||
X      (roomno == RS_BATHROOM) ||
X      (roomno == RS_BEDROOM) ||
X      (roomno == RS_DININGROOM) ||
X      (roomno == RS_CLOSET) ||
X      (roomno > ROOMBASE))
X    if ((! loc_statusp(Player.x,Player.y,LIT)) && 
X	(! Player.status[BLINDED]) &&
X	(Player.status[ILLUMINATION] || (difficulty() < 6))) {
X      showroom(Level->site[Player.x][Player.y].roomnumber);
X      spreadroomlight(Player.x,Player.y,roomno);
X      levelrefresh();
X    }
X  if ((oldroomno != roomno) || (oldlevel != Level)) {
X    showroom(roomno);
X    oldroomno = roomno;
X    oldlevel = Level;
X  }
X}
X
X
X
X
X
X/* ask for mercy */
Xvoid surrender(m)
Xstruct monster *m;
X{
X  int i,bestitem,bestvalue;
X  pml ml;
X  switch(random_range(4)) {
X  case 0: print1("You grovel at the monster's feet..."); break;
X  case 1: print1("You cry 'uncle'!"); break;
X  case 2: print1("You beg for mercy."); break;
X  case 3: print1("You yield to the monster."); break;
X  }
X  if ((m->id == ML0+3) && (! m_statusp(m,HOSTILE))) {
X    print2("The guard (bored): Have you broken a law? [yn] ");
X    if (ynq2() == 'y') {
X      print2("The guard grabs you, and drags you to court.");
X      for(ml=Level->mlist;ml!=NULL;ml=ml->next)
X	if (ml->m->id == ML0+3)
X	  m_status_reset(ml->m,HOSTILE);
X      morewait();
X      send_to_jail();
X    }
X    else print2("Then don't bother me. Scat!");
X  }
X  else if ((m->talkf==M_NO_OP) ||
X	   (m->talkf==M_TALK_STUPID))
X    print3("Your plea is ignored.");
X  else  {
X    morewait();
X    print1("Your surrender is accepted.");
X    if (Player.cash > 0) nprint1(" All your gold is taken....");
X    Player.cash = 0;
X    bestvalue = 0;
X    bestitem = ABORT;
X    for (i=1;i<MAXITEMS;i++)
X      if (Player.possessions[i] != NULL)
X	if (bestvalue < true_item_value(Player.possessions[i])) {
X          bestitem = i;
X          bestvalue = true_item_value(Player.possessions[i]);
X        }
X    if (bestitem != ABORT) {
X      print2("You also give away your best item... ");
X      nprint2(itemid(Player.possessions[bestitem]));
X      nprint2(".");
X      morewait();
X      givemonster(m,Player.possessions[bestitem]);
X      morewait(); /* msgs come from givemonster */
X      conform_lost_object(Player.possessions[bestitem]);
X    }
X    print2("You feel less experienced... ");
X    Player.xp = max(0,Player.xp - m->xpv);
X    nprint2("The monster seems more experienced!");
X    m->level = (min(10,m->level+1));
X    m->hp += m->level*20;
X    m->hit += m->level;
X    m->dmg += m->level;
X    m->ac += m->level;
X    m->xpv += m->level*10;
X    morewait();
X    clearmsg();
X    if ((m->talkf == M_TALK_EVIL) && random_range(10)) {
X      print1("It continues to attack you, laughing evilly!");
X      m_status_set(m,HOSTILE);
X      m_status_reset(m,GREEDY);
X    }
X    else if (m->id == ML0+0 || m->id == ML0+3)
X      print1("It continues to attack you. ");
X    else {
X      print1("The monster leaves, chuckling to itself....");
X      m_teleport(m);
X    }
X  }
X  dataprint();
X}
X
X
X/* threaten a monster */
Xvoid threaten(m)
Xstruct monster *m;
X{
X  char response;
X  switch(random_range(4)) {
X  case 0:mprint("You demand that your opponent surrender!"); break;
X  case 1:mprint("You threaten to do bodily harm to it."); break;
X  case 2:mprint("You attempt to bluster it into submission."); break;
X  case 3:mprint("You try to cow it with your awesome presence."); break;
X  }
X  if (! m_statusp(m,HOSTILE)) {
X    print3("You only annoy it with your futile demand.");
X    m_status_set(m,HOSTILE);
X  }
X  else if (((m->level*2 > Player.level) && (m->hp > Player.dmg)) || 
X	   (m->uniqueness != COMMON))
X    print1("It sneers contemptuously at you.");
X  else if ((m->talkf != M_TALK_GREEDY) &&
X	   (m->talkf != M_TALK_HUNGRY) &&
X	   (m->talkf != M_TALK_EVIL) &&
X	   (m->talkf != M_TALK_MAN) &&
X	   (m->talkf != M_TALK_BEG) &&
X	   (m->talkf != M_TALK_THIEF) &&
X	   (m->talkf != M_TALK_MERCHANT) &&
X	   (m->talkf != M_TALK_IM)) 
X    print1("Your demand is ignored");
X  else {
X    print1("It yields to your mercy.");
X    Player.alignment+=3;
X    print2("Kill it, rob it, or free it? [krf] ");
X    do response = mcigetc();
X    while ((response != 'k')&&(response != 'r')&&(response !='f'));
X    if (response == 'k') {
X      m_death(m);
X      print2("You treacherous rogue!");
X      Player.alignment -= 13;
X    }
X    else if (response == 'r') {
X      Player.alignment-=2;
X      print2("It drops its treasure and flees.");
X      m_dropstuff(m);
X      m->hp = -1;
X      Level->site[m->x][m->y].creature = NULL;
X      putspot(m->x,m->y,getspot(m->x,m->y,FALSE));
X    }
X    else {
X      Player.alignment+=2;
X      print2("'If you love something set it free ... '");
X      if (random_range(100)==13) {
X	morewait();
X	print2("'...If it doesn't come back, hunt it down and kill it.'");
X      }
X      print3("It departs with a renewed sense of its own mortality.");
X      m->hp = -1;
X      Level->site[m->x][m->y].creature = NULL;
X      putspot(m->x,m->y,getspot(m->x,m->y,FALSE));
X    }
X  }
X}
X
X/* name of the player's experience level */
Xchar *levelname(level)
X{
X  switch(level) {
X  case 0:strcpy(Str3,"neophyte");break;
X  case 1:strcpy(Str3,"beginner");break;
X  case 2:strcpy(Str3,"tourist");break;
X  case 3:strcpy(Str3,"traveller");break;
X  case 4:strcpy(Str3,"wayfarer");break;
X  case 5:strcpy(Str3,"peregrinator");break;
X  case 6:strcpy(Str3,"wanderer");break;
X  case 7:strcpy(Str3,"hunter");break;
X  case 8:strcpy(Str3,"scout");break;
X  case 9:strcpy(Str3,"trailblazer");break;
X  case 10:strcpy(Str3,"discoverer");break;
X  case 11:strcpy(Str3,"explorer");break;
X  case 12:strcpy(Str3,"senior explorer");break;
X  case 13:strcpy(Str3,"ranger");break;
X  case 14:strcpy(Str3,"ranger captain");break;
X  case 15:strcpy(Str3,"ranger knight");break;
X  case 16:strcpy(Str3,"adventurer");break;
X  case 17:strcpy(Str3,"experienced adventurer");break;
X  case 18:strcpy(Str3,"skilled adventurer");break;
X  case 19:strcpy(Str3,"master adventurer");break;
X  case 20:strcpy(Str3,"hero");break;
X  case 21:strcpy(Str3,"superhero");break;
X  case 22:strcpy(Str3,"demigod");break;
X  default:
X    if (level < 100) {
X      strcpy(Str3,"Order ");
X      Str3[6] = ((level/10)-2) + '0';
X      Str3[7] = 0;
X      strcat(Str3," Master of Omega");
X    }
X    else strcpy(Str3,"Ultimate Master of Omega");
X    break;
X  }
X  return(Str3);
X}
END_OF_FILE
if test 25805 -ne `wc -c <'oaux1.c'`; then
    echo shar: \"'oaux1.c'\" unpacked with wrong size!
fi
# end of 'oaux1.c'
fi
if test -f 'ocity.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ocity.c'\"
else
echo shar: Extracting \"'ocity.c'\" \(16928 characters\)
sed "s/^X//" >'ocity.c' <<'END_OF_FILE'
X/* omega copyright (C) by Laurence Raphael Brothers, 1987,1988,1989 */
X/* ocity.c */
X/* some functions to make the city level */
X
X#include "oglob.h"
X
X
X/* loads the city level */
Xvoid load_city()
X{
X  int i,j;
X  pml ml;
X  char site;
X  
X  FILE *fd;
X  
X  for(i=0;i<NUMCITYSITES;i++) 
X    CitySiteList[i][0] = FALSE;
X
X  strcpy(Str3,OMEGALIB);
X  strcat(Str3,"ocity.dat");
X  fd = fopen(Str3,"r");
X
X
X  TempLevel = Level;
X  if (ok_to_free(TempLevel)) {
X#ifndef MSDOS
X    free((char *) TempLevel);
X#endif
X    TempLevel = NULL;
X  }
X#ifndef MSDOS
X  Level = ((plv) malloc(sizeof(levtype)));
X#else
X  msdos_changelevel(TempLevel,0,-1);
X  Level = &TheLevel;
X#endif
X  clear_level(Level);
X  Level->depth = 0;
X  Level->environment = E_CITY;
X  for(j=0;j<LENGTH;j++) {
X    for(i=0;i<WIDTH;i++) {
X      lset(i,j,SEEN);
X      site = getc(fd);
X
X      switch(site) {
X      case 'g':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_GARDEN;
X	break;
X      case 'z':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_MAZE;
X	break;
X      case 'y':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_CEMETARY;
X	break;
X      case 'x':
X	assign_city_function(i,j);
X	break;
X      case 't':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_TEMPLE;
X	CitySiteList[L_TEMPLE-CITYSITEBASE][0] = TRUE;
X	CitySiteList[L_TEMPLE-CITYSITEBASE][1] = i;
X	CitySiteList[L_TEMPLE-CITYSITEBASE][2] = j;
X	break;
X      case 'T':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_PORTCULLIS_TRAP;
X	Level->site[i][j].aux = NOCITYMOVE;
X	break;
X      case 'R':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_RAISE_PORTCULLIS;
X	Level->site[i][j].aux = NOCITYMOVE;
X	break;
X      case '7':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_PORTCULLIS;
X	Level->site[i][j].aux = NOCITYMOVE;
X	break;
X      case 'C':
X	Level->site[i][j].locchar = OPEN_DOOR;
X	Level->site[i][j].p_locf = L_COLLEGE;
X	CitySiteList[L_COLLEGE-CITYSITEBASE][0] = TRUE;
X	CitySiteList[L_COLLEGE-CITYSITEBASE][1] = i;
X	CitySiteList[L_COLLEGE-CITYSITEBASE][2] = j;
X	break;
X      case 's':
X	Level->site[i][j].locchar = OPEN_DOOR;
X	Level->site[i][j].p_locf = L_SORCERORS;
X	CitySiteList[L_SORCERORS-CITYSITEBASE][0] = TRUE;
X	CitySiteList[L_SORCERORS-CITYSITEBASE][1] = i;
X	CitySiteList[L_SORCERORS-CITYSITEBASE][2] = j;
X	break;
X      case 'M':
X	Level->site[i][j].locchar = OPEN_DOOR;
X	Level->site[i][j].p_locf = L_MERC_GUILD;
X	CitySiteList[L_MERC_GUILD-CITYSITEBASE][0] = TRUE;
X	CitySiteList[L_MERC_GUILD-CITYSITEBASE][1] = i;
X	CitySiteList[L_MERC_GUILD-CITYSITEBASE][2] = j;
X	break;
X      case 'c':
X	Level->site[i][j].locchar = OPEN_DOOR;
X	Level->site[i][j].p_locf = L_CASTLE;
X	CitySiteList[L_CASTLE-CITYSITEBASE][0] = TRUE;
X	CitySiteList[L_CASTLE-CITYSITEBASE][1] = i;
X	CitySiteList[L_CASTLE-CITYSITEBASE][2] = j;
X	break;
X      case '?':
X	mazesite(i,j);
X	break;
X      case 'P':
X        Level->site[i][j].locchar = OPEN_DOOR;
X	Level->site[i][j].p_locf = L_ORDER;
X	CitySiteList[L_ORDER-CITYSITEBASE][0] = TRUE;
X	CitySiteList[L_ORDER-CITYSITEBASE][1] = i;
X	CitySiteList[L_ORDER-CITYSITEBASE][2] = j;
X	break;
X      case 'H':
X        Level->site[i][j].locchar = OPEN_DOOR;
X	Level->site[i][j].p_locf = L_CHARITY;
X	CitySiteList[L_CHARITY-CITYSITEBASE][0] = TRUE;
X	CitySiteList[L_CHARITY-CITYSITEBASE][1] = i;
X	CitySiteList[L_CHARITY-CITYSITEBASE][2] = j;
X	break;
X      case 'j':
X        Level->site[i][j].locchar = FLOOR;
X	make_justiciar(i,j);
X        break;
X      case 'J':
X	Level->site[i][j].locchar = CLOSED_DOOR;
X	Level->site[i][j].p_locf = L_JAIL;
X	break;
X      case 'A':
X	Level->site[i][j].locchar = OPEN_DOOR;
X	Level->site[i][j].p_locf = L_ARENA;
X	CitySiteList[L_ARENA-CITYSITEBASE][0] = TRUE;
X	CitySiteList[L_ARENA-CITYSITEBASE][1] = i;
X	CitySiteList[L_ARENA-CITYSITEBASE][2] = j;
X	break;
X      case 'B':
X	Level->site[i][j].locchar = OPEN_DOOR;
X	Level->site[i][j].p_locf = L_BANK;
X	CitySiteList[L_BANK-CITYSITEBASE][0] = TRUE;
X	CitySiteList[L_BANK-CITYSITEBASE][1] = i;
X	CitySiteList[L_BANK-CITYSITEBASE][2] = j;
X	lset(i,j+1,STOPS);
X	lset(i+1,j,STOPS);
X	lset(i-1,j,STOPS);
X	lset(i,j-1,STOPS);
X	break;
X      case 'X':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_COUNTRYSIDE;
X	CitySiteList[L_COUNTRYSIDE-CITYSITEBASE][0] = TRUE;
X	CitySiteList[L_COUNTRYSIDE-CITYSITEBASE][1] = i;
X	CitySiteList[L_COUNTRYSIDE-CITYSITEBASE][2] = j;
X	break;
X      case 'V':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_VAULT;
X	Level->site[i][j].aux = NOCITYMOVE;
X	lset(i,j,SECRET);
X	break;
X      case '\\':
X	Level->site[i][j].aux = NOCITYMOVE;
X	Level->site[i][j].showchar = WALL;
X	Level->site[i][j].locchar = CLOSED_DOOR;
X	Level->site[i][j].p_locf = L_VAULT;
X	lset(i,j,SECRET);
X	break;
X      case 'S':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].aux = NOCITYMOVE;
X	lset(i,j,SECRET);
X	break;
X      case 'G':
X	Level->site[i][j].locchar = FLOOR;
X	make_site_monster(i,j,ML0+3);
X	break;
X      case 'u':
X	Level->site[i][j].locchar = FLOOR;
X	make_minor_undead(i,j);
X	break;
X      case 'U':
X	Level->site[i][j].locchar = FLOOR;
X	make_major_undead(i,j);
X	break;
X      case '%':
X	Level->site[i][j].showchar = WALL;
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_TRAP_SIREN;
X	make_site_treasure(i,j,5);
X	Level->site[i][j].aux = NOCITYMOVE;
X	lset(i,j,SECRET);
X	break;
X      case '$':
X	Level->site[i][j].locchar = FLOOR;
X	make_site_treasure(i,j,5);
X	break;
X      case '2':
X	Level->site[i][j].locchar = ALTAR;
X	Level->site[i][j].p_locf = L_ALTAR;
X	Level->site[i][j].aux = ODIN;
X	break;
X      case '3':
X	Level->site[i][j].locchar = ALTAR;
X	Level->site[i][j].p_locf = L_ALTAR;
X	Level->site[i][j].aux = SET;
X	break;
X      case '4':
X	Level->site[i][j].locchar = ALTAR;
X	Level->site[i][j].p_locf = L_ALTAR;
X	Level->site[i][j].aux = ATHENA;
X	break;
X      case '5':
X	Level->site[i][j].locchar = ALTAR;
X	Level->site[i][j].p_locf = L_ALTAR;
X	Level->site[i][j].aux = HECATE;
X	break;
X      case '6':
X	Level->site[i][j].locchar = ALTAR;
X	Level->site[i][j].p_locf = L_ALTAR;
X	Level->site[i][j].aux = DESTINY;
X	break;
X      case 'O':
X	Level->site[i][j].locchar = OPEN_DOOR;
X	Level->site[i][j].p_locf = L_ORACLE;
X	CitySiteList[L_ORACLE-CITYSITEBASE][1] = i;
X	CitySiteList[L_ORACLE-CITYSITEBASE][2] = j;
X	break;
X      case '^':
X	Level->site[i][j].showchar = WALL;
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = TRAP_BASE+random_range(NUMTRAPS);
X	lset(i,j,SECRET);
X	break;
X      case '"':
X	Level->site[i][j].locchar = HEDGE;
X	break;
X      case '~':
X	Level->site[i][j].locchar = WATER;
X	Level->site[i][j].p_locf = L_WATER;
X	break;
X      case '=':
X	Level->site[i][j].locchar = WATER;
X	Level->site[i][j].p_locf = L_MAGIC_POOL;
X	break;
X      case '>':
X	Level->site[i][j].locchar = DOWN;
X	Level->site[i][j].p_locf = L_SEWER;
X	break;
X      case '*':
X	Level->site[i][j].locchar = WALL;
X	Level->site[i][j].aux = 10;
X	break;
X      case '#':
X	Level->site[i][j].locchar = WALL;
X	Level->site[i][j].aux = 500;
X	break;
X      case '.':
X	Level->site[i][j].locchar = FLOOR;
X	break;
X      case ',':
X	Level->site[i][j].showchar = WALL;
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].aux = NOCITYMOVE;
X	lset(i,j,SECRET);
X	break;
X      default:
X	Level->site[i][j].locchar = site;
X	break;
X      }
X
X      if (loc_statusp(i,j,SEEN)) {
X	if (loc_statusp(i,j,SECRET))
X	  Level->site[i][j].showchar = '#';
X	else Level->site[i][j].showchar = Level->site[i][j].locchar;
X      }
X    }
X    fscanf(fd,"\n");
X  }
X  City = Level;
X
X  /* make all city monsters asleep, and shorten their wakeup range to 2 */
X  /* to prevent players from being molested by vicious monsters on */
X  /* the streets */
X  for(ml=Level->mlist;ml!=NULL;ml=ml->next) {
X    m_status_reset(ml->m,AWAKE);
X    ml->m->wakeup = 2;
X  }
X  fclose(fd);
X}
X
X
Xvoid assign_city_function(x,y)
Xint x,y;
X{
X  static int setup=0;
X  static int next=0;
X  static int permutation[64]; /* number of x's in city map */
X  int i,j,k,l;
X
X  Level->site[x][y].aux = TRUE;
X
X  lset(x,y+1,STOPS);
X  lset(x+1,y,STOPS);
X  lset(x-1,y,STOPS);
X  lset(x,y-1,STOPS);
X
X
X  if (setup == 0) {
X    setup = 1;
X    for(i=0;i<64;i++)
X      permutation[i] = i;
X    for(i=0;i<500;i++) {
X      j = random_range(64);
X      k = random_range(64);
X      l = permutation[j];
X      permutation[j] = permutation[k];
X      permutation[k] = l;
X    }
X  }
X  if (next > 63) { /* in case someone changes the no. of x's */
X    Level->site[x][y].locchar = CLOSED_DOOR;
X    Level->site[x][y].p_locf = L_HOUSE;
X    if(random_range(5)) Level->site[x][y].aux = LOCKED;
X  }
X  else switch(permutation[next]) {
X  case 0:
X    Level->site[x][y].locchar = OPEN_DOOR;
X    Level->site[x][y].p_locf = L_ARMORER;
X    CitySiteList[L_ARMORER-CITYSITEBASE][1] = x;
X    CitySiteList[L_ARMORER-CITYSITEBASE][2] = y;
X    break;
X  case 1:
X    Level->site[x][y].locchar = OPEN_DOOR;
X    Level->site[x][y].p_locf = L_CLUB;
X    CitySiteList[L_CLUB-CITYSITEBASE][1] = x;
X    CitySiteList[L_CLUB-CITYSITEBASE][2] = y;
X    break;
X  case 2:
X    Level->site[x][y].locchar = OPEN_DOOR;
X    Level->site[x][y].p_locf = L_GYM;
X    CitySiteList[L_GYM-CITYSITEBASE][1] = x;
X    CitySiteList[L_GYM-CITYSITEBASE][2] = y;
X    break;
X  case 3:
X    Level->site[x][y].locchar = CLOSED_DOOR;
X    Level->site[x][y].p_locf = L_THIEVES_GUILD;
X    CitySiteList[L_THIEVES_GUILD-CITYSITEBASE][1] = x;
X    CitySiteList[L_THIEVES_GUILD-CITYSITEBASE][2] = y;
X    break;
X  case 4:
X    Level->site[x][y].locchar = OPEN_DOOR;
X    Level->site[x][y].p_locf = L_HEALER;
X    CitySiteList[L_HEALER-CITYSITEBASE][1] = x;
X    CitySiteList[L_HEALER-CITYSITEBASE][2] = y;
X    break;
X  case 5:
X    Level->site[x][y].locchar = OPEN_DOOR;
X    Level->site[x][y].p_locf = L_CASINO;
X    CitySiteList[L_CASINO-CITYSITEBASE][1] = x;
X    CitySiteList[L_CASINO-CITYSITEBASE][2] = y;
X    break;
X  case 7: 
X    Level->site[x][y].locchar = OPEN_DOOR;
X    Level->site[x][y].p_locf = L_DINER;
X    CitySiteList[L_DINER-CITYSITEBASE][1] = x;
X    CitySiteList[L_DINER-CITYSITEBASE][2] = y;
X    break;
X  case 8: 
X    Level->site[x][y].locchar = OPEN_DOOR;
X    Level->site[x][y].p_locf = L_CRAP;
X    CitySiteList[L_CRAP-CITYSITEBASE][1] = x;
X    CitySiteList[L_CRAP-CITYSITEBASE][2] = y;
X    break;
X  case 6:
X  case 9: 
X  case 20: 
X    Level->site[x][y].locchar = OPEN_DOOR;
X    Level->site[x][y].p_locf = L_COMMANDANT;
X    CitySiteList[L_COMMANDANT-CITYSITEBASE][1] = x;
X    CitySiteList[L_COMMANDANT-CITYSITEBASE][2] = y;
X    break;
X  case 21:
X    Level->site[x][y].locchar = OPEN_DOOR;
X    Level->site[x][y].p_locf = L_TAVERN;
X    CitySiteList[L_TAVERN-CITYSITEBASE][1] = x;
X    CitySiteList[L_TAVERN-CITYSITEBASE][2] = y;
X    break;
X  case 10:
X    Level->site[x][y].locchar = OPEN_DOOR;
X    Level->site[x][y].p_locf = L_ALCHEMIST;
X    CitySiteList[L_ALCHEMIST-CITYSITEBASE][1] = x;
X    CitySiteList[L_ALCHEMIST-CITYSITEBASE][2] = y;
X    break;
X  case 11:
X    Level->site[x][y].locchar = OPEN_DOOR;
X    Level->site[x][y].p_locf = L_DPW;
X    CitySiteList[L_DPW-CITYSITEBASE][1] = x;
X    CitySiteList[L_DPW-CITYSITEBASE][2] = y;
X    break;
X  case 12:
X    Level->site[x][y].locchar = OPEN_DOOR;
X    Level->site[x][y].p_locf = L_LIBRARY;
X    CitySiteList[L_LIBRARY-CITYSITEBASE][1] = x;
X    CitySiteList[L_LIBRARY-CITYSITEBASE][2] = y;
X    break;
X  case 13:
X    Level->site[x][y].locchar = OPEN_DOOR;
X    Level->site[x][y].p_locf = L_PAWN_SHOP;
X    CitySiteList[L_PAWN_SHOP-CITYSITEBASE][1] = x;
X    CitySiteList[L_PAWN_SHOP-CITYSITEBASE][2] = y;
X    break;
X  case 14:
X    Level->site[x][y].locchar = OPEN_DOOR;
X    Level->site[x][y].p_locf = L_CONDO;
X    CitySiteList[L_CONDO-CITYSITEBASE][1] = x;
X    CitySiteList[L_CONDO-CITYSITEBASE][2] = y;
X    break;
X  case 15:
X    Level->site[x][y].locchar = CLOSED_DOOR;
X    Level->site[x][y].p_locf = L_BROTHEL;
X    break;
X  default:
X    Level->site[x][y].locchar = CLOSED_DOOR;
X    switch(random_range(6)) {
X    case 0: Level->site[x][y].p_locf = L_HOVEL; break;
X    case 1: case 2: case 3:
X    case 4: Level->site[x][y].p_locf = L_HOUSE; break;
X    case 5: Level->site[x][y].p_locf = L_MANSION; break;
X    }
X    if(random_range(5)) Level->site[x][y].aux = LOCKED;
X    break;
X  }
X  next++;
X}
X
X  
X
X
X/* makes a hiscore npc for mansions */
Xvoid make_justiciar(i,j)
Xint i,j;
X{
X  pml ml = ((pml) malloc(sizeof(mltype)));
X  ml->m = ((pmt) malloc(sizeof(montype)));
X  *(ml->m) = Monsters[NPC];
X  make_hiscore_npc(ml->m,15);
X  ml->m->x = i;
X  ml->m->y = j;
X  Level->site[i][j].creature = ml->m;
X  ml->m->click = (Tick + 1) % 60;
X  ml->next = Level->mlist;
X  Level->mlist = ml;
X  m_status_reset(ml->m,AWAKE);
X}
X
X
X
X/* loads the city level */
Xvoid resurrect_guards()
X{
X  int i,j;
X  pml ml;
X  char site;
X  
X  FILE *fd;
X  
X  strcpy(Str3,OMEGALIB);
X  strcat(Str3,"ocity.dat");
X  fd = fopen(Str3,"r");
X
X
X  for(j=0;j<LENGTH;j++) {
X    for(i=0;i<WIDTH;i++) {
X      site = getc(fd);
X      if (site == 'G') {
X	make_site_monster(i,j,ML0+3);
X	Level->site[i][j].creature->monstring =
X	  salloc("undead guardsman");
X	Level->site[i][j].creature->meleef = M_MELEE_SPIRIT;
X	Level->site[i][j].creature->movef = M_MOVE_SPIRIT;
X	Level->site[i][j].creature->strikef = M_STRIKE_MISSILE;
X	Level->site[i][j].creature->immunity = EVERYTHING-pow2(NORMAL_DAMAGE);
X	Level->site[i][j].creature->hp *= 2;
X	Level->site[i][j].creature->hit *= 2;
X	Level->site[i][j].creature->dmg *= 2;
X	Level->site[i][j].creature->ac *= 2;
X	m_status_set(Level->site[i][j].creature,HOSTILE);
X	m_status_set(Level->site[i][j].creature,AWAKE);
X      }
X    }
X    fscanf(fd,"\n");
X  }
X  City = Level;
X
X  fclose(fd);
X}
X
X
Xvoid mazesite(i,j)
Xint i,j;
X{
X  static FILE *fd=NULL;
X  static int k=0;
X  char site;
X  if (fd==NULL) {
X    strcpy(Str2,OMEGALIB);
X    strcpy(Str4,"omaze .dat");
X    Str4[5]='1'+random_range(4);
X    strcat(Str2,Str4);
X    fd = fopen(Str2,"r");
X  }
X  site = getc(fd);
X  k++;
X  if (k == 282) fclose(fd);
X  switch(site) {
X  case '"':
X    Level->site[i][j].locchar = HEDGE;
X    if (random_range(10))
X      Level->site[i][j].p_locf = L_HEDGE;
X    else
X      Level->site[i][j].p_locf = L_TRIFID;
X    break;
X  case '-':
X    Level->site[i][j].locchar = CLOSED_DOOR;
X  case '.':
X    Level->site[i][j].locchar = FLOOR;
X    break;
X  case '>':
X    Level->site[i][j].locchar = DOWN;
X    Level->site[i][j].p_locf = L_SEWER;
X    break;
X  case 'z':
X    Level->site[i][j].locchar = FLOOR;
X    Level->site[i][j].p_locf = L_MAZE;
X    break;
X  case 'O':
X    Level->site[i][j].locchar = OPEN_DOOR;
X    Level->site[i][j].p_locf = L_ORACLE;
X    CitySiteList[L_ORACLE-CITYSITEBASE][1] = i;
X    CitySiteList[L_ORACLE-CITYSITEBASE][2] = j;
X    break;
X  case '?':
X    randommazesite(i,j);
X    break;
X  }
X  lreset(i,j,SEEN);
X}
X
Xvoid randommazesite(i,j)
Xint i,j;
X{
X  switch(random_range(7)) {
X  case 0: case 1:
X    Level->site[i][j].locchar = FLOOR;
X    Level->site[i][j].p_locf = TRAP_BASE+random_range(NUMTRAPS);
X    break;
X  case 2: case 3:
X    Level->site[i][j].locchar = FLOOR;
X    make_site_monster(i,j,-1);
X    break;
X  case 4: case 5:
X    Level->site[i][j].locchar = FLOOR;
X    make_site_treasure(i,j,5);
X    break;
X  default:
X    Level->site[i][j].locchar = FLOOR;    
X  }
X}
X
X
X/* undead are not hostile unless disturbed.... */
Xvoid make_minor_undead(i,j)
Xint i,j;
X{
X  int mid;
X  if (random_range(2)) mid = ML2+6; /*ghost */
X  else mid = ML4+5; /*haunt*/
X  make_site_monster(i,j,mid);
X  m_status_reset(Level->site[i][j].creature,AWAKE);
X  m_status_reset(Level->site[i][j].creature,HOSTILE);
X}    
X
X/* undead are not hostile unless disturbed.... */
Xvoid make_major_undead(i,j)
Xint i,j;
X{
X  int mid;
X  if (random_range(2)) mid = ML6+5; /* lich */
X  else mid = ML9+5; /*vampire lord*/
X  make_site_monster(i,j,mid);
X  m_status_reset(Level->site[i][j].creature,AWAKE);
X  m_status_reset(Level->site[i][j].creature,HOSTILE);
X}    
X
X
Xstatic char jail[5][11] = 
X{
X   '#', '#', '*', '#', '#', '*', '#', '#', '*', '#', '#',
X   '#', '#', '*', '#', '#', '*', '#', '*', '#', '#', '#',  
X   '#', '#', 'T', '#', 'T', '#', 'T', '#', 'T', '#', '#',  
X   '#', '#', '7', '#', '7', '#', '7', '#', '7', '#', '#',  
X   '#', '#', 'R', '#', 'R', '#', 'R', '#', 'R', '#', '#', 
X};
X
X/* fixes up the jail in case it has been munged by player action */
Xvoid repair_jail()
X{
X  int i,j;
X  for(i=0;i<11;i++)
X    for(j=0;j<5;j++) {
X      switch(jail[j][i]) {
X      case '#':
X	City->site[i+35][j+52].locchar = WALL;
X	City->site[i+35][j+52].p_locf = L_NO_OP;
X	City->site[i+35][j+52].aux = 666;
X	break;
X      case '*':
X	City->site[i+35][j+52].locchar = WALL;
X	City->site[i+35][j+52].p_locf = L_NO_OP;
X	City->site[i+35][j+52].aux = 10;
X	break;
X      case 'T':
X	City->site[i+35][j+52].locchar = FLOOR;
X	City->site[i+35][j+52].p_locf = L_PORTCULLIS_TRAP;
X	City->site[i+35][j+52].aux = NOCITYMOVE;
X	break;
X      case '7':
X	City->site[i+35][j+52].locchar = FLOOR;
X	City->site[i+35][j+52].p_locf = L_PORTCULLIS;
X	City->site[i+35][j+52].aux = NOCITYMOVE;
X	break;
X      case 'R':
X	City->site[i+35][j+52].locchar = FLOOR;
X	City->site[i+35][j+52].p_locf = L_RAISE_PORTCULLIS;
X	City->site[i+35][j+52].aux = NOCITYMOVE;
X	break;
X      }
X    }
X}
END_OF_FILE
if test 16928 -ne `wc -c <'ocity.c'`; then
    echo shar: \"'ocity.c'\" unpacked with wrong size!
fi
# end of 'ocity.c'
fi
if test -f 'oenv.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'oenv.c'\"
else
echo shar: Extracting \"'oenv.c'\" \(8114 characters\)
sed "s/^X//" >'oenv.c' <<'END_OF_FILE'
X/* omega copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
X/* oenv.c */
X/* some load_* routines for special environments */
X
X#include "oglob.h"
X
X/* loads the arena level into Level*/
Xvoid load_arena()
X{
X  int i,j;
X  char site;
X  pob box=((pob)malloc(sizeof(objtype)));
X  FILE *fd;
X
X  *box = Objects[THINGID+0];
X
X  TempLevel = Level;
X  if (ok_to_free(TempLevel)) {
X#ifndef MSDOS
X    free((char *) TempLevel);
X#endif
X    TempLevel = NULL;
X  }
X#ifndef MSDOS
X  Level = ((plv) malloc(sizeof(levtype)));
X#else
X  msdos_changelevel(TempLevel,0,-1);
X  Level = &TheLevel;
X#endif
X  clear_level(Level);
X  Level->environment = E_ARENA;
X  strcpy(Str3,OMEGALIB);
X  strcat(Str3,"oarena.dat");
X  fd = fopen(Str3,"r");
X  for(j=0;j<LENGTH;j++) {
X    for(i=0;i<WIDTH;i++) {
X      Level->site[i][j].lstatus = SEEN+LIT;
X      Level->site[i][j].roomnumber = RS_ARENA;
X      site = getc(fd);
X      switch(site) {
X      case 'P':
X	Level->site[i][j].locchar = PORTCULLIS;
X	Level->site[i][j].p_locf = L_PORTCULLIS;
X	break;
X      case 'R':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_RAISE_PORTCULLIS;
X	break;
X      case 'p':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_PORTCULLIS;
X	break;
X      case '7':
X	Level->site[i][j].locchar = PORTCULLIS;
X	Level->site[i][j].p_locf = L_PORTCULLIS;
X	break;
X      case 'T':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_DROP_EVERY_PORTCULLIS;
X	break;
X      case 'X':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_ARENA_EXIT;
X	break;
X      default:
X	Level->site[i][j].locchar = site;
X	Level->site[i][j].p_locf = L_NO_OP;
X	break;
X      }
X      Level->site[i][j].showchar = Level->site[i][j].locchar;
X    }
X    fscanf(fd,"\n");
X
X  }
X  Level->site[60][7].creature = Arena_Monster;
X  Arena_Monster->x = 60;
X  Arena_Monster->y = 7;
X  Arena_Monster->sense = 50;
X  m_pickup(Arena_Monster,box);
X  m_status_set(Arena_Monster,AWAKE);
X  Level->mlist = (pml) malloc(sizeof(mltype));
X  Level->mlist->m = Arena_Monster;
X  Level->mlist->next = NULL;
X  /* hehehehe cackled the dungeon master.... */
X  mprint("Your opponent holds the only way you can leave!");
X  Arena_Monster->hp += Arena_Monster->level*10;
X  Arena_Monster->hit += Arena_Monster->hit;
X  Arena_Monster->dmg += Arena_Monster->dmg/2;
X}
X
X/* loads the sorcereror's circle into Level*/
Xvoid load_circle()
X{
X  int i,j;
X  int safe = (Player.rank[CIRCLE] > 0);
X  char site;
X  FILE *fd;
X
X  TempLevel = Level;
X  if (ok_to_free(TempLevel)) {
X#ifndef MSDOS
X    free((char *) TempLevel);
X#endif
X    TempLevel = NULL;
X  }
X#ifndef MSDOS
X  Level = ((plv) malloc(sizeof(levtype)));
X#else
X  msdos_changelevel(TempLevel,0,-1);
X  Level = &TheLevel;
X#endif
X  clear_level(Level);
X  Level->environment = E_CIRCLE;
X  strcpy(Str3,OMEGALIB);
X  strcat(Str3,"ocircle.dat");
X  fd = fopen(Str3,"r");
X  for(j=0;j<LENGTH;j++) {
X    for(i=0;i<WIDTH;i++) {
X      Level->site[i][j].lstatus = 0;
X      Level->site[i][j].roomnumber = RS_CIRCLE;
X      Level->site[i][j].p_locf = L_NO_OP;
X      site = getc(fd);
X      switch(site) {
X      case 'P':
X	Level->site[i][j].locchar = FLOOR;
X	make_prime(i,j); /* prime sorceror */
X	Level->site[i][j].creature->specialf = M_SP_PRIME;
X	if (! safe) m_status_set(Level->site[i][j].creature,HOSTILE);
X	break;
X      case 'D':
X	Level->site[i][j].locchar = FLOOR;
X	make_site_monster(i,j,ML9+7); /* prime circle demon */
X	if (safe) m_status_reset(Level->site[i][j].creature,HOSTILE);
X	Level->site[i][j].creature->specialf = M_SP_PRIME;
X	break;
X      case 's':
X	Level->site[i][j].locchar = FLOOR;
X	make_site_monster(i,j,ML4+13); /* servant of chaos */
X	Level->site[i][j].creature->specialf = M_SP_COURT;
X	if (safe) m_status_reset(Level->site[i][j].creature,HOSTILE);
X	break;
X      case 'e':
X	Level->site[i][j].locchar = FLOOR;
X	make_site_monster(i,j,ML2+7); /* enchanter */
X	Level->site[i][j].creature->specialf = M_SP_COURT;
X	if (safe) m_status_reset(Level->site[i][j].creature,HOSTILE);
X	break;
X      case 'n':
X	Level->site[i][j].locchar = FLOOR;
X	make_site_monster(i,j,ML5+6); /* necromancer */
X	Level->site[i][j].creature->specialf = M_SP_COURT;
X	if (safe) m_status_reset(Level->site[i][j].creature,HOSTILE);
X	break;
X      case 'T':
X	Level->site[i][j].locchar = FLOOR;
X	make_site_monster(i,j,ML9+4); /* High Thaumaturgist */
X	Level->site[i][j].creature->specialf = M_SP_COURT;
X	if (safe) m_status_reset(Level->site[i][j].creature,HOSTILE);
X	break;
X      case '#':
X	Level->site[i][j].locchar = WALL;
X	Level->site[i][j].aux = 1000; 
X	break;
X      case 'L':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_CIRCLE_LIBRARY;
X	break;
X      case '?':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_TOME1;
X	break;
X      case '!':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].p_locf = L_TOME2;
X	break;
X      case 'S':
X	Level->site[i][j].locchar = FLOOR;
X	lset(i,j,SECRET);
X	break;
X      case '.':
X	Level->site[i][j].locchar = FLOOR;
X	break;
X      case '-':
X	Level->site[i][j].locchar = CLOSED_DOOR;
X	break;
X      }
X    }
X    fscanf(fd,"\n");
X  }
X  fclose(fd);
X}
X
X/* make the prime sorceror */
Xvoid make_prime(i,j)
Xint i,j;
X{
X  pml ml = ((pml) malloc(sizeof(mltype)));
X  pmt m = ((pmt) malloc(sizeof(montype)));
X  pol ol;
X  pob o;
X  make_hiscore_npc(m,10); /* 10 is index for prime */
X  m->x = i;
X  m->y = j;
X  Level->site[i][j].creature = m;
X  ml->m = m;
X  ml->next = Level->mlist;
X  Level->mlist = ml;
X  
X  if (! gamestatusp(COMPLETED_ASTRAL)) {
X    ol  = ((pol) malloc(sizeof(oltype)));
X    o  = ((pob) malloc(sizeof(objtype)));
X    *o = Objects[ARTIFACTID+21];
X    ol->thing = o;
X    ol->next = NULL;
X    m->possessions = ol;
X  }
X
X}
X
X
X
X
X
X
X/* loads the court of the archmage into Level*/
Xvoid load_court()
X{
X  int i,j;
X  char site;
X  FILE *fd;
X
X  TempLevel = Level;
X  if (ok_to_free(TempLevel)) {
X#ifndef MSDOS
X    free((char *) TempLevel);
X#endif
X    TempLevel = NULL;
X  }
X#ifndef MSDOS
X  Level = ((plv) malloc(sizeof(levtype)));
X#else
X  msdos_changelevel(TempLevel,0,-1);
X  Level = &TheLevel;
X#endif
X  clear_level(Level);
X  Level->environment = E_COURT;
X  strcpy(Str3,OMEGALIB);
X  strcat(Str3,"ocourt.dat");
X  fd = fopen(Str3,"r");
X  for(j=0;j<LENGTH;j++) {
X    for(i=0;i<WIDTH;i++) {
X      Level->site[i][j].lstatus = 0;
X      Level->site[i][j].roomnumber = RS_COURT;
X      Level->site[i][j].p_locf = L_NO_OP;
X      site = getc(fd);
X      switch(site) {
X      case '5':
X	Level->site[i][j].locchar = CHAIR;
X	Level->site[i][j].p_locf = L_THRONE;
X	make_specific_treasure(i,j,ARTIFACTID+22);
X	make_archmage(i,j);
X	m_status_reset(Level->site[i][j].creature,HOSTILE);
X	m_status_reset(Level->site[i][j].creature,MOBILE);
X	break;
X      case 'e':
X	Level->site[i][j].locchar = FLOOR;
X	make_site_monster(i,j,ML2+7); /* enchanter */
X	m_status_reset(Level->site[i][j].creature,HOSTILE);
X	Level->site[i][j].creature->specialf = M_SP_COURT;
X	break;
X      case 'n':
X	Level->site[i][j].locchar = FLOOR;
X	make_site_monster(i,j,ML5+6); /* necromancer */
X	m_status_reset(Level->site[i][j].creature,HOSTILE);
X	Level->site[i][j].creature->specialf = M_SP_COURT;
X	break;
X      case 'T':
X	Level->site[i][j].locchar = FLOOR;
X	make_site_monster(i,j,ML9+4); /* High Thaumaturgist */
X	m_status_reset(Level->site[i][j].creature,HOSTILE);
X	Level->site[i][j].creature->specialf = M_SP_COURT;
X	break;
X      case '#':
X	Level->site[i][j].locchar = WALL;
X	Level->site[i][j].aux = 1000; 
X	break;
X      case 'G':
X	Level->site[i][j].locchar = FLOOR;
X	Level->site[i][j].locchar = FLOOR;
X	make_site_monster(i,j,ML0+3); /* guard */
X	m_status_reset(Level->site[i][j].creature,HOSTILE);
X	break;
X      case '<':
X	Level->site[i][j].locchar = UP;
X	Level->site[i][j].p_locf = L_ESCALATOR;
X	break;
X      case '.':
X	Level->site[i][j].locchar = FLOOR;
X	break;
X      }
X    }
X    fscanf(fd,"\n");
X  }
X  fclose(fd);
X}
X
X
X
X/* make the archmage */
Xvoid make_archmage(i,j)
Xint i,j;
X{
X  pml ml = ((pml) malloc(sizeof(mltype)));
X  pmt m = ((pmt) malloc(sizeof(montype)));
X  make_hiscore_npc(m,9); /* 10 is index for archmage */
X  m->x = i;
X  m->y = j;
X  Level->site[i][j].creature = m;
X  ml->m = m;
X  ml->next = Level->mlist;
X  Level->mlist = ml;
X  m->specialf = M_SP_COURT;
X}
X
END_OF_FILE
if test 8114 -ne `wc -c <'oenv.c'`; then
    echo shar: \"'oenv.c'\" unpacked with wrong size!
fi
# end of 'oenv.c'
fi
echo shar: End of archive 13 \(of 20\).
cp /dev/null ark13isdone
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