billr@saab.CNA.TEK.COM (Bill Randle) (07/13/89)
Submitted-by: "Laurence R. Brothers" <brothers@paul.rutgers.edu>
Posting-number: Volume 7, Issue 26
Archive-name: omega3/Part07
Supersedes: omega2: Volume 5, Issue 11-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 7 (of 20)."
# Contents: omon.c omspec.c otime.c
# Wrapped by billr@saab on Thu Jun 29 08:14:02 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'omon.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'omon.c'\"
else
echo shar: Extracting \"'omon.c'\" \(29973 characters\)
sed "s/^X//" >'omon.c' <<'END_OF_FILE'
X/* omega copyright (c) 1987,1988,1989 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+0) { /* 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#ifdef MSDOS
X unsigned tmp;
X#endif
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#ifndef MSDOS
X m->hp = min(100000,100+m->dmg*10);
X#else
X /* In order not to have to make the hp's into longs or unsigned,
X which would involve lots of changes, I'll make it max out at 30000. */
X tmp = 100+m->dmg*10;
X m->hp = (tmp > 30000) ? 30000 : tmp;
X#endif
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 29973 -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'\" \(18439 characters\)
sed "s/^X//" >'omspec.c' <<'END_OF_FILE'
X/* omega copyright (c) 1987,1988,1989 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 18439 -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'\" \(2394 characters\)
sed "s/^X//" >'otime.c' <<'END_OF_FILE'
X/* omega copyright (c) 1987,1988,1989 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 2394 -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 7 \(of 20\).
cp /dev/null ark7isdone
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