games@tekred.TEK.COM (07/28/88)
Submitted by: "Laurence R. Brothers" <brothers@paul.rutgers.edu>
Comp.sources.games: Volume 5, Issue 38
Archive-name: omega2/Part13
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 13 (of 19)."
# Contents: oabyss.c ocity.c olev.c ospell.c
# Wrapped by billr@saab on Wed Jul 13 10:46:55 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'oabyss.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'oabyss.c'\"
else
echo shar: Extracting \"'oabyss.c'\" \(1698 characters\)
sed "s/^X//" >'oabyss.c' <<'END_OF_FILE'
X/* omega copyright (C) by Laurence Raphael Brothers, 1987,1988 */
X/* oabyss.c */
X/* some functions to make the abyss level and run the final challenge */
X
X#include "oglob.h"
X
X
X/* loads the abyss level into Level*/
Xvoid load_abyss()
X{
X int i,j;
X char site;
X
X FILE *fd;
X
X TempLevel = Level;
X if (ok_to_free(TempLevel)) {
X free((char *) TempLevel);
X TempLevel = NULL;
X }
X Level = ((plv) malloc(sizeof(levtype)));
X
X clear_level(Level);
X
X strcpy(Str3,OMEGALIB);
X strcat(Str3,"oabyss.dat");
X fd = fopen(Str3,"r");
X for(j=0;j<LENGTH;j++) {
X for(i=0;i<WIDTH;i++) {
X site = getc(fd);
X switch(site) {
X case '0':
X Level->site[i][j].locchar = ' ';
X Level->site[i][j].p_locf = L_VOID;
X break;
X case 'V':
X Level->site[i][j].locchar = ' ';
X Level->site[i][j].p_locf = L_VOID_STATION;
X break;
X case '1':
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].p_locf = L_VOICE1;
X break;
X case '2':
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].p_locf = L_VOICE2;
X break;
X case '3':
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].p_locf = L_VOICE3;
X break;
X case '~':
X Level->site[i][j].locchar = WATER;
X Level->site[i][j].p_locf = L_WATER_STATION;
X break;
X case ';':
X Level->site[i][j].locchar = FIRE;
X Level->site[i][j].p_locf = L_FIRE_STATION;
X break;
X case '"':
X Level->site[i][j].locchar = HEDGE;
X Level->site[i][j].p_locf = L_EARTH_STATION;
X break;
X case '6':
X Level->site[i][j].locchar = WHIRLWIND;
X Level->site[i][j].p_locf = L_AIR_STATION;
X break;
X case '#':
X Level->site[i][j].locchar = WALL;
X break;
X case '.':
X Level->site[i][j].locchar = FLOOR;
X break;
X }
X }
X fscanf(fd,"\n");
X }
X}
END_OF_FILE
if test 1698 -ne `wc -c <'oabyss.c'`; then
echo shar: \"'oabyss.c'\" unpacked with wrong size!
fi
# end of 'oabyss.c'
fi
if test -f 'ocity.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'ocity.c'\"
else
echo shar: Extracting \"'ocity.c'\" \(16797 characters\)
sed "s/^X//" >'ocity.c' <<'END_OF_FILE'
X/* omega copyright (C) by Laurence Raphael Brothers, 1987,1988 */
X/* ocity.c */
X/* some functions to make the city level */
X
X#include "oglob.h"
X
X
X/* loads the city level */
Xvoid load_city()
X{
X int i,j;
X pml ml;
X char site;
X
X FILE *fd;
X
X for(i=0;i<NUMCITYSITES;i++)
X CitySiteList[i][0] = FALSE;
X
X strcpy(Str3,OMEGALIB);
X strcat(Str3,"ocity.dat");
X fd = fopen(Str3,"r");
X
X
X TempLevel = Level;
X if (ok_to_free(TempLevel)) {
X free((char *) TempLevel);
X TempLevel = NULL;
X }
X Level = ((plv) malloc(sizeof(levtype)));
X clear_level(Level);
X Level->environment = E_CITY;
X for(j=0;j<LENGTH;j++) {
X for(i=0;i<WIDTH;i++) {
X lset(i,j,SEEN);
X site = getc(fd);
X
X switch(site) {
X case 'g':
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].p_locf = L_GARDEN;
X break;
X case 'z':
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].p_locf = L_MAZE;
X break;
X case 'y':
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].p_locf = L_CEMETARY;
X break;
X case 'x':
X assign_city_function(i,j);
X break;
X case 't':
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].p_locf = L_TEMPLE;
X CitySiteList[L_TEMPLE-CITYSITEBASE][0] = TRUE;
X CitySiteList[L_TEMPLE-CITYSITEBASE][1] = i;
X CitySiteList[L_TEMPLE-CITYSITEBASE][2] = j;
X break;
X case 'T':
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].p_locf = L_PORTCULLIS_TRAP;
X Level->site[i][j].aux = NOCITYMOVE;
X break;
X case 'R':
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].p_locf = L_RAISE_PORTCULLIS;
X Level->site[i][j].aux = NOCITYMOVE;
X break;
X case '7':
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].p_locf = L_PORTCULLIS;
X Level->site[i][j].aux = NOCITYMOVE;
X break;
X case 'C':
X Level->site[i][j].locchar = OPEN_DOOR;
X Level->site[i][j].p_locf = L_COLLEGE;
X CitySiteList[L_COLLEGE-CITYSITEBASE][0] = TRUE;
X CitySiteList[L_COLLEGE-CITYSITEBASE][1] = i;
X CitySiteList[L_COLLEGE-CITYSITEBASE][2] = j;
X break;
X case 's':
X Level->site[i][j].locchar = OPEN_DOOR;
X Level->site[i][j].p_locf = L_SORCERORS;
X CitySiteList[L_SORCERORS-CITYSITEBASE][0] = TRUE;
X CitySiteList[L_SORCERORS-CITYSITEBASE][1] = i;
X CitySiteList[L_SORCERORS-CITYSITEBASE][2] = j;
X break;
X case 'M':
X Level->site[i][j].locchar = OPEN_DOOR;
X Level->site[i][j].p_locf = L_MERC_GUILD;
X CitySiteList[L_MERC_GUILD-CITYSITEBASE][0] = TRUE;
X CitySiteList[L_MERC_GUILD-CITYSITEBASE][1] = i;
X CitySiteList[L_MERC_GUILD-CITYSITEBASE][2] = j;
X break;
X case 'c':
X Level->site[i][j].locchar = OPEN_DOOR;
X Level->site[i][j].p_locf = L_CASTLE;
X CitySiteList[L_CASTLE-CITYSITEBASE][0] = TRUE;
X CitySiteList[L_CASTLE-CITYSITEBASE][1] = i;
X CitySiteList[L_CASTLE-CITYSITEBASE][2] = j;
X break;
X case '?':
X mazesite(i,j);
X break;
X case 'P':
X Level->site[i][j].locchar = OPEN_DOOR;
X Level->site[i][j].p_locf = L_ORDER;
X CitySiteList[L_ORDER-CITYSITEBASE][0] = TRUE;
X CitySiteList[L_ORDER-CITYSITEBASE][1] = i;
X CitySiteList[L_ORDER-CITYSITEBASE][2] = j;
X break;
X case 'H':
X Level->site[i][j].locchar = OPEN_DOOR;
X Level->site[i][j].p_locf = L_CHARITY;
X CitySiteList[L_CHARITY-CITYSITEBASE][0] = TRUE;
X CitySiteList[L_CHARITY-CITYSITEBASE][1] = i;
X CitySiteList[L_CHARITY-CITYSITEBASE][2] = j;
X break;
X case 'j':
X Level->site[i][j].locchar = FLOOR;
X make_justiciar(i,j);
X break;
X case 'J':
X Level->site[i][j].locchar = CLOSED_DOOR;
X Level->site[i][j].p_locf = L_JAIL;
X break;
X case 'A':
X Level->site[i][j].locchar = OPEN_DOOR;
X Level->site[i][j].p_locf = L_ARENA;
X CitySiteList[L_ARENA-CITYSITEBASE][0] = TRUE;
X CitySiteList[L_ARENA-CITYSITEBASE][1] = i;
X CitySiteList[L_ARENA-CITYSITEBASE][2] = j;
X break;
X case 'B':
X Level->site[i][j].locchar = OPEN_DOOR;
X Level->site[i][j].p_locf = L_BANK;
X CitySiteList[L_BANK-CITYSITEBASE][0] = TRUE;
X CitySiteList[L_BANK-CITYSITEBASE][1] = i;
X CitySiteList[L_BANK-CITYSITEBASE][2] = j;
X lset(i,j+1,STOPS);
X lset(i+1,j,STOPS);
X lset(i-1,j,STOPS);
X lset(i,j-1,STOPS);
X break;
X case 'X':
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].p_locf = L_COUNTRYSIDE;
X CitySiteList[L_COUNTRYSIDE-CITYSITEBASE][0] = TRUE;
X CitySiteList[L_COUNTRYSIDE-CITYSITEBASE][1] = i;
X CitySiteList[L_COUNTRYSIDE-CITYSITEBASE][2] = j;
X break;
X case 'V':
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].p_locf = L_VAULT;
X Level->site[i][j].aux = NOCITYMOVE;
X lset(i,j,SECRET);
X break;
X case '\\':
X Level->site[i][j].aux = NOCITYMOVE;
X Level->site[i][j].showchar = WALL;
X Level->site[i][j].locchar = CLOSED_DOOR;
X Level->site[i][j].p_locf = L_VAULT;
X lset(i,j,SECRET);
X break;
X case 'S':
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].aux = NOCITYMOVE;
X lset(i,j,SECRET);
X break;
X case 'G':
X Level->site[i][j].locchar = FLOOR;
X make_site_monster(i,j,ML0+3);
X break;
X case 'u':
X Level->site[i][j].locchar = FLOOR;
X make_minor_undead(i,j);
X break;
X case 'U':
X Level->site[i][j].locchar = FLOOR;
X make_major_undead(i,j);
X break;
X case '%':
X Level->site[i][j].showchar = WALL;
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].p_locf = L_TRAP_SIREN;
X make_site_treasure(i,j,5);
X Level->site[i][j].aux = NOCITYMOVE;
X lset(i,j,SECRET);
X break;
X case '$':
X Level->site[i][j].locchar = FLOOR;
X make_site_treasure(i,j,5);
X break;
X case '2':
X Level->site[i][j].locchar = ALTAR;
X Level->site[i][j].p_locf = L_ALTAR;
X Level->site[i][j].aux = ODIN;
X break;
X case '3':
X Level->site[i][j].locchar = ALTAR;
X Level->site[i][j].p_locf = L_ALTAR;
X Level->site[i][j].aux = SET;
X break;
X case '4':
X Level->site[i][j].locchar = ALTAR;
X Level->site[i][j].p_locf = L_ALTAR;
X Level->site[i][j].aux = ATHENA;
X break;
X case '5':
X Level->site[i][j].locchar = ALTAR;
X Level->site[i][j].p_locf = L_ALTAR;
X Level->site[i][j].aux = HECATE;
X break;
X case '6':
X Level->site[i][j].locchar = ALTAR;
X Level->site[i][j].p_locf = L_ALTAR;
X Level->site[i][j].aux = DESTINY;
X break;
X case 'O':
X Level->site[i][j].locchar = OPEN_DOOR;
X Level->site[i][j].p_locf = L_ORACLE;
X CitySiteList[L_ORACLE-CITYSITEBASE][1] = i;
X CitySiteList[L_ORACLE-CITYSITEBASE][2] = j;
X break;
X case '^':
X Level->site[i][j].showchar = WALL;
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].p_locf = TRAP_BASE+random_range(NUMTRAPS);
X lset(i,j,SECRET);
X break;
X case '"':
X Level->site[i][j].locchar = HEDGE;
X break;
X case '~':
X Level->site[i][j].locchar = WATER;
X Level->site[i][j].p_locf = L_WATER;
X break;
X case '=':
X Level->site[i][j].locchar = WATER;
X Level->site[i][j].p_locf = L_MAGIC_POOL;
X break;
X case '>':
X Level->site[i][j].locchar = DOWN;
X Level->site[i][j].p_locf = L_SEWER;
X break;
X case '*':
X Level->site[i][j].locchar = WALL;
X Level->site[i][j].aux = 10;
X break;
X case '#':
X Level->site[i][j].locchar = WALL;
X Level->site[i][j].aux = 500;
X break;
X case '.':
X Level->site[i][j].locchar = FLOOR;
X break;
X case ',':
X Level->site[i][j].showchar = WALL;
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].aux = NOCITYMOVE;
X lset(i,j,SECRET);
X break;
X default:
X Level->site[i][j].locchar = site;
X break;
X }
X
X if (loc_statusp(i,j,SEEN)) {
X if (loc_statusp(i,j,SECRET))
X Level->site[i][j].showchar = '#';
X else Level->site[i][j].showchar = Level->site[i][j].locchar;
X }
X }
X fscanf(fd,"\n");
X }
X City = Level;
X
X /* make all city monsters asleep, and shorten their wakeup range to 2 */
X /* to prevent players from being molested by vicious monsters on */
X /* the streets */
X for(ml=Level->mlist;ml!=NULL;ml=ml->next) {
X m_status_reset(ml->m,AWAKE);
X ml->m->wakeup = 2;
X }
X fclose(fd);
X}
X
X
Xvoid assign_city_function(x,y)
Xint x,y;
X{
X static int setup=0;
X static int next=0;
X static int permutation[64]; /* number of x's in city map */
X int i,j,k,l;
X
X Level->site[x][y].aux = TRUE;
X
X lset(x,y+1,STOPS);
X lset(x+1,y,STOPS);
X lset(x-1,y,STOPS);
X lset(x,y-1,STOPS);
X
X
X if (setup == 0) {
X setup = 1;
X for(i=0;i<64;i++)
X permutation[i] = i;
X for(i=0;i<500;i++) {
X j = random_range(64);
X k = random_range(64);
X l = permutation[j];
X permutation[j] = permutation[k];
X permutation[k] = l;
X }
X }
X if (next > 63) { /* in case someone changes the no. of x's */
X Level->site[x][y].locchar = CLOSED_DOOR;
X Level->site[x][y].p_locf = L_HOUSE;
X if(random_range(5)) Level->site[x][y].aux = LOCKED;
X }
X else switch(permutation[next]) {
X case 0:
X Level->site[x][y].locchar = OPEN_DOOR;
X Level->site[x][y].p_locf = L_ARMORER;
X CitySiteList[L_ARMORER-CITYSITEBASE][1] = x;
X CitySiteList[L_ARMORER-CITYSITEBASE][2] = y;
X break;
X case 1:
X Level->site[x][y].locchar = OPEN_DOOR;
X Level->site[x][y].p_locf = L_CLUB;
X CitySiteList[L_CLUB-CITYSITEBASE][1] = x;
X CitySiteList[L_CLUB-CITYSITEBASE][2] = y;
X break;
X case 2:
X Level->site[x][y].locchar = OPEN_DOOR;
X Level->site[x][y].p_locf = L_GYM;
X CitySiteList[L_GYM-CITYSITEBASE][1] = x;
X CitySiteList[L_GYM-CITYSITEBASE][2] = y;
X break;
X case 3:
X Level->site[x][y].locchar = CLOSED_DOOR;
X Level->site[x][y].p_locf = L_THIEVES_GUILD;
X CitySiteList[L_THIEVES_GUILD-CITYSITEBASE][1] = x;
X CitySiteList[L_THIEVES_GUILD-CITYSITEBASE][2] = y;
X break;
X case 4:
X Level->site[x][y].locchar = OPEN_DOOR;
X Level->site[x][y].p_locf = L_HEALER;
X CitySiteList[L_HEALER-CITYSITEBASE][1] = x;
X CitySiteList[L_HEALER-CITYSITEBASE][2] = y;
X break;
X case 5:
X Level->site[x][y].locchar = OPEN_DOOR;
X Level->site[x][y].p_locf = L_CASINO;
X CitySiteList[L_CASINO-CITYSITEBASE][1] = x;
X CitySiteList[L_CASINO-CITYSITEBASE][2] = y;
X break;
X case 7:
X Level->site[x][y].locchar = OPEN_DOOR;
X Level->site[x][y].p_locf = L_DINER;
X CitySiteList[L_DINER-CITYSITEBASE][1] = x;
X CitySiteList[L_DINER-CITYSITEBASE][2] = y;
X break;
X case 8:
X Level->site[x][y].locchar = OPEN_DOOR;
X Level->site[x][y].p_locf = L_CRAP;
X CitySiteList[L_CRAP-CITYSITEBASE][1] = x;
X CitySiteList[L_CRAP-CITYSITEBASE][2] = y;
X break;
X case 6:
X case 9:
X case 20:
X Level->site[x][y].locchar = OPEN_DOOR;
X Level->site[x][y].p_locf = L_COMMANDANT;
X CitySiteList[L_COMMANDANT-CITYSITEBASE][1] = x;
X CitySiteList[L_COMMANDANT-CITYSITEBASE][2] = y;
X break;
X case 21:
X Level->site[x][y].locchar = OPEN_DOOR;
X Level->site[x][y].p_locf = L_TAVERN;
X CitySiteList[L_TAVERN-CITYSITEBASE][1] = x;
X CitySiteList[L_TAVERN-CITYSITEBASE][2] = y;
X break;
X case 10:
X Level->site[x][y].locchar = OPEN_DOOR;
X Level->site[x][y].p_locf = L_ALCHEMIST;
X CitySiteList[L_ALCHEMIST-CITYSITEBASE][1] = x;
X CitySiteList[L_ALCHEMIST-CITYSITEBASE][2] = y;
X break;
X case 11:
X Level->site[x][y].locchar = OPEN_DOOR;
X Level->site[x][y].p_locf = L_DPW;
X CitySiteList[L_DPW-CITYSITEBASE][1] = x;
X CitySiteList[L_DPW-CITYSITEBASE][2] = y;
X break;
X case 12:
X Level->site[x][y].locchar = OPEN_DOOR;
X Level->site[x][y].p_locf = L_LIBRARY;
X CitySiteList[L_LIBRARY-CITYSITEBASE][1] = x;
X CitySiteList[L_LIBRARY-CITYSITEBASE][2] = y;
X break;
X case 13:
X Level->site[x][y].locchar = OPEN_DOOR;
X Level->site[x][y].p_locf = L_PAWN_SHOP;
X CitySiteList[L_PAWN_SHOP-CITYSITEBASE][1] = x;
X CitySiteList[L_PAWN_SHOP-CITYSITEBASE][2] = y;
X break;
X case 14:
X Level->site[x][y].locchar = OPEN_DOOR;
X Level->site[x][y].p_locf = L_CONDO;
X CitySiteList[L_CONDO-CITYSITEBASE][1] = x;
X CitySiteList[L_CONDO-CITYSITEBASE][2] = y;
X break;
X case 15:
X Level->site[x][y].locchar = CLOSED_DOOR;
X Level->site[x][y].p_locf = L_BROTHEL;
X break;
X default:
X Level->site[x][y].locchar = CLOSED_DOOR;
X switch(random_range(6)) {
X case 0: Level->site[x][y].p_locf = L_HOVEL; break;
X case 1: case 2: case 3:
X case 4: Level->site[x][y].p_locf = L_HOUSE; break;
X case 5: Level->site[x][y].p_locf = L_MANSION; break;
X }
X if(random_range(5)) Level->site[x][y].aux = LOCKED;
X break;
X }
X next++;
X}
X
X
X
X
X/* makes a hiscore npc for mansions */
Xvoid make_justiciar(i,j)
Xint i,j;
X{
X pml ml = ((pml) malloc(sizeof(mltype)));
X ml->m = ((pmt) malloc(sizeof(montype)));
X *(ml->m) = Monsters[NPC];
X make_hiscore_npc(ml->m,15);
X ml->m->x = i;
X ml->m->y = j;
X Level->site[i][j].creature = ml->m;
X ml->m->click = (Tick + 1) % 60;
X ml->next = Level->mlist;
X Level->mlist = ml;
X m_status_reset(ml->m,AWAKE);
X}
X
X
X
X/* loads the city level */
Xvoid resurrect_guards()
X{
X int i,j;
X pml ml;
X char site;
X
X FILE *fd;
X
X strcpy(Str3,OMEGALIB);
X strcat(Str3,"ocity.dat");
X fd = fopen(Str3,"r");
X
X
X for(j=0;j<LENGTH;j++) {
X for(i=0;i<WIDTH;i++) {
X site = getc(fd);
X if (site == 'G') {
X make_site_monster(i,j,ML0+3);
X Level->site[i][j].creature->monstring =
X salloc("undead guardsman");
X Level->site[i][j].creature->meleef = M_MELEE_SPIRIT;
X Level->site[i][j].creature->movef = M_MOVE_SPIRIT;
X Level->site[i][j].creature->strikef = M_STRIKE_MISSILE;
X Level->site[i][j].creature->immunity = EVERYTHING-pow2(NORMAL_DAMAGE);
X Level->site[i][j].creature->hp *= 2;
X Level->site[i][j].creature->hit *= 2;
X Level->site[i][j].creature->dmg *= 2;
X Level->site[i][j].creature->ac *= 2;
X m_status_set(Level->site[i][j].creature,HOSTILE);
X m_status_set(Level->site[i][j].creature,AWAKE);
X }
X }
X fscanf(fd,"\n");
X }
X City = Level;
X
X fclose(fd);
X}
X
X
Xvoid mazesite(i,j)
Xint i,j;
X{
X static FILE *fd=NULL;
X static int k=0;
X char site;
X if (fd==NULL) {
X strcpy(Str2,OMEGALIB);
X strcpy(Str4,"omaze .dat");
X Str4[5]='1'+random_range(4);
X strcat(Str2,Str4);
X fd = fopen(Str2,"r");
X }
X site = getc(fd);
X k++;
X if (k == 282) fclose(fd);
X switch(site) {
X case '"':
X Level->site[i][j].locchar = HEDGE;
X if (random_range(10))
X Level->site[i][j].p_locf = L_HEDGE;
X else
X Level->site[i][j].p_locf = L_TRIFID;
X break;
X case '-':
X Level->site[i][j].locchar = CLOSED_DOOR;
X case '.':
X Level->site[i][j].locchar = FLOOR;
X break;
X case '>':
X Level->site[i][j].locchar = DOWN;
X Level->site[i][j].p_locf = L_SEWER;
X break;
X case 'z':
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].p_locf = L_MAZE;
X break;
X case 'O':
X Level->site[i][j].locchar = OPEN_DOOR;
X Level->site[i][j].p_locf = L_ORACLE;
X CitySiteList[L_ORACLE-CITYSITEBASE][1] = i;
X CitySiteList[L_ORACLE-CITYSITEBASE][2] = j;
X break;
X case '?':
X randommazesite(i,j);
X break;
X }
X lreset(i,j,SEEN);
X}
X
Xvoid randommazesite(i,j)
Xint i,j;
X{
X switch(random_range(7)) {
X case 0: case 1:
X Level->site[i][j].locchar = FLOOR;
X Level->site[i][j].p_locf = TRAP_BASE+random_range(NUMTRAPS);
X break;
X case 2: case 3:
X Level->site[i][j].locchar = FLOOR;
X make_site_monster(i,j,-1);
X break;
X case 4: case 5:
X Level->site[i][j].locchar = FLOOR;
X make_site_treasure(i,j,5);
X break;
X default:
X Level->site[i][j].locchar = FLOOR;
X }
X}
X
X
X/* undead are not hostile unless disturbed.... */
Xvoid make_minor_undead(i,j)
Xint i,j;
X{
X int mid;
X if (random_range(2)) mid = ML2+6; /*ghost */
X else mid = ML4+5; /*haunt*/
X make_site_monster(i,j,mid);
X m_status_reset(Level->site[i][j].creature,AWAKE);
X m_status_reset(Level->site[i][j].creature,HOSTILE);
X}
X
X/* undead are not hostile unless disturbed.... */
Xvoid make_major_undead(i,j)
Xint i,j;
X{
X int mid;
X if (random_range(2)) mid = ML6+5; /* lich */
X else mid = ML9+5; /*vampire lord*/
X make_site_monster(i,j,mid);
X m_status_reset(Level->site[i][j].creature,AWAKE);
X m_status_reset(Level->site[i][j].creature,HOSTILE);
X}
X
X
Xstatic char jail[11][5] =
X{
X '#', '#', '*', '#', '#', '*', '#', '#', '*', '#', '#',
X '#', '#', '*', '#', '#', '*', '#', '*', '#', '#', '#',
X '#', '#', 'T', '#', 'T', '#', 'T', '#', 'T', '#', '#',
X '#', '#', '7', '#', '7', '#', '7', '#', '7', '#', '#',
X '#', '#', 'R', '#', 'R', '#', 'R', '#', 'R', '#', '#',
X};
X
X/* fixes up the jail in case it has been munged by player action */
Xvoid repair_jail()
X{
X int i,j;
X for(i=0;i<11;i++)
X for(j=0;j<5;j++) {
X switch(jail[i][j]) {
X case '#':
X City->site[i+35][j+52].locchar = WALL;
X City->site[i+35][j+52].p_locf = L_NO_OP;
X City->site[i+35][j+52].aux = 666;
X break;
X case '*':
X City->site[i+35][j+52].locchar = WALL;
X City->site[i+35][j+52].p_locf = L_NO_OP;
X City->site[i+35][j+52].aux = 10;
X break;
X case 'T':
X City->site[i+35][j+52].locchar = FLOOR;
X City->site[i+35][j+52].p_locf = L_PORTCULLIS_TRAP;
X City->site[i+35][j+52].aux = NOCITYMOVE;
X break;
X case '7':
X City->site[i+35][j+52].locchar = FLOOR;
X City->site[i+35][j+52].p_locf = L_PORTCULLIS;
X City->site[i+35][j+52].aux = NOCITYMOVE;
X break;
X case 'R':
X City->site[i+35][j+52].locchar = FLOOR;
X City->site[i+35][j+52].p_locf = L_RAISE_PORTCULLIS;
X City->site[i+35][j+52].aux = NOCITYMOVE;
X break;
X }
X }
X}
END_OF_FILE
if test 16797 -ne `wc -c <'ocity.c'`; then
echo shar: \"'ocity.c'\" unpacked with wrong size!
fi
# end of 'ocity.c'
fi
if test -f 'olev.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'olev.c'\"
else
echo shar: Extracting \"'olev.c'\" \(15956 characters\)
sed "s/^X//" >'olev.c' <<'END_OF_FILE'
X/* omega copyright (c) 1987,1988 by Laurence Raphael Brothers */
X/* olev.c */
X
X#include "oglob.h"
X
X/* Functions dealing with dungeon and country levels aside from actual
Xlevel structure generation */
X
X
X/* monsters for tactical encounters */
Xvoid make_country_monsters(terrain)
Xchar terrain;
X{
X pml tml,ml=NULL;
X static int plains[10] =
X {BUNNY,BUNNY,BLACKSNAKE,HAWK,IMPALA,WOLF,LION,BRIGAND,RANDOM};
X static int forest[10] =
X {BUNNY,QUAIL,HAWK,BADGER,DEER,DEER,WOLF,BEAR,BRIGAND,RANDOM};
X static int jungle[10] =
X {ANTEATER,PARROT,MAMBA,ANT,ANT,HYENA,HYENA,ELEPHANT,LION,RANDOM};
X static int river[10] =
X {QUAIL,TROUT,TROUT,MANOWAR,BASS,BASS,CROC,CROC,BRIGAND,RANDOM};
X static int swamp[10] =
X {BASS,BASS,CROC,CROC,BOGTHING,ANT,ANT,RANDOM,RANDOM,RANDOM};
X static int desert[10] =
X {HAWK,HAWK,CAMEL,CAMEL,HYENA,HYENA,LION,LION,RANDOM,RANDOM};
X static int tundra[10] =
X {WOLF,WOLF,BEAR,BEAR,DEER,DEER,RANDOM,RANDOM,RANDOM,RANDOM};
X static int mountain[10] =
X {BUNNY,SHEEP,WOLF,WOLF,HAWK,HAWK,HAWK,RANDOM,RANDOM,RANDOM};
X int *monsters,i,nummonsters;
X
X nummonsters = (random_range(5)+1) * (random_range(3)+1);
X
X switch(terrain) {
X case PLAINS: monsters = plains; break;
X case FOREST: monsters = forest; break;
X case JUNGLE: monsters = jungle; break;
X case RIVER: monsters = river; break;
X case SWAMP: monsters = swamp; break;
X case MOUNTAINS: case PASS: case VOLCANO: monsters = mountain; break;
X case DESERT: monsters = desert; break;
X case TUNDRA: monsters = tundra; break;
X default: monsters = NULL;
X }
X for(i=0;i<nummonsters;i++) {
X tml = ((pml) malloc(sizeof(mltype)));
X tml->m = ((pmt) malloc(sizeof(montype)));
X if (monsters == NULL) tml->m =
X m_create(random_range(WIDTH),random_range(LENGTH),TRUE,difficulty());
X else {
X tml->m = make_creature(*(monsters+random_range(10)));
X tml->m->x = random_range(WIDTH);
X tml->m->y = random_range(LENGTH);
X }
X Level->site[tml->m->x][tml->m->y].creature = tml->m;
X tml->m->sense = WIDTH;
X if (m_statusp(tml->m,ONLYSWIM)) {
X Level->site[tml->m->x][tml->m->y].locchar = WATER;
X Level->site[tml->m->x][tml->m->y].p_locf = L_WATER;
X }
X
X tml->next = ml;
X ml = tml;
X }
X Level->mlist = ml;
X}
X
X
X
X/* monstertype is more or less Current_Dungeon */
X/* The caves and sewers get harder as you penetrate them; the castle
Xis completely random, but also gets harder as it is explored;
Xthe astral and the volcano just stay hard... */
Xvoid populate_level(monstertype)
Xint monstertype;
X{
X pml head,tml;
X int i,j,k,monsterid,nummonsters=(random_range(difficulty()/3)+1)*3+8;
X
X if (monstertype == E_CASTLE) nummonsters += 10;
X else if (monstertype == E_ASTRAL) nummonsters += 10;
X else if (monstertype == E_VOLCANO) nummonsters += 20;
X
X head = tml = ((pml) malloc(sizeof(mltype)));
X
X for(k=0;k<nummonsters;k++) {
X
X findspace(&i,&j,-1);
X
X switch(monstertype) {
X case E_CAVES:
X if (Level->depth*10+random_range(100) > 150)
X monsterid = ML3+7; /* Goblin Shaman*/
X else if (Level->depth*10+random_range(100) > 100)
X monsterid = ML2+9; /* Goblin Chieftain */
X else if (random_range(100) > 50) monsterid = ML1+6; /* Goblin */
X else monsterid = -1; /* IE, random monster */
X break;
X case E_SEWERS:
X if (! random_range(3)) monsterid = -1;
X else switch(random_range(Level->depth+3)) {
X case 0: monsterid = ML1+3; break; /* sewer rat */
X case 1: monsterid = ML1+4; break; /* aggravator fungus */
X case 2: monsterid = ML1+5; break; /* blipper rat */
X case 3: monsterid = ML2+1; break; /* night gaunt */
X case 4: monsterid = ML2+5; break; /* transparent nasty */
X case 5: monsterid = ML2+8; break; /* murk fungus */
X case 6: monsterid = ML3+1; break; /* catoblepas */
X case 7: monsterid = ML3+3; break; /* acid cloud */
X case 8: monsterid = ML4+3; break; /* denebian slime devil */
X case 9: monsterid = ML4+8; break; /* giant crocodile */
X case 10: monsterid = ML5+1; break; /* tesla monster */
X case 11: monsterid = ML5+7; break; /* shadow spirit */
X case 12: monsterid = ML5+8; break; /* bogthing */
X case 13: monsterid = ML6+2; break; /* water elemental */
X case 14: monsterid = ML6+6; break; /* triton */
X case 15: monsterid = ML7+3; break; /* ROUS */
X default: monsterid = -1; break;
X }
X break;
X case E_ASTRAL:
X if (random_range(2)) /* random astral creatures */
X switch(random_range(12)) {
X case 0: monsterid = ML3+14; break; /* thought form */
X case 1: monsterid = ML4+11; break; /* astral fuzzy */
X case 2: monsterid = ML4+15; break; /* ban sidhe */
X case 3: monsterid = ML4+16; break; /* astral grue */
X case 4: monsterid = ML5+7; break; /* shadow spirit */
X case 5: monsterid = ML5+9; break; /* astral vampire */
X case 6: monsterid = ML5+11; break; /* manaburst */
X case 7: monsterid = ML6+9; break; /* rakshasa */
X case 8: monsterid = ML7+4; break; /* illusory fiend */
X case 9: monsterid = ML7+9; break; /* mirror master */
X case 10: monsterid = ML7+10; break; /* elder etheric grue */
X case 11: monsterid = ML8+8; break; /* shadow slayer */
X }
X else if (random_range(2) && (Level->depth == 1)) /* plane of earth */
X monsterid = ML6+3; /* earth elemental */
X else if (random_range(2) && (Level->depth == 2)) /* plane of air */
X monsterid = ML6+1; /* air elemental */
X else if (random_range(2) && (Level->depth == 3)) /* plane of water */
X monsterid = ML6+2; /* water elemental */
X else if (random_range(2) && (Level->depth == 4)) /* plane of fire */
X monsterid = ML6+0; /* fire elemental */
X else if (random_range(2) && (Level->depth == 5)) /* deep astral */
X switch (random_range(12)) {
X case 0:monsterid = ML2+1; break; /* night gaunt */
X case 1:monsterid = ML4+12; break; /* servant of law */
X case 2:monsterid = ML4+13; break; /* servant of chaos */
X case 3:monsterid = ML5+4; break; /* lesser frost demon */
X case 4:monsterid = ML5+12; break; /* outer circle demon */
X case 5:monsterid = ML6+10; break; /* demon serpent */
X case 6:monsterid = ML6+11; break; /* angel */
X case 7:monsterid = ML7+14; break; /* inner circle demon */
X case 8:monsterid = ML8+5; break; /* frost demon lord */
X case 9:monsterid = ML8+11; break; /* high angel */
X case 10:monsterid = ML9+7; break; /* prime circle demon */
X case 11:monsterid = ML9+6; break; /* archangel */
X }
X else monsterid = -1;
X break;
X case E_VOLCANO:
X if (random_range(2)) {
X do monsterid = random_range(ML10-ML4)+ML4;
X while (Monsters[monsterid].uniqueness != COMMON);
X }
X else switch(random_range(Level->depth/2+2)) { /* evil & fire creatures */
X case 0: monsterid = ML4+5; break;
X case 1: monsterid = ML4+6; break;
X case 2: monsterid = ML5+0; break;
X case 3: monsterid = ML5+4; break;
X case 4: monsterid = ML5+5; break;
X case 5: monsterid = ML5+10; break;
X case 6: monsterid = ML6+0; break;
X case 7: monsterid = ML6+5; break;
X case 8: monsterid = ML6+9; break;
X case 9: monsterid = ML6+10; break;
X case 10: monsterid = ML7+1; break;
X case 11: monsterid = ML7+6; break;
X case 12: monsterid = ML7+11; break;
X case 13: monsterid = ML7+12; break;
X case 14: monsterid = ML7+14; break;
X case 15: monsterid = ML7+3; break;
X case 16: monsterid = ML8+3; break;
X case 17: monsterid = ML8+5; break;
X case 18: monsterid = ML8+8; break;
X case 19: monsterid = ML7+3; break;
X case 20: monsterid = ML9+5; break;
X case 21: monsterid = ML9+7; break;
X default: monsterid = -1; break;
X }
X break;
X case E_CASTLE:
X if (random_range(4)==1) {
X if (difficulty() < 5)
X monsterid = ML2+7;
X else if (difficulty() < 6)
X monsterid = ML5+6;
X else if (difficulty() < 8)
X monsterid = ML6+0;
X else monsterid = ML9+4;
X }
X else monsterid = -1;
X break;
X
X default: monsterid = -1; break;
X }
X
X if (monsterid > -1)
X Level->site[i][j].creature = make_creature(monsterid);
X else Level->site[i][j].creature = m_create(i,j,TRUE,difficulty());
X
X
X Level->site[i][j].creature->x = i;
X Level->site[i][j].creature->y = j;
X
X if (m_statusp(Level->site[i][j].creature,ONLYSWIM)) {
X Level->site[i][j].locchar = WATER;
X Level->site[i][j].p_locf = L_WATER;
X }
X
X tml->next = ((pml) malloc(sizeof(mltype)));
X tml->next->m = Level->site[i][j].creature;
X tml = tml->next;
X }
X
X if (Level->mlist==NULL) {
X tml->next = NULL;
X Level->mlist = head->next;
X }
X else {
X tml->next = Level->mlist;
X Level->mlist = head->next;
X }
X}
X
X
X
X/* Add a wandering monster possibly */
Xvoid wandercheck()
X{
X int x,y;
X pml tml;
X if (random_range(MaxDungeonLevels) < difficulty()) {
X findspace(&x,&y,-1);
X tml = ((pml) malloc(sizeof(mltype)));
X tml->next = Level->mlist;
X tml->m = Level->site[x][y].creature = m_create(x,y,WANDERING,difficulty());
X Level->mlist = tml;
X }
X}
X
X
X
X/* call make_creature and place created monster on Level->mlist and Level */
Xvoid make_site_monster(i,j,mid)
Xint i,j,mid;
X{
X pml ml = ((pml) malloc(sizeof(mltype)));
X pmt m;
X if (mid > -1) Level->site[i][j].creature = (m = make_creature(mid));
X else Level->site[i][j].creature = (m = m_create(i,j,WANDERING,difficulty()));
X m->x = i;
X m->y = j;
X ml->m = m;
X ml->next = Level->mlist;
X Level->mlist = ml;
X}
X
X
X/* make and return an appropriate monster for the level and depth*/
X/* called by populate_level, doesn't actually add to mlist for some reason*/
X/* eventually to be more intelligent */
Xpmt m_create(x,y,kind,level)
Xint x,y,kind,level;
X{
X pmt newmonster;
X int monster_range;
X int mid;
X
X switch(level) {
X case 0:monster_range = ML1; break;
X case 1:monster_range = ML2; break;
X case 2:monster_range = ML3; break;
X case 3:monster_range = ML4; break;
X case 4:monster_range = ML5; break;
X case 5:monster_range = ML6; break;
X case 6:monster_range = ML7; break;
X case 7:monster_range = ML8; break;
X case 8:monster_range = ML9; break;
X case 9:monster_range = ML10; break;
X default:monster_range = NUMMONSTERS; break;
X }
X
X do
X mid = random_range(monster_range);
X while (Monsters[mid].uniqueness != COMMON);
X newmonster = make_creature(mid);
X
X /* no duplicates of unique monsters */
X if (kind == WANDERING) m_status_set(newmonster,WANDERING);
X newmonster->x = x;
X newmonster->y = y;
X return(newmonster);
X}
X
X
X
X/* make creature # mid, totally random if mid == -1 */
X/* make creature allocates space for the creature */
Xpmt make_creature(mid)
Xint mid;
X{
X pmt newmonster = ((pmt) malloc(sizeof(montype)));
X pob ob;
X int i,treasures;
X
X if (mid == -1) mid = random_range(ML9);
X *newmonster = Monsters[mid];
X if ((mid == ML6+11) || (mid == ML8+11) || (mid == ML9+6)) {
X /* aux1 field of an angel is its deity */
X newmonster->aux1 = random_range(6)+1;
X newmonster->corpsestr = salloc(Monsters[mid].corpsestr);
X strcpy(Str3,Monsters[mid].monstring);
X switch(newmonster->aux1) {
X case ODIN: strcat(Str3," of Odin"); break;
X case SET: strcat(Str3," of Set"); break;
X case HECATE: strcat(Str3," of Hecate"); break;
X case ATHENA: strcat(Str3," of Athena"); break;
X case DESTINY: strcat(Str3," of Destiny"); break;
X case DRUID: strcat(Str3," of the Balance"); break;
X }
X newmonster->monstring = salloc(Str3);
X }
X else if (mid == ML0+7) {
X /* generic 0th level human */
X newmonster->monstring = salloc(mantype());
X strcpy(Str1,"dead ");
X strcat(Str1,newmonster->monstring);
X newmonster->corpsestr = salloc(Str1);
X }
X else if (newmonster->monchar == '!') {
X /* the nymph/satyr and incubus/succubus */
X if (Player.preference == 'f') {
X newmonster->monchar = 'n';
X newmonster->monstring = salloc("nymph");
X newmonster->corpsestr = salloc("dead nymph");
X }
X else {
X newmonster->monchar = 's';
X newmonster->monstring = salloc("satyr");
X newmonster->corpsestr = salloc("dead satyr");
X }
X if (newmonster->id == ML4+6) {
X if (Player.preference == 'f')
X newmonster->corpsestr = salloc("dead succubus");
X else newmonster->corpsestr = salloc("dead incubus");
X }
X }
X if (mid == NPC)
X make_log_npc(newmonster);
X else {
X if (newmonster->sleep < random_range(100))
X m_status_set(newmonster,AWAKE);
X if (newmonster->startthing > -1) {
X ob = ((pob) malloc(sizeof(objtype)));
X *ob = Objects[newmonster->startthing];
X m_pickup(newmonster,ob);
X }
X treasures = random_range(newmonster->treasure);
X for(i=0;i<treasures;i++) {
X ob = ((pob) malloc(sizeof(objtype)));
X do ob = ((pob) (create_object(newmonster->level)));
X while (ob->uniqueness != 0);
X m_pickup(newmonster,ob);
X }
X }
X newmonster->click = (Tick + 1) % 50;
X return(newmonster);
X}
X
X
X
X
X/* drop treasures randomly onto level */
Xvoid stock_level()
X{
X int i,j,k,numtreasures=2*random_range(difficulty()/4)+4;
X
X /* put cash anywhere, including walls, put other treasures only on floor */
X for (k=0;k<numtreasures+10;k++) {
X do {
X i = random_range(WIDTH);
X j = random_range(LENGTH);
X } while (Level->site[i][j].locchar != FLOOR);
X make_site_treasure(i,j,difficulty());
X i = random_range(WIDTH);
X j = random_range(LENGTH);
X Level->site[i][j].things = ((pol) malloc(sizeof(oltype)));
X Level->site[i][j].things->thing = ((pob) malloc(sizeof(objtype)));
X make_cash(Level->site[i][j].things->thing,difficulty());
X Level->site[i][j].things->next = NULL;
X /* caves have more random cash strewn around */
X if (Current_Dungeon == E_CAVES) {
X i = random_range(WIDTH);
X j = random_range(LENGTH);
X Level->site[i][j].things = ((pol) malloc(sizeof(oltype)));
X Level->site[i][j].things->thing = ((pob) malloc(sizeof(objtype)));
X make_cash(Level->site[i][j].things->thing,difficulty());
X Level->site[i][j].things->next = NULL;
X i = random_range(WIDTH);
X j = random_range(LENGTH);
X Level->site[i][j].things = ((pol) malloc(sizeof(oltype)));
X Level->site[i][j].things->thing = ((pob) malloc(sizeof(objtype)));
X make_cash(Level->site[i][j].things->thing,difficulty());
X Level->site[i][j].things->next = NULL;
X }
X }
X}
X
X
X/* make a new object (of at most level itemlevel) at site i,j on level*/
Xvoid make_site_treasure(i,j,itemlevel)
Xint i,j,itemlevel;
X{
X pol tmp = ((pol) malloc(sizeof(oltype)));
X tmp->thing = ((pob) create_object(itemlevel));
X tmp->next = Level->site[i][j].things;
X Level->site[i][j].things = tmp;
X}
X
X/* make a specific new object at site i,j on level*/
Xvoid make_specific_treasure(i,j,itemid)
Xint i,j,itemid;
X{
X pol tmp = ((pol) malloc(sizeof(oltype)));
X tmp->thing = ((pob) malloc(sizeof(objtype)));
X *(tmp->thing) = Objects[itemid];
X tmp->next = Level->site[i][j].things;
X Level->site[i][j].things = tmp;
X}
X
X
X
X/* returns a "level of difficulty" based on current environment
X and depth in dungeon. Is somewhat arbitrary. value between 1 and 10.
X May not actually represent real difficulty, but instead level
X of items, monsters encountered. */
Xint difficulty()
X{
X int depth = 1;
X if (Level != NULL) depth = Level->depth;
X switch(Current_Environment) {
X case E_COUNTRYSIDE: return(7); break;
X case E_CITY: return(3); break;
X case E_VILLAGE: return(1); break;
X case E_TACTICAL_MAP: return(7); break;
X case E_SEWERS: return(depth/6)+3;break;
X case E_CASTLE: return(depth/4)+4;break;
X case E_CAVES: return(depth/3)+1;break;
X case E_VOLCANO: return(depth/4)+5;break;
X case E_ASTRAL: return(8);break;
X case E_ARENA: return(5);break;
X case E_HOVEL: return(3);break;
X case E_MANSION: return(7);break;
X case E_HOUSE: return(5);break;
X case E_DLAIR: return(9);break;
X case E_ABYSS: return(10);break;
X case E_STARPEAK: return(9);break;
X case E_CIRCLE: return(8);break;
X case E_MAGIC_ISLE: return(8);break;
X case E_TEMPLE: return(8);break;
X default: return(3); break;
X }
X}
END_OF_FILE
if test 15956 -ne `wc -c <'olev.c'`; then
echo shar: \"'olev.c'\" unpacked with wrong size!
fi
# end of 'olev.c'
fi
if test -f 'ospell.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'ospell.c'\"
else
echo shar: Extracting \"'ospell.c'\" \(16531 characters\)
sed "s/^X//" >'ospell.c' <<'END_OF_FILE'
X/* omega copyright (C) by Laurence Raphael Brothers, 1987,1988 */
X/* ospell.c */
X/* functions having to do with spellcasting */
X
X#include "oglob.h"
X
X
Xvoid s_wish()
X{
X if (random_range(100) > Player.iq+Player.pow+Player.level) {
X mprint("Your concentration is flawed!");
X mprint("The spell energy backfires!");
X p_damage(random_range(Spells[S_WISH].powerdrain),
X UNSTOPPABLE,
X "a backfired wish spell");
X }
X else {
X wish(0);
X mprint("The power of the spell is too much for you to withstand!");
X mprint("All memory of the spell is expunged from your brain.");
X Spells[S_WISH].known = FALSE;
X }
X}
X
Xvoid s_firebolt()
X{
X int x=Player.x,y=Player.y;
X setspot(&x,&y);
X fbolt(Player.x,Player.y,x,y,Player.dex*2+Player.level,Player.level*10+10);
X}
X
Xvoid s_missile()
X{
X int x=Player.x,y=Player.y;
X setspot(&x,&y);
X nbolt(Player.x,Player.y,x,y,Player.dex*2+Player.level,Player.level*3+3);
X}
X
Xvoid s_teleport()
X{
X p_teleport(0);
X}
X
Xvoid s_disrupt()
X{
X int x=Player.x,y=Player.y;
X setspot(&x,&y);
X disrupt(x,y,Player.level*10+25);
X}
X
X
Xvoid s_disintegrate()
X{
X int x=Player.x,y=Player.y;
X setspot(&x,&y);
X disintegrate(x,y);
X}
X
X
Xvoid s_sleep()
X{
X sleep_monster(0);
X}
X
Xvoid s_heal()
X{
X heal(3);
X}
X
Xvoid s_dispel()
X{
X dispel((Player.level+Player.maxpow)/10);
X}
X
Xvoid s_breathe()
X{
X breathe(0);
X}
X
Xvoid s_invisible()
X{
X invisible(0);
X}
X
X
Xvoid s_warp()
X{
X warp(1);
X}
X
Xvoid s_enchant()
X{
X enchant(1);
X}
X
X
Xvoid s_bless()
X{
X bless(0);
X}
X
X
Xvoid s_restore()
X{
X recover_stat(0);
X}
X
X
Xvoid s_cure()
X{
X cure(0);
X}
X
X
Xvoid s_truesight()
X{
X truesight(0);
X}
X
X
Xvoid s_hellfire()
X{
X int x=Player.x,y=Player.y;
X setspot(&x,&y);
X hellfire(x,y,0);
X}
X
X
Xvoid s_knowledge()
X{
X knowledge(0);
X}
X
X
Xvoid s_hero()
X{
X hero(0);
X}
X
X/* spell takes longer and longer to work deeper into dungeon */
Xvoid s_return()
X{
X mprint("You hear a whine as your spell begins to charge up.");
X Player.status[RETURNING] =
X ((Current_Environment == Current_Dungeon) ? difficulty() : 1);
X}
X
Xvoid s_desecrate()
X{
X sanctify(-1);
X}
X
X
Xvoid s_haste()
X{
X haste(0);
X}
X
X
Xvoid s_summon()
X{
X summon(0,-1);
X}
X
X
Xvoid s_sanctuary()
X{
X sanctuary();
X}
X
Xvoid s_sanctify()
X{
X sanctify(1);
X}
X
X
Xvoid s_accuracy()
X{
X accuracy(0);
X}
X
Xvoid s_fear()
X{
X int x = Player.x,y=Player.y;
X setspot(&x,&y);
X inflict_fear(x,y);
X}
X
X
X/* Has all kinds of effects in different circumstances.
X Eventually will be more interesting */
Xvoid s_ritual()
X{
X pob symbol;
X int i,roomno;
X mprint("You begin your ritual....");
X mprint("You enter a deep trance. Time Passes...");
X setgamestatus(SKIP_PLAYER);
X time_clock(FALSE);
X setgamestatus(SKIP_PLAYER);
X time_clock(FALSE);
X setgamestatus(SKIP_PLAYER);
X time_clock(FALSE);
X setgamestatus(SKIP_PLAYER);
X time_clock(FALSE);
X setgamestatus(SKIP_PLAYER);
X time_clock(FALSE);
X if (RitualHour == hour())
X mprint("Your mental fatigue prevents from completing the ritual!");
X else if (random_range(100) > Player.iq+Player.pow+Player.level)
X mprint("Your concentration was broken -- the ritual fails!");
X else {
X mprint("You charge the ritual with magical energy and focus your will.");
X mprint("Time Passes...");
X setgamestatus(SKIP_PLAYER);
X time_clock(FALSE);
X setgamestatus(SKIP_PLAYER);
X time_clock(FALSE);
X setgamestatus(SKIP_PLAYER);
X time_clock(FALSE);
X setgamestatus(SKIP_PLAYER);
X time_clock(FALSE);
X setgamestatus(SKIP_PLAYER);
X time_clock(FALSE);
X RitualHour = hour();
X /* set of random conditions for different ritual effects */
X if (Current_Environment == E_CITY) {
X mprint("Flowing waves of mystical light congeal all around you.");
X mprint("'Like wow, man! Colors!'");
X mprint("Appreciative citizens throw you spare change.");
X Player.cash +=random_range(50);
X }
X else if ((roomno=Level->site[Player.x][Player.y].roomnumber) >= 0) {
X if (RitualRoom == roomno)
X mprint("For some reason the ritual doesn't work this time...");
X else {
X RitualRoom = roomno;
X switch (RitualRoom) {
X case ROOMBASE+9: /* ransacked treasure chamber */
X mprint("Your spell sets off frenetic growth all around you!");
X for(i=0;i<8;i++){
X Level->site[Player.x+Dirs[0][i]][Player.y+Dirs[1][i]].locchar =
X HEDGE;
X Level->site[Player.x+Dirs[0][i]][Player.y+Dirs[1][i]].p_locf =
X L_TRIFID;
X }
X break;
X case ROOMBASE+22: /* boudoir */
X mprint("A secret panel opens next to the bed....");
X if (random_range(2))
X summon(0,ML4+6); /* succubus/incubus */
X else summon(0,ML4+7); /* satyr/nymph */
X break;
X case ROOMBASE+26: /*shrine to high magic */
X mprint("A storm of mana coaelesces around you.");
X mprint("You are buffeted by bursts of random magic.");
X p_damage(random_range(Player.pow),UNSTOPPABLE,"high magic");
X mprint("Continue ritual? Could be dangerous.... [yn] ");
X if (ynq()=='y') s_wish();
X else mprint("The mana fades away to nothingness.");
X Level->site[Player.x][Player.y].roomnumber = RS_ZORCH;
X break;
X case ROOMBASE+27: /* magician's lab */
X mprint("Your magical activity sets off a latent spell in the lab!");
X cast_spell(random_range(NUMSPELLS));
X break;
X case ROOMBASE+28: /* pentagram room */
X mprint("A smoky form begins to coalesce....");
X summon(-1,-1);
X mprint("Fortunately, it seems confined to the pentagram.");
X m_status_reset(Level->mlist->m,MOBILE);
X break;
X case ROOMBASE+29: /* blue omega room */
X mprint("The Lords of Destiny look upon you....");
X if (Player.level > 10) {
X mprint("A curtain of blue flames leaps up from the omega.");
X mprint("Enter it? [yn] ");
X if (ynq()=='y') l_adept();
X }
X else {
X if (Player.patron == DESTINY) {
X mprint("Your patrons take pity on you.");
X if ((Player.rank[PRIESTHOOD]<SPRIEST) &&
X (! find_item(&symbol,ARTIFACTID+19,-1))) {
X symbol = ((pob) malloc(sizeof(objtype)));
X *symbol = Objects[ARTIFACTID+19];
X symbol->known = 2;
X symbol->charge = 17;
X gain_item(symbol);
X mprint("You feel uplifted.");
X }
X else gain_experience(min(1000,Player.xp));
X }
X else if (random_range(3)==1) {
X mprint("You feel Fated.");
X gain_experience(Player.level*Player.level*10);
X Player.hp = Player.maxhp;
X }
X else if (random_range(2)) {
X mprint("You feel Doomed.");
X Player.hp = 1;
X Player.mana = 0;
X Player.xp = 0;
X }
X else mprint("The Lords of Destiny laugh at you!");
X }
X break;
X default:
X mprint("Well, not much effect. Chalk it up to experience.");
X gain_experience(Player.level*5);
X break;
X }
X }
X }
X else {
X if (RitualRoom == Level->site[Player.x][Player.y].roomnumber)
X mprint("The ritual fails for some unexplainable reason.");
X else {
X mprint("The ritual seems to be generating some spell effect.");
X RitualRoom = Level->site[Player.x][Player.y].roomnumber;
X switch (RitualRoom) {
X case RS_WALLSPACE:
X shadowform();
X break;
X case RS_CORRIDOR:
X haste(0);
X break;
X case RS_PONDS:
X breathe(0);
X break;
X case RS_ADEPT:
X hero(1);
X break;
X default:
X mprint("The ritual doesn't seem to produce any tangible results...");
X gain_experience(Player.level*6);
X }
X }
X }
X }
X}
X
X
X
Xvoid s_apport()
X{
X apport(0);
X}
X
Xvoid s_shadowform()
X{
X shadowform();
X}
X
Xvoid s_alert()
X{
X alert(0);
X}
X
Xvoid s_regenerate()
X{
X regenerate(0);
X}
X
Xvoid s_clairvoyance()
X{
X clairvoyance(10);
X}
X
Xvoid s_drain()
X{
X drain(0);
X}
X
Xvoid s_levitate()
X{
X levitate(0);
X}
X
Xvoid s_polymorph()
X{
X polymorph(0);
X}
X
X
X/* lball spell */
Xvoid s_lball()
X{
X int x=Player.x,y=Player.y;
X setspot(&x,&y);
X lball(Player.x,Player.y,x,y,Player.level*10+10);
X}
X
Xvoid s_identify()
X{
X identify(0);
X}
X
Xvoid s_objdet()
X{
X objdet(1);
X}
X
Xvoid s_mondet()
X{
X mondet(1);
X}
X
X
X/* select a spell to cast */
Xint getspell()
X{
X int spell= -2;
X do {
X mprint("Cast Spell: [type spell abbrev, ?, or ESCAPE]: ");
X spell = spellparse();
X } while (spell < ABORT);
X return(spell);
X}
X
X
Xchar *spellid(id)
Xint id;
X{
X switch(id) {
X case S_MON_DET:return("monster detection");break;
X case S_OBJ_DET:return("object detection");break;
X case S_IDENTIFY:return("identification");break;
X case S_FIREBOLT:return("firebolt");break;
X case S_LBALL:return("ball lightning");break;
X case S_SLEEP:return("sleep");break;
X case S_DISRUPT:return("disrupt");break;
X case S_DISINTEGRATE:return("disintegrate");break;
X case S_TELEPORT:return("teleport");break;
X case S_MISSILE:return("magic missile"); break;
X case S_HEAL:return("healing"); break;
X case S_DISPEL:return("dispelling"); break;
X case S_BREATHE:return("breathing"); break;
X case S_INVISIBLE:return("invisibility"); break;
X case S_WARP:return("the warp"); break;
X case S_ENCHANT:return("enchantment"); break;
X case S_BLESS:return("blessing"); break;
X case S_RESTORE:return("restoration"); break;
X case S_CURE:return("curing"); break;
X case S_TRUESIGHT:return("true sight"); break;
X case S_HELLFIRE:return("hellfire"); break;
X case S_KNOWLEDGE:return("self knowledge"); break;
X case S_HERO:return("heroism"); break;
X case S_RETURN:return("return"); break;
X case S_DESECRATE:return("desecration"); break;
X case S_HASTE:return("haste"); break;
X case S_SUMMON:return("summoning"); break;
X case S_SANCTUARY:return("sanctuary"); break;
X case S_ACCURACY:return("accuracy"); break;
X case S_RITUAL:return("ritual magic"); break;
X case S_APPORT:return("apportation"); break;
X case S_SHADOWFORM:return("shadow form"); break;
X case S_ALERT:return("alertness"); break;
X case S_REGENERATE:return("regeneration"); break;
X case S_SANCTIFY:return("sanctification"); break;
X case S_CLAIRVOYANCE:return("clairvoyance"); break;
X case S_DRAIN:return("energy drain"); break;
X case S_LEVITATE:return("levitate"); break;
X case S_POLYMORPH:return("polymorph"); break;
X case S_FEAR:return("fear"); break;
X case S_WISH:return("wishing"); break;
X default:return("???"); break;
X }
X}
X
X
X
Xvoid initspells()
X{
X int i;
X
X for (i=0; i<NUMSPELLS; i++)
X Spells[i].known = FALSE;
X
X Spells[S_MON_DET].powerdrain = 3;
X Spells[S_MON_DET].id = S_MON_DET;
X
X Spells[S_OBJ_DET].powerdrain = 3;
X Spells[S_OBJ_DET].id = S_OBJ_DET;
X
X Spells[S_IDENTIFY].powerdrain = 10;
X Spells[S_IDENTIFY].id = S_IDENTIFY;
X
X Spells[S_FIREBOLT].powerdrain = 20;
X Spells[S_FIREBOLT].id = S_FIREBOLT;
X
X Spells[S_SLEEP].powerdrain = 15;
X Spells[S_SLEEP].id = S_SLEEP;
X
X Spells[S_LBALL].powerdrain = 25;
X Spells[S_LBALL].id = S_LBALL;
X
X Spells[S_TELEPORT].powerdrain = 20;
X Spells[S_TELEPORT].id = S_TELEPORT;
X
X Spells[S_DISRUPT].powerdrain = 30;
X Spells[S_DISRUPT].id = S_DISRUPT;
X
X Spells[S_DISINTEGRATE].powerdrain = 40;
X Spells[S_DISINTEGRATE].id = S_DISINTEGRATE;
X
X Spells[S_MISSILE].powerdrain = 10;
X Spells[S_MISSILE].id = S_MISSILE;
X
X Spells[S_HEAL].powerdrain = 15;
X Spells[S_HEAL].id = S_HEAL;
X
X Spells[S_DISPEL].powerdrain = 40;
X Spells[S_DISPEL].id = S_DISPEL;
X
X Spells[S_BREATHE].powerdrain = 20;
X Spells[S_BREATHE].id = S_BREATHE;
X
X Spells[S_INVISIBLE].powerdrain = 15;
X Spells[S_INVISIBLE].id = S_INVISIBLE;
X
X Spells[S_WARP].powerdrain = 50;
X Spells[S_WARP].id = S_WARP;
X
X Spells[S_ENCHANT].powerdrain = 30;
X Spells[S_ENCHANT].id = S_ENCHANT;
X
X Spells[S_BLESS].powerdrain = 30;
X Spells[S_BLESS].id = S_BLESS;
X
X Spells[S_RESTORE].powerdrain = 20;
X Spells[S_RESTORE].id = S_RESTORE;
X
X Spells[S_CURE].powerdrain = 20;
X Spells[S_CURE].id = S_CURE;
X
X Spells[S_TRUESIGHT].powerdrain = 20;
X Spells[S_TRUESIGHT].id = S_TRUESIGHT;
X
X Spells[S_HELLFIRE].powerdrain = 90;
X Spells[S_HELLFIRE].id = S_HELLFIRE;
X
X Spells[S_KNOWLEDGE].powerdrain = 10;
X Spells[S_KNOWLEDGE].id = S_KNOWLEDGE;
X
X Spells[S_HERO].powerdrain = 20;
X Spells[S_HERO].id = S_HERO;
X
X Spells[S_RETURN].powerdrain = 10;
X Spells[S_RETURN].id = S_RETURN;
X
X Spells[S_DESECRATE].powerdrain = 50;
X Spells[S_DESECRATE].id = S_DESECRATE;
X
X Spells[S_HASTE].powerdrain = 15;
X Spells[S_HASTE].id = S_HASTE;
X
X Spells[S_SUMMON].powerdrain = 20;
X Spells[S_SUMMON].id = S_SUMMON;
X
X Spells[S_SANCTUARY].powerdrain = 75;
X Spells[S_SANCTUARY].id = S_SANCTUARY;
X
X Spells[S_ACCURACY].powerdrain = 20;
X Spells[S_ACCURACY].id = S_ACCURACY;
X
X Spells[S_RITUAL].powerdrain = 50;
X Spells[S_RITUAL].id = S_RITUAL;
X
X Spells[S_APPORT].powerdrain = 15;
X Spells[S_APPORT].id = S_APPORT;
X
X Spells[S_SHADOWFORM].powerdrain = 50;
X Spells[S_SHADOWFORM].id = S_SHADOWFORM;
X
X Spells[S_ALERT].powerdrain = 15;
X Spells[S_ALERT].id = S_ALERT;
X
X Spells[S_REGENERATE].powerdrain = 20;
X Spells[S_REGENERATE].id = S_REGENERATE;
X
X Spells[S_SANCTIFY].powerdrain = 75;
X Spells[S_SANCTIFY].id = S_SANCTIFY;
X
X Spells[S_CLAIRVOYANCE].powerdrain = 10;
X Spells[S_CLAIRVOYANCE].id = S_CLAIRVOYANCE;
X
X Spells[S_DRAIN].powerdrain = 40;
X Spells[S_DRAIN].id = S_DRAIN;
X
X Spells[S_LEVITATE].powerdrain = 25;
X Spells[S_LEVITATE].id = S_LEVITATE;
X
X Spells[S_POLYMORPH].powerdrain = 30;
X Spells[S_POLYMORPH].id = S_POLYMORPH;
X
X Spells[S_FEAR].powerdrain = 10;
X Spells[S_FEAR].id = S_FEAR;
X
X Spells[S_WISH].powerdrain = 100;
X Spells[S_WISH].id = S_WISH;
X
X}
X
X
X
X
X
X
Xvoid cast_spell(spell)
Xint spell;
X{
X switch(spell) {
X case S_MON_DET:s_mondet();
X break;
X case S_OBJ_DET:s_objdet();
X break;
X case S_IDENTIFY:s_identify();
X break;
X case S_FIREBOLT:s_firebolt();
X break;
X case S_SLEEP:s_sleep();
X break;
X case S_LBALL:s_lball();
X break;
X case S_TELEPORT:s_teleport();
X break;
X case S_DISRUPT:s_disrupt();
X break;
X case S_DISINTEGRATE:s_disintegrate();
X break;
X case S_MISSILE:s_missile();
X break;
X case S_HEAL:s_heal();
X break;
X case S_DISPEL:s_dispel();
X break;
X case S_BREATHE:s_breathe();
X break;
X case S_INVISIBLE:s_invisible();
X break;
X case S_WARP:s_warp();
X break;
X case S_ENCHANT:s_enchant();
X break;
X case S_BLESS:s_bless();
X break;
X case S_RESTORE:s_restore();
X break;
X case S_CURE:s_cure();
X break;
X case S_TRUESIGHT:s_truesight();
X break;
X case S_HELLFIRE:s_hellfire();
X break;
X case S_KNOWLEDGE:s_knowledge();
X break;
X case S_HERO:s_hero();
X break;
X case S_RETURN:s_return();
X break;
X case S_DESECRATE:s_desecrate();
X break;
X case S_HASTE:s_haste();
X break;
X case S_SUMMON:s_summon();
X break;
X case S_SANCTUARY:s_sanctuary();
X break;
X case S_ACCURACY:s_accuracy();
X break;
X case S_RITUAL:s_ritual();
X break;
X case S_APPORT:s_apport();
X break;
X case S_SHADOWFORM:s_shadowform();
X break;
X case S_ALERT:s_alert();
X break;
X case S_REGENERATE:s_regenerate();
X break;
X case S_SANCTIFY:s_sanctify();
X break;
X case S_CLAIRVOYANCE:s_clairvoyance();
X break;
X case S_DRAIN:s_drain();
X break;
X case S_LEVITATE:s_levitate();
X break;
X case S_FEAR:s_fear();
X break;
X case S_POLYMORPH:s_polymorph();
X break;
X case S_WISH:s_wish();
X break;
X default: mprint("Your odd spell fizzles with a small 'sput'.");
X break;
X }
X}
X
X
X
X
X
Xint spellparse()
X{
X int spell= -3,place=0;
X char byte,prefix[80];
X
X prefix[0]=0;
X
X do {
X byte = mgetc();
X if ((byte >= 'A') && (byte <= 'Z')) {
X maddch(byte+'a'-'A');
X prefix[place] = byte+'a'-'A';
X prefix[place+1] = 0;
X place++;
X }
X else if ((byte == ' ') || ((byte >= 'a') && (byte <= 'z'))) {
X maddch(byte);
X prefix[place] = byte;
X prefix[place+1] = 0;
X place++;
X }
X else if ((byte == 8) || (byte == 127)) { /* ^h or delete */
X prefix[place]=0;
X if (place > 0) {
X place--;
X dobackspace();
X }
X }
X else if (byte == '?') {
X maddch(byte);
X expandspellabbrevs(prefix);
X dobackspace();
X }
X else if (byte == '\n')
X spell = expandspell(prefix);
X else if (byte == ESCAPE)
X spell = ABORT;
X } while (spell == -3);
X xredraw();
X return(spell);
X}
X
Xvoid expandspellabbrevs(prefix)
Xchar prefix[80];
X{
X int i,printed=FALSE;
X
X menuclear();
X menuprint("\nPossible Spells:\n");
X for (i=0;i<NUMSPELLS;i++)
X if (Spells[i].known && strprefix(prefix,spellid(i))) {
X menuspellprint(i);
X printed = TRUE;
X }
X if (! printed)
X menuprint("\nNo spells match that prefix!");
X}
X
X
Xint expandspell(prefix)
Xchar prefix[80];
X{
X int i,spell,matched=0;
X
X for (i=0;i<NUMSPELLS;i++)
X if (Spells[i].known && strprefix(prefix,spellid(i))) {
X spell = i;
X matched++;
X }
X if (matched==0) {
X mprint("No spells match that prefix!");
X return(-2);
X }
X else if (matched > 1) {
X mprint("That is an ambiguous abbreviation!");
X return(-2);
X }
X else return(spell);
X}
X
END_OF_FILE
if test 16531 -ne `wc -c <'ospell.c'`; then
echo shar: \"'ospell.c'\" unpacked with wrong size!
fi
# end of 'ospell.c'
fi
echo shar: End of archive 13 \(of 19\).
cp /dev/null ark13isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 19 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0