billr@saab.CNA.TEK.COM (Bill Randle) (07/14/90)
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu> Posting-number: Volume 10, Issue 90 Archive-name: nethack3p9/Part45 Supersedes: NetHack3: Volume 7, Issue 56-93 #! /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 45 (of 56)." # Contents: mac/macinit.c src/music.c src/o_init.c src/spell.c # vms/vmstparam.c # Wrapped by billr@saab on Wed Jul 11 17:12:01 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'mac/macinit.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mac/macinit.c'\" else echo shar: Extracting \"'mac/macinit.c'\" \(11148 characters\) sed "s/^X//" >'mac/macinit.c' <<'END_OF_FILE' X/* SCCS Id: @(#)macinit.c 3.0 88/08/05 X/* Copyright (c) Johnny Lee, 1989. */ X/* NetHack may be freely redistributed. See license for details. */ X X/* Initialization routine for the Macintosh */ X X#include "hack.h" X X#ifdef MACOS X# ifdef THINK_C X#include <MemoryMgr.h> X# else X#include <Memory.h> X#define ApplLimit 0x130 /* application limit [pointer]*/ X# endif X X/* Global variables */ Xextern WindowPtr HackWindow; /* points to NetHack's window */ Xchar *keys[8]; Xshort macflags; XBoolean lowMem; Xlong lowMemLimit; Xtypedef struct defaultData { X long defaultFlags; X long lowMemLimit; X Str255 fontName; X} defaultData; X#define fDFZoomWindow 0x02L X#define fDFUseDefaultFont 0x01L Xshort altCurs; X X Xint Xinitterm(row, col) Xshort row, col; X{ X register short i, j; X short tempFont, tempSize, fontNum, size; X char *l, *m; X EventRecord theEvent; X FontInfo fInfo; X Handle temp; X MenuHandle theMenu; X OSErr error; X Rect boundsRect; X Str255 appName, font; X defaultData *dD; X term_info *t; X X /* standard Mac initialization */ X#ifdef THINK_C X SetApplLimit((Ptr)ApplLimit - 8192); /* an extra 8K for stack */ X#else X SetApplLimit(*(long *)ApplLimit - 8192); X#endif X MaxApplZone(); X UnloadSeg(mprintf); X for (i = 2; i<9; i++) { X temp = GetResource('CODE', i); X HUnlock(temp); X MoveHHi(temp); X HLock(temp); X } X X MoreMasters(); X MoreMasters(); X MoreMasters(); X MoreMasters(); X lowMem = (FreeMem() < 700 *1024) ? TRUE : FALSE; X InitGraf(&MAINGRAFPORT); X X InitFonts(); X InitWindows(); X InitMenus(); X InitCursor(); X FlushEvents(everyEvent, 0); X if (error = GetVol((StringPtr)&appName, &tempSize)) X SysBeep(1); X X /* Application-specific startup code */ X theMenu = NewMenu(appleMenu, "\001\024"); /* apple menu */ X { X char tmp[256]; X Sprintf(&tmp[1],"About NetHack %s\311;(-", VERSION); X tmp[0] = (char)strlen(&tmp[1]); X AppendMenu(theMenu,tmp); X } X AddResMenu(theMenu, 'DRVR'); X InsertMenu(theMenu, 0); X DisableItem(theMenu,0); X X t = (term_info *)malloc(sizeof(term_info)); X t->recordVRefNum = tempSize; X X for (i = fileMenu; i <= extendMenu; i++) { X theMenu = GetMenu(i); X if (theMenu) { X InsertMenu(theMenu, 0); X DisableItem(theMenu, 0); X } X if (i == editMenu) { X t->shortMBarHandle = GetMenuBar(); X } X } X t->fullMBarHandle = GetMenuBar(); X X DrawMenuBar(); X HiliteMenu(0); X for (i = 0;i <= 7;i++) { X temp = GetResource(HACK_DATA,(i + 100 + appleMenu)); X if (!temp) { X SysBeep(1); X panic("Can't get MENU_DATA resource"); X } X MoveHHi(temp); X HLock(temp); X DetachResource(temp); X keys[i] = *temp; X } X X macflags = (fToggleNumPad | fDoNonKeyEvt); X X /* Set font to monaco, user-defined font or to Hackfont if available */ X if ((SCREEN_BITS.bounds.bottom - SCREEN_BITS.bounds.top) >400 X && (SCREEN_BITS.bounds.right - SCREEN_BITS.bounds.left) > 580) X size = 12; X else X size = 9; X Strcpy((char *)&font[0], "\006Monaco"); X X temp = GetResource(HACK_DATA, DEFAULT_DATA); X if (temp) { X HLock(temp); X dD = (defaultData *)(*temp); X lowMemLimit = dD->lowMemLimit; X strncpy((char *)&font[0], (char *)&dD->fontName[0], X (short)dD->fontName[0] + 1); X if (dD->defaultFlags & fDFZoomWindow) X macflags |= fZoomOnContextSwitch; X HUnlock(temp); X ReleaseResource(temp); X } X X tempFont = MAINGRAFPORT->txFont; X tempSize = MAINGRAFPORT->txSize; X GetFNum(font, &fontNum); X TextFont(fontNum); X TextSize(size); X GetFontInfo(&fInfo); X TextFont(tempFont); X TextSize(tempSize); X X if (!(dD->defaultFlags & fDFUseDefaultFont)) { X Strcpy((char *)&appName[0], "\010HackFont"); X GetFNum(appName,&tempFont); X if (tempFont) { X fontNum = tempFont; X tempFont = MAINGRAFPORT->txFont; X TextFont(fontNum); X TextSize(size); X GetFontInfo(&fInfo); X TextFont(tempFont); X TextSize(tempSize); X macflags |= fUseCustomFont; X } X } X X i = fInfo.ascent + fInfo.descent + fInfo.leading; X j = fInfo.widMax; X if ((row * i + 2 * Screen_Border) > X (SCREEN_BITS.bounds.bottom - SCREEN_BITS.bounds.top) X || X (col * j + 2 * Screen_Border) > X (SCREEN_BITS.bounds.right - SCREEN_BITS.bounds.left)) { X size = 9; X Strcpy((char *)&font[0], "\006Monaco"); X tempFont = MAINGRAFPORT->txFont; X tempSize = MAINGRAFPORT->txSize; X GetFNum(font, &fontNum); X TextFont(fontNum); X TextSize(size); X GetFontInfo(&fInfo); X TextFont(tempFont); X TextSize(tempSize); X i = fInfo.ascent + fInfo.descent + fInfo.leading; X j = fInfo.widMax; X macflags &= ~fUseCustomFont; X } X X t->ascent = fInfo.ascent; X t->descent = fInfo.descent; X t->height = i; X t->charWidth = j; X X t->fontNum = fontNum; X t->fontSize = size; X t->maxRow = row; X t->maxCol = col; X t->tcur_x = 0; X t->tcur_y = 0; X t->auxFileVRefNum = 0; X if (error = SysEnvirons(1, &(t->system))) { X SysBeep(1); X } X X /* Some tweaking to allow for intl. ADB keyboard (unknown) */ X if (t->system.machineType > envMacPlus && !t->system.keyBoardType) { X t->system.keyBoardType = envStandADBKbd; X } X X#define KEY_MAP 103 X temp = GetResource(HACK_DATA, KEY_MAP); X if (temp) { X MoveHHi(temp); X HLock(temp); X DetachResource(temp); X t->keyMap = (char *)(*temp); X } else X panic("Can't get keymap resource"); X X SetRect(&boundsRect, LEFT_OFFSET, TOP_OFFSET + 10, X (col * fInfo.widMax) + LEFT_OFFSET + 2 * Screen_Border, X TOP_OFFSET + (row * t->height) + 2 * Screen_Border + 10); X X t->screen = (char **)malloc(row * sizeof(char *)); X t->scrAttr = (char **)malloc(row * sizeof(char *)); X l = malloc(row * col * sizeof(char)); X m = malloc(row * col * sizeof(char)); X for (i = 0;i < row;i++) { X t->screen[i] = (char *)(l + (i * col * sizeof(char))); X t->scrAttr[i] = (char *)(m + (i * col * sizeof(char))); X } X for (i = 0; i < row; i++) { X for (j = 0; j < col; j++) { X t->screen[i][j] = ' '; X t->scrAttr[i][j] = '\0'; X } X } X t->curHilite = 0; X t->curAttr = 0; X X /* give time for Multifinder to bring NetHack window to front */ X for(tempFont = 0; tempFont<10; tempFont++) { X SystemTask(); X (void)GetNextEvent(nullEvent,&theEvent); X } X X HackWindow = NewWindow(0L, &boundsRect, "\016NetHack [MOVE]", X TRUE, noGrowDocProc, (WindowPtr)-1, FALSE, (long)t); X X t->inColor = 0; X#ifdef TEXTCOLOR X t->color[0] = blackColor; X t->color[1] = redColor; X t->color[2] = greenColor; X t->color[3] = yellowColor; X t->color[4] = blueColor; X t->color[5] = magentaColor; X t->color[6] = cyanColor; X t->color[7] = whiteColor; X X if (t->system.hasColorQD) { X Rect r; X GDHandle gd; X X r = (**(*(WindowPeek)HackWindow).contRgn).rgnBBox; X LocalToGlobal(&r.top); X LocalToGlobal(&r.bottom); X gd = GetMaxDevice(&r); X t->inColor = (**(**gd).gdPMap).pixelSize > 1; X } X#endif X X temp = GetResource(HACK_DATA, MONST_DATA); X if (temp) { X DetachResource(temp); X MoveHHi(temp); X HLock(temp); X i = GetHandleSize(temp); X mons = (struct permonst *)(*temp); X } else { X panic("Can't get MONST resource data."); X } X X temp = GetResource(HACK_DATA, OBJECT_DATA); X if (temp) { X DetachResource(temp); X MoveHHi(temp); X HLock(temp); X i = GetHandleSize(temp); X objects = (struct objclass *)(*temp); X for (j = 0; j< NROFOBJECTS+1; j++) { X objects[j].oc_name = sm_obj[j].oc_name; X objects[j].oc_descr = sm_obj[j].oc_descr; X } X } else { X panic("Can't get OBJECT resource data."); X } X X for (j = 30; j >= 0; j -= 10) { X for (i = 0; i<=8; i++) { X t->cursor[i] = GetCursor(100+i+j); /* self-contained cursors */ X } X } X X (void)aboutBox(0); X return 0; X} X X/* not really even needed. NH never gets to the end of main(), */ X/* so this never gets called */ Xint Xfreeterm() X{ X return 0; X} X X#ifdef SMALLDATA X/* SOME [:-( ] Mac compilers have a 32K global & static data limit */ X/* these routines help the HANDICAPPED things */ Xvoid Xinit_decl() X{ X short i; X char *l; X extern char **Map; X X l = calloc(COLNO , sizeof(struct rm **)); X level.locations = (struct rm **)l; X l = calloc(ROWNO * COLNO , sizeof(struct rm)); X for (i = 0; i < COLNO; i++) { X level.locations[i] = X (struct rm *)(l + (i * ROWNO * sizeof(struct rm))); X } X X l = calloc(COLNO , sizeof(struct obj ***)); X level.objects = (struct obj ***)l; X l = calloc(ROWNO * COLNO , sizeof(struct obj *)); X for (i = 0; i < COLNO; i++) { X level.objects[i] = X (struct obj **)(l + (i * ROWNO * sizeof(struct obj *))); X } X X l = calloc(COLNO , sizeof(struct monst ***)); X level.monsters = (struct monst ***)l; X l = calloc(ROWNO * COLNO , sizeof(struct monst *)); X for (i = 0; i < COLNO; i++) { X level.monsters[i] = X (struct monst **)(l + (i * ROWNO * sizeof(struct monst *))); X } X level.objlist = (struct obj *)0L; X level.monlist = (struct monst *)0L; X Xl = calloc(COLNO, sizeof(char *)); XMap = (char **)l; Xl = calloc(ROWNO * COLNO, sizeof(char)); Xfor (i = 0; i < COLNO; i++) { X Map[i] = X (char *)(l + (i * ROWNO * sizeof(char))); X} X X} X X/* Since NetHack usually exits before reaching end of main() */ X/* this routine could probably left out. - J.L. */ Xvoid Xfree_decl() X{ X X free((char *)level.locations[0]); X free((char *)level.locations); X free((char *)level.objects[0]); X free((char *)level.objects); X free((char *)level.monsters[0]); X free((char *)level.monsters); X} X#endif /* SMALLDATA */ X X#define OPTIONS "Nethack prefs" X X# ifdef AZTEC X#undef OMASK X#define OMASK O_RDONLY X# else X#undef OMASK X#define OMASK (O_RDONLY | O_BINARY ) X# endif X Xint Xread_config_file() X{ X term_info *t; X int optfd; X Str255 name; X short oldVol; X X optfd = 0; X t = (term_info *)GetWRefCon(HackWindow); X X GetVol(name, &oldVol); X SetVol(0L, t->system.sysVRefNum); X if ( (optfd = open(OPTIONS, OMASK)) <= 0) { X SetVol(0L, t->recordVRefNum); X optfd = open(OPTIONS, OMASK); X } X if ( optfd > (short)NULL){ X read_opts(optfd); X (void) close(optfd); X } X SetVol(0L, oldVol); X} X Xint Xwrite_opts() X{ X int fd; X short temp_flags; X term_info *t; X X t = (term_info *)GetWRefCon(HackWindow); X SetVol(0L, t->system.sysVRefNum); X X if((fd = open(OPTIONS, O_WRONLY | O_BINARY)) <= 0) { X OSErr result; X char *tmp; X X SetVol(0L, t->recordVRefNum); X if((fd = open(OPTIONS, O_WRONLY | O_BINARY)) <= 0) { X SetVol(0L, t->system.sysVRefNum); X tmp = CtoPstr(OPTIONS); X result = Create((StringPtr)tmp, (short)0, CREATOR, AUXIL_TYPE); X if (result == noErr) X fd = open(OPTIONS, O_WRONLY | O_BINARY); X } X } X X if (fd < 0) X pline("can't create options file!"); X else { X write(fd, &flags, sizeof(flags)); X X write(fd, plname, PL_NSIZ); X X write(fd, dogname, 63); X X write(fd, catname, 63); X X temp_flags = (macflags & fZoomOnContextSwitch) ? 1 : 0; X write(fd, &temp_flags, sizeof(short)); X X write(fd, &altCurs, sizeof(short)); X X#ifdef TUTTI_FRUTTI X write(fd, pl_fruit, PL_FSIZ); X#endif X write(fd, inv_order, strlen(inv_order)+1); X close(fd); X } X X SetVol(0L, t->recordVRefNum); X X return 0; X} X Xint Xread_opts(fd) Xint fd; X{ char tmp_order[20]; X short temp_flags; X X read(fd, (char *)&flags, sizeof(flags)); X X read(fd, plname, PL_NSIZ); X X read(fd, dogname, 63); X X read(fd, catname, 63); X X read(fd, &temp_flags, sizeof(short)); X if (temp_flags & 0x01) X macflags |= fZoomOnContextSwitch; X else X macflags &= ~fZoomOnContextSwitch; X X read(fd, &altCurs, sizeof(short)); X X#ifdef TUTTI_FRUTTI X read(fd, pl_fruit, PL_FSIZ); X#endif X read(fd,tmp_order,strlen(inv_order)+1); X if(strlen(tmp_order) == strlen(inv_order)) X Strcpy(inv_order,tmp_order); X X return 0; X} X X#endif /* MACOS */ END_OF_FILE if test 11148 -ne `wc -c <'mac/macinit.c'`; then echo shar: \"'mac/macinit.c'\" unpacked with wrong size! fi # end of 'mac/macinit.c' fi if test -f 'src/music.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/music.c'\" else echo shar: Extracting \"'src/music.c'\" \(11331 characters\) sed "s/^X//" >'src/music.c' <<'END_OF_FILE' X/* SCCS Id: @(#)music.c 3.0 88/10/22 X/* Copyright (c) 1989 by Jean-Christophe Collet */ X/* NetHack may be freely redistributed. See license for details. */ X X/* X * This file contains the different functions designed to manipulate the X * musical instruments and their various effects. X * X * Actually the list of instruments / effects is : X * X * Flute may calm snakes if player has enough dexterity X * Magic flute may put monsters to sleep: area of effect depends X * on player level. X * Horn Will awaken monsters: area of effect depends on player X * level. May also scare monsters. X * Fire horn Acts like a wand of fire. X * Frost horn Acts like a wand of cold. X * Bugle Will awaken soldiers (if any): area of effect depends X * on player level. X * Harp May calm nymph if player has enough dexterity. X * Magic harp Charm monsters: area of effect depends on player X * level. X * Drum Will awaken monsters like the horn. X * Drum of earthquake Will initiate an earthquake whose intensity depends X * on player level. That is, it creates ramdom pits X * called here chasms. X */ X X X#include "hack.h" X X#ifdef MUSIC X#include <ctype.h> X Xstatic void FDECL(awaken_monsters,(int)); Xstatic void FDECL(put_monsters_to_sleep,(int)); Xstatic void FDECL(charm_snakes,(int)); Xstatic void FDECL(calm_nymphs,(int)); Xstatic void NDECL(awaken_soldiers); Xstatic void FDECL(charm_monsters,(int)); Xstatic void FDECL(do_earthquake,(int)); Xstatic int FDECL(do_improvisation,(struct obj *)); X X/* X * Wake every monster in range... X */ X Xstatic void Xawaken_monsters(distance) Xint distance; X{ X register struct monst *mtmp = fmon; X X while(mtmp) { X if (dist(mtmp->mx, mtmp->my) < distance/3) { X /* May scare some monsters */ X if (!resist(mtmp, SCROLL_SYM, 0, NOTELL)) X mtmp->mflee = 1; X } else if (dist(mtmp->mx, mtmp->my) < distance) { X mtmp->msleep = 0; X mtmp->mcanmove = 1; X mtmp->mfrozen = 0; X } X mtmp = mtmp->nmon; X } X} X X/* X * Make monsters fall asleep. Note that they may resist the spell. X */ X Xstatic void Xput_monsters_to_sleep(distance) Xint distance; X{ X register struct monst *mtmp = fmon; X X while(mtmp) { X if (dist(mtmp->mx, mtmp->my) < distance) X if(mtmp->mcanmove && !resist(mtmp, WAND_SYM, 0, NOTELL)) X mtmp->mcanmove = mtmp->mfrozen = 0; X mtmp = mtmp->nmon; X } X} X X/* X * Charm snakes in range. Note that the snakes are NOT tamed. X */ X Xstatic void Xcharm_snakes(distance) Xint distance; X{ X register struct monst *mtmp = fmon; X X while (mtmp) { X if (mtmp->data->mlet == S_SNAKE && dist(mtmp->mx, mtmp->my) < distance) { X mtmp->mpeaceful = 1; X if (cansee(mtmp->mx, mtmp->my)) X pline("%s freezes and sways with the music, then seems quieter.",defmonnam(mtmp)); X } X mtmp = mtmp->nmon; X } X} X X/* X * Calm nymphs in range. X */ X Xstatic void Xcalm_nymphs(distance) Xint distance; X{ X register struct monst *mtmp = fmon; X X while (mtmp) { X if (mtmp->data->mlet == S_NYMPH && dist(mtmp->mx, mtmp->my) < distance) { X mtmp->mpeaceful = 1; X if (cansee(mtmp->mx, mtmp->my)) X pline("%s listens cheerfully to the music, then seems quieter.",defmonnam(mtmp)); X } X mtmp = mtmp->nmon; X } X} X X/* Awake only soldiers of the level. */ X Xstatic void Xawaken_soldiers() { X#ifdef ARMY X#define IS_SOLDIER(dat) ((int)((dat) - mons) >= PM_UNARMORED_SOLDIER && \ X (int) ((dat) - mons) <= PM_CAPTAIN) X register struct monst *mtmp = fmon; X X while(mtmp) { X if (IS_SOLDIER(mtmp->data)) { X mtmp->mpeaceful = mtmp->msleep = 0; X mtmp->mcanmove = 1; X } X mtmp = mtmp->nmon; X } X#endif /* ARMY /**/ X} X X/* Charm monsters in range. Note that they may resist the spell. */ X Xstatic void Xcharm_monsters(distance) Xint distance; X{ X register struct monst *mtmp = fmon, *mtmp2; X X while(mtmp) { X mtmp2 = mtmp->nmon; X if(dist(mtmp->mx, mtmp->my) <= distance) X if(!resist(mtmp, SCROLL_SYM, 0, NOTELL)) X (void) tamedog(mtmp, (struct obj *) 0); X mtmp = mtmp2; X } X X} X X/* Generate earthquake :-) of desired force. X * That is: create random chasms (pits). X */ X Xstatic void Xdo_earthquake(force) Xint force; X{ X register int x,y; X struct monst *mtmp; X struct trap *chasm; X int start_x, start_y, end_x, end_y; X X start_x = u.ux - (force * 2); X start_y = u.uy - (force * 2); X end_x = u.ux + (force * 2); X end_y = u.uy + (force * 2); X if (start_x < 1) start_x = 1; X if (start_y < 1) start_y = 1; X if (end_x >= COLNO) end_x = COLNO - 1; X if (end_y >= ROWNO) end_y = ROWNO - 1; X for (x=start_x; x<=end_x; x++) X for (y=start_y; y<=end_y; y++) X if (!rn2(14 - force)) { X switch (levl[x][y].typ) { X#ifdef FOUNTAINS X case FOUNTAIN : /* Make the fountain disappear */ X if (cansee(x,y)) X pline("The fountain falls into a chasm."); X goto do_pit; X#endif X#ifdef SINKS X case SINK : X if (cansee(x,y)) X pline("The kitchen sink falls into a chasm."); X goto do_pit; X#endif X#ifdef ALTARS X case ALTAR : X if (cansee(x,y)) X pline("The altar falls into a chasm."); X goto do_pit; X#endif X#ifdef THRONES X case THRONE : X if (cansee(x,y)) X pline("The throne falls into a chasm."); X /* Falls into next case */ X#endif X case ROOM : X case CORR : /* Make a pit */ Xdo_pit: chasm = maketrap(x,y,PIT); X chasm->tseen = 1; X X levl[x][y].doormask = 0; X X /* We have to check whether monsters or player X fall in a chasm... */ X X if (MON_AT(x, y)) { X mtmp = m_at(x,y); X if(!is_flyer(mtmp->data)) { X mtmp->mtrapped = 1; X if(cansee(x,y)) X pline("%s falls into a chasm!", X Monnam(mtmp)); X else if (flags.soundok && humanoid(mtmp->data)) X You("hear a scream!"); X if ((mtmp->mhp -= rnd(6)) <= 0) { X if(!cansee(x,y)) X pline("It is destroyed!"); X else { X You("destroy %s!", X mtmp->mtame ? X a2_monnam(mtmp, "poor") : X mon_nam(mtmp)); X } X xkilled(mtmp,0); X } X } X } else if (x == u.ux && y == u.uy) { X if (Levitation X#ifdef POLYSELF X || is_flyer(uasmon) X#endif X ) { X pline("A chasm opens up under you!"); X You("don't fall in!"); X } else { X You("fall into a chasm!"); X u.utrap = rn1(6,2); X u.utraptype = TT_PIT; X losehp(rnd(6),"fell into a chasm", X NO_KILLER_PREFIX); X selftouch("Falling, you"); X } X } else X newsym(x,y); X break; X case DOOR : /* Make the door collapse */ X if (levl[x][y].doormask == D_NODOOR) break; X if (cansee(x,y)) X pline("The door collapses."); X levl[x][y].doormask = D_NODOOR; X mnewsym(x,y); X if (!MON_AT(x, y) && !(x == u.ux && y == u.uy)) X newsym(x,y); X if (cansee(x,y)) prl(x,y); X break; X } X } X} X X/* X * The player is trying to extract something from his/her instrument. X */ X Xstatic int Xdo_improvisation(instr) Xstruct obj *instr; X{ X int damage; X X if (Confusion) X pline("What you produce is quite far from music..."); X else X You("start playing the %s.", xname(instr)); X switch (instr->otyp) { X case FLUTE: /* May charm snakes */ X if (rn2(ACURR(A_DEX)) + u.ulevel > 25) X charm_snakes((int)u.ulevel*3); X break; X case MAGIC_FLUTE: /* Make monster fall asleep */ X if (instr->spe > 0) { X instr->spe--; X You("produce soft music."); X put_monsters_to_sleep((int)u.ulevel*5); X } X break; X case HORN: /* Awaken monsters or scare monsters */ X You("produce a frightful, grave sound."); X awaken_monsters((int)u.ulevel*30); X break; X case FROST_HORN: /* Idem wand of cold */ X case FIRE_HORN: /* Idem wand of fire */ X if (instr->spe > 0) { X instr->spe--; X if (!getdir(1)) { X if (!Blind) X pline("The %s glows then fades.", xname(instr)); X } else { X if (!u.dx && !u.dy && !u.dz) { X if((damage = zapyourself(instr))) X losehp(damage, X self_pronoun("using a magical horn on %sself", "him"), X NO_KILLER_PREFIX); X makeknown(instr->otyp); X return(2); X } X buzz((instr->otyp == FROST_HORN) ? 3 : 1, rn1(6,6), u.ux, u.uy, u.dx, u.dy); X makeknown(instr->otyp); X return(2); X } X } X break; X case BUGLE: /* Awaken & attract soldiers */ X You("extract a loud noise from the %s.",xname(instr)); X awaken_soldiers(); X break; X case HARP: /* May calm Nymph */ X if (rn2(ACURR(A_DEX)) + u.ulevel > 25) X calm_nymphs((int)u.ulevel*3); X break; X case MAGIC_HARP: /* Charm monsters */ X if (instr->spe > 0) { X pline("The %s produces very attractive music.", xname(instr)); X instr->spe--; X charm_monsters(((int)u.ulevel - 1) / 3 + 1); X } X break; X case DRUM: /* Awaken monsters */ X You("beat a deafening row!"); X awaken_monsters((int)u.ulevel * 40); X break; X case DRUM_OF_EARTHQUAKE: /* create several pits */ X if (instr->spe > 0) { X You("produce a heavy, thunderous rolling!"); X pline("The entire dungeon is shaking around you!"); X instr->spe--; X do_earthquake(((int)u.ulevel - 1) / 3 + 1); X makeknown(DRUM_OF_EARTHQUAKE); X } X break; X default: X impossible("What a weird instrument (%d)!",instr->otyp); X break; X } X return (2); /* That takes time */ X} X X/* X * So you want music... X */ X Xint Xdo_play_instrument(instr) Xstruct obj *instr; X{ X#ifdef STRONGHOLD X char buf[BUFSZ], *s, c = 'y'; X int x,y; X boolean ok; X X if (instr->otyp != DRUM && instr->otyp != DRUM_OF_EARTHQUAKE) { X pline("Improvise? "); X c = yn(); X } X if (c == 'n') { X pline("What tune are you playing? [what 5 notes] "); X getlin(buf); X for(s=buf;*s;s++) X if (islower(*s)) *s=toupper(*s); X You("extract a strange sound from the %s!",xname(instr)); X /* Check if there was the Stronghold drawbridge near X * and if the tune conforms to what we're waiting for. X */ X if (dlevel == stronghold_level) X if (!strcmp(buf,tune)) { X /* Search for the drawbridge */ X for(y=u.uy-1; y<=u.uy+1; y++) X for(x=u.ux-1;x<=u.ux+1;x++) X if(isok(x,y)) X if (find_drawbridge(&x,&y)) { X if (levl[x][y].typ == DRAWBRIDGE_DOWN) X close_drawbridge(x,y); X else X open_drawbridge(x,y); X return 0; X } X } else if (flags.soundok) { X /* Okay, it wasn't the right tune, but perhaps X * we can give the player some hints like in the X * Mastermind game */ X ok = FALSE; X for(y = u.uy-1; y <= u.uy+1 && !ok; y++) X for(x = u.ux-1; x <= u.ux+1 && !ok; x++) X if(isok(x,y)) X if(IS_DRAWBRIDGE(levl[x][y].typ) || X is_drawbridge_wall(x,y) >= 0) X ok = TRUE; X if (ok) { /* There is a drawbridge near */ X int tumblers, gears; X boolean matched[5]; X X tumblers = gears = 0; X for(x=0; x < 5; x++) X matched[x] = FALSE; X X for(x=0; x < strlen(buf); x++) X if(x < 5) { X if(buf[x] == tune[x]) { X gears++; X matched[x] = TRUE; X } else X for(y=0; y < 5; y++) X if(!matched[y] && X buf[x] == tune[y] && X buf[y] != tune[y]) { X tumblers++; X matched[y] = TRUE; X break; X } X } X if(tumblers) X if(gears) X You("hear %d tumbler%s click and %d gear%s turn.", X tumblers, plur((long)tumblers), X gears, plur((long)gears)); X else X You("hear %d tumbler%s click.", X tumblers, plur((long)tumblers)); X else if(gears) X You("hear %d gear%s turn.", X gears, plur((long)gears)); X } X } X return 1; X } else X#endif /* STRONGHOLD /**/ X return do_improvisation(instr); X} X X#endif /* MUSIC /**/ END_OF_FILE if test 11331 -ne `wc -c <'src/music.c'`; then echo shar: \"'src/music.c'\" unpacked with wrong size! fi # end of 'src/music.c' fi if test -f 'src/o_init.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/o_init.c'\" else echo shar: Extracting \"'src/o_init.c'\" \(9660 characters\) sed "s/^X//" >'src/o_init.c' <<'END_OF_FILE' X/* SCCS Id: @(#)o_init.c 3.0 88/07/06 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X#include "hack.h" /* for typedefs */ X X#if defined(LATTICE) /* This is NOT */ X# define MACOS /* a typo! */ X#endif X Xstatic void NDECL(setgemprobs); Xstatic void FDECL(shuffle,(int,int,BOOLEAN_P)); Xstatic boolean FDECL(interesting_to_discover,(int)); X X/* note that NROFOBJECTS is the number of legal objects, which does not count X * the strange object and null object that take up positions 0 and NROFOBJECTS+1 X * in the objects array X */ X#define TOTAL_OBJS (NROFOBJECTS+2) X#ifdef MACOS Xshort *switches; /* used to allow position independent loads of app */ X /* by storing the number of the description string */ X /* [at startup of the game] not the pointer to the string */ X#endif X Xconst char obj_symbols[] = { X ILLOBJ_SYM, AMULET_SYM, FOOD_SYM, WEAPON_SYM, TOOL_SYM, X BALL_SYM, CHAIN_SYM, ROCK_SYM, ARMOR_SYM, X POTION_SYM, SCROLL_SYM, WAND_SYM, X#ifdef SPELLS X SPBOOK_SYM, X#endif X RING_SYM, GEM_SYM, 0 }; X Xint NEARDATA bases[sizeof(obj_symbols)] = DUMMY; Xstatic int NEARDATA disco[TOTAL_OBJS] = DUMMY; X Xint Xletindex(let) register char let; { Xregister int i = 0; Xregister char ch; X while((ch = obj_symbols[i++]) != 0) X if(ch == let) return(i); X return(0); X} X Xstatic void Xsetgemprobs() X{ X register int j,first; X#ifdef STRONGHOLD X int lev = (dlevel > MAXLEVEL) ? MAXLEVEL : dlevel; X#endif X X first = bases[letindex(GEM_SYM)]; X X#ifdef STRONGHOLD X for(j = 0; j < 9-lev/3; j++) X#else X for(j = 0; j < 9-dlevel/3; j++) X#endif X objects[first+j].oc_prob = 0; X first += j; X if(first >= LAST_GEM || first > NROFOBJECTS || X objects[first].oc_olet != GEM_SYM || X objects[first].oc_name == NULL) X Printf("Not enough gems? - first=%d j=%d LAST_GEM=%d\n", X first, j, LAST_GEM); X for(j = first; j < LAST_GEM; j++) X objects[j].oc_prob = (184+j-first)/(LAST_GEM-first); X} X X/* shuffle descriptions on objects o_low to o_high */ Xstatic void Xshuffle(o_low, o_high, domaterial) X X register int o_low, o_high; X register boolean domaterial; X{ X register int i, j; X const char *desc; X#ifdef TEXTCOLOR X int color; X#endif /* TEXTCOLOR */ X int tmp; X#ifdef MACOS X short sw; X#endif X X for(j=o_low; j <= o_high; j++) { X i = o_low + rn2(j+1-o_low); X desc = objects[j].oc_descr; X objects[j].oc_descr = objects[i].oc_descr; X objects[i].oc_descr = desc; X#ifdef TEXTCOLOR X color = objects[j].oc_color; X objects[j].oc_color = objects[i].oc_color; X objects[i].oc_color = color; X#endif /* TEXTCOLOR */ X /* shuffle discovery list */ X tmp = disco[j]; X disco[j] = disco[i]; X disco[i] = tmp; X /* shuffle material */ X if(domaterial) { X tmp = objects[j].oc_material; X objects[j].oc_material = objects[i].oc_material; X objects[i].oc_material = tmp; X } X#ifdef MACOS X /* keep track of shuffling of object descriptions */ X sw=switches[j]; X switches[j]=switches[i]; X switches[i]=sw; X#endif X } X} X Xvoid Xinit_objects(){ Xregister int i, j, first, last, sum, end; Xregister char let; X X /* bug fix to prevent "initialization error" abort on Intel Xenix. X * reported by mikew@semike X */ X for(i = 0; i != sizeof(obj_symbols); i++) X bases[i] = 0; X for(i = 0; i != TOTAL_OBJS; i++) X disco[i] = i; X#ifdef NAMED_ITEMS X init_exists(); /* zero out the "artifact exists" list */ X#endif X /* init base; if probs given check that they add up to 1000, X otherwise compute probs; shuffle descriptions */ X end = TOTAL_OBJS; X first = 0; X while( first < end ) { X let = objects[first].oc_olet; X last = first+1; X while(last < end && objects[last].oc_olet == let X && objects[last].oc_name != NULL) last++; X i = letindex(let); X if((!i && let != ILLOBJ_SYM && let != '.') || bases[i] != 0) X error("initialization error for %c", let); X bases[i] = first; X X if(let == GEM_SYM) setgemprobs(); X check: X sum = 0; X for(j = first; j < last; j++) sum += objects[j].oc_prob; X if(sum == 0) { X for(j = first; j < last; j++) X objects[j].oc_prob = (1000+j-first)/(last-first); X goto check; X } X if(sum != 1000) X error("init-prob error for %c (%d%%)", let, sum); X X if(objects[first].oc_descr != NULL && X let != TOOL_SYM && let != WEAPON_SYM && let != ARMOR_SYM) { X X /* shuffle, also some additional descriptions */ X while(last < end && objects[last].oc_olet == let) X last++; X j = last; X if (let == GEM_SYM) { X while(--j > first) X if(!strcmp(objects[j].oc_name,"turquoise")) { X if(rn2(2)) { /* change from green? */ X objects[j].oc_descr = blue; X#ifdef TEXTCOLOR X objects[j].oc_color = BLUE; X#endif X } X } else if (!strcmp(objects[j].oc_name,"aquamarine")) { X if(rn2(2)) { /* change from green? */ X objects[j].oc_descr = blue; X#ifdef TEXTCOLOR X objects[j].oc_color = BLUE; X#endif X } X } else if (!strcmp(objects[j].oc_name,"fluorite")) { X switch (rn2(4)) { /* change from violet? */ X case 0: break; X case 1: X objects[j].oc_descr = blue; X#ifdef TEXTCOLOR X objects[j].oc_color = BLUE; X#endif X break; X case 2: X objects[j].oc_descr = white; X#ifdef TEXTCOLOR X objects[j].oc_color = WHITE; X#endif X break; X case 3: X objects[j].oc_descr = green; X#ifdef TEXTCOLOR X objects[j].oc_color = GREEN; X#endif X break; X } X } X } else { X if (let == AMULET_SYM || let == POTION_SYM) X j--; /* THE amulet doesn't have description */ X /* and water is always "clear" - 3. */ X shuffle(first, --j, TRUE); X } X } X first = last; X } X X /* shuffle the helmets */ X shuffle(HELMET, HELM_OF_TELEPATHY, FALSE); X X /* shuffle the gloves */ X shuffle(LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY, FALSE); X X /* shuffle the cloaks */ X shuffle(CLOAK_OF_PROTECTION, CLOAK_OF_DISPLACEMENT, FALSE); X X /* shuffle the boots */ X shuffle(SPEED_BOOTS, LEVITATION_BOOTS, FALSE); X} X Xvoid Xoinit() /* level dependent initialization */ X{ X setgemprobs(); X} X Xvoid Xsavenames(fd) Xregister int fd; X{ X register int i; X unsigned int len; X#ifdef MACOS X char *descr[TOTAL_OBJS]; X#endif X struct objclass *now = &objects[0]; X bwrite(fd, (genericptr_t)&now, sizeof now); X bwrite(fd, (genericptr_t)bases, sizeof bases); X bwrite(fd, (genericptr_t)disco, sizeof disco); X#ifdef MACOS X for (i = 0 ; i < TOTAL_OBJS; i++) { X descr[i] = objects[i].oc_descr; X objects[i].oc_descr = (const char *)switches[i]; X } X#endif X bwrite(fd, (genericptr_t)objects, sizeof(struct objclass) * TOTAL_OBJS); X /* as long as we use only one version of Hack we X need not save oc_name and oc_descr, but we must save X oc_uname for all objects */ X for(i=0; i < TOTAL_OBJS; i++) { X#ifdef MACOS X objects[i].oc_descr = descr[i]; X#endif X if(objects[i].oc_uname) { X len = strlen(objects[i].oc_uname)+1; X bwrite(fd, (genericptr_t)&len, sizeof len); X bwrite(fd, (genericptr_t)objects[i].oc_uname, len); X } X } X} X Xvoid Xrestnames(fd) Xregister int fd; X{ X register int i; X unsigned int len; X struct objclass *then; X long differ; X#ifdef MACOS X /* provides position-independent save & restore */ X /* by giving each object a number, keep track of it */ X /* when shuffled and save the numbers instead of the */ X /* description strings (which can change between */ X /* executions of the program) */ X /* On restore, the retrieved numbers are matched with the */ X /* numbers and object descriptions in the program */ X struct descr { X char *name, X *descr; X } d[TOTAL_OBJS]; X X /* save the current object descriptions */ X for (i = 0; i < TOTAL_OBJS; i++) { X d[i].name = objects[i].oc_name; X d[i].descr = objects[i].oc_descr; X } X#endif X mread(fd, (genericptr_t) &then, sizeof then); X mread(fd, (genericptr_t) bases, sizeof bases); X mread(fd, (genericptr_t) disco, sizeof disco); X mread(fd, (genericptr_t) objects, sizeof(struct objclass) * TOTAL_OBJS); X#ifdef MACOS X for (i = 0; i < TOTAL_OBJS; i++) { X objects[i].oc_name = d[i].name; X switches[i] = (short)objects[i].oc_descr; X objects[i].oc_descr = d[switches[i]].descr; X } X#else X# if !defined(MSDOS) && !defined(M_XENIX) && !defined(HPUX) && !defined(VAXC) X differ = (genericptr_t)&objects[0] - (genericptr_t)then; X# else X differ = (long)&objects[0] - (long)then; X# endif X#endif /* MACOS */ X for(i=0; i < TOTAL_OBJS; i++) { X#ifndef MACOS X if (objects[i].oc_name) { X# if !defined(MSDOS) && !defined(M_XENIX) && !defined(HPUX) && !defined(VAXC) X objects[i].oc_name += differ; X# else X objects[i].oc_name = X (const char *)((long)(objects[i].oc_name) + differ); X# endif X } X if (objects[i].oc_descr) { X# if !defined(MSDOS) && !defined(M_XENIX) && !defined(HPUX) && !defined(VAXC) X objects[i].oc_descr += differ; X# else X objects[i].oc_descr = X (const char *)((long)(objects[i].oc_descr) + differ); X# endif X } X#endif /* MACOS */ X if (objects[i].oc_uname) { X mread(fd, (genericptr_t) &len, sizeof len); X objects[i].oc_uname = (char *) alloc(len); X mread(fd, (genericptr_t)objects[i].oc_uname, len); X } X } X} X Xstatic boolean Xinteresting_to_discover(i) Xregister int i; X{ X return objects[i].oc_uname != NULL || X (objects[i].oc_name_known && objects[i].oc_descr != NULL); X} X Xint Xdodiscovered() /* free after Robert Viduya */ X{ X register int i, dis; X int ct = 0; X char class = -1; X X cornline(0, "Discoveries"); X X for (i = 0; i <= NROFOBJECTS; i++) { X if (interesting_to_discover(dis = disco[i])) { X ct++; X if (objects[dis].oc_olet != class) { X class = objects[dis].oc_olet; X cornline(1, let_to_name(class)); X } X cornline(1, typename(dis)); X } X } X if (ct == 0) { X You("haven't discovered anything yet..."); X cornline(3, NULL); X } else X cornline(2, NULL); X X return 0; X} END_OF_FILE if test 9660 -ne `wc -c <'src/o_init.c'`; then echo shar: \"'src/o_init.c'\" unpacked with wrong size! fi # end of 'src/o_init.c' fi if test -f 'src/spell.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/spell.c'\" else echo shar: Extracting \"'src/spell.c'\" \(11119 characters\) sed "s/^X//" >'src/spell.c' <<'END_OF_FILE' X/* SCCS Id: @(#)spell.c 3.0 88/09/18 X * X * Copyright (c) M. Stephenson 1988 X */ X/* NetHack may be freely redistributed. See license for details. */ X X#include "hack.h" X#ifdef SPELLS Xstatic schar NEARDATA delay; /* moves left for this spell */ Xstatic struct obj NEARDATA *book; /* last/current book being xscribed */ X X#ifdef HARD X#define spelluses(spell) spl_book[spell-1].sp_uses X#define decrnuses(spell) spl_book[spell-1].sp_uses-- X#endif /* HARD */ X#define spellev(spell) spl_book[spell-1].sp_lev X#define spellname(spell) objects[spl_book[spell-1].sp_id].oc_name X#define spellid(spell) spl_book[spell-1].sp_id X Xstatic void FDECL(cursed_book, (int)); XSTATIC_PTR int NDECL(learn); Xstatic int NDECL(getspell); Xstatic char FDECL(spellet, (int)); X Xstatic void Xcursed_book(lev) X register int lev; X{ X switch(rn2(lev)) { X case 0: X You("feel a wrenching sensation."); X tele(); /* teleport him */ X break; X case 1: X You("feel threatened."); X aggravate(); X break; X case 2: X make_blinded(Blinded + rn1(100,250),TRUE); X break; X case 3: X take_gold(); X break; X case 4: X pline("These runes were just too much to comprehend."); X make_confused(HConfusion + rn1(7,16),FALSE); X break; X case 5: X pline("The book was coated with contact poison!"); X if (uarmg) { X if (uarmg->rustfree) X Your("gloves seem unaffected."); X else if (uarmg->spe > -2) { X Your("gloves corrode!"); X uarmg->spe--; X } else X Your("gloves %s quite corroded.",Blind ? "feel":"look"); X break; X } X if(Poison_resistance) { X losestr(rn1(1,2)); X losehp(rnd(6), "contact-poisoned spellbook", KILLED_BY_AN); X } else { X losestr(rn1(4,3)); X losehp(rnd(10), "contact-poisoned spellbook", KILLED_BY_AN); X } X break; X case 6: X if(Antimagic) { X shieldeff(u.ux, u.uy); X pline("The book explodes, but you are unharmed!"); X } else { X pline("As you read the book, it explodes in your %s!", X body_part(FACE)); X losehp (2*rnd(10)+5, "exploding rune", KILLED_BY_AN); X } X break; X default: X rndcurse(); X break; X } X return; X} X XSTATIC_PTR Xint Xlearn() X{ X register int i; X register unsigned booktype; X X if (delay) { /* not if (delay++), so at end delay == 0 */ X delay++; X return(1); /* still busy */ X } X X booktype = book->otyp; X for (i = 0; i < MAXSPELL; i++) { X if (spl_book[i].sp_id == booktype) { X#ifdef HARD X Your("knowledge of that spell is keener."); X spl_book[i].sp_uses += rn1(3,8-spl_book[i].sp_lev); X#else X pline("Oh, you already know that one!"); X#endif X break; X } else if (spl_book[i].sp_id == NO_SPELL) { X spl_book[i].sp_id = booktype; X spl_book[i].sp_lev = objects[booktype].spl_lev; X spl_book[i].sp_flags = objects[booktype].bits; X#ifdef HARD X /* spells have 2 .. 10-level uses. */ X /* ie 2 or 3 uses w/ most potent */ X spl_book[i].sp_uses = rn1(3,8-spl_book[i].sp_lev); X#endif X You("add the spell to your repertoire."); X makeknown(booktype); X break; X } X } X if (i == MAXSPELL) impossible("Too many spells memorized!"); X X if (book->cursed) { /* maybe a demon cursed it */ X cursed_book(objects[booktype].spl_lev); X } X X useup(book); X book = 0; X return(0); X} X Xint Xstudy_book(spellbook) Xregister struct obj *spellbook; X{ X register int booktype = spellbook->otyp; X X if (delay && spellbook == book) X You("continue your efforts to memorize the spell."); X else { X switch(booktype) { X X/* level 1 spells */ X case SPE_HEALING: X case SPE_DETECT_MONSTERS: X case SPE_FORCE_BOLT: X case SPE_LIGHT: X case SPE_SLEEP: X case SPE_KNOCK: X/* level 2 spells */ X case SPE_MAGIC_MISSILE: X case SPE_CONFUSE_MONSTER: X case SPE_SLOW_MONSTER: X case SPE_CURE_BLINDNESS: X case SPE_CREATE_MONSTER: X case SPE_DETECT_FOOD: X case SPE_WIZARD_LOCK: X delay = -objects[booktype].oc_delay; X break; X/* level 3 spells */ X case SPE_HASTE_SELF: X case SPE_CAUSE_FEAR: X case SPE_CURE_SICKNESS: X case SPE_DETECT_UNSEEN: X case SPE_EXTRA_HEALING: X case SPE_CHARM_MONSTER: X case SPE_CLAIRVOYANCE: X/* level 4 spells */ X case SPE_LEVITATION: X case SPE_RESTORE_ABILITY: X case SPE_INVISIBILITY: X case SPE_FIREBALL: X case SPE_DETECT_TREASURE: X delay = -(objects[booktype].spl_lev - 1) * objects[booktype].oc_delay; X break; X/* level 5 spells */ X case SPE_REMOVE_CURSE: X case SPE_MAGIC_MAPPING: X case SPE_CONE_OF_COLD: X case SPE_IDENTIFY: X case SPE_DIG: X/* level 6 spells */ X case SPE_TURN_UNDEAD: X case SPE_POLYMORPH: X case SPE_CREATE_FAMILIAR: X case SPE_TELEPORT_AWAY: X delay = -objects[booktype].spl_lev * objects[booktype].oc_delay; X break; X/* level 7 spells */ X case SPE_CANCELLATION: X case SPE_FINGER_OF_DEATH: X case SPE_GENOCIDE: X delay = -8 * objects[booktype].oc_delay; X break; X/* impossible */ X default: X impossible("Unknown spellbook, %d;", booktype); X return(0); X } X X if(!spellbook->blessed && X (spellbook->cursed || X rn2(20) > (ACURR(A_INT) + 4 + (int)(u.ulevel/2) X - 2*objects[booktype].spl_lev))) { X cursed_book(objects[booktype].spl_lev); X nomul(delay); /* study time */ X delay = 0; X useup(spellbook); X return(1); X } X X You("begin to memorize the runes."); X } X X book = spellbook; X set_occupation(learn, "studying", 0); X return(1); X} X Xstatic int Xgetspell() { X X register int maxs, ilet, i; X char lets[BUFSZ], buf[BUFSZ]; X X if (spl_book[0].sp_id == NO_SPELL) { X X You("don't know any spells right now."); X return(0); X } else { X X for(maxs = 1; (maxs < MAXSPELL) && (spl_book[maxs].sp_id != NO_SPELL); maxs++); X if (maxs >= MAXSPELL) { X X impossible("Too many spells memorized."); X return(0); X } X X for(i = 0; (i < maxs) && (i < 26); buf[++i] = 0) buf[i] = 'a' + i; X for(i = 26; (i < maxs) && (i < 52); buf[++i] = 0) buf[i] = 'A' + i - 26; X X if (maxs == 1) Strcpy(lets, "a"); X else if (maxs < 27) Sprintf(lets, "a-%c", 'a' + maxs - 1); X else if (maxs == 27) Sprintf(lets, "a-z A"); X else Sprintf(lets, "a-z A-%c", 'A' + maxs - 27); X for(;;) { X X pline("Cast which spell? [%s ?] ", lets); X if ((ilet = readchar()) == '?') { X (void) dovspell(); X continue; X } else if ((ilet == '\033')||(ilet == '\n')||(ilet == ' ')) X return(0); X else for(i = 0; buf[i] != 0; i++) if(ilet == buf[i]) return(++i); X You("don't know that spell."); X } X } X} X Xint Xdocast() X{ X register int spell; X X spell = getspell(); X if (!spell) return(0); X X return(spelleffects(spell,FALSE)); X} X Xint Xspelleffects(spell,atme) Xregister int spell; Xboolean atme; X{ X register int energy, damage; X#ifdef HARD X boolean confused = (Confusion != 0); X#endif X struct obj *pseudo; X X#ifdef HARD X /* note that trying to cast it decrements the # of uses, */ X /* even if the mage does not have enough food/energy to use */ X /* the spell */ X switch (spelluses(spell)) { X case 0: X pline ("That spell is too hard to recall at the moment."); X return(0); X case 1: X pline ("You can barely remember the runes of this spell."); X break; X case 2: X pline ("This spell is starting to be over-used."); X break; X default: X break; X } X decrnuses(spell); X#endif X energy = spellev(spell); X if (u.uhave_amulet) { X You("feel the amulet draining your energy away."); X energy *= rnd(6); X } X if(energy > u.uen) { X You("don't have enough energy to cast that spell."); X return(0); X } else if ((u.uhunger <= 100 && spell != SPE_DETECT_FOOD) || X (ACURR(A_STR) < 6)) { X You("lack the strength for that spell."); X return(0); X } else { X if (spell != SPE_DETECT_FOOD) X morehungry(energy * 10); X u.uen -= energy; X } X flags.botl = 1; X X#ifdef HARD X if (confused || X ((int)(ACURR(A_INT) + Luck) - 3 * spellev(spell)) < 0) { X X if (Hallucination) X pline("Far out... a light show!"); X else pline("The air around you crackles as you goof up."); X return(0); X } X#endif X X/* pseudo is a temporary "false" object containing the spell stats. */ X pseudo = mksobj(spellid(spell),FALSE); X pseudo->blessed = pseudo->cursed = 0; X pseudo->quan = 20; /* do not let useup get it */ X switch(pseudo->otyp) { X X/* These spells are all duplicates of wand effects */ X case SPE_FORCE_BOLT: X case SPE_SLEEP: X case SPE_MAGIC_MISSILE: X case SPE_KNOCK: X case SPE_SLOW_MONSTER: X case SPE_WIZARD_LOCK: X case SPE_FIREBALL: X case SPE_CONE_OF_COLD: X case SPE_DIG: X case SPE_TURN_UNDEAD: X case SPE_POLYMORPH: X case SPE_TELEPORT_AWAY: X case SPE_CANCELLATION: X case SPE_FINGER_OF_DEATH: X case SPE_LIGHT: X case SPE_DETECT_UNSEEN: X#ifdef MACOS X if (pseudo->otyp == SPE_DIG) X { X segments |= SEG_SPELL; X } X#endif X if (!(objects[pseudo->otyp].bits & NODIR)) { X if (atme) u.dx = u.dy = u.dz = 0; X else (void) getdir(1); X if(!u.dx && !u.dy && !u.dz) { X if((damage = zapyourself(pseudo))) X losehp(damage, X self_pronoun("zapped %sself with a spell", "him"), X NO_KILLER_PREFIX); X } else weffects(pseudo); X } else weffects(pseudo); X break; X/* These are all duplicates of scroll effects */ X case SPE_CONFUSE_MONSTER: X case SPE_DETECT_FOOD: X case SPE_CAUSE_FEAR: X case SPE_CHARM_MONSTER: X case SPE_REMOVE_CURSE: X case SPE_MAGIC_MAPPING: X case SPE_CREATE_MONSTER: X case SPE_IDENTIFY: X case SPE_GENOCIDE: X (void) seffects(pseudo); X break; X case SPE_HASTE_SELF: X case SPE_DETECT_TREASURE: X case SPE_DETECT_MONSTERS: X case SPE_LEVITATION: X case SPE_RESTORE_ABILITY: X case SPE_INVISIBILITY: X (void) peffects(pseudo); X break; X case SPE_HEALING: X You("feel a bit better."); X healup(rnd(8), 0, 0, 0); X break; X case SPE_CURE_BLINDNESS: X healup(0, 0, 0, 1); X break; X case SPE_CURE_SICKNESS: X if (Sick) You("are no longer ill."); X healup(0, 0, 1, 0); X break; X case SPE_EXTRA_HEALING: X You("feel a fair bit better."); X healup(d(2,8), 1, 0, 0); X break; X case SPE_CREATE_FAMILIAR: X make_familiar((struct obj *)0); X break; X case SPE_CLAIRVOYANCE: X do_vicinity_map(); X break; X default: X impossible("Unknown spell %d attempted.", spell); X obfree(pseudo, (struct obj *)0); X return(0); X } X obfree(pseudo, (struct obj *)0); /* now, get rid of it */ X return(1); X} X Xvoid Xlosespells() { X register boolean confused = (Confusion != 0); X register int n, nzap, i; X X book = 0; X for(n = 0;(spl_book[n].sp_id != NO_SPELL) && (n < MAXSPELL); n++); X if (!n) return; X if (n < MAXSPELL) { X nzap = rnd(n); X if (nzap < n) nzap += confused; X for (i = 0; i < nzap; i++) spl_book[n-i-1].sp_id = NO_SPELL; X } else impossible("Too many spells memorized!"); X return; X} X Xstatic char Xspellet(spl) Xint spl; X{ X return (spl < 27) ? ('a' + spl - 1) : ('A' + spl - 27); X} X Xint Xdovspell() { X X register int maxs, i; X char buf[BUFSZ], any[BUFSZ]; X X if (spl_book[0].sp_id == NO_SPELL) { X X You("don't know any spells right now."); X return 0; X } X X for(maxs = 1; (maxs < MAXSPELL) && (spl_book[maxs].sp_id != NO_SPELL); maxs++); X if (maxs >= MAXSPELL) { X X impossible("Too many spells memorized."); X return 0; X } X morc = 0; /* just to be sure */ X cornline(0, "Currently known spells:"); X X for(i = 1; i <= maxs; i++) { X X#ifdef HARD X Sprintf(buf, "%c %c %s (%d)", X spellet(i), (spelluses(i)) ? '-' : '*', X spellname(i), spellev(i)); X#else X Sprintf(buf, "%c %s (%d)", X spellet(i), X spellname(i), spellev(i)); X#endif X cornline(1, buf); X any[i-1] = spellet(i); X } X any[i-1] = 0; X cornline(2, any); X X return 0; X} X X X#endif /* SPELLS /**/ END_OF_FILE if test 11119 -ne `wc -c <'src/spell.c'`; then echo shar: \"'src/spell.c'\" unpacked with wrong size! fi # end of 'src/spell.c' fi if test -f 'vms/vmstparam.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'vms/vmstparam.c'\" else echo shar: Extracting \"'vms/vmstparam.c'\" \(11344 characters\) sed "s/^X//" >'vms/vmstparam.c' <<'END_OF_FILE' X/* Merge parameters into a termcap entry string. X Copyright (C) 1985, 1987 Free Software Foundation, Inc. X X X NO WARRANTY X X BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY XNO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT XWHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, XRICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS" XWITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, XBUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND XFITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY XAND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE XDEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR XCORRECTION. X X IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. XSTALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY XWHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE XLIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR XOTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE XUSE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR XDATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR XA FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS XPROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH XDAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. X X GENERAL PUBLIC LICENSE TO COPY X X 1. You may copy and distribute verbatim copies of this source file Xas you receive it, in any medium, provided that you conspicuously and Xappropriately publish on each copy a valid copyright notice "Copyright X(C) 1986 Free Software Foundation, Inc."; and include following the Xcopyright notice a verbatim copy of the above disclaimer of warranty Xand of this License. You may charge a distribution fee for the Xphysical act of transferring a copy. X X 2. You may modify your copy or copies of this source file or Xany portion of it, and copy and distribute such modifications under Xthe terms of Paragraph 1 above, provided that you also do the following: X X a) cause the modified files to carry prominent notices stating X that you changed the files and the date of any change; and X X b) cause the whole of any work that you distribute or publish, X that in whole or in part contains or is a derivative of this X program or any part thereof, to be licensed at no charge to all X third parties on terms identical to those contained in this X License Agreement (except that you may choose to grant more extensive X warranty protection to some or all third parties, at your option). X X c) You may charge a distribution fee for the physical act of X transferring a copy, and you may at your option offer warranty X protection in exchange for a fee. X XMere aggregation of another unrelated program with this program (or its Xderivative) on a volume of a storage or distribution medium does not bring Xthe other program under the scope of these terms. X X 3. You may copy and distribute this program (or a portion or derivative Xof it, under Paragraph 2) in object code or executable form under the terms Xof Paragraphs 1 and 2 above provided that you also do one of the following: X X a) accompany it with the complete corresponding machine-readable X source code, which must be distributed under the terms of X Paragraphs 1 and 2 above; or, X X b) accompany it with a written offer, valid for at least three X years, to give any third party free (except for a nominal X shipping charge) a complete machine-readable copy of the X corresponding source code, to be distributed under the terms of X Paragraphs 1 and 2 above; or, X X c) accompany it with the information you received as to where the X corresponding source code may be obtained. (This alternative is X allowed only for noncommercial distribution and only if you X received the program in object code or executable form alone.) X XFor an executable file, complete source code means all the source code for Xall modules it contains; but, as a special exception, it need not include Xsource code for modules which are standard libraries that accompany the Xoperating system on which the executable file runs. X X 4. You may not copy, sublicense, distribute or transfer this program Xexcept as expressly provided under this License Agreement. Any attempt Xotherwise to copy, sublicense, distribute or transfer this program is void and Xyour rights to use the program under this License agreement shall be Xautomatically terminated. However, parties who have received computer Xsoftware programs from you with this License Agreement will not have Xtheir licenses terminated so long as such parties remain in full compliance. X X 5. If you wish to incorporate parts of this program into other free Xprograms whose distribution conditions are different, write to the Free XSoftware Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet Xworked out a simple rule that can be stated here, but we will often permit Xthis. We will be guided by the two goals of preserving the free status of Xall derivatives of our free software and of promoting the sharing and reuse of Xsoftware. X X XIn other words, you are welcome to use, share and improve this program. XYou are forbidden to forbid anyone else to use, share and improve Xwhat you give them. Help stamp out software-hoarding! */ X X X/* config.h may rename various library functions such as malloc. */ X#ifdef emacs X#include "config.h" X#endif X X/* Assuming STRING is the value of a termcap string entry X containing `%' constructs to expand parameters, X merge in parameter values and store result in block OUTSTRING points to. X LEN is the length of OUTSTRING. If more space is needed, X a block is allocated with `malloc'. X X The value returned is the address of the resulting string. X This may be OUTSTRING or may be the address of a block got with `malloc'. X In the latter case, the caller must free the block. X X The fourth and following args to tparam serve as the parameter values. */ X Xstatic char *tparam1 (); X X/* VARARGS 2 */ Xchar * Xtparam (string, outstring, len, arg0, arg1, arg2, arg3) X char *string; X char *outstring; X int len; X int arg0, arg1, arg2, arg3; X{ X#ifdef NO_ARG_ARRAY X int arg[4]; X arg[0] = arg0; X arg[1] = arg1; X arg[2] = arg2; X arg[3] = arg3; X return tparam1 (string, outstring, len, 0, 0, arg); X#else X return tparam1 (string, outstring, len, 0, 0, &arg0); X#endif X} X Xchar *BC; Xchar *UP; X Xstatic char tgoto_buf[50]; X Xchar * Xtgoto (cm, hpos, vpos) X char *cm; X int hpos, vpos; X{ X int args[2]; X if (!cm) X return 0; X args[0] = vpos; X args[1] = hpos; X return tparam1 (cm, tgoto_buf, 50, UP, BC, args); X} X Xstatic char * Xtparam1 (string, outstring, len, up, left, argp) X char *string; X char *outstring; X int len; X char *up, *left; X register int *argp; X{ X register int c; X register char *p = string; X register char *op = outstring; X char *outend; X int outlen = 0; X X register int tem; X int *oargp = argp; X int doleft = 0; X int doup = 0; X X outend = outstring + len; X X while (1) X { X /* If the buffer might be too short, make it bigger. */ X if (op + 5 >= outend) X { X register char *new; X if (outlen == 0) X { X new = (char *) malloc (outlen = 40 + len); X outend += 40; X } X else X { X outend += outlen; X new = (char *) realloc (outstring, outlen *= 2); X } X op += new - outstring; X outend += new - outstring; X outstring = new; X } X if (!(c = *p++)) X break; X if (c == '%') X { X c = *p++; X tem = *argp; X switch (c) X { X case 'd': /* %d means output in decimal */ X if (tem < 10) X goto onedigit; X if (tem < 100) X goto twodigit; X case '3': /* %3 means output in decimal, 3 digits. */ X if (tem > 999) X { X *op++ = tem / 1000 + '0'; X tem %= 1000; X } X *op++ = tem / 100 + '0'; X case '2': /* %2 means output in decimal, 2 digits. */ X twodigit: X tem %= 100; X *op++ = tem / 10 + '0'; X onedigit: X *op++ = tem % 10 + '0'; X argp++; X break; X X case 'C': X /* For c-100: print quotient of value by 96, if nonzero, X then do like %+ */ X if (tem >= 96) X { X *op++ = tem / 96; X tem %= 96; X } X case '+': /* %+x means add character code of char x */ X tem += *p++; X case '.': /* %. means output as character */ X if (left) X { X /* If want to forbid output of 0 and \n and \t, X and this is one of them, increment it. */ X while (tem == 0 || tem == '\n' || tem == '\t') X { X tem++; X if (argp == oargp) X doleft++, outend -= strlen (left); X else X doup++, outend -= strlen (up); X } X } X *op++ = tem | 0200; X case 'f': /* %f means discard next arg */ X argp++; X break; X X case 'b': /* %b means back up one arg (and re-use it) */ X argp--; X break; X X case 'r': /* %r means interchange following two args */ X argp[0] = argp[1]; X argp[1] = tem; X oargp++; X break; X X case '>': /* %>xy means if arg is > char code of x, */ X if (argp[0] > *p++) /* then add char code of y to the arg, */ X argp[0] += *p; /* and in any case don't output. */ X p++; /* Leave the arg to be output later. */ X break; X X case 'a': /* %a means arithmetic */ X /* Next character says what operation. X Add or subtract either a constant or some other arg */ X /* First following character is + to add or - to subtract X or = to assign. */ X /* Next following char is 'p' and an arg spec X (0100 plus position of that arg relative to this one) X or 'c' and a constant stored in a character */ X tem = p[2] & 0177; X if (p[1] == 'p') X tem = argp[tem - 0100]; X if (p[0] == '-') X argp[0] -= tem; X else if (p[0] == '+') X argp[0] += tem; X else if (p[0] == '*') X argp[0] *= tem; X else if (p[0] == '/') X argp[0] /= tem; X else X argp[0] = tem; X X p += 3; X break; X X case 'i': /* %i means add one to arg, */ X argp[0] ++; /* and leave it to be output later. */ X argp[1] ++; /* Increment the following arg, too! */ X break; X X case '%': /* %% means output %; no arg. */ X goto ordinary; X X case 'n': /* %n means xor each of next two args with 140 */ X argp[0] ^= 0140; X argp[1] ^= 0140; X break; X X case 'm': /* %m means xor each of next two args with 177 */ X argp[0] ^= 0177; X argp[1] ^= 0177; X break; X X case 'B': /* %B means express arg as BCD char code. */ X argp[0] += 6 * (tem / 10); X break; X X case 'D': /* %D means weird Delta Data transformation */ X argp[0] -= 2 * (tem % 16); X break; X } X } X else X /* Ordinary character in the argument string. */ X ordinary: X *op++ = c; X } X *op = 0; X while (doleft-- > 0) X strcpy (op, left); X while (doup-- > 0) X strcpy (op, up); X return outstring; X} X X#ifdef DEBUG X Xmain (argc, argv) X int argc; X char **argv; X{ X char buf[50]; X int args[3]; X args[0] = atoi (argv[2]); X args[1] = atoi (argv[3]); X args[2] = atoi (argv[4]); X tparam1 (argv[1], buf, "LEFT", "UP", args); X printf ("%s\n", buf); X return 0; X} X X#endif /* DEBUG */ END_OF_FILE if test 11344 -ne `wc -c <'vms/vmstparam.c'`; then echo shar: \"'vms/vmstparam.c'\" unpacked with wrong size! fi # end of 'vms/vmstparam.c' fi echo shar: End of archive 45 \(of 56\). cp /dev/null ark45isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 56 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone echo Building monst.c from monst.c1 and monst.c2 cat src/monst.c1 src/monst.c2 > src/monst.c else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0