[comp.sources.games] v05i016: omega2 - rogue like dungeon exploration

games@tekred.TEK.COM (07/22/88)

Submitted by: "Laurence R. Brothers" <brothers@paul.rutgers.edu>
Comp.sources.games: Volume 5, Issue 16
Archive-name: omega2/Part06



#! /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 6 (of 19)."
# Contents:  omegahi.bak omon.c omspec.c otime.c
# Wrapped by billr@saab on Wed Jul 13 10:46:44 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'omegahi.bak' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'omegahi.bak'\"
else
echo shar: Extracting \"'omegahi.bak'\" \(283 characters\)
sed "s/^X//" >'omegahi.bak' <<'END_OF_FILE'
XZippy
XKilled by a pun
X0
X0
X2713
XArioch
X10
X-100
X2712
XAriel
X10
X100
X2711
XCormorant
X10
X2718
XMorgon
X10
X2718
XSonders
X10
X2713
XSpartacus
X10
X2713
XOz
X10
X2933
XBlackskull
X10
X2932
XShadowspawn
X10
X2712
XGallow
X10
X2711
XKharst
X10
X2712
XAllana
X10
X2931
XDara
X10
X2932
XThistleman
X10
X2933
XHumperdinck
X10
X5718
END_OF_FILE
if test 283 -ne `wc -c <'omegahi.bak'`; then
    echo shar: \"'omegahi.bak'\" unpacked with wrong size!
fi
# end of 'omegahi.bak'
fi
if test -f 'omon.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'omon.c'\"
else
echo shar: Extracting \"'omon.c'\" \(29701 characters\)
sed "s/^X//" >'omon.c' <<'END_OF_FILE'
X/* omega copyright (c) 1987,1988 by Laurence Raphael Brothers */
X/* omon.c */
X/* various functions to do with monsters */
X
X#include "oglob.h"
X
X
X
X/* consider one monster's action */
Xvoid m_pulse(m)
Xstruct monster *m;
X{
X  int range = distance(m->x, m->y, Player.x,Player.y);
X
X  if (Time % 10 == 0) 
X    if (m->hp < Monsters[m->id].hp)
X      m->hp++;
X  
X  if ((! m_statusp(m,AWAKE)) && (range <= m->wakeup)) {
X    m_status_set(m,AWAKE);
X    resetgamestatus(FAST_MOVE);
X  }
X  
X  if (m_statusp(m,AWAKE)) {
X    if (m_statusp(m,WANDERING)) {
X      if (m_statusp(m,MOBILE)) m_random_move(m);
X      if (range <= m->sense) m_status_reset(m,WANDERING);
X    }
X    else /* not wandering */ {
X      if (m_statusp(m,HOSTILE)) {
X	if ((range > 2) && (range < m->sense) && (random_range(2) == 1))
X	  if (los_p(m->x,m->y,Player.x,Player.y) &&
X	      (Player.status[INVISIBLE] == 0)) monster_strike(m);
X      }
X      if ((m_statusp(m,HOSTILE) || m_statusp(m,NEEDY))
X	  && (range > 1)
X	  && m_statusp(m,MOBILE)) {
X	monster_move(m);
X	/* if monster is greedy, picks up treasure it finds */
X	if (m_statusp(m,GREEDY))
X	  while (Level->site[m->x][m->y].things != NULL) {
X	    m_pickup(m,Level->site[m->x][m->y].things->thing);
X	    Level->site[m->x][m->y].things =
X	      Level->site[m->x][m->y].things->next;
X	  }
X      }
X      if (m_statusp(m,HOSTILE) && (range ==1)) {
X	resetgamestatus(FAST_MOVE);
X	tacmonster(m);
X      }
X    }
X    /* prevents monsters from casting spells from other side of dungeon */
X    if (range < max(5,m->level)) 
X      monster_special(m);
X  }
X}
X    
X
X
X
X
X
X
X/* actually make a move */
Xvoid movemonster(m,newx,newy)
Xstruct monster *m;
Xint newx,newy;
X{
X  Level->site[m->x][m->y].creature = NULL;
X  m->x = newx;
X  m->y = newy;
X  Level->site[m->x][m->y].creature = m;
X  m_movefunction(m,Level->site[m->x][m->y].p_locf);
X}
X
X
X/* give object o to monster m */
Xvoid m_pickup(m,o)
Xstruct monster *m;
Xstruct object *o;
X{
X  pol tmp = ((pol) malloc(sizeof(oltype)));
X  tmp->thing = o;
X  tmp->next = m->possessions;
X  m->possessions = tmp;
X}
X
Xvoid m_dropstuff(m)
Xstruct monster *m;
X{
X  pol tmp = m->possessions;
X  if (tmp != NULL) {
X    while (tmp->next != NULL)
X      tmp = tmp->next;
X
X    tmp->next = Level->site[m->x][m->y].things;
X    Level->site[m->x][m->y].things = m->possessions;
X    m->possessions = NULL;
X  }
X}
X
X
X
Xvoid m_status_set(m,s)
Xstruct monster *m;
Xint s;
X{
X  m->status |= s;
X}
X
Xvoid m_status_reset(m,s)
Xstruct monster *m;
Xint s;
X{
X  m->status &= ~s;
X}
X
X
X
X/* monster status predicate */
Xint m_statusp(m,s)
Xstruct monster *m;
Xint s;
X{
X  return(m->status & s);
X}
X
X/* monster immunity predicate */
Xint m_immunityp(m,s)
Xstruct monster *m;
Xint s;
X{
X  return(m->immunity & pow2(s));
X}
X
X
X
Xvoid m_damage(m,dmg,dtype)
Xstruct monster *m;
Xint dmg,dtype;
X{
X  m_status_set(m,AWAKE);
X  m_status_set(m,HOSTILE);
X  if (m_immunityp(m,dtype)) {
X    if (los_p(Player.x,Player.y,m->x,m->y)) { 
X      if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X      else {
X	strcpy(Str1,"The ");
X	strcat(Str1,m->monstring);
X      }
X      strcat(Str1," ignores the attack!");
X      mprint(Str1);
X    }
X  }
X  else if ((m->hp -= dmg) < 1) m_death(m);
X}
X
X
Xvoid m_death(m)
Xstruct monster *m;
X{
X  pob corpse;
X  pml ml;
X  int x,y,found=FALSE;
X  m->hp = -1;
X  if (los_p(Player.x,Player.y,m->x,m->y)) {
X    putspot(m->x,m->y,getspot(m->x,m->y,FALSE));
X    gain_experience(m->xpv);
X    calc_melee();
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X    strcat(Str1," is dead! ");
X    mprint(Str1);
X  }
X  m_dropstuff(m);
X  if (m->id == ML10+10) { /* death */
X    mprint("Death lies sprawled out on the ground......");
X    mprint("Death laughs ironically and gets back to his feet.");
X    mprint("He gestures and another scythe appears in his hands.");
X    switch(random_range(10)) {
X    case 0:
X      mprint("Death performs a little bow and goes back on guard."); 
X      break;
X    case 1:
X      mprint("'A hit! A palpable hit!' Death goes back on the attack."); 
X      break;
X    case 2:
X      mprint("'Ah, if only it could be so simple!' snickers Death.");
X      break;
X    case 3:
X      mprint("'This fool thinks he can slay death! What a jest!' says Death.");
X      break;
X    case 4:
X      mprint("'Your point is well taken.' says Death, attacking again.");
X      break;
X    case 5:
X      mprint("'Oh, come now, stop delaying the inevitable.' says Death.");
X      break;
X    case 6:
X      mprint("'Your destiny ends here with me.' says Death, scythe raised.");
X      break;
X    case 7:
X      mprint("'I almost felt that.' says Death, smiling.");
X      break;
X    case 8:
X      mprint("'Timeo Mortis?' asks Death quizzically, 'Not me!'");
X      break;
X    case 9:
X      mprint("Death sighs theatrically. 'They never learn.'");
X      break;
X    }
X    strengthen_death(m);
X  }
X  else {
X    Level->site[m->x][m->y].creature = NULL;
X    if (random_range(2) || (m->uniqueness != COMMON)) {
X      corpse=((pob) malloc(sizeof(objtype)));
X      make_corpse(corpse,m);
X      drop_at(m->x,m->y,corpse);
X    }
X    plotspot(m->x,m->y,FALSE);
X    switch(m->id) {
X    case ML0+8: /* hiscore npc */
X      switch(m->aux2) {
X      case 0:
X	mprint("You hear a faroff dirge. You feel a sense of triumph.");
X	break;
X      case 1:case 2: case 3:case 4:case 5:case 6:
X	mprint("You hear a faroff sound like angels crying....");
X	strcpy(Priest[1],nameprint());
X	Priestbehavior[1] = 2933;
X	break;
X      case 7:
X      mprint("A furtive figure dashes out of the shadows, takes a look at");
X	mprint("the corpse, and runs away!");
X	strcpy(Shadowlord,nameprint());
X	Shadowlordbehavior = 2912;
X	break;
X      case 8:
X	mprint("An aide-de-camp approaches, removes the corpse's insignia,");
X	mprint("and departs.");
X	strcpy(Commandant,nameprint());
X	Commandantbehavior = 2912;
X	break;
X      case 9:
X	mprint("An odd glow surrounds the corpse, and slowly fades.");
X	strcpy(Archmage,nameprint());
X	Archmagebehavior = 2933;
X	break;
X      case 10:
X	mprint("A demon materializes, takes a quick look at the corpse,");
X	mprint("and teleports away with a faint popping noise.");
X	strcpy(Prime,nameprint());
X	Primebehavior = 2932;
X	break;
X      case 11:
X	mprint("A sports columnist rushes forward and takes a quick photo");
X	mprint("of the corpse and rushes off muttering about a deadline.");
X	strcpy(Champion,nameprint());
X	Championbehavior = 2913;
X	break;
X      case 12:
X	mprint("You hear a fanfare in the distance, and feel dismayed.");
X	strcpy(Duke,nameprint());
X	Dukebehavior = 2911;
X	break;
X      case 13:
X	if (Player.alignment > 10) mprint("You feel smug.");
X	else if (Player.alignment < 10) mprint("You feel ashamed.");
X	strcpy(Chaoslord,nameprint());
X	Chaoslordbehavior = 2912;
X	break;
X      case 14:
X	if (Player.alignment < 10) mprint("You feel smug.");
X	else if (Player.alignment > 10) mprint("You feel ashamed.");
X	strcpy(Lawlord,nameprint());
X	Lawlordbehavior = 2911;
X	break;
X      case 15: 
X	/* just a tad complicated. Promote a new justiciar if any
X	   guards are left in the city, otherwise Destroy the Order! */
X	Player.alignment -= 100;
X	if (! gamestatusp(DESTROYED_ORDER)) {
X	  mprint("In the distance you hear a trumpet. A Servant of Law");
X	  mprint("materializes, sheds a tear, and leaves.");
X	  strcpy(Justiciar,nameprint());
X	  Justiciarbehavior = 2911;
X	  /* promote one of the city guards to be justiciar */
X	  ml = City->mlist;
X	  while ((! found) && (ml != NULL)) {
X	    found = ((ml->m->id == ML0+3) && (ml->m->hp > 0));
X	    if (! found) ml=ml->next;
X	  }
X	  if (ml != NULL) {
X	    mprint("A new justiciar has been promoted!");
X	    x = ml->m->x; y = ml->m->y;
X	    make_hiscore_npc(ml->m,15);
X	    ml->m->x = x;
X	    ml->m->y = y;
X	    ml->m->click = (Tick + 1) % 60;
X	    m_status_reset(ml->m,AWAKE);
X	    m_status_reset(ml->m,HOSTILE);
X	  }
X	  alert_guards(); 
X	  /* will cause order to be destroyed if no guards or justiciar*/
X	}
X	else {
X	  mprint("A Servant of Chaos materializes, grabs the corpse,");
X	  mprint("snickers a bit, and vanishes.");
X	}
X	break;
X      }
X      break;
X    case ML0+3: /* guard */
X      Player.alignment -= 10;
X      if ((Current_Environment == E_CITY) || 
X	  (Current_Environment == E_VILLAGE))
X	alert_guards();
X      break;
X    case ML3+5: 
X      if (! gamestatusp(ATTACKED_ORACLE)) {
X	mprint("You seem to hear a woman's voice from far off:");
X	mprint("'Well done! Come to me now....'");
X      }
X      setgamestatus(COMPLETED_CAVES); 
X      break; /* gob king */
X    case ML7+5: 
X      if (! gamestatusp(ATTACKED_ORACLE)) {
X	mprint("A female voice sounds from just behind your ear:");
X	mprint("'Well fought! I have some new advice for you....'");
X      }
X      setgamestatus(COMPLETED_SEWERS); 
X      break; /*grt worm */
X    case ML10+1:
X      setgamestatus(KILLED_EATER);
X      break;
X    case ML10+2:
X      setgamestatus(KILLED_LAWBRINGER);
X      break;
X    case ML10+3:
X      setgamestatus(KILLED_DRAGONLORD);
X      break;
X    case ML10+4:
X      setgamestatus(COMPLETED_VOLCANO);
X      if (! gamestatusp(ATTACKED_ORACLE)) {
X	mprint("You feel a soft touch on your shoulder...");
X	mprint("You turn around but there is no one there!");
X	mprint("You turn back and see a note: 'See me soon.'");
X	mprint("The note vanishes in a burst of blue fire!");
X      }
X      break;
X    case ML10+9: 
X      if (! gamestatusp(ATTACKED_ORACLE)) {
X	mprint("Words appear before you, traced in blue flame!");
X	mprint("'Return to the Prime Plane via the Circle of Sorcerors....'");
X      }
X      break; /* elem mast */
X    }
X  }
X  dodrawspot(m->x,m->y);
X}
X
X
X
X
X    
X    
X				   
Xvoid monster_move(m)
Xstruct monster *m;
X{
X  monster_action(m,m->movef);
X}
X
X
X
X
X
X
X
X
X
Xvoid monster_strike(m)
Xstruct monster *m;
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    monster_action(m,m->strikef);
X  }
X}
X
Xvoid monster_special(m)
Xstruct monster *m;
X{
X  /* since many special functions are really attacks, cancel them
X     all if on sanctuary */
X  if (! player_on_sanctuary())
X    monster_action(m,m->specialf);
X}  
X
X
Xvoid monster_talk(m)
Xstruct monster *m;
X{
X  monster_action(m,m->talkf);
X}
X
Xvoid monster_action(m,action)
Xstruct monster *m;
Xint action;
X{
X  int meleef;
X  if ((action >= M_MELEE_NORMAL) && (action < M_MOVE_NORMAL)) {
X    /* kluge allows multiple attack forms */
X    if (distance(m->x,m->y,Player.x,Player.y)<2) {
X      meleef = m->meleef;
X      m->meleef = action;
X      tacmonster(m);
X      m->meleef = meleef;
X    }
X  }
X  else switch(action) {
X
X  case M_NO_OP:m_no_op(m); break;
X    
X  case M_MOVE_NORMAL:m_normal_move(m); break;
X  case M_MOVE_FLUTTER:m_flutter_move(m); break;
X  case M_MOVE_FOLLOW:m_follow_move(m); break;
X  case M_MOVE_TELEPORT:m_teleport(m); break;
X  case M_MOVE_RANDOM:m_random_move(m); break;
X  case M_MOVE_SMART:m_smart_move(m); break;
X  case M_MOVE_SPIRIT:m_spirit_move(m); break;
X  case M_MOVE_CONFUSED:m_confused_move(m); break;
X  case M_MOVE_SCAREDY:m_scaredy_move(m); break;
X  case M_MOVE_ANIMAL:m_move_animal(m); break;
X
X  case M_STRIKE_MISSILE:m_nbolt(m); break;
X  case M_STRIKE_FBOLT:m_firebolt(m); break;
X  case M_STRIKE_LBALL:m_lball(m); break;
X  case M_STRIKE_FBALL:m_fireball(m); break;
X  case M_STRIKE_SNOWBALL:m_snowball(m); break;
X  case M_STRIKE_BLIND:m_blind_strike(m); break;
X  case M_STRIKE_SONIC:m_strike_sonic(m); break;
X    
X  case M_TALK_HORSE:m_talk_horse(m); break;
X  case M_TALK_THIEF:m_talk_thief(m);break;
X  case M_TALK_STUPID:m_talk_stupid(m); break;
X  case M_TALK_SILENT:m_talk_silent(m); break;
X  case M_TALK_HUNGRY:m_talk_hungry(m); break;
X  case M_TALK_GREEDY:m_talk_greedy(m); break;
X  case M_TALK_TITTER:m_talk_titter(m); break;
X  case M_TALK_MP:m_talk_mp(m); break;
X  case M_TALK_IM:m_talk_im(m); break;
X  case M_TALK_MAN:m_talk_man(m); break;
X  case M_TALK_ROBOT:m_talk_robot(m); break;
X  case M_TALK_EVIL:m_talk_evil(m); break;
X  case M_TALK_GUARD:m_talk_guard(m); break;
X  case M_TALK_MIMSY:m_talk_mimsy(m); break;
X  case M_TALK_SLITHY:m_talk_slithy(m); break;
X  case M_TALK_BURBLE:m_talk_burble(m); break;
X  case M_TALK_BEG:m_talk_beg(m); break;
X  case M_TALK_HINT:m_talk_hint(m); break;
X  case M_TALK_EF:m_talk_ef(m); break;
X  case M_TALK_GF:m_talk_gf(m); break;
X  case M_TALK_SEDUCTOR:m_talk_seductor(m); break;
X  case M_TALK_DEMONLOVER:m_talk_demonlover(m); break;
X  case M_TALK_NINJA:m_talk_ninja(m); break;
X  case M_TALK_ASSASSIN:m_talk_assassin(m); break;
X  case M_TALK_SERVANT: m_talk_servant(m); break;
X  case M_TALK_ANIMAL: m_talk_animal(m); break;
X  case M_TALK_SCREAM: m_talk_scream(m); break;
X  case M_TALK_PARROT: m_talk_parrot(m); break;
X  case M_TALK_HYENA: m_talk_hyena(m); break;
X  case M_TALK_DRUID: m_talk_druid(m); break;
X  case M_TALK_ARCHMAGE: m_talk_archmage(m); break;
X  case M_TALK_MERCHANT: m_talk_merchant(m); break;
X  case M_TALK_PRIME: m_talk_prime(m); break;
X
X  case M_SP_BOG:m_sp_bogthing(m); break;
X  case M_SP_LEASH:m_sp_leash(m); break;
X  case M_SP_WERE:m_sp_were(m); break;
X  case M_SP_WHISTLEBLOWER:m_sp_whistleblower(m); break;
X  case M_SP_MERCHANT:m_sp_merchant(m); break;
X  case M_SP_SURPRISE:m_sp_surprise(m); break;
X  case M_SP_MP:m_sp_mp(m); break;
X  case M_SP_THIEF:m_thief_f(m); break;
X  case M_SP_DEMONLOVER:m_sp_demonlover(m); break;
X  case M_SP_AGGRAVATE:m_aggravate(m); break;
X  case M_SP_POISON_CLOUD:m_sp_poison_cloud(m); break;
X  case M_SP_HUGE:m_huge_sounds(m); break;
X  case M_SP_SUMMON:m_summon(m); break;
X  case M_SP_ILLUSION:m_illusion(m); break;
X  case M_SP_ESCAPE:m_sp_escape(m); break;
X  case M_SP_FLUTTER:m_flutter_move(m); break;
X  case M_SP_EXPLODE:m_sp_explode(m); break;
X  case M_SP_DEMON:m_sp_demon(m); break;
X  case M_SP_ACID_CLOUD:m_sp_acid_cloud(m); break;
X  case M_SP_GHOST:m_sp_ghost(m); break;
X  case M_SP_SPELL:m_sp_spell(m); break;
X  case M_SP_SEDUCTOR:m_sp_seductor(m); break;
X  case M_SP_EATER:m_sp_eater(m); break;
X  case M_SP_DRAGONLORD:m_sp_dragonlord(m); break;
X  case M_SP_BLACKOUT:m_sp_blackout(m); break;
X  case M_SP_SWARM: m_sp_swarm(m); break;
X  case M_SP_ANGEL: m_sp_angel(m); break;
X  case M_SP_SERVANT: m_sp_servant(m); break;
X  case M_SP_AV: m_sp_av(m); break;
X  case M_SP_LW: m_sp_lw(m); break;
X  case M_SP_MB: m_sp_mb(m); break;
X  case M_SP_RAISE: m_sp_raise(m); break;
X  case M_SP_MIRROR: m_sp_mirror(m); break;
X  case M_SP_COURT: m_sp_court(m); break;
X  case M_SP_LAIR: m_sp_lair(m); break;
X  case M_SP_PRIME: m_sp_prime(m); break;
X  }
X}
X  
X/* makes one of the highscore npc's */    
Xvoid make_hiscore_npc(npc,npcid)
Xpmt npc;
Xint npcid;
X{
X  int behavior,level;
X  int st = -1;
X  pob ob;
X  *npc = Monsters[HISCORE_NPC];
X  npc->aux2 = npcid;
X  /* each of the high score npc's can be created here */
X  switch(npcid) {
X  case 0:
X    level = Hilevel;
X    behavior = Hibehavior;
X    strcpy(Str2,Hiscorer);
X    break;
X  case 1:
X    level = Priestlevel[1];
X    behavior = Priestbehavior[1];
X    strcpy(Str2,Priest[1]);
X    st = ARTIFACTID+14; /* hs of odin */
X    break;
X  case 2:
X    level = Priestlevel[2];
X    behavior = Priestbehavior[2];
X    strcpy(Str2,Priest[2]);
X    st = ARTIFACTID+17; /* hs of set */
X    break;
X  case 3:
X    level = Priestlevel[3];
X    behavior = Priestbehavior[3];
X    strcpy(Str2,Priest[3]);
X    st = ARTIFACTID+16; /* hs of athena */
X    break;
X  case 4:
X    level = Priestlevel[4];
X    behavior = Priestbehavior[4];
X    strcpy(Str2,Priest[4]);
X    st = ARTIFACTID+15; /* hs of hecate */
X    break;
X  case 5:
X    level = Priestlevel[5];
X    behavior = Priestbehavior[5];
X    strcpy(Str2,Priest[5]);
X    st = ARTIFACTID+18; /* hs of druid */
X    npc->talkf = M_TALK_DRUID;
X    break;
X  case 6:
X    level = Priestlevel[6];
X    behavior = Priestbehavior[6];
X    strcpy(Str2,Priest[6]);
X    st = ARTIFACTID+19; /* hs of destiny */
X    break;
X  case 7:
X    level = Shadowlordlevel;
X    behavior = Shadowlordbehavior;
X    strcpy(Str2,Shadowlord);
X    break;
X  case 8:
X    level = Commandantlevel;
X    behavior = Commandantbehavior;
X    strcpy(Str2,Commandant);
X    break;
X  case 9:
X    level = Archmagelevel;
X    behavior = Archmagebehavior;
X    strcpy(Str2,Archmage);
X    st = ARTIFACTID+9; /* kolwynia */
X    npc->talkf = M_TALK_ARCHMAGE;
X    break;
X  case 10:
X    level = Primelevel;
X    behavior = Primebehavior;
X    strcpy(Str2,Prime);
X    npc->talkf = M_TALK_PRIME;
X    npc->specialf = M_SP_PRIME;
X    break;
X  case 11:
X    level = Championlevel;
X    behavior = Championbehavior;
X    strcpy(Str2,Champion);
X    break;
X  case 12:
X    level = Dukelevel;
X    behavior = Dukebehavior;
X    strcpy(Str2,Duke);
X    break;
X  case 13:
X    level = Chaoslordlevel;
X    behavior = Chaoslordbehavior;
X    strcpy(Str2,Chaoslord);
X    break;
X  case 14:
X    level = Lawlordlevel;
X    behavior = Lawlordbehavior;
X    strcpy(Str2,Lawlord);
X    break;
X  case 15:
X    st = THINGID+16;
X    level = Justiciarlevel;
X    behavior = Justiciarbehavior;
X    strcpy(Str2,Justiciar);
X    npc->talkf = M_TALK_GUARD;
X    npc->specialf = M_SP_WHISTLEBLOWER;
X    break;
X  }
X  if (st > -1) {
X    ob = ((pob) malloc(sizeof(objtype)));
X    *ob = Objects[st];
X    m_pickup(npc,ob);
X  }
X  npc->monstring = salloc(Str2);
X  strcpy(Str1,"The body of ");
X  strcat(Str1,Str2);
X  npc->corpsestr = salloc(Str1);
X  determine_npc_behavior(npc,level,behavior);
X}
X
X
X
X
X/* sets npc behavior given level and behavior code */
Xvoid determine_npc_behavior(npc,level,behavior)
Xpmt npc;
Xint level,behavior;
X{
X  int combatype,competence,talktype;
X  npc->hp = (level+1)*20;
X  npc->status = AWAKE+MOBILE+WANDERING;
X  combatype = (behavior % 100) / 10;
X  competence = (behavior % 1000) / 100;
X  talktype = behavior / 1000;
X  npc->level = competence;
X  if (npc->level < 2*difficulty()) npc->status += HOSTILE;
X  npc->xpv = npc->level*20;
X  switch (combatype) {
X  case 1: /* melee */
X    npc->meleef = M_MELEE_NORMAL;
X    npc->dmg = competence*5;
X    npc->hit = competence*3;
X    npc->speed = 3;
X    break;
X  case 2: /*missile*/
X    npc->meleef = M_MELEE_NORMAL;
X    npc->strikef = M_STRIKE_MISSILE;
X    npc->dmg = competence*3;
X    npc->hit = competence*2;
X    npc->speed = 4;
X    break;
X  case 3: /* spellcasting */
X    npc->meleef = M_MELEE_NORMAL;
X    npc->dmg = competence;
X    npc->hit = competence;
X    npc->specialf = M_SP_SPELL;
X    npc->speed = 6;
X    break;
X  case 4: /* thievery */
X    npc->meleef = M_MELEE_NORMAL;
X    npc->dmg = competence;
X    npc->hit = competence;
X    npc->specialf=M_SP_THIEF;
X    npc->speed = 3;
X    break;
X  case 5: /* flee */
X    npc->dmg = competence;
X    npc->hit = competence;
X    npc->meleef = M_MELEE_NORMAL;
X    npc->specialf = M_MOVE_SCAREDY;
X    npc->speed = 3;
X    break;
X  }
X  if (npc->talkf == M_TALK_MAN)
X    switch (talktype) {
X    case 1: npc->talkf = M_TALK_EVIL; break;
X    case 2: npc->talkf = M_TALK_MAN; break;
X    case 3: npc->talkf = M_TALK_HINT; break;
X    case 4: npc->talkf = M_TALK_BEG; break;
X    case 5: npc->talkf = M_TALK_SILENT; break;
X    default: mprint("Say Whutt? (npc talk weirdness)"); break;
X    }
X  npc->uniqueness = UNIQUE_MADE;
X}
X
X
X/* makes an ordinary npc (maybe undead) */
Xvoid make_log_npc(npc)
Xstruct monster *npc;
X{
X  int b,s,l,i,j,n = -1;
X  int behavior,status,level;
X  FILE *fd;
X
X  /* in case the log file is null */
X  behavior = 2718;
X  level = 1;
X  status = 2;
X  strcpy(Str2,"Malaprop the Misnamed");
X  
X  strcpy(Str1,OMEGALIB);
X  strcat(Str1,"omega.log");
X  fd = fopen(Str1,"r");
X  i = getc(fd);
X  while(i!=EOF) {
X    fscanf(fd,"%d %d %d ",&s,&l,&b);
X    filescanstring(fd,Str2);
X    if ((j=random_range(10000))>n) {
X      status = s; 
X      level = l; 
X      behavior = b;
X      n = j;
X    }
X    i = fgetc(fd);
X  }
X  fclose(fd);
X  npc->hp = level*20;
X  if (status==1) {
X    if (level < 3) {
X      *npc = Monsters[GHOST];
X      strcpy(Str1,"ghost named ");
X    }
X    else if (level < 7) {
X      *npc = Monsters[HAUNT];
X      strcpy(Str1,"haunt named ");
X    }
X    else if (level < 12) {
X      *npc = Monsters[SPECTRE];
X      strcpy(Str1,"spectre named ");
X    }
X    else {
X      *npc = Monsters[LICHE];
X      strcpy(Str1,"lich named ");
X    }
X    strcat(Str1,Str2);
X    npc->monstring = salloc(Str1);
X    strcpy(Str3,"the mortal remains of ");
X    strcat(Str3,Str2);
X    npc->corpsestr = salloc(Str3);
X  }
X  else {
X    npc->monstring=salloc(Str2);
X    strcpy(Str3,"the corpse of ");
X    strcat(Str3,Str2);
X    npc->corpsestr = salloc(Str3);
X    determine_npc_behavior(npc,level,behavior);
X  }
X}
X
X
X
X
X
Xvoid m_trap_dart(m)
Xstruct monster *m;
X{
X  if (los_p(m->x,m->y,Player.x,Player.y)) {
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X    strcat(Str1," was hit by a dart!");
X    mprint(Str1);
X  Level->site[m->x][m->y].locchar = TRAP;
X  }
X  m_damage(m,difficulty()*2,NORMAL_DAMAGE);
X}
X
Xvoid m_trap_pit(m)
Xstruct monster *m;
X{
X  if (los_p(m->x,m->y,Player.x,Player.y)) {
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X    strcat(Str1," fell into a pit!");
X    mprint(Str1);
X  Level->site[m->x][m->y].locchar = TRAP;
X  }
X  if (! m_statusp(m,INTANGIBLE))
X    m_status_reset(m,MOBILE);
X  m_damage(m,difficulty()*5,NORMAL_DAMAGE);
X
X}
X
Xvoid m_trap_door(m)
Xstruct monster *m;
X{
X  if (los_p(m->x,m->y,Player.x,Player.y)) {
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X    strcat(Str1," fell into a trap door!");
X    mprint(Str1);
X  Level->site[m->x][m->y].locchar = TRAP;
X  }
X  m_vanish(m);
X}
X
Xvoid m_trap_abyss(m)
Xstruct monster *m;
X{
X  char Str1[80];
X  if (los_p(m->x,m->y,Player.x,Player.y)) {
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X    strcat(Str1," fell into the infinite abyss!");
X    mprint(Str1);
X  Level->site[m->x][m->y].locchar = ABYSS;
X  Level->site[m->x][m->y].p_locf = L_ABYSS;
X  }
X  m_vanish(m);
X}
X
Xvoid m_trap_snare(m)
Xstruct monster *m;
X{
X  char Str1[80];
X  Level->site[m->x][m->y].locchar = TRAP;
X  if (los_p(m->x,m->y,Player.x,Player.y)) {
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X    strcat(Str1," was caught in a snare!");
X    mprint(Str1);
X  }
X  if (! m_statusp(m,INTANGIBLE)) m_status_reset(m,MOBILE);
X}
X
Xvoid m_trap_blade(m)
Xstruct monster *m;
X{
X  char Str1[80];
X  Level->site[m->x][m->y].locchar = TRAP;
X  if (los_p(m->x,m->y,Player.x,Player.y)) { 
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X    strcat(Str1," was hit by a blade trap!");
X    mprint(Str1); } 
X  m_damage(m,(difficulty()+1)*7-Player.defense,NORMAL_DAMAGE);
X}
X
Xvoid m_trap_fire(m)
Xstruct monster *m;
X{
X  char Str1[80];
X  Level->site[m->x][m->y].locchar = TRAP;
X  if (los_p(m->x,m->y,Player.x,Player.y)) { 
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X    strcat(Str1," was hit by a fire trap!");
X    mprint(Str1); 
X  } 
X  m_damage(m,(difficulty()+1)*5,FLAME);
X}
X
X
Xvoid m_fire(m)
Xstruct monster *m;
X{
X  char Str1[80];
X  if (los_p(m->x,m->y,Player.x,Player.y)) { 
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X    strcat(Str1," was blasted by fire!");
X    mprint(Str1); 
X  } 
X  m_damage(m,random_range(100),FLAME);
X}
X
Xvoid m_trap_teleport(m)
Xstruct monster *m;
X{
X  char Str1[80];
X  Level->site[m->x][m->y].locchar = TRAP;
X  if (los_p(m->x,m->y,Player.x,Player.y)) { 
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X    strcat(Str1," walked into a teleport trap!");
X    mprint(Str1); 
X  } 
X  m_teleport(m);
X}
X
Xvoid m_trap_disintegrate(m)
Xstruct monster *m;
X{
X  char Str1[80];
X  if (los_p(m->x,m->y,Player.x,Player.y)) { 
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X    strcat(Str1," walked into a disintegration trap!");
X    mprint(Str1); 
X    Level->site[m->x][m->y].locchar = TRAP;
X  } 
X  disintegrate(m->x,m->y);
X}
X
Xvoid m_trap_sleepgas(m)
Xstruct monster *m;
X{
X  char Str1[80];
X  if (los_p(m->x,m->y,Player.x,Player.y)) { 
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X    strcat(Str1," walked into a sleepgas trap!");
X    mprint(Str1); 
X    Level->site[m->x][m->y].locchar = TRAP;
X  } 
X  if (! m_immunityp(m,SLEEP)) m_status_reset(m,AWAKE);
X}
X
Xvoid m_trap_acid(m)
Xstruct monster *m;
X{
X  char Str1[80];
X  if (los_p(m->x,m->y,Player.x,Player.y)) { 
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X    strcat(Str1," walked into an acid bath trap!");
X    mprint(Str1); 
X    Level->site[m->x][m->y].locchar = TRAP;
X  } 
X  m_damage(m,random_range(difficulty()*difficulty()),ACID);
X}
X
Xvoid m_trap_manadrain(m)
Xstruct monster *m;
X{
X  char Str1[80];
X  if (los_p(m->x,m->y,Player.x,Player.y)) { 
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X    strcat(Str1," walked into a manadrain trap!");
X    mprint(Str1); 
X    Level->site[m->x][m->y].locchar = TRAP;
X  } 
X  if (m->specialf == M_SP_SPELL) m->specialf = M_NO_OP;
X}
X
X
Xvoid m_water(m)
Xstruct monster *m;
X{
X  char Str1[80];
X  if ((! m_statusp(m,INTANGIBLE)) && 
X      (! m_statusp(m,SWIMMING)) &&
X      (! m_statusp(m,ONLYSWIM))) {
X    if (los_p(m->x,m->y,Player.x,Player.y)) { 
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X      strcat(Str1," drowned!");
X      mprint(Str1); 
X    }
X    m_death(m);
X  }
X}
X
X
Xvoid m_abyss(m)
Xstruct monster *m;
X{
X  char Str1[80];
X  if (los_p(m->x,m->y,Player.x,Player.y)) {
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X    strcat(Str1," fell into the infinite abyss!");
X    mprint(Str1);
X  }
X  m_vanish(m);
X}
X
X
X
Xvoid m_lava(m)
Xstruct monster *m;
X{
X  char Str1[80];
X  if ((! m_immunityp(m,FLAME)) ||
X      ((! m_statusp(m,SWIMMING))&& (! m_statusp(m,ONLYSWIM)))) {
X    if (los_p(m->x,m->y,Player.x,Player.y)) { 
X    if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X    else {
X      strcpy(Str1,"The ");
X      strcat(Str1,m->monstring);
X    }
X      strcat(Str1," died in a pool of lava!");
X      mprint(Str1); 
X    }
X    m_death(m);
X  }
X}
X
Xvoid m_altar(m)
Xstruct monster *m;
X{
X  int visible = view_los_p(Player.x,Player.y,m->x,m->y);
X  if (m->uniqueness != COMMON) strcpy(Str1,m->monstring);
X  else {
X    strcpy(Str1,"The ");
X    strcat(Str1,m->monstring);
X  }
X  strcat(Str1," walks next to an altar...");
X  if (visible) mprint(Str1);
X  if (Level->site[m->x][m->y].aux==Player.patron) {
X    if (visible) {
X      mprint("Your deity is angry!");
X      mprint("A bolt of godsfire strikes the monster....");
X    }
X    disrupt(m->x,m->y,Player.rank[PRIESTHOOD]*50);
X  }
X  else if ((Player.patron == ODIN) || (Player.patron == ATHENA)) {
X    if ((Level->site[m->x][m->y].aux == SET) ||
X	(Level->site[m->x][m->y].aux == HECATE)) {
X      if (visible) {
X	mprint("The deity of the altar smiles on the monster....");
X	mprint("A shaft of light zaps the altar...");
X      }
X      m->hp = Monsters[m->id].hp*2;
X    }
X    else if (visible) mprint("but nothing much seems to happen");
X  }
X  else if ((Player.patron == SET) || (Player.patron == HECATE)) {
X    if ((Level->site[m->x][m->y].aux == ODIN) ||
X	(Level->site[m->x][m->y].aux == ATHENA)) {
X      if (visible) {
X	mprint("The deity of the altar smiles on the monster....");
X	mprint("A shaft of light zaps the altar...");
X      }
X      m->hp = Monsters[m->id].hp*2;
X    }
X    else if (visible) mprint("but nothing much seems to happen");
X  }
X  else if (visible) mprint("but nothing much seems to happen");
X}
X
X
X/* who knows what ml will point to when this is done... */
Xvoid free_mlist(ml)
Xpml ml;
X{
X  pml tml;
X   while (ml != NULL) {
X    tml = ml;
X    ml= ml->next;
X    free((char *) tml->m);
X    free((char *) tml);
X  }
X}
X
X
Xchar *mantype()
X{
X  switch(random_range(20)) {
X  case 0: strcpy(Str3,"janitor"); break;
X  case 1: strcpy(Str3,"beggar"); break;
X  case 2: strcpy(Str3,"barbarian"); break;
X  case 3: strcpy(Str3,"hairdresser"); break;
X  case 4: strcpy(Str3,"accountant"); break;
X  case 5: strcpy(Str3,"lawyer"); break;
X  case 6: strcpy(Str3,"indian chief"); break;
X  case 7: strcpy(Str3,"tinker"); break;
X  case 8: strcpy(Str3,"tailor"); break;
X  case 9: strcpy(Str3,"soldier"); break;
X  case 10: strcpy(Str3,"spy"); break;
X  case 11: strcpy(Str3,"doctor"); break;
X  case 12: strcpy(Str3,"miner"); break;
X  case 13: strcpy(Str3,"noble"); break;
X  case 14: strcpy(Str3,"serf"); break;
X  case 15: strcpy(Str3,"neer-do-well"); break;
X  case 16: strcpy(Str3,"vendor"); break;
X  case 17: strcpy(Str3,"dilettante"); break;
X  case 18: strcpy(Str3,"surveyor"); break;
X  case 19: strcpy(Str3,"jongleur"); break;
X  }
X  return(Str3);
X}
X
X
Xvoid strengthen_death(m)
Xstruct monster *m;
X{
X  pol ol = ((pol)malloc(sizeof(oltype)));
X  pob scythe = ((pob)malloc(sizeof(objtype)));
X  m->xpv += min(10000,m->xpv+1000);
X  m->hit += min(1000,m->hit+10);
X  m->dmg = min(10000,m->dmg*2);
X  m->ac += min(1000,m->ac+10);
X  m->speed = max(m->speed-1,1);
X  m->hp = min(100000,100+m->dmg*10);
X  *scythe = Objects[WEAPONID+39];
X  ol->thing = scythe;
X  ol->next = NULL;
X  m->possessions = ol;
X}
X
X
X
X
Xvoid m_no_op(m)
Xstruct monster *m;
X{
X}
END_OF_FILE
if test 29701 -ne `wc -c <'omon.c'`; then
    echo shar: \"'omon.c'\" unpacked with wrong size!
fi
# end of 'omon.c'
fi
if test -f 'omspec.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'omspec.c'\"
else
echo shar: Extracting \"'omspec.c'\" \(18434 characters\)
sed "s/^X//" >'omspec.c' <<'END_OF_FILE'
X/* omega copyright (c) 1987,1988 by Laurence Raphael Brothers */
X/* omspec.c */
X/* monster special functions */
X
X#include "oglob.h"
X
X
Xvoid m_sp_mp(m)
Xstruct monster *m;
X{
X  if (m->attacked && (random_range(3) == 1)) {
X    mprint("You feel cursed!");
X    p_damage(10,UNSTOPPABLE,"a mendicant priest's curse");
X    m_vanish(m);
X  }
X  else if (! m_statusp(m,NEEDY)) {
X    mprint("The mendicant priest makes a mystical gesture....");
X    mprint("You feel impressed...");
X    Player.alignment += 5;
X    if (Player.alignment > 20)
X      Player.hp = max(Player.hp,Player.maxhp);
X    m_vanish(m);
X  }
X}
X
X
X
Xvoid m_sp_ng(m)
Xstruct monster *m;
X{
X  if (distance(m->x,m->y,Player.x,Player.y) < 2)
X    if ((random_range(5) == 1) || (Player.status[VULNERABLE]>0)) {
X      mprint("The night gaunt grabs you and carries you off!");
X      mprint("Its leathery wings flap and flap, and it giggles insanely.");
X      mprint("It tickles you cunningly to render you incapable of escape.");
X      mprint("Finally, it deposits you in a strange place.");
X      p_teleport(0);
X    }
X}
X
X
X
X
X
Xvoid m_sp_poison_cloud(m)
Xstruct monster *m;
X{
X  if (distance(m->x,m->y,Player.x,Player.y) < 3) {
X    mprint("A cloud of poison gas surrounds you!");
X    if (Player.status[BREATHING] > 0)
X      mprint("You can breathe freely, however.");
X    else p_poison(7);
X  }
X}
X
X
Xvoid m_sp_explode(m)
Xstruct monster *m;
X{
X  if ((distance(Player.x,Player.y,m->x,m->y)<2) &&
X      (m-> hp > 0) && 
X      (m->hp < Monsters[m->id].hp))
X    fball(m->x,m->y,m->x,m->y,m->hp);
X}
X
X
X
Xvoid m_sp_demon(m)
Xstruct monster *m;
X{
X  int mid;
X
X  if (random_range(2)) {
X    if ((m->id != ML4+6) && /*succubi don't give fear */
X	los_p(m->x,m->y,Player.x,Player.y) &&
X	(random_range(30) > Player.level+10) &&
X	(Player.status[AFRAID] == 0)) {
X      mprint("You are stricken with fear!");
X      if (! p_immune(FEAR)) Player.status[AFRAID] += m->level;
X      else mprint("You master your reptile brain and stand fast.");
X    }
X    else m_sp_spell(m);
X  }
X  if ((m->hp < (m->level * 5)) && (m->hp > 1)) {
X    mprint("The demon uses its waning lifeforce to summon help!");
X    m->hp = 1;
X    switch(m->level) {
X    case 3: mid = ML2+1; break; /* night gaunt */
X    case 4:
X    case 5: mid = ML3+2; break; /* lesser frost demon */
X    case 6: mid = ML5+4; break; /* frost demon */
X    case 7: mid = ML5+12; break; /* outer circle demon */
X    case 8: mid = ML6+10; break; /* demon serpent */
X    case 9: mid = ML7+14; break; /* inner circle demon */
X    }
X    summon(-1,mid);
X    summon(-1,mid);
X  }
X}
X
X
Xvoid m_sp_acid_cloud(m)
Xstruct monster *m;
X{
X  if (m_statusp(m,HOSTILE) &&
X      (distance(m->x,m->y,Player.x,Player.y) < 3))
X    acid_cloud();
X}
X
X	  
Xvoid m_sp_escape(m)
Xstruct monster *m;
X{
X  if (m_statusp(m,HOSTILE))
X    m_vanish(m);
X}
X
X
Xvoid m_sp_ghost(m)
Xstruct monster *m;
X{
X  if (m_statusp(m,HOSTILE)) {
X    mprint("The ghost moans horribly....");
X    p_damage(1,FEAR,"a ghost-inspired heart attack");
X    mprint("You've been terrorized!");
X    if (! p_immune(FEAR)) Player.status[AFRAID] += m->level;
X    else mprint("You master your reptile brain and stand fast.");
X  }
X}
X
X
X
X
X/* random spell cast by monster */
Xvoid m_sp_spell(m)
Xstruct monster *m;
X{
X  char action[80];
X  if (m_statusp(m,HOSTILE) && los_p(Player.x,Player.y,m->x,m->y)) {
X    if (m->uniqueness == COMMON) strcpy(action,"The ");
X    else strcpy(action,"");
X    strcat(action,m->monstring);
X    strcat(action," casts a spell...");
X    mprint(action);
X    if (! magic_resist(m->level)) switch (random_range(m->level+7)) {
X    case 0: 
X      nbolt(m->x,m->y,Player.x,Player.y,m->hit,10);
X      break;
X    case 1:
X      mprint("It seems stronger..."); 
X      m->hp += random_range(m->level*m->level);
X      break;
X    case 2:
X      haste(-1);
X      break;
X    case 3:
X      cure(-1);
X      break;
X    case 4:
X      lball(m->x,m->y,Player.x,Player.y,20);
X      break;
X    case 5:
X      enchant(-1);
X    case 6:
X      snowball(m->x,m->y,Player.x,Player.y,30);
X      break;
X    case 7:
X      bless(0-m->level);
X      break;
X    case 8:
X      p_poison(m->level);
X      break;
X    case 9:
X      sleep_player(m->level/2);
X      break;
X    case 10:
X      fbolt(m->x,m->y,Player.x,Player.y,m->hit*3,50);
X      break;
X    case 11:
X      acquire(0-m->level);
X      break;
X    case 12:
X      dispel(-1);
X      break;
X    case 13:
X      disrupt(Player.x,Player.y,50);
X      break;
X    case 14:
X      if (m->uniqueness == COMMON) {
X	strcpy(Str2,"a ");
X	strcat(Str2,m->monstring);
X      }
X      else strcpy(Str2,m->monstring);
X      level_drain(m->level,Str2);
X      break;
X    case 15:
X    case 16:
X      disintegrate(Player.x,Player.y);
X      break;
X    }
X  }
X}
X
X
X
X/* monsters with this have some way to hide, camouflage, etc until they 
X   attack */
Xvoid m_sp_surprise(m)
Xstruct monster *m;
X{
X  if (m->attacked) {
X    if (m_statusp(m,HOSTILE) && 
X	(! Player.status[TRUESIGHT]) &&
X	m_statusp(m,M_INVISIBLE)) {
X      m->monchar = Monsters[m->id].monchar;
X      if (! Player.status[ALERT]) {
X	switch(random_range(4)) {
X	case 0: 
X	  mprint("You are surprised by a sudden treacherous attack!");
X	  break;
X	case 1: 
X	  mprint("You are shocked out of your reverie by the scream of battle!");
X	  break;
X	case 2: 
X	  mprint("Suddenly, from out of the shadows, a surprise attack!");
X	  break;
X	case 3: 
X	  mprint("A shriek of hatred causes you to momentarily freeze up!");
X	  break;
X	}
X	morewait();
X	setgamestatus(SKIP_PLAYER);
X	m_status_reset(m,M_INVISIBLE);
X      }
X      else {
X	mprint("You alertly sense the presence of an attacker!");
X	m_status_reset(m,M_INVISIBLE);
X      }	
X    }
X  }
X}
X
Xvoid m_sp_whistleblower(m)
Xstruct monster *m;
X{
X  pml ml;
X  if (m_statusp(m,HOSTILE)) {
X    alert_guards();
X    m->specialf = M_MELEE_NORMAL;
X  }
X}
X
X
Xvoid m_sp_seductor(m)
Xstruct monster *m;
X{
X  if (m_statusp(m,HOSTILE)) {
X    if (m->uniqueness == COMMON) {
X      strcpy(Str2,"The ");
X      strcat(Str2,m->monstring);
X    }
X    else strcpy(Str2,m->monstring);
X    strcat(Str2," runs away screaming for help....");
X    mprint(Str2);
X    m_vanish(m);
X    summon(-1,-1);
X    summon(-1,-1);
X    summon(-1,-1);
X  }
X  else if (distance(Player.x,Player.y,m->x,m->y) < 2) 
X    m_talk_seductor(m);
X
X}
X
X
Xvoid m_sp_demonlover(m)
Xstruct monster *m;
X{
X  if (distance(Player.x,Player.y,m->x,m->y) < 2) 
X    m_talk_demonlover(m);
X}
X
Xvoid m_sp_eater(m)
Xstruct monster *m;
X{
X  int i;
X  if (Player.rank[COLLEGE]) m_status_set(m,HOSTILE);
X  if (m_statusp(m,HOSTILE))
X    if (los_p(m->x,m->y,Player.x,Player.y)) {
X      mprint("A strange numbing sensation comes over you...");
X      morewait();
X      Player.mana = Player.mana / 2;
X      if (random_range(4)) enchant(-1);
X      else dispel(-1);
X      Player.pow--;
X      if (--Player.pow < 1) p_death("The Eater of Magic");
X    }
X  if (m->hp < 10) {
X    mprint("The Eater explodes in a burst of mana!");
X    for(i=0;i<9;i++) 
X      manastorm(m->x+Dirs[0][i],m->y+Dirs[0][i],100);
X  }
X}
X
X
Xvoid m_sp_dragonlord(m)
Xstruct monster *m;
X{
X  if (m_statusp(m,HOSTILE)) {
X    if (distance(m->x,m->y,Player.x,Player.y)<2) {
X      if (! Player.status[IMMOBILE]) {
X	mprint("A gust of wind from the Dragonlord's wings knocks you down!");
X	p_damage(25,NORMAL_DAMAGE,"a gust of wind");
X	setgamestatus(SKIP_PLAYER);
X	Player.status[IMMOBILE]+=2;
X      }
X      else if (! Constriction) {
X	mprint("The Dragonlord grabs you with his tail!");
X	Constriction = 25;
X	Player.status[IMMOBILE]+=1;
X      }
X      else if (random_range(2)) {
X	mprint("The coils squeeze tighter and tighter...");
X	p_damage(Constriction,NORMAL_DAMAGE,"The Dragonlord");
X	Player.status[IMMOBILE]+=1;
X	Constriction *=2;
X      }
X      else {
X	mprint("The dragonlord hurls you to the ground!");
X	p_damage(2*Constriction,NORMAL_DAMAGE,"The Dragonlord");
X	Constriction = 0;
X      }
X      m_sp_spell(m);
X    }
X    else {
X      Constriction = 0;
X      if (view_los_p(m->x,m->y,Player.x,Player.y)) {
X	if ((! Player.immunity[FEAR]) && (! Player.status[AFRAID])) {
X	  mprint("You are awestruck at the sight of the Dragonlord.");
X	  Player.status[AFRAID]+=5;
X	}
X	if (random_range(3)) {
X	  m_sp_spell(m);
X	  m_sp_spell(m);
X	}
X      }
X    }
X  }
X  else if (distance(m->x,m->y,Player.x,Player.y)<2)
X    mprint("You are extremely impressed at the sight of the Dragonlord.");
X}
X
X
Xvoid m_sp_blackout(m)
Xstruct monster *m;
X{
X  if ((distance(m->x,m->y,Player.x,Player.y) < 4) &&
X      (Player.status[BLINDED] == 0)) {
X    mprint("The fungus emits a burst of black spores. You've been blinded!");
X    if (Player.status[TRUESIGHT] > 0) mprint("The blindness quickly passes.");
X    else Player.status[BLINDED]+=4;
X  }
X  if (loc_statusp(m->x,m->y,LIT)) {
X    mprint("The fungus chirps.... ");
X    mprint("The area is plunged into darkness.");
X    torch_check();torch_check();torch_check();
X    torch_check();torch_check();torch_check();
X    spreadroomdark(m->x,m->y,Level->site[m->x][m->y].roomnumber);
X    levelrefresh();
X  }
X}
X
X
Xvoid m_sp_bogthing(m)
Xstruct monster *m;
X{
X  if (Player.status[IMMOBILE] && 
X      (distance(Player.x,Player.y,m->x,m->y) < 2)) {
X    if (! Player.status[AFRAID]) {
X      mprint("As the bogthing touches you, you feel a frisson of terror....");
X      if (Player.immunity[FEAR]) mprint("which you shake off.");
X      else Player.status[AFRAID]+=2;
X    }
X    else {
X      mprint("The bogthing's touch causes you scream in agony!");
X      p_damage(50,UNSTOPPABLE,"fright");
X      mprint("Your struggles grow steadily weaker....");
X      Player.con--;
X      Player.str--;
X      if ((Player.con < 3) || (Player.str < 3))
X	p_death("congestive heart failure");
X    }
X  }
X}
X
X
Xvoid m_sp_were(m)
Xstruct monster *m;
X{
X  int mid;
X  if (m_statusp(m,HOSTILE) || (Phase == 6)) {
X    do mid = random_range(ML9-NML_0)+ML1;
X    while ((Monsters[mid].uniqueness != COMMON) ||
X	   (! m_statusp(&(Monsters[mid]),MOBILE)) ||
X	   (! m_statusp(&(Monsters[mid]),HOSTILE)));
X    m->id = Monsters[mid].id;
X    m->hp += Monsters[mid].hp;
X    m->status |= Monsters[mid].status;
X    m->ac = Monsters[mid].ac;
X    m->dmg = Monsters[mid].dmg;
X    m->speed = Monsters[mid].speed;
X    m->immunity |= Monsters[mid].immunity;
X    m->xpv += Monsters[mid].xpv;
X    m->corpseweight = Monsters[mid].corpseweight;
X    m->monchar = Monsters[mid].monchar;
X    m->talkf = Monsters[mid].talkf;
X    m->meleef = Monsters[mid].meleef;
X    m->strikef = Monsters[mid].strikef;
X    m->specialf = Monsters[mid].specialf;
X    strcpy(Str1,"were-");
X    strcat(Str1,Monsters[mid].monstring);
X    strcpy(Str2,"dead were-");
X    strcat(Str2,Monsters[mid].monstring);
X    m->monstring = salloc(Str1);
X    m->corpsestr = salloc(Str2);
X    m->immunity += pow2(NORMAL_DAMAGE);
X    if (los_p(m->x,m->y,Player.x,Player.y)) 
X      mprint("You witness a hideous transformation!");
X    else mprint("You hear a distant howl.");
X  }
X}    
X
X
Xvoid m_sp_leash(m)
Xstruct monster *m;
X{
X  if (m->aux1 < 0) {
X    m->aux1 = m->x;
X    m->aux2 = m->y;
X  }
X  else if (distance(m->x,m->y,m->aux1,m->aux2) > 5) {
X    Level->site[m->x][m->y].creature = NULL;
X    m->x = m->aux1;
X    m->y = m->aux2;
X    Level->site[m->x][m->y].creature = m;
X    if (los_p(Player.x,Player.y,m->x,m->y)) 
X      mprint("You see the dog jerked back by its chain!");
X    else mprint("You hear a strangled sort of yelp!");
X  }
X}
X
Xvoid m_sp_servant(m)
Xstruct monster *m;
X{
X  pml ml;
X  if ((m->id == ML4+12) && (Player.alignment < 0))
X    m_status_set(m,HOSTILE);
X  else if ((m->id == ML4+13) && (Player.alignment > 0))
X    m_status_set(m,HOSTILE);
X}
X
X
Xvoid m_sp_av(m)
Xstruct monster *m;
X{
X  if (Player.mana > 0) {
X    mprint("You feel a sudden loss of mana!");
X    Player.mana -= (max(0,10-distance(m->x,m->y,Player.x,Player.y)));
X    dataprint();
X  }
X}
X
Xvoid m_sp_lw(m)
Xstruct monster *m;
X{
X  if (random_range(2)) {
X    if (Level->site[m->x][m->y].locchar == FLOOR) {
X      Level->site[m->x][m->y].locchar = LAVA;
X      Level->site[m->x][m->y].p_locf = L_LAVA;
X    }
X    else if (Level->site[m->x][m->y].locchar == WATER) {
X      Level->site[m->x][m->y].locchar = FLOOR;
X      Level->site[m->x][m->y].p_locf = L_NO_OP;
X    }
X  }
X}
X
X
Xvoid m_sp_angel(m)
Xstruct monster *m;
X{
X  int mid,hostile = FALSE;
X  switch(m->aux1) {
X  case ATHENA:
X  case ODIN: 
X    hostile = ((Player.patron == HECATE) || (Player.patron == SET));
X    break;
X  case SET:
X  case HECATE: 
X    hostile = ((Player.patron == ODIN) || (Player.patron == ATHENA));
X    break;
X  case DESTINY:
X    hostile = (Player.patron != DESTINY);
X    break;
X  }
X  if (hostile)
X    m_status_set(m,HOSTILE);
X  if (m_statusp(m,HOSTILE)) {
X    mprint("The angel summons a heavenly host!");
X    switch(m->level) {
X    case 9: mid = ML8+11; break; /* high angel */
X    case 8: mid = ML6+11; break; /* angel */
X    default:
X    case 6: mid = ML3+4; break; /* phantom */
X    }
X    summon(-1,mid);
X    summon(-1,mid);
X    summon(-1,mid);
X    /* prevent angel from summoning infinitely */
X    m->specialf = M_NO_OP;
X  }
X}
X
X
X/* Could completely fill up level */
Xvoid m_sp_swarm(m)
Xstruct monster *m;
X{
X  if (random_range(5)==1) {
X    if (view_los_p(m->x,m->y,Player.x,Player.y))
X      mprint("The swarm expands!");
X    else mprint("You hear an aggravating humming noise.");
X    summon(-1,ML4+14);
X  }
X}
X
X
X
X
X/* raise nearby corpses from the dead.... */
Xvoid m_sp_raise(m)
Xstruct monster *m;
X{
X  int x,y;
X  pol t;
X  for(x=m->x-2;x<=m->x+2;x++)
X    for(y=m->y-2;y<=m->y+2;y++)
X      if (inbounds(x,y)) 
X	if (Level->site[x][y].things != NULL)
X	  if (Level->site[x][y].things->thing->id == CORPSEID) {
X	    mprint("The Zombie Overlord makes a mystical gesture...");
X	    summon(-1,Level->site[x][y].things->thing->charge);
X	    t = Level->site[x][y].things;
X	    Level->site[x][y].things = Level->site[x][y].things->next;
X	    free((char *) t);
X	  }
X}
X
X
X
X
Xvoid m_sp_mb(m)
Xstruct monster *m;
X{
X  if (distance(m->x,m->y,Player.x,Player.y)==1) {
X    mprint("The manaburst explodes!");
X    if (m_statusp(m,HOSTILE)) {
X      mprint("You get blasted!");
X      p_damage(random_range(100),UNSTOPPABLE,"a manaburst");
X      mprint("You feel cold all over!");
X      Player.pow-=3;
X      Player.iq--;
X      Player.con--;
X      Player.str-=2;
X      Player.dex--;
X      Player.agi--;
X      dispel(-1);
X    }
X    else {
X      mprint("You feel toasty warm inside!");
X      Player.pow++;
X      Player.mana = max(Player.mana,calcmana());
X      Player.hp = max(Player.hp,++Player.maxhp);
X    }
X    m->hp = 0;
X  }
X}
X
X
Xvoid m_sp_mirror(m)
Xstruct monster *m;
X{
X  int i,x,y;
X  if (view_los_p(m->x,m->y,Player.x,Player.y)) {
X    if (random_range(20)+6 < m->level) {
X      summon(-1,m->id);
X      mprint("You hear the sound of a mirror shattering!");
X    }
X    else for(i=0;i<5;i++) {
X      x = m->x + random_range(13)-6;
X      y = m->y + random_range(13)-6;
X      if (inbounds(x,y)) {
X	Level->site[x][y].showchar = m->monchar;
X	putspot(x,y,m->monchar);
X      }
X    }
X  }
X}
X
X
X
Xvoid m_illusion(m)
Xstruct monster *m;
X{
X  int i = random_range(NUMMONSTERS);
X  if (i==ML0+4) i = m->id; /* can't imitate NPC */
X  if (Player.status[TRUESIGHT]) {
X    m->monchar = Monsters[m->id].monchar;
X    m->monstring = Monsters[m->id].monstring;
X  }
X  else  if (random_range(5) == 1) {
X    m->monchar = Monsters[i].monchar;
X    m->monstring = Monsters[i].monstring;
X  }
X}
X
X
X
X
Xvoid m_huge_sounds(m)
Xstruct monster *m;
X{
X  if (m_statusp(m,AWAKE) &&
X      (! los_p(m->x,m->y,Player.x,Player.y)) &&
X      (random_range(10) == 1))
X    mprint("The dungeon shakes!");
X}
X
X
X
Xvoid m_thief_f(m)
Xstruct monster *m;
X{
X  int i = random_item();
X  if (random_range(3) == 1) {
X    if (distance(Player.x,Player.y,m->x,m->y) < 2) {
X      if (p_immune(THEFT) || (Player.level > (m->level*2)+random_range(20))) 
X	mprint("You feel secure.");
X      else {
X	if (i == ABORT)
X	  mprint("You feel fortunate.");
X	else if ((Player.possessions[i]->used) || 
X		 (Player.dex < m->level*random_range(10))) {
X	  mprint("You feel a sharp tug.... You hold on!");
X	}
X	else {
X	  mprint("You feel uneasy for a moment.");
X	  if (m->uniqueness == COMMON) {
X	    strcpy(Str2,"The ");
X	    strcat(Str2,m->monstring);
X	  }
X	  else strcpy(Str2,m->monstring);
X	  strcat(Str2,"suddenly runs away for some reason.");
X	  mprint(Str2);
X	  m_teleport(m);
X	  m->movef = M_MOVE_SCAREDY;
X	  m->specialf = M_MOVE_SCAREDY;
X	  m_pickup(m,Player.possessions[i]);
X	  conform_lost_object(Player.possessions[i]);
X	}
X      }
X    }
X  }
X}
X
X
Xvoid m_summon(m)
Xstruct monster *m;
X{
X  if ((distance(Player.x,Player.y,m->x,m->y) < 2) &&
X      (random_range(3) == 1)) {
X	summon(0,-1);
X	summon(0,-1);
X      }
X}	  
X
X
Xvoid m_aggravate(m)
Xstruct monster *m;
X{
X
X  if (m_statusp(m,HOSTILE)) {
X    if (m->uniqueness == COMMON) {
X      strcpy(Str2,"The ");
X      strcat(Str2,m->monstring);
X    }
X    else strcpy(Str2,m->monstring);
X    strcat(Str2," emits an irritating humming sound.");
X    mprint(Str2);
X    aggravate();
X    m_status_reset(m,HOSTILE);
X  }
X}
X
X
X
Xvoid m_sp_merchant(m)
Xstruct monster *m;
X{
X  pml ml;
X  if (m_statusp(m,HOSTILE))
X    if (Current_Environment == E_VILLAGE) {
X      mprint("The merchant screams: 'Help! Murder! Guards! Help!'");
X      mprint("You hear the sound of police whistles and running feet.");
X      for (ml=Level->mlist;ml!=NULL;ml=ml->next) {
X	m_status_set(ml->m,AWAKE);
X	m_status_set(ml->m,HOSTILE);
X      }
X      m->specialf = M_NO_OP;
X    }
X}
X
X/* The special function of the various people in the court of the archmage */
X/* and the sorcerors' circle */
Xvoid m_sp_court(m)
Xstruct monster *m;
X{
X  pml ml;
X  if (m_statusp(m,HOSTILE)) {
X    mprint("A storm of spells hits you!");
X    for(ml=Level->mlist;ml!=NULL;ml=ml->next) {
X      m_status_set(ml->m,HOSTILE);
X      m_sp_spell(ml->m);
X      if (ml->m->specialf == M_SP_COURT)
X	ml->m->specialf = M_SP_SPELL;
X    }
X  }
X}
X
X
X/* The special function of the dragons in the dragons' lair */
Xvoid m_sp_lair(m)
Xstruct monster *m;
X{
X  pml ml;
X  if (m_statusp(m,HOSTILE)) {
X    if (m->id == ML10+3) m->specialf = M_SP_DRAGONLORD;
X    mprint("You notice a number of dragons waking up....");
X    mprint("You are struck by a quantity of firebolts.");
X    for(ml=Level->mlist;ml!=NULL;ml=ml->next) {
X      m_status_set(ml->m,HOSTILE);
X      fbolt(ml->m->x,ml->m->y,Player.x,Player.y,100,100);
X      if (ml->m->specialf == M_SP_LAIR)
X	ml->m->specialf = M_STRIKE_FBOLT;
X    }
X  }
X}
X
X
Xvoid m_sp_prime(m)
Xstruct monster *m;
X{
X  if (m_statusp(m,HOSTILE)) {
X    mprint("The prime sorceror gestures and a pentacular gate opens!");
X    mprint("You are surrounded by demons!");
X    summon(-1,ML9+7);
X    summon(-1,ML9+7);
X    summon(-1,ML9+7);
X    summon(-1,ML9+7);
X  }
X  m->specialf = M_SP_SPELL;
X}
END_OF_FILE
if test 18434 -ne `wc -c <'omspec.c'`; then
    echo shar: \"'omspec.c'\" unpacked with wrong size!
fi
# end of 'omspec.c'
fi
if test -f 'otime.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'otime.c'\"
else
echo shar: Extracting \"'otime.c'\" \(2389 characters\)
sed "s/^X//" >'otime.c' <<'END_OF_FILE'
X/* omega copyright (c) 1987,1988 by Laurence Raphael Brothers */
X/* otime.c */
X
X/* this file deals with the passage of time in omega */
X
X#include "oglob.h"
X
X/* This function coordinates monsters and player actions, as well as
Xrandom events. Each tick is a second. There are therefore 60 ticks to
Xthe minute and 60 minutes to the hour.
X*/
X
Xvoid time_clock(reset)
Xint reset;
X{
X  pml ml;
X
X  if (++Tick > 60) {
X    Tick = 0;
X    minute_status_check(); /* see about some player statuses each minute */
X    if (++Time % 10 == 0) tenminute_check();
X  }
X  
X  if (reset) Tick = (Player.click = 0);
X
X  while ((Tick == Player.click) && (Current_Environment != E_COUNTRYSIDE)) {
X    if (! gamestatusp(SKIP_PLAYER))
X      do {
X	resetgamestatus(SKIP_MONSTERS);
X	if ((! Player.status[SLEPT])  && 
X	    (Current_Environment != E_COUNTRYSIDE)) p_process(); 
X      } while (gamestatusp(SKIP_MONSTERS) && 
X	       (Current_Environment != E_COUNTRYSIDE));
X    else resetgamestatus(SKIP_PLAYER);
X    Player.click = (Player.click + Command_Duration) % 60;
X  }
X
X  /* klugy but what the heck. w/o this line, if the player caused
X  a change-environment to the country, the monsters on the old Level
X  will still act, causing all kinds of anomalies and core dumps,
X  intermittently. However, any other environment change will reset
X  Level appropriately, so only have to check for countryside */
X
X  if (Current_Environment != E_COUNTRYSIDE) {
X
X    /* no longer search for dead monsters every round -- waste of time.
X     Instead, just skip dead monsters. Eventually, the whole level
X     will be freed, getting rid of the dead 'uns */
X
X    for(ml=Level->mlist;ml!=NULL;ml=ml->next) 
X      if (ml->m->hp > 0) {
X
X	/* following is a hack until I discover source of phantom monsters */
X	if (Level->site[ml->m->x][ml->m->y].creature != ml->m)
X	  fix_phantom(ml->m); 
X
X	if (Tick == ml->m->click) {
X	  ml->m->click += ml->m->speed;
X	  while (ml->m->click > 60) ml->m->click -= 60;
X	  m_pulse(ml->m);
X	}
X      }
X  }
X}
X
X
X
X
X
X/* remedies occasional defective monsters */
Xvoid fix_phantom(m)
Xstruct monster *m;
X{
X  if (Level->site[m->x][m->y].creature == NULL) {
X    mprint("You hear a sound like a sigh of relief....");
X    Level->site[m->x][m->y].creature = m;
X  }
X  else {
X    mprint("You hear a puff of displaced air....");
X    findspace(&(m->x),&(m->y),-1);
X    Level->site[m->x][m->y].creature = m;
X    m_death(m);
X  }
X}
END_OF_FILE
if test 2389 -ne `wc -c <'otime.c'`; then
    echo shar: \"'otime.c'\" unpacked with wrong size!
fi
# end of 'otime.c'
fi
echo shar: End of archive 6 \(of 19\).
cp /dev/null ark6isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 19 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