billr@saab.CNA.TEK.COM (Bill Randle) (07/25/89)
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu> Posting-number: Volume 7, Issue 83 Archive-name: NetHack3/Part28 #! /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 28 (of 38)." # Contents: src/attrib.c src/dothrow.c src/end.c src/termcap.c # src/worm.c # Wrapped by billr@saab on Sun Jul 23 21:33:11 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'src/attrib.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/attrib.c'\" else echo shar: Extracting \"'src/attrib.c'\" \(11413 characters\) sed "s/^X//" >'src/attrib.c' <<'END_OF_FILE' X/* X * attrib.c - attribute modification routines. X * X * Copyright 1988, M. Stephenson X */ X/* NetHack may be freely redistributed. See license for details. */ X X#include "hack.h" X Xconst char *plusattr[] = { /* part of the output on gain of attribute */ X X "strong", "smart", "wise", "agile", "tough", "charismatic" X}; X Xconst char *minusattr[] = { /* part of the output on loss of attribute */ X X "weak", "stupid", "foolish", "clumsy", "vulnerable", "ugly" X}; X Xstruct attribs attrmax = { /* max values for the attributes */ X X 118, 18, 18, 18, 18, 18 X}, X attrmin = { /* min values for the attributes */ X X 3, 3, 3, 3, 3, 3 X}; X Xconst struct innate { X X schar ulevel; X long *ability; X char *gainstr, *losestr; X} a_abil[] = { { 0, &(Stealth), "", "" }, X { 0, &(Fast), "", "" }, X { 10, &(Searching), "perceptive", "" }, X { 0, 0, 0, 0 } }, X X b_abil[] = { { 0, &(HPoison_resistance), "", "" }, X { 7, &(Fast), "quick", "slow" }, X { 15, &(Stealth), "stealthy", "" }, X { 0, 0, 0, 0 } }, X X c_abil[] = { { 7, &(Fast), "quick", "slow" }, X { 15, &(Warning), "sensitive", "" }, X { 0, 0, 0, 0 } }, X X e_abil[] = { { 0, &(Fast), "", "" }, X { 0, &(HSee_invisible), "", "" }, X { 0, &(Searching), "", "" }, X { 0, &(HSleep_resistance), "", "" }, X { 0, 0, 0, 0 } }, X X h_abil[] = { { 0, &(HPoison_resistance), "", "" }, X { 15, &(Warning), "sensitive", "" }, X { 0, 0, 0, 0 } }, X X k_abil[] = { { 7, &(Fast), "quick", "slow" }, X { 0, 0, 0, 0 } }, X X p_abil[] = { { 15, &(Warning), "sensitive", "" }, X { 20, &(HFire_resistance), "cool", "warmer" }, X { 0, 0, 0, 0 } }, X X r_abil[] = { { 0, &(Stealth), "", "" }, X { 10, &(Searching), "perceptive", "" }, X { 0, 0, 0, 0 } }, X X s_abil[] = { { 0, &(Fast), "", "" }, X { 15, &(Stealth), "stealthy", "" }, X { 0, 0, 0, 0 } }, X X t_abil[] = { { 10, &(Searching), "perceptive", "" }, X { 20, &(HPoison_resistance), "hardy", "" }, X { 0, 0, 0, 0 } }, X X v_abil[] = { { 0, &(HCold_resistance), "", "" }, X { 0, &(Stealth), "", "" }, X { 7, &(Fast), "quick", "slow" }, X { 0, 0, 0, 0 } }, X X w_abil[] = { { 15, &(Warning), "sensitive", "" }, X { 17, &(HTeleport_control), "controlled","uncontrolled" }, X { 0, 0, 0, 0 } }; X Xconst struct clattr { X X struct attribs base, dist; X schar align, aligntyp; X schar shp, hd, xlev, ndx; X/* According to AD&D, HD for some classes (i.e. Wizard) should be smaller X * (4-sided for wizards). But this is not AD&D, and using the AD&D X * rule here produces an unplayable character. This I have used a minimum X * of an 10-sided hit die for everything. Another AD&D change: wizards get X * a minimum strength of 6 since without one you can't teleport or cast X * spells. --KAA X */ X struct innate *abil; X} a_attr = { { 6, 9, 9, 6, 6, 6 }, /* Archeologist */ X { 20, 20, 20, 10, 20, 10 }, X 10, 1, 13, 10, 14, 2, a_abil }, X X b_attr = { { 15, 6, 6, 14, 15, 5 }, /* Barbarian */ X { 30, 6, 7, 20, 30, 7 }, X 10, -1, 16, 12, 10, 3, b_abil }, X X c_attr = { { 9, 6, 6, 6, 7, 5 }, /* Caveman (fighter) */ X { 30, 6, 7, 20, 30, 7 }, X 0, 1, 16, 10, 10, 3, c_abil }, X X/* X e_attr = { { 13, 13, 14, 6, 14, 6 }, X */ X e_attr = { { 12, 12, 12, 8, 12, 6 }, /* Elf (ranger) */ X { 30, 10, 10, 20, 20, 10 }, X 10, 1, 15, 10, 11, 2, e_abil }, X X h_attr = { { 6, 6, 12, 6, 10, 15 }, /* Healer (druid) */ X { 15, 20, 20, 15, 25, 10 }, X 10, 1, 13, 10, 20, 2, h_abil }, X X k_attr = { { 12, 6, 13, 6, 9, 17 }, /* Knight (paladin) */ X { 20, 15, 15, 10, 20, 10 }, X 10, 1, 16, 10, 10, 3, k_abil }, X X p_attr = { { 6, 6, 9, 6, 6, 6 }, /* Priest (cleric) */ X { 15, 10, 30, 15, 20, 10 }, X 0, 0, 14, 10, 10, 2, p_abil }, X X r_attr = { { 6, 6, 6, 9, 6, 5 }, /* Rogue (thief) */ X { 20, 10, 10, 30, 20, 10 }, X 10, -1, 12, 10, 11, 2, r_abil }, X X s_attr = { { 9, 6, 6, 9, 17, 5 }, /* Samurai (fighter/thief) */ X { 30, 10, 10, 30, 14, 10 }, X 10, 1, 15, 10, 11, 2, s_abil }, X X t_attr = { { 6, 9, 5, 6, 6, 9 }, /* Tourist */ X { 15, 10, 10, 15, 30, 20 }, X 0, 0, 10, 10, 14, 1, t_abil }, X X v_attr = { { 9, 6, 6, 6, 9, 6 }, /* Valkyrie (fighter) */ X { 30, 6, 7, 20, 30, 7 }, X 0, -1, 16, 10, 10, 3, v_abil }, X X w_attr = { { 6, 9, 6, 6, 6, 6 }, /* Wizard (magic-user) */ X { 10, 30, 10, 20, 20, 10 }, X 0, 0, 12, 10, 12, 1, w_abil }, X X X_attr = { { 3, 3, 3, 3, 3, 3 }, X { 20, 15, 15, 15, 20, 15 }, X 0, 0, 12, 10, 14, 1, 0 }; X Xvoid Xadjattrib(ndx, incr, silent) X X int ndx, incr; X boolean silent; X{ X if(!incr) return; X X if(incr > 0) { X if((AMAX(ndx) >= attrmax.a[ndx]) && (ACURR(ndx) == AMAX(ndx))) { X X if(!silent && flags.verbose) X pline("You're already as %s as you can get.", X plusattr[ndx]); X ABASE(ndx) = AMAX(ndx) = attrmax.a[ndx]; /* just in case */ X return; X } X X ABASE(ndx) += incr; X if(ABASE(ndx) > AMAX(ndx)) { X incr = ABASE(ndx) - AMAX(ndx); X AMAX(ndx) += incr; X if(AMAX(ndx) > attrmax.a[ndx]) X AMAX(ndx) = attrmax.a[ndx]; X ABASE(ndx) = AMAX(ndx); X } X } else { X if((AMAX(ndx) <= attrmin.a[ndx]) && (ABASE(ndx) == AMAX(ndx))) { X if(!silent && flags.verbose) X pline("You're already as %s as you can get.", X minusattr[ndx]); X ABASE(ndx) = AMAX(ndx) = attrmin.a[ndx]; /* just in case */ X return; X } X X ABASE(ndx) += incr; X if(ABASE(ndx) < attrmin.a[ndx]) { X incr = ABASE(ndx) - attrmin.a[ndx]; X ABASE(ndx) = attrmin.a[ndx]; X AMAX(ndx) += incr; X if(AMAX(ndx) < attrmin.a[ndx]) X AMAX(ndx) = attrmin.a[ndx]; X } X } X if(!silent) X You("feel %s%s!", X (incr > 1) ? "very ": "", X (incr > 0) ? plusattr[ndx] : minusattr[ndx]); X flags.botl = 1; X return; X} X Xvoid Xgainstr(otmp, incr) X register struct obj *otmp; X register int incr; X{ X int num = 1; X X if(incr) num = incr; X else { X if(ABASE(A_STR) < 18) num = (rn2(4) ? 1 : rnd(6) ); X else if (ABASE(A_STR) < 103) num = rnd(10); X } X adjattrib(A_STR, (otmp && otmp->cursed) ? -num : num, TRUE); X} X Xvoid Xlosestr(num) /* may kill you; cause may be poison or monster like 'a' */ X register int num; X{ X int ustr = ABASE(A_STR) - num; X X while(ustr < 3) { X ustr++; X num--; X u.uhp -= 6; X u.uhpmax -= 6; X } X adjattrib(A_STR, -num, TRUE); X} X Xvoid Xchange_luck(n) X register schar n; X{ X u.uluck += n; X if (u.uluck < 0 && u.uluck < LUCKMIN) u.uluck = LUCKMIN; X if (u.uluck > 0 && u.uluck > LUCKMAX) u.uluck = LUCKMAX; X} X Xint Xstone_luck(parameter) Xboolean parameter; /* So I can't think up of a good name. So sue me. --KAA */ X{ X register struct obj *otmp; X register int bonchance = 0; X X for(otmp = invent; otmp; otmp=otmp->nobj) X if(otmp->otyp == LUCKSTONE) { X if (otmp->cursed) bonchance -= otmp->quan; X else if (otmp->blessed) bonchance += otmp->quan; X else if (parameter) bonchance += otmp->quan; X } X X return sgn(bonchance); X} X Xvoid Xrestore_attrib() { X X int i; X X for(i = 0; i < A_MAX; i++) { /* all temporary losses/gains */ X X if(ATEMP(i) && ATIME(i)) { X if(!(--(ATIME(i)))) { /* countdown for change */ X ATEMP(i) += ATEMP(i) > 0 ? -1 : 1; X X if(ATEMP(i)) /* reset timer */ X ATIME(i) = 100 / ACURR(A_CON); X } X } X } X} X Xstatic struct clattr * Xclx() { X X register struct clattr *attr; X X switch (pl_character[0]) { X X case 'A': attr = &a_attr; X break; X case 'B': attr = &b_attr; X break; X case 'C': attr = &c_attr; X break; X case 'E': attr = &e_attr; X break; X case 'H': attr = &h_attr; X break; X case 'K': attr = &k_attr; X break; X case 'P': attr = &p_attr; X break; X case 'R': attr = &r_attr; X break; X case 'S': attr = &s_attr; X break; X case 'T': attr = &t_attr; X break; X case 'V': attr = &v_attr; X break; X case 'W': attr = &w_attr; X break; X default: /* unknown type */ X attr = &X_attr; X break; X } X return(attr); X} X Xstatic void Xinit_align() { /* called from newhp if u.ulevel is 0 */ X X register struct clattr *attr = clx(); X X u.ualign = (int)attr->align; X u.ualigntyp = attr->aligntyp; X} X Xvoid Xinit_attr(np) X register int np; X{ X register int i, x, tryct; X register struct clattr *attr = clx(); X X for(i = 0; i < A_MAX; i++) { X X ABASE(i) = AMAX(i) = attr->base.a[i]; X ATEMP(i) = ATIME(i) = 0; X np -= attr->base.a[i]; X } X X tryct = 0; X while(np > 0 && tryct < 100) { X X x = rn2(100); X for(i = 0; (i < A_MAX) && ((x -= attr->dist.a[i]) > 0); i++); X if(i >= A_MAX) continue; /* impossible */ X X if(ABASE(i) >= attrmax.a[i]) { X X tryct++; X continue; X } X tryct = 0; X ABASE(i)++; X AMAX(i)++; X np--; X } X X tryct = 0; X while(np < 0 && tryct < 100) { /* for redistribution */ X X x = rn2(100); X for(i = 0; (i < A_MAX) && ((x -= attr->dist.a[i]) > 0); i++); X if(i >= A_MAX) continue; /* impossible */ X X if(ABASE(i) <= attrmin.a[i]) { X X tryct++; X continue; X } X tryct = 0; X ABASE(i)--; X AMAX(i)--; X np++; X } X} X X#ifdef POLYSELF Xvoid Xredist_attr() { X X register int i, tmp; X X for(i = 0; i < A_MAX; i++) { X if (i==A_INT || i==A_WIS) continue; X /* Polymorphing doesn't change your mind */ X tmp = AMAX(i); X AMAX(i) += (rn2(5)-2); X if (AMAX(i) > attrmax.a[i]) AMAX(i) = attrmax.a[i]; X if (AMAX(i) < attrmin.a[i]) AMAX(i) = attrmin.a[i]; X ABASE(i) = ABASE(i) * AMAX(i) / tmp; X /* ABASE(i) > attrmax.a[i] is impossible */ X if (ABASE(i) < attrmin.a[i]) ABASE(i) = attrmin.a[i]; X } X} X#endif X Xvoid Xadjabil(flag) X X int flag; /* +ve/-ve = gain/lose */ X{ X register struct clattr *attr = clx(); X register struct innate *abil = attr->abil; X X if(abil) { X X for(; abil->ability; abil++) { X if ((flag>0 && u.ulevel >= abil->ulevel) || X (flag<0 && u.ulevel < abil->ulevel)) { X if(flag > 0) { X if(!(*(abil->ability) & INTRINSIC)) { X *(abil->ability) |= INTRINSIC; X if(strlen(abil->gainstr)) X You("feel %s!", abil->gainstr); X } X } else { X if((*(abil->ability) & INTRINSIC)) { X *(abil->ability) &= ~INTRINSIC; X if(strlen(abil->losestr)) X You("feel %s!", abil->losestr); X else if(strlen(abil->gainstr)) X You("feel less %s!", abil->gainstr); X } X } X } X } X } X} X Xint Xnewhp() { X register struct clattr *attr = clx(); X int hp, conplus; X X if(u.ulevel == 0) { X X hp = attr->shp; X init_align(); /* initialize alignment stuff */ X return hp; X } else { X X if(u.ulevel < attr->xlev) X hp = rnd(attr->hd); X else X hp = attr->ndx; X } X X switch(ACURR(A_CON)) { X case 3: conplus = -2; break; X case 4: X case 5: X case 6: conplus = -1; break; X case 15: X case 16: conplus = 1; break; X case 17: conplus = 2; break; X case 18: conplus = 3; break; X default: conplus = 0; X } X hp += conplus; X return((hp <= 0) ? 1 : hp); X} X Xschar Xacurr(x) { X register int tmp = (u.abon.a[x] + u.atemp.a[x] + u.acurr.a[x]); X X if (x == A_STR) { X if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER) return(125); X else return((tmp >= 125) ? 125 : (tmp <= 3) ? 3 : tmp); X } X else return((tmp >= 25) ? 25 : (tmp <= 3) ? 3 : tmp); X} X X/* avoid possible problems with alignment overflow, and provide a centralized X * location for any future alignment limits X */ Xvoid Xadjalign(n) Xregister int n; X{ X register int newalign = u.ualign + n; X X if(n < 0) { X if(newalign < u.ualign) X u.ualign = newalign; X } else X if(newalign > u.ualign) X u.ualign = newalign; X} END_OF_FILE if test 11413 -ne `wc -c <'src/attrib.c'`; then echo shar: \"'src/attrib.c'\" unpacked with wrong size! fi # end of 'src/attrib.c' fi if test -f 'src/dothrow.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/dothrow.c'\" else echo shar: Extracting \"'src/dothrow.c'\" \(11169 characters\) sed "s/^X//" >'src/dothrow.c' <<'END_OF_FILE' X/* SCCS Id: @(#)dothrow.c 3.0 88/10/22 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X/* Contains code for 't' (throw) */ X X#include "hack.h" X Xstatic void gem_accept P((struct monst *, struct obj *)); Xstatic int throw_gold P((struct obj *)); Xstatic const char toss_objs[] = { '0', GOLD_SYM, '#', WEAPON_SYM, 0 }; X#ifdef WORM Xextern boolean notonhead; X#endif X Xint Xdothrow() { X register struct obj *obj; X X obj = getobj(toss_objs, "throw"); X /* it is also possible to throw food */ X /* (or jewels, or iron balls... ) */ X X if(!obj || !getdir(1)) { /* ask "in what direction?" */ X if(obj && obj->olet == GOLD_SYM) u.ugold += OGOLD(obj); X return(0); X } X X if(obj->olet == GOLD_SYM) return(throw_gold(obj)); X X if(!canletgo(obj,"throw")) X return(0); X if(obj->otyp == BOULDER X#ifdef POLYSELF X && !throws_rocks(uasmon) X#endif X ) { X pline("It's too heavy."); X return(1); X } X if(!u.dx && !u.dy && !u.dz) { X You("cannot throw an object at yourself."); X return(0); X } X u_wipe_engr(2); X X if(obj == uwep) { X if(welded(obj)) { X weldmsg(obj, FALSE); X return(1); X } X if(obj->quan > 1) X setuwep(splitobj(obj, 1)); X else { X setuwep((struct obj *)0); X if (uwep) return(1); /* unwielded, died, rewielded */ X } X } X else if(obj->quan > 1) X (void) splitobj(obj, 1); X freeinv(obj); X return(throwit(obj)); X} X Xstatic void Xhitfloor(obj) Xregister struct obj *obj; X{ X#ifdef ALTARS X if (IS_ALTAR(levl[u.ux][u.uy].typ)) doaltarobj(obj); X else X#endif X pline("%s hits the floor.", Doname2(obj)); X if (breaks(obj, TRUE)) return; X else if(obj->olet == POTION_SYM) { X pline("The flask breaks, and you smell a peculiar odor..."); X potionbreathe(obj); X obfree(obj, (struct obj *)0); X } else X dropy(obj); X} X Xint Xthrowit(obj) Xregister struct obj *obj; X{ X register struct monst *mon; X register int range; X X if(u.uswallow) { X mon = u.ustuck; X bhitpos.x = mon->mx; X bhitpos.y = mon->my; X } else if(u.dz) { X if(u.dz < 0) { X pline("%s hits the ceiling, then falls back on top of your %s.", X Doname2(obj), /* note: obj->quan == 1 */ X body_part(HEAD)); X if(obj->olet == POTION_SYM) X potionhit(&youmonst, obj); X else { X if(uarmh) pline("Fortunately, you are wearing a helmet!"); X losehp(uarmh ? 1 : rnd((int)(obj->owt)), "falling object"); X if (!breaks(obj, TRUE)) dropy(obj); X } X } else hitfloor(obj); X return(1); X X } else if(obj->otyp == BOOMERANG) { X mon = boomhit(u.dx, u.dy); X if(mon == &youmonst) { /* the thing was caught */ X (void) addinv(obj); X return(1); X } X } else { X if(obj->otyp == PICK_AXE && shkcatch(obj)) X return(1); X X range = (int)((ACURR(A_STR) > 18 ? 20 : ACURR(A_STR))/2 - obj->owt/4); X if (obj == uball) { X if (u.ustuck) range = 1; X else if (range >= 5) range = 5; X } X if (range < 1) range = 1; X X if ((obj->olet == WEAPON_SYM || obj->olet == GEM_SYM) && X uwep && X objects[obj->otyp].w_propellor == X -objects[uwep->otyp].w_propellor) X range++; X#ifdef POLYSELF X if (obj->otyp == BOULDER) range = 20; X#endif X X mon = bhit(u.dx, u.dy, range, obj->olet, X (int (*)()) 0, (int (*)()) 0, obj); X } X if(mon) { X /* awake monster if sleeping */ X wakeup(mon); X#ifdef WORM X if(bhitpos.x != mon->mx || bhitpos.y != mon->my) X notonhead = TRUE; X#endif X if(thitmonst(mon, obj)) return(1); X } X if(!u.uswallow) { X char let = obj->olet; X X /* the code following might become part of dropy() */ X if (breaks(obj, TRUE)) { X tmp_at(-1, let); X tmp_at(-3, (int)AT_OBJ); X tmp_at(bhitpos.x, bhitpos.y); X tmp_at(-1, -1); X return(1); X } X if(flooreffects(obj,bhitpos.x,bhitpos.y)) return(1); X#ifdef WORM X if(obj->otyp == CRYSKNIFE) X obj->otyp = WORM_TOOTH; X#endif X obj->ox = bhitpos.x; X obj->oy = bhitpos.y; X obj->nobj = fobj; X fobj = obj; X levl[bhitpos.x][bhitpos.y].omask = 1; X if(obj->unpaid && costly_spot(bhitpos.x, bhitpos.y)) X subfrombill(obj); X stackobj(obj); X if(obj == uball && X (bhitpos.x != u.ux || bhitpos.y != u.uy)){ X if(u.utrap){ X if(u.utraptype == TT_PIT) X pline("The ball pulls you out of the pit!"); X else if(u.utraptype == TT_WEB) { X pline("The ball pulls you out of the web!"); X pline("The web is destroyed!"); X deltrap(t_at(u.ux,u.uy)); X } else { X register long side = X rn2(3) ? LEFT_SIDE : RIGHT_SIDE; X pline("The ball pulls you out of the bear trap."); X Your("%s %s is severely damaged.", X (side == LEFT_SIDE) ? "left" : "right", X body_part(LEG)); X set_wounded_legs(side, 500+rn2(1000)); X losehp(2, "thrown ball"); X } X u.utrap = 0; X } X unsee(); X u.ux = bhitpos.x - u.dx; X u.uy = bhitpos.y - u.dy; X movobj(uchain,u.ux,u.uy); X setsee(); X spoteffects(); X } X if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y); X } else X mpickobj(u.ustuck,obj); X return(1); X} X Xint Xthitmonst(mon, obj) Xregister struct monst *mon; Xregister struct obj *obj; X{ X register int tmp; /* Base chance to hit */ X X /* Differences from melee weapons: X * X * Dex still gives a bonus, but strength does not. X * Polymorphed players lacking attacks may still throw. X * There's a base -2 to hit. X * No bonuses for fleeing or stunned targets (they don't dodge X * melee blows as readily, but dodging arrows is hard anyway). X * Not affected by traps, etc... X * Certain items which don't in themselves do damage ignore tmp. X */ X tmp = -2 + Luck + mon->data->ac; X#ifdef POLYSELF X if (u.umonnum >= 0) tmp += uasmon->mlevel; X else X#endif X tmp += u.ulevel; X if(ACURR(A_DEX) < 4) tmp -= 3; X else if(ACURR(A_DEX) < 6) tmp -= 2; X else if(ACURR(A_DEX) < 8) tmp -= 1; X else if(ACURR(A_DEX) > 15) tmp += (ACURR(A_DEX) - 15); X X if(mon->msleep) { X mon->msleep = 0; X tmp += 2; X } X if(mon->mfroz) { X tmp += 4; X if(!rn2(10)) mon->mfroz = 0; X } X if (is_orc(mon->data) && pl_character[0]=='E') tmp++; X if (u.uswallow && mon == u.ustuck) tmp += 1000; /* Guaranteed hit */ X X if(obj->olet == GEM_SYM && mon->data->mlet == S_UNICORN) { X if (mon->mtame) X kludge("%s catches and drops the %s.", X Monnam(mon), xname(obj)); X else { X kludge("%s catches the %s.", Monnam(mon), xname(obj)); X gem_accept(mon, obj); X } X return(1); X } X if(obj->olet == WEAPON_SYM || obj->otyp == ROCK || obj->olet == GEM_SYM) { X if(obj->otyp < DART || obj->otyp == ROCK || obj->olet == GEM_SYM) { X if (!uwep || X objects[obj->otyp].w_propellor != X -objects[uwep->otyp].w_propellor) X tmp -= 4; X else tmp += uwep->spe; X } else if(obj->otyp == BOOMERANG) tmp += 4; X tmp += obj->spe; X if(tmp >= rnd(20)) { X if(hmon(mon,obj,1) == TRUE){ X /* mon still alive */ X#ifdef WORM X cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp); X#endif X } else mon = 0; X /* projectiles thrown disappear sometimes */ X if((obj->otyp < BOOMERANG || obj->olet == GEM_SYM) X && rn2(3)) { X /* check bill; free */ X obfree(obj, (struct obj *)0); X return(1); X } X } else miss(xname(obj), mon); X } else if(obj->otyp == HEAVY_IRON_BALL) { X if(obj != uball) tmp += 2; X if(tmp >= rnd(20)) { X if(hmon(mon,obj,1) == FALSE) X mon = 0; /* he died */ X } else miss(xname(obj), mon); X } else if (obj->otyp == BOULDER) { X tmp += 6; /* Likely to hit! */ X if(tmp >= rnd(20)) { X if(hmon(mon,obj,1) == FALSE) X mon = 0; /* he died */ X } else miss(xname(obj), mon); X } else if((obj->otyp == CREAM_PIE X#ifdef POLYSELF X || obj->otyp == BLINDING_VENOM X#endif X ) && ACURR(A_DEX) >= rnd(10)) { X (void) hmon(mon,obj,1); /* can't die from it */ X#ifdef POLYSELF X } else if(obj->otyp == ACID_VENOM && ACURR(A_DEX) >= rnd(10)) { X if(hmon(mon,obj,1) == FALSE) X mon = 0; X#endif X } else if(obj->olet == POTION_SYM && ACURR(A_DEX) >= rnd(15)) { X potionhit(mon, obj); X return(1); X } else { X pline("The %s misses %s.", xname(obj), X cansee(bhitpos.x,bhitpos.y) ? mon_nam(mon) : "it"); X if(obj->olet == FOOD_SYM && X (mon->data->mlet == S_DOG || mon->data->mlet == S_FELINE)) X if(tamedog(mon,obj)) return(1); X } X return(0); X} X Xstatic void Xgem_accept(mon, obj) Xregister struct monst *mon; Xregister struct obj *obj; X{ X char buf[BUFSZ]; X static const char nogood[] = " is not interested in your junk."; X static const char maybeluck[] = " hesitatingly accepts your gift."; X static const char addluck[] = " graciously accepts your gift."; X X Strcpy(buf,Monnam(mon)); X X mon->mpeaceful = 1; X if(obj->dknown && objects[obj->otyp].oc_name_known) { X if(objects[obj->otyp].g_val > 0) { X if(mon->data == &mons[ X ((u.ualigntyp== U_CHAOTIC) ? PM_BLACK_UNICORN : X (u.ualigntyp == U_LAWFUL) ? PM_WHITE_UNICORN X : PM_GREY_UNICORN)]) { X Strcat(buf, addluck); X change_luck(5); X } else { X Strcat(buf, maybeluck); X change_luck(rn2(7)-3); X } X } else { X Strcat(buf,nogood); X goto nopick; X } X } else { /* value unknown to @ */ X change_luck(1); X Strcat(buf,addluck); X } X mpickobj(mon, obj); Xnopick: X if(!Blind) pline(buf); X rloc(mon); X} X X/* returns 0 if object doesn't break */ X/* returns 1 if object broke */ Xint Xbreaks(obj, loose) Xregister struct obj *obj; Xregister boolean loose; /* if not loose, obj is in fobj chain */ X{ X switch(obj->otyp) { X#ifdef MEDUSA X case MIRROR: X change_luck(-2); /* and fall through */ X#endif X case EXPENSIVE_CAMERA: X case CRYSTAL_BALL: X if(!Blind) X pline("%s shatters into a thousand pieces!", X Doname2(obj)); X else You("hear something shatter!"); X break; X case EGG: X pline("Splat!"); X break; X case CREAM_PIE: X pline("What a mess!"); X break; X case ACID_VENOM: X case BLINDING_VENOM: X pline("Splash!"); X break; X default: X return 0; X } X X if(loose) { X unpobj(obj); X obfree(obj, (struct obj *)0); X } else { X addtobill(obj, FALSE); X delobj(obj); X } X return(1); X} X Xstatic boolean Xmartial() X{ X return((pl_character[0] == 'S' || pl_character[0] == 'P')); X} X Xstatic int Xthrow_gold(obj) Xstruct obj *obj; X{ X int range = 0, odx, ody; X long zorks = OGOLD(obj); X register struct monst *mon; X X free((genericptr_t) obj); X if(zorks < 0) { X /* watch negative overflows a la drop() */ X u.ugold += zorks; X pline("The LRS would be very interested to know you have that much."); X return(0); X } X X if(u.uswallow) { X pline("The gold disappears in the %s's entrails.", X mon_nam(u.ustuck)); X u.ustuck->mgold += zorks; X return(1); X } X X if(u.dz) { X if(u.dz < 0) { X pline("The gold hits the ceiling, then falls back on top of your %s.", X body_part(HEAD)); X /* some self damage? */ X if(uarmh) pline("Fortunately, you are wearing a helmet!"); X } else pline("The gold hits the floor."); X bhitpos.x = u.ux; /* a msg is needed here */ X bhitpos.y = u.uy; X goto skip; X } X X range = rnd((int)ACURR(A_STR)); X if(martial()) range = range + rnd(3); X X /* see if the gold has a place to move into */ X odx = u.ux + u.dx; X ody = u.uy + u.dy; X if(bad_kick_throw_pos(odx,ody)) { X bhitpos.x = u.ux; X bhitpos.y = u.uy; X } else { X if (mon = ghit(u.dx, u.dy, range)) X if (ghitm(mon, zorks)) /* was it caught? */ X zorks = 0; X } Xskip: X if (zorks) /* perhaps it was caught */ X mkgold(zorks, bhitpos.x, bhitpos.y); X if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y); X return(1); X} END_OF_FILE if test 11169 -ne `wc -c <'src/dothrow.c'`; then echo shar: \"'src/dothrow.c'\" unpacked with wrong size! fi # end of 'src/dothrow.c' fi if test -f 'src/end.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/end.c'\" else echo shar: Extracting \"'src/end.c'\" \(11591 characters\) sed "s/^X//" >'src/end.c' <<'END_OF_FILE' X/* SCCS Id: @(#)end.c 3.0 88/05/03 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X#ifndef TOS X#include <signal.h> X#endif X X/* block some unused #defines to avoid overloading some cpp's */ X#define MONATTK_H X#include "hack.h" X X#include "eshk.h" X Xvoid end_box_display(); X Xint Xdone1() X{ X#ifndef TOS X (void) signal(SIGINT,SIG_IGN); X#endif X if(flags.ignintr) { X#ifndef TOS X (void) signal(SIGINT, (SIG_RET_TYPE) done1); X#endif X clrlin(); X curs_on_u(); X (void) fflush(stdout); X if(multi > 0) nomul(0); X return 0; X } X return done2(); X} X Xint Xdone2() X{ X pline("Really quit? "); X if(yn() == 'n') { X#ifndef TOS X (void) signal(SIGINT, (SIG_RET_TYPE) done1); X#endif X clrlin(); X curs_on_u(); X (void) fflush(stdout); X if(multi > 0) nomul(0); X return 0; X } X#if defined(WIZARD) && defined(UNIX) X if(wizard) { X pline("Dump core? "); X if(yn() == 'y') { X (void) signal(SIGINT, (SIG_RET_TYPE) done1); X settty(NULL); X#ifdef SYSV X (void) X#endif X abort(); X } X } X#endif X#ifndef LINT X done("quit"); X#endif X return 0; X} X Xstatic Xint Xdone_intr(){ X done_stopprint++; X#ifndef TOS X (void) signal(SIGINT, SIG_IGN); X#ifdef UNIX X (void) signal(SIGQUIT, SIG_IGN); X#endif X#endif /* TOS /* */ X return 0; X} X X#ifdef UNIX Xstatic Xint Xdone_hangup(){ X done_hup++; X (void)signal(SIGHUP, SIG_IGN); X (void)done_intr(); X return 0; X} X#endif X Xvoid Xdone_in_by(mtmp) Xregister struct monst *mtmp; X{ X char buf[BUFSZ]; X X You("die..."); X buf[0] = '\0'; X if (mtmp->minvis) X Sprintf(eos(buf), "invisible "); X if (Hallucination) X Sprintf(eos(buf), "hallucinogen-distorted "); X X if(mtmp->data->mlet == S_GHOST) { X register char *gn = (char *) mtmp->mextra; X if (!Hallucination && !mtmp->minvis && *gn) X Sprintf(eos(buf), "the "); X Sprintf(eos(buf), (*gn ? "ghost of %s" : "ghost%s"), gn); X } else if(mtmp->isshk) { X Sprintf(eos(buf), "%s %s, the shopkeeper", X (ESHK(mtmp)->ismale ? "Mr." : "Ms."), shkname(mtmp)); X } else if (mtmp->iswiz) X Sprintf(eos(buf), "the %s", mons[PM_WIZARD_OF_YENDOR].mname); X else Sprintf(eos(buf), "%s", mtmp->data->mname); X if (mtmp->mnamelth) Sprintf(eos(buf), " called %s", NAME(mtmp)); X killer = buf; X if (mtmp->data->mlet == S_WRAITH) X u.ugrave_arise = PM_WRAITH; X else if (mtmp->data->mlet == S_MUMMY) X u.ugrave_arise = (pl_character[0]=='E') ? X PM_ELF_MUMMY : PM_HUMAN_MUMMY; X else if (mtmp->data->mlet == S_VAMPIRE) X u.ugrave_arise = PM_VAMPIRE; X if (u.ugrave_arise > -1 && (mons[u.ugrave_arise].geno & G_GENOD)) X u.ugrave_arise = -1; X if (mtmp->data->mlet == S_COCKATRICE) X done("stoned"); X else X done("died"); X return; X} X X/*VARARGS1*/ Xboolean panicking; Xextern boolean hu; /* from save.c */ X Xvoid Xpanic(str,a1,a2,a3,a4,a5,a6) Xchar *str; X{ X if(panicking++) X#ifdef SYSV X (void) X#endif X abort(); /* avoid loops - this should never happen*/ X /* was exit(1) */ X home(); cls(); X (void) puts(" Suddenly, the dungeon collapses."); X#ifdef WIZARD X# ifndef MSDOS X if(!wizard) { X pline("Report error to %s and it may be possible to rebuild.",WIZARD); X more(); X } X Sprintf (SAVEF, "%s.e", SAVEF); X hu = FALSE; X (void) dosave0(); X# endif X#endif X (void) fputs(" ERROR: ", stdout); X Printf(str,a1,a2,a3,a4,a5,a6); X more(); /* contains a fflush() */ X#ifdef WIZARD X# ifdef UNIX X if (wizard) X# ifdef SYSV X (void) X# endif X abort(); /* generate core dump */ X# endif X#endif X done("panicked"); X} X X/* called with arg "died", "drowned", "escaped", "quit", "choked", "panicked", X "burned", "starved", "stoned", or "tricked" */ X/* Be careful not to call panic from here! */ Xvoid Xdone(st1) Xregister char *st1; X{ X struct permonst *upmon; X char buf[BUFSZ], buf1[BUFSZ], buf2[BUFSZ]; X char c; X boolean taken; X#ifdef WIZARD X if (wizard && *st1=='t') { X You("are a very tricky wizard, it seems."); X return; X } X#endif X if(Lifesaved && index("bcds", *st1)){ X u.uswldtim = 0; X if(u.uhpmax < 0) u.uhpmax = 10; /* arbitrary */ X u.uhp = u.uhpmax; X adjattrib(A_CON, -1, TRUE); X pline("But wait..."); X makeknown(AMULET_OF_LIFE_SAVING); X Your("medallion %s!", X !Blind ? "begins to glow" : "feels warm"); X You("feel much better!"); X pline("The medallion crumbles to dust!"); X useup(uamul); X Lifesaved = 0; X if (u.uhunger < 500) u.uhunger = 500; X nomovemsg = "You survived that attempt on your life."; X curs_on_u(); X flags.move = 0; X if(multi > 0) multi = 0; else multi = -1; X flags.botl = 1; X u.ugrave_arise = -1; X if (!strncmp(killer, "genocide", 8)) { X pline("Unfortunately you are still genocided..."); X done("died"); X } X return; X } X#if defined(WIZARD) || defined(EXPLORE_MODE) X if((wizard || discover) && index("bcds", *st1)){ X pline("Die? "); X if(yn() == 'y') goto die; X u.uswldtim = 0; X if(u.uhpmax < 0) u.uhpmax = 100; /* arbitrary */ X u.uhp = u.uhpmax; X if (u.uhunger < 500) u.uhunger = 500; X pline("Ok, so you don't die."); X nomovemsg = "You survived that attempt on your life."; X curs_on_u(); X flags.move = 0; X if(multi > 0) multi = 0; else multi = -1; X flags.botl = 1; X u.ugrave_arise = -1; X return; X } X#endif /* WIZARD || EXPLORE_MODE */ Xdie: X#ifndef TOS X (void) signal(SIGINT, (SIG_RET_TYPE) done_intr); X#ifdef UNIX X (void) signal(SIGQUIT, (SIG_RET_TYPE) done_intr); X (void) signal(SIGHUP, (SIG_RET_TYPE) done_hangup); X#endif X#endif /* TOS /* */ X upmon = player_mon(); X if(u.ugrave_arise > -1) /* create no corpse */ ; X else if(*st1 == 's' && st1[2] == 'o') X (mk_named_object(STATUE, upmon, u.ux, u.uy, plname, X strlen(plname)))->spe = 0; X else X (void) mk_named_object(CORPSE, upmon, u.ux, u.uy, plname, X strlen(plname)); X if(*st1 == 'q' && u.uhp < 1){ X st1 = "died"; X killer = "quit while already on Charon's boat"; X } X if(*st1 == 's' && st1[2] == 'a') killer = "starvation"; else X if(*st1 == 'd' && st1[1] == 'r') killer = "drowning"; else X if(*st1 == 'p') killer = "panic"; else X if(*st1 == 't') killer = "trickery"; else X if(!index("bcds", *st1)) killer = st1; X taken = paybill(); X paygd(); X clearlocks(); X if(flags.toplin == 1) more(); X X if(invent) { X if(taken) X pline("Do you want to see what you had when you %s? ", X (*st1=='q') ? "quit" : "died"); X else X pline("Do you want your possessions identified? "); X /* New dump format by maartenj@cs.vu.nl */ X if ((c = yn_function(ynqchars,'y')) == 'y') { X struct obj *obj; X X for(obj = invent; obj && !done_stopprint; obj = obj->nobj) { X makeknown(obj->otyp); X obj->known = obj->bknown = obj->dknown = 1; X } X doinv(NULL); X end_box_display(); X } X if (c == 'q') done_stopprint++; X if (taken) { X /* paybill has already given the inventory locations in the shop X * and put it on the main object list X */ X struct obj *obj; X X for(obj = invent; obj; obj = obj->nobj) { X obj->owornmask = 0; X if(rn2(5)) curse(obj); X } X invent = (struct obj *) 0; X } X } X X if(index("bcds", *st1)){ X#ifdef WIZARD X if(wizard) { X pline("Save bones? "); X if(yn() == 'y') savebones(); X } else X#endif X savebones(); X if(!flags.notombstone) outrip(); X } X if(*st1 == 'c') killer = st1; /* after outrip() */ X if(*st1 == 's' && st1[2] == 'o') { X Sprintf(buf, "turned to stone by %s",killer); X /* No a or an; topten.c will do that. */ X killer = buf; X st1 = "turned to stone"; X } X Strcpy(buf1, st1); X if(u.uhave_amulet) Strcat(killer," (with the Amulet)"); X settty(NULL); /* does a clear_screen() */ X Strcpy(buf2, plname); X if('a' <= buf2[0] && buf2[0] <= 'z') buf2[0] += 'A'-'a'; X if(!done_stopprint) X Printf("Goodbye %s the %s...\n\n", buf2, X#ifdef ENDGAME X *st1 != 'a' ? pl_character : "Demigod"); X#else X pl_character); X#endif X { long int tmp; X tmp = u.ugold - u.ugold0; X if(tmp < 0) X tmp = 0; X if(*st1 == 'd' || *st1 == 'b') X tmp -= tmp/10; X u.urexp += tmp; X u.urexp += 50 * maxdlevel; X if(maxdlevel > 20) X u.urexp += 1000*((maxdlevel > 30) ? 10 : maxdlevel - 20); X#ifdef ENDGAME X if(*st1 == 'a') u.urexp *= 2; X#endif X } X if(*st1 == 'e') { X register struct monst *mtmp; X register struct obj *otmp; X long i; X register unsigned int worthlessct = 0; X X killer = st1; X keepdogs(); X mtmp = mydogs; X if(mtmp) { X if(!done_stopprint) Printf("You"); X while(mtmp) { X if(!done_stopprint) X Printf(" and %s", mon_nam(mtmp)); X if(mtmp->mtame) X u.urexp += mtmp->mhp; X mtmp = mtmp->nmon; X } X if(!done_stopprint) X Printf("\nescaped from the dungeon with %ld points,\n", X u.urexp); X } else X if(!done_stopprint) X Printf("You escaped from the dungeon with %ld points,\n", X u.urexp); X get_all_from_box(); /* don't forget things in boxes and bags */ X for(otmp = invent; otmp; otmp = otmp->nobj) { X if(otmp->olet == GEM_SYM && otmp->otyp < LUCKSTONE) { X makeknown(otmp->otyp); X i = (long) otmp->quan * X objects[otmp->otyp].g_val; X if(i == 0) { X worthlessct += otmp->quan; X continue; X } X u.urexp += i; X Printf(" %s (worth %ld Zorkmids),\n", X doname(otmp), i); X } else if(otmp->olet == AMULET_SYM) { X otmp->known = 1; X i = (otmp->spe < 0) ? 2 : X otmp->otyp == AMULET_OF_YENDOR ? X 5000 : 500; X u.urexp += i; X Printf(" %s (worth %ld Zorkmids),\n", X doname(otmp), i); X } X } X if(worthlessct) X Printf(" %u worthless piece%s of colored glass,\n", X worthlessct, plur((long)worthlessct)); X if(u.uhave_amulet) killer = "escaped (with Amulet)"; X else killer = "escaped"; X } else X if(!done_stopprint) { X Printf("You %s ", X !strcmp(st1, "tricked") ? "were tricked" : st1); X#ifdef ENDGAME X if (*st1 != 'a') { X if(dlevel == ENDLEVEL) X Printf("in the endgame "); X else Printf("on dungeon level %d ", dlevel); X } X#else X Printf("on dungeon level %d ", dlevel); X#endif X Printf("with %ld points,\n", u.urexp); X } X if(!done_stopprint) X Printf("and %ld piece%s of gold, after %ld move%s.\n", X u.ugold, plur(u.ugold), moves, plur(moves)); X if(!done_stopprint) X Printf("You were level %u with a maximum of %d hit points when you %s.\n", X u.ulevel, u.uhpmax, buf1); X if(*st1 == 'e' && !done_stopprint){ X getret(); /* all those pieces of coloured glass ... */ X cls(); X } X#if defined(WIZARD) || defined(EXPLORE_MODE) X if(wizard || discover) X Printf("\nSince you were in %s mode, the score list \ Xwill not be checked.\n", wizard ? "wizard" : "discover"); X else X#endif X topten(); X/* "So when I die, the first thing I will see in Heaven is a score list?" */ X if(done_stopprint) Printf("\n\n"); X#ifdef APOLLO X getret(); X#endif X exit(0); X} X Xvoid Xclearlocks(){ X#if defined(DGK) && !defined(TOS) X eraseall(levels, alllevels); X if (ramdisk) X eraseall(permbones, alllevels); X#else X#if defined(UNIX) || (defined(MSDOS) && !defined(TOS)) X register int x; X#ifdef UNIX X (void) signal(SIGHUP,SIG_IGN); X#endif X for(x = maxdlevel; x >= 0; x--) { X glo(x); X (void) unlink(lock); /* not all levels need be present */ X } X#endif X#endif X} X X#ifdef NOSAVEONHANGUP Xint Xhangup() X{ X (void) signal(SIGINT, SIG_IGN); X clearlocks(); X exit(1); X} X#endif X Xvoid Xend_box_display() X{ X register struct obj *box, *obj; X char buf[BUFSZ]; X X for(box=invent; box; box=box->nobj) { X if (Is_container(box) && box->otyp != BAG_OF_TRICKS) { X int cnt=0; X X for(obj=fcobj; obj; obj=obj->nobj) { X if (obj->cobj == box) { X if (!cnt) { X Sprintf(buf, "Contents of the %s:",xname(box)); X cornline(0, buf); X } X makeknown(obj->otyp); X obj->known = obj->bknown = obj->dknown = 1; X cornline(1,doname(obj)); X cnt++; X } X } X if (!cnt) pline("The %s is empty.", xname(box)); X else cornline(2,""); X } X } X} END_OF_FILE if test 11591 -ne `wc -c <'src/end.c'`; then echo shar: \"'src/end.c'\" unpacked with wrong size! fi # end of 'src/end.c' fi if test -f 'src/termcap.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/termcap.c'\" else echo shar: Extracting \"'src/termcap.c'\" \(11334 characters\) sed "s/^X//" >'src/termcap.c' <<'END_OF_FILE' X/* SCCS Id: @(#)termcap.c 3.0 88/11/20 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X#include <ctype.h> /* for isdigit() */ X X/* block some unused #defines to avoid overloading some cpp's */ X#define MONATTK_H X#include "hack.h" /* for ROWNO, COLNO, *HI, *HE, *AS, *AE */ X X#if !defined(SYSV) || defined(TOS) || defined(UNIXPC) X# ifndef LINT Xextern /* it is defined in libtermlib (libtermcap) */ X# endif X short ospeed; /* terminal baudrate; used by tputs */ X#else Xshort ospeed = 0; /* gets around "not defined" error message */ X#endif X Xstatic void nocmov(); X#ifdef MSDOSCOLOR Xstatic void init_hilite(); X#endif /* MSDOSCOLOR */ X Xstatic char tbuf[512]; Xstatic char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE; Xstatic char *VS, *VE, *US, *UE; Xstatic char *MR, *ME; X#if 0 Xstatic char *MB, *MD, *MH; X#endif Xstatic int SG; Xstatic char PC = '\0'; X X#if defined(MSDOS) && !defined(TERMLIB) Xstatic char tgotobuf[20]; X#ifdef TOS X#define tgoto(fmt, x, y) (Sprintf(tgotobuf, fmt, y+' ', x+' '), tgotobuf) X#else X#define tgoto(fmt, x, y) (Sprintf(tgotobuf, fmt, y+1, x+1), tgotobuf) X#endif X#endif /* MSDOS /**/ X Xvoid Xstartup() X{ X#ifdef TOS X HO = "\033H"; X CL = "\033E"; /* the VT52 termcap */ X CE = "\033K"; X UP = "\033A"; X CM = "\033Y%c%c"; /* used with function tgoto() */ X ND = "\033C"; X XD = "\033B"; X BC = "\033D"; X SO = "\033p"; X SE = "\033q"; X HI = "\033p"; X HE = "\033q"; X#else X register char *term; X register char *tptr; X char *tbufptr, *pc; X register int i; X X tptr = (char *) alloc(1024); X X tbufptr = tbuf; X if(!(term = getenv("TERM"))) X# ifdef ANSI_DEFAULT X { X HO = "\033[H"; X CL = "\033[2J"; /* the ANSI termcap */ X/* CD = "\033[J"; */ X CE = "\033[K"; X CM = "\033[%i%d;%dH"; X UP = "\033[A"; X ND = "\033[C"; X XD = "\033[B"; X BC = "\033[D"; X HI = SO = "\033[1m"; X US = "\033[4m"; X TI = HE = SE = UE = "\033[0m"; X /* strictly, SE should be 2, and UE should be 24, X but we can't trust all ANSI emulators to be X that complete. -3. */ X AS = "\016"; X AE = "\017"; X VS = VE = ""; X } else { X# else X error("Can't get TERM."); X# endif X if(!strncmp(term, "5620", 4)) X flags.nonull = 1; /* this should be a termcap flag */ X if(tgetent(tptr, term) < 1) X error("Unknown terminal type: %s.", term); X if(pc = tgetstr("pc", &tbufptr)) X PC = *pc; X#ifdef TERMINFO X if(!(BC = tgetstr("le", &tbufptr))) { X#else X if(!(BC = tgetstr("bc", &tbufptr))) { X#endif X#if !defined(MINIMAL_TERM) && !defined(HISX) X if(!tgetflag("bs")) X error("Terminal must backspace."); X#endif X BC = tbufptr; X tbufptr += 2; X *BC = '\b'; X } X#ifdef MINIMAL_TERM X HO = NULL; X#else X HO = tgetstr("ho", &tbufptr); X#endif X CO = tgetnum("co"); X LI = tgetnum("li"); X if(CO < COLNO || LI < ROWNO+2) X setclipped(); X if(!(CL = tgetstr("cl", &tbufptr))) X error("Hack needs CL."); X ND = tgetstr("nd", &tbufptr); X if(tgetflag("os")) X error("Hack can't have OS."); X CE = tgetstr("ce", &tbufptr); X UP = tgetstr("up", &tbufptr); X /* It seems that xd is no longer supported, and we should use X a linefeed instead; unfortunately this requires resetting X CRMOD, and many output routines will have to be modified X slightly. Let's leave that till the next release. */ X XD = tgetstr("xd", &tbufptr); X/* not: XD = tgetstr("do", &tbufptr); */ X if(!(CM = tgetstr("cm", &tbufptr))) { X if(!UP && !HO) X error("Hack needs CM or UP or HO."); X Printf("Playing hack on terminals without cm is suspect...\n"); X getret(); X } X SO = tgetstr("so", &tbufptr); X SE = tgetstr("se", &tbufptr); X US = tgetstr("us", &tbufptr); X UE = tgetstr("ue", &tbufptr); X SG = tgetnum("sg"); /* -1: not fnd; else # of spaces left by so */ X if(!SO || !SE || (SG > 0)) SO = SE = US = UE = ""; X TI = tgetstr("ti", &tbufptr); X TE = tgetstr("te", &tbufptr); X VS = VE = ""; X#if 0 X MB = tgetstr("mb", &tbufptr); /* blink */ X MD = tgetstr("md", &tbufptr); /* boldface */ X MH = tgetstr("mh", &tbufptr); /* dim */ X#endif X MR = tgetstr("mr", &tbufptr); /* reverse */ X ME = tgetstr("me", &tbufptr); X X /* Get rid of padding numbers for HI and HE. Hope they X * aren't really needed!!! HI and HE are ouputted to the X * pager as a string - so how can you send it NULLS??? X * -jsb X */ X HI = (char *) alloc((unsigned)(strlen(SO)+1)); X HE = (char *) alloc((unsigned)(strlen(SE)+1)); X i = 0; X while(isdigit(SO[i])) i++; X Strcpy(HI, &SO[i]); X i = 0; X while(isdigit(SE[i])) i++; X Strcpy(HE, &SE[i]); X AS = tgetstr("as", &tbufptr); X AE = tgetstr("ae", &tbufptr); X CD = tgetstr("cd", &tbufptr); X# ifdef ANSI_DEFAULT X } X# endif X set_whole_screen(); /* uses LI and CD */ X if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n"); X free((genericptr_t)tptr); X#ifdef MSDOSCOLOR X init_hilite(); X#endif X#endif /* TOS /* */ X} X Xvoid Xstart_screen() X{ X xputs(TI); X xputs(VS); X#ifdef DECRAINBOW X /* Select normal ASCII and line drawing character sets. X */ X if (flags.DECRainbow) { X xputs("\033(B\033)0"); X if (!AS) { X AS = "\016"; X AE = "\017"; X } X } X#endif /* DECRAINBOW */ X} X Xvoid Xend_screen() X{ X clear_screen(); X xputs(VE); X xputs(TE); X} X X/* Cursor movements */ X Xvoid Xcurs(x, y) Xregister int x, y; /* not xchar: perhaps xchar is unsigned and X curx-x would be unsigned as well */ X{ X X if (y == cury && x == curx) X return; X if(!ND && (curx != x || x <= 3)) { /* Extremely primitive */ X cmov(x, y); /* bunker!wtm */ X return; X } X if(abs(cury-y) <= 3 && abs(curx-x) <= 3) X nocmov(x, y); X else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) { X (void) putchar('\r'); X curx = 1; X nocmov(x, y); X } else if(!CM) { X nocmov(x, y); X } else X cmov(x, y); X} X Xstatic void Xnocmov(x, y) X{ X if (cury > y) { X if(UP) { X while (cury > y) { /* Go up. */ X xputs(UP); X cury--; X } X } else if(CM) { X cmov(x, y); X } else if(HO) { X home(); X curs(x, y); X } /* else impossible("..."); */ X } else if (cury < y) { X if(XD) { X while(cury < y) { X xputs(XD); X cury++; X } X } else if(CM) { X cmov(x, y); X } else { X while(cury < y) { X xputc('\n'); X curx = 1; X cury++; X } X } X } X if (curx < x) { /* Go to the right. */ X if(!ND) cmov(x, y); else /* bah */ X /* should instead print what is there already */ X while (curx < x) { X xputs(ND); X curx++; X } X } else if (curx > x) { X while (curx > x) { /* Go to the left. */ X xputs(BC); X curx--; X } X } X} X Xvoid Xcmov(x, y) Xregister int x, y; X{ X xputs(tgoto(CM, x-1, y-1)); X cury = y; X curx = x; X} X Xvoid Xxputc(c) Xchar c; X{ X (void) fputc(c, stdout); X} X Xvoid Xxputs(s) Xchar *s; X{ X#if defined(MSDOS) && !defined(TERMLIB) X (void) fputs(s, stdout); X#else X# ifdef __STDC__ X tputs(s, 1, (int (*)())xputc); X# else X tputs(s, 1, xputc); X# endif X#endif X} X Xvoid Xcl_end() { X if(CE) X xputs(CE); X else { /* no-CE fix - free after Harold Rynes */ X /* this looks terrible, especially on a slow terminal X but is better than nothing */ X register int cx = curx, cy = cury; X X while(curx < COLNO) { X xputc(' '); X curx++; X } X curs(cx, cy); X } X} X Xvoid Xclear_screen() { X xputs(CL); X home(); X} X Xvoid Xhome() X{ X if(HO) X xputs(HO); X else if(CM) X xputs(tgoto(CM, 0, 0)); X else X curs(1, 1); /* using UP ... */ X curx = cury = 1; X} X Xvoid Xstandoutbeg() X{ X if(SO) xputs(SO); X} X Xvoid Xstandoutend() X{ X if(SE) xputs(SE); X} X Xvoid Xrevbeg() X{ X if(MR) xputs(MR); X} X X#if 0 /* if you need one of these, uncomment it (here and in extern.h) */ Xvoid Xboldbeg() X{ X if(MD) xputs(MD); X} X Xvoid Xblinkbeg() X{ X if(MB) xputs(MB); X} X Xvoid Xdimbeg() X/* not in most termcap entries */ X{ X if(MH) xputs(MH); X} X#endif X Xvoid Xm_end() X{ X if(ME) xputs(ME); X} X Xvoid Xbacksp() X{ X xputs(BC); X} X Xvoid Xbell() X{ X if (flags.silent) return; X (void) putchar('\007'); /* curx does not change */ X (void) fflush(stdout); X} X Xvoid Xgraph_on() { X if (AS) xputs(AS); X} X Xvoid Xgraph_off() { X if (AE) xputs(AE); X} X X#ifndef MSDOS Xstatic const short tmspc10[] = { /* from termcap */ X 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5 X}; X#endif X Xvoid Xdelay_output() { X /* delay 50 ms - could also use a 'nap'-system call */ X /* BUG: if the padding character is visible, as it is on the 5620 X then this looks terrible. */ X#ifdef MSDOS X /* simulate the delay with "cursor here" */ X register int i; X for (i = 0; i < 3; i++) { X cmov(curx, cury); X (void) fflush(stdout); X } X#else /* MSDOS /**/ X if(!flags.nonull) X#ifdef TERMINFO X /* cbosgd!cbcephus!pds for SYS V R2 */ X# ifdef __STDC__ X tputs("$<50>", 1, (int (*)())xputc); X# else X tputs("$<50>", 1, xputc); X# endif X#else X tputs("50", 1, xputs); X#endif X X else if(ospeed > 0 || ospeed < SIZE(tmspc10)) if(CM) { X /* delay by sending cm(here) an appropriate number of times */ X register int cmlen = strlen(tgoto(CM, curx-1, cury-1)); X register int i = 500 + tmspc10[ospeed]/2; X X while(i > 0) { X cmov(curx, cury); X i -= cmlen*tmspc10[ospeed]; X } X } X#endif /* MSDOS /**/ X} X Xvoid Xcl_eos() /* free after Robert Viduya */ X{ /* must only be called with curx = 1 */ X X if(CD) X xputs(CD); X else { X register int cx = curx, cy = cury; X while(cury <= LI-2) { X cl_end(); X xputc('\n'); X curx = 1; X cury++; X } X cl_end(); X curs(cx, cy); X } X} X X#ifdef MSDOSCOLOR X/* Sets up highlighting, using ANSI escape sequences, for monsters, X * objects, and gold (highlight code found in pri.c). X * The termcap entry for HI (from SO) is scanned to find the background X * color. If everything is OK, monsters are displayed in the color X * used to define HILITE_MONSTER, objects are displayed in the color X * used to define HILITE_OBJECT, and gold is displayed in the color X * used to define HILITE_GOLD. -3. */ X X#define ESC 0x1b X#define NONE 0 X#define HIGH_INTENSITY 1 X#define BLACK 0 X#define RED 1 X#define GREEN 2 X#define YELLOW 3 X#define BLUE 4 X#define MAGENTA 5 X#define CYAN 6 X#define WHITE 7 X X#define HILITE_ATTRIB HIGH_INTENSITY X Xstatic void Xinit_hilite() X{ X int backg = BLACK, foreg = WHITE, len; X register int c, color; X X HI_RED = HI_YELLOW = HI_GREEN = HI_BLUE = HI_WHITE = HI; X X /* find the background color, HI[len] == 'm' */ X len = strlen(HI) - 1; X X if (HI[len] != 'm' || len < 3) return; X X c = 2; X while (c < len) { X if ((color = atoi(&HI[c])) == 0) { X /* this also catches errors */ X foreg = WHITE; backg = BLACK; X } else if (color >= 30 && color <= 37) { X foreg = color - 30; X } else if (color >= 40 && color <= 47) { X backg = color - 40; X } X while (isdigit(HI[++c])); X c++; X } X X /* avoid invisibility */ X if (foreg != RED && backg != RED) { X HI_RED = (char *) alloc(sizeof("E[0;33;44;54m")); X Sprintf(HI_RED, "%c[%d;3%d;4%dm", ESC, HILITE_ATTRIB, X RED, backg); X } X X if (foreg != YELLOW && backg != YELLOW) { X HI_YELLOW = (char *) alloc(sizeof("E[0;33;44;54m")); X Sprintf(HI_YELLOW, "%c[%d;3%d;4%dm", ESC, HILITE_ATTRIB, X YELLOW, backg); X } X X if (foreg != GREEN && backg != GREEN) { X HI_GREEN = (char *) alloc(sizeof("E[0;33;44;54m")); X Sprintf(HI_GREEN, "%c[%d;3%d;4%dm", ESC, HILITE_ATTRIB, X GREEN, backg); X } X X if (foreg != BLUE && backg != BLUE) { X HI_BLUE = (char *) alloc(sizeof("E[0;33;44;54m")); X Sprintf(HI_BLUE, "%c[%d;3%d;4%dm", ESC, HILITE_ATTRIB, X BLUE, backg); X } X X if (foreg != WHITE && backg != WHITE) { X HI_WHITE = (char *) alloc(sizeof("E[0;33;44;54m")); X Sprintf(HI_WHITE, "%c[%d;3%d;4%dm", ESC, HILITE_ATTRIB, X WHITE, backg); X } X} X X#endif END_OF_FILE if test 11334 -ne `wc -c <'src/termcap.c'`; then echo shar: \"'src/termcap.c'\" unpacked with wrong size! fi # end of 'src/termcap.c' fi if test -f 'src/worm.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/worm.c'\" else echo shar: Extracting \"'src/worm.c'\" \(4990 characters\) sed "s/^X//" >'src/worm.c' <<'END_OF_FILE' X/* SCCS Id: @(#)worm.c 3.0 88/11/11 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X#include "hack.h" X X#ifdef WORM X#include "wseg.h" X Xstruct wseg *wsegs[32] = DUMMY, *wheads[32] = DUMMY, *m_atseg = 0; Xlong wgrowtime[32] = DUMMY; X Xint Xgetwn(mtmp) Xstruct monst *mtmp; X{ X register int tmp; X X for(tmp = 1; tmp < 32; tmp++) X if(!wsegs[tmp]) { X mtmp->wormno = tmp; X return(1); X } X return(0); /* level infested with worms */ X} X X/* called to initialize a worm unless cut in half */ Xvoid Xinitworm(mtmp) Xstruct monst *mtmp; X{ X register struct wseg *wtmp; X register int tmp = mtmp->wormno; X X if(!tmp) return; X wheads[tmp] = wsegs[tmp] = wtmp = newseg(); X wgrowtime[tmp] = 0; X wtmp->wx = mtmp->mx; X wtmp->wy = mtmp->my; X/* wtmp->wdispl = 0; */ X wtmp->nseg = 0; X} X Xstatic void Xremseg(mtmp,wtmp) Xstruct monst *mtmp; Xregister struct wseg *wtmp; X{ X if (mtmp->mx != wtmp->wx || mtmp->my != wtmp->wy) X levl[wtmp->wx][wtmp->wy].mmask = 0; X if(wtmp->wdispl) newsym(wtmp->wx, wtmp->wy); X free((genericptr_t) wtmp); X} X Xvoid Xworm_move(mtmp) Xstruct monst *mtmp; X{ X register struct wseg *wtmp, *whd; X register int tmp = mtmp->wormno; X X wtmp = newseg(); X wtmp->wx = mtmp->mx; X wtmp->wy = mtmp->my; X wtmp->nseg = 0; X/* wtmp->wdispl = 0; */ X (whd = wheads[tmp])->nseg = wtmp; X wheads[tmp] = wtmp; X if(cansee(whd->wx,whd->wy)){ X unpmon(mtmp); X atl(whd->wx, whd->wy, S_WORM_TAIL); X whd->wdispl = 1; X } else whd->wdispl = 0; X if(wgrowtime[tmp] <= moves) { X if(!wgrowtime[tmp]) wgrowtime[tmp] = moves + rnd(5); X else wgrowtime[tmp] += 2+rnd(15); X mtmp->mhp += 3; X if (mtmp->mhp > MHPMAX) mtmp->mhp = MHPMAX; X if (mtmp->mhp > mtmp->mhpmax) mtmp->mhpmax = mtmp->mhp; X return; X } X whd = wsegs[tmp]; X wsegs[tmp] = whd->nseg; X remseg(mtmp, whd); X} X Xvoid Xworm_nomove(mtmp) Xregister struct monst *mtmp; X{ X register int tmp; X register struct wseg *wtmp; X X tmp = mtmp->wormno; X wtmp = wsegs[tmp]; X if(wtmp == wheads[tmp]) return; X if(wtmp == 0 || wtmp->nseg == 0) panic("worm_nomove?"); X wsegs[tmp] = wtmp->nseg; X remseg(mtmp, wtmp); X if (mtmp->mhp > 3) mtmp->mhp -= 3; /* mhpmax not changed ! */ X else mtmp->mhp = 1; X} X Xvoid Xwormdead(mtmp) Xregister struct monst *mtmp; X{ X register int tmp = mtmp->wormno; X register struct wseg *wtmp, *wtmp2; X X if(!tmp) return; X mtmp->wormno = 0; X for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2) { X wtmp2 = wtmp->nseg; X remseg(mtmp, wtmp); X } X wsegs[tmp] = 0; X} X Xvoid Xwormhit(mtmp) Xregister struct monst *mtmp; X{ X register int tmp = mtmp->wormno; X register struct wseg *wtmp; X X if(!tmp) return; /* worm without tail */ X for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg) X if (dist(wtmp->wx, wtmp->wy) < 3) (void) mattacku(mtmp); X} X Xvoid Xwormsee(tmp) Xregister unsigned int tmp; X{ X register struct wseg *wtmp = wsegs[tmp]; X X if(!wtmp) panic("wormsee: wtmp==0"); X X for(; wtmp->nseg; wtmp = wtmp->nseg) X if(!cansee(wtmp->wx,wtmp->wy) && wtmp->wdispl) { X newsym(wtmp->wx, wtmp->wy); X wtmp->wdispl = 0; X } X} X Xvoid Xcutworm(mtmp, x, y, weptyp) Xregister struct monst *mtmp; Xregister xchar x,y; Xregister unsigned weptyp; /* uwep->otyp or 0 */ X{ X register struct wseg *wtmp, *wtmp2; X register struct monst *mtmp2; X register int tmp, tmp2; X X if(mtmp->mx == x && mtmp->my == y) return; /* hit headon */ X X /* cutting goes best with axe or sword */ X tmp = rnd(20); X if(weptyp >= SHORT_SWORD && weptyp <= KATANA || X weptyp == AXE) X tmp += 5; X X if(tmp < 12) return; X X /* if tail then worm just loses a tail segment */ X tmp = mtmp->wormno; X wtmp = wsegs[tmp]; X if(wtmp->wx == x && wtmp->wy == y){ X wsegs[tmp] = wtmp->nseg; X remseg(mtmp, wtmp); X return; X } X X /* cut the worm in two halves */ X mtmp2 = newmonst(0); X *mtmp2 = *mtmp; X mtmp2->mxlth = mtmp2->mnamelth = 0; X X /* sometimes the tail end dies */ X if(rn2(3) || !getwn(mtmp2)){ X monfree(mtmp2); X levl[mtmp2->mx][mtmp2->my].mmask = 1; X /* since mtmp is still on that spot */ X tmp2 = 0; X } else { X tmp2 = mtmp2->wormno; X wsegs[tmp2] = wsegs[tmp]; X wgrowtime[tmp2] = 0; X } X do { X if(wtmp->nseg->wx == x && wtmp->nseg->wy == y){ X if(tmp2) wheads[tmp2] = wtmp; X wsegs[tmp] = wtmp->nseg->nseg; X remseg(mtmp, wtmp->nseg); X wtmp->nseg = 0; X if(tmp2) { X You("cut the worm in half."); X /* devalue the monster level of both halves of the worm */ X mtmp->m_lev = (mtmp->m_lev <= 2) ? 2 : mtmp->m_lev - 2; X mtmp2->m_lev = mtmp->m_lev; X /* calculate the mhp on the new (lower) monster level */ X mtmp2->mhpmax = mtmp2->mhp = d((int)mtmp2->m_lev, 8); X mtmp2->mx = wtmp->wx; X mtmp2->my = wtmp->wy; X levl[mtmp2->mx][mtmp2->my].mmask = 1; X mtmp2->nmon = fmon; X fmon = mtmp2; X mtmp2->mdispl = 0; X pmon(mtmp2); X } else { X You("cut off part of the worm's tail."); X remseg(mtmp, wtmp); X } X mtmp->mhp /= 2; X return; X } X wtmp2 = wtmp->nseg; X if(!tmp2) remseg(mtmp, wtmp); X wtmp = wtmp2; X } while(wtmp->nseg); X panic("Cannot find worm segment"); X} X X#endif /* WORM /**/ END_OF_FILE if test 4990 -ne `wc -c <'src/worm.c'`; then echo shar: \"'src/worm.c'\" unpacked with wrong size! fi # end of 'src/worm.c' fi echo shar: End of archive 28 \(of 38\). cp /dev/null ark28isdone 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 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 38 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