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