Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83 (MC830713); site ark.UUCP Path: utzoo!watmath!clyde!cbosgd!cbdkc1!desoto!packard!edsel!bentley!hoxna!houxm!whuxlm!harpo!decvax!genrad!panda!talcott!harvard!seismo!mcvax!vu44!botter!ark!huisjes From: huisjes@ark.UUCP (Michiel B. Huisjes) Newsgroups: net.sources Subject: Hack sources for PDP11/44 and PDP11/45 (part 2 of 5) Message-ID: <420@ark.UUCP> Date: Wed, 6-Feb-85 01:47:31 EST Article-I.D.: ark.420 Posted: Wed Feb 6 01:47:31 1985 Date-Received: Sat, 9-Feb-85 08:27:28 EST Reply-To: huisjes@ark.UUCP (Michiel Huisjes) Organization: VU Informatica, Amsterdam Lines: 2265 #!/bin/sh # # # # This is a shell archive. These archives are packed by the program # packmail(1). If you have the program unshar(1), I suggest you use it. # If you don't remove anything before the cut line and then feed to # sh(1) # # =====CUT HERE=======CUT HERE=======CUT HERE=======CUT HERE=======CUT HERE=== # echo 'Start of Hack, part 02 of 05:' echo 'x - hack.do1.c' sed 's/^X//' > hack.do1.c << '/' X/* X * Hack.do1.c X */ X X#include "hack.h" X Xextern char NOTHIN[], WAND[]; X Xextern MONSTER shopkeeper; XMONSTER vaultkeeper; X Xchar *wandeffect[] = { X "magic missile", X "bolt of fire", X "sleep ray", X "bolt of cold", X "death ray", X "bolt of confusion" X}; X X#define MAXLEVEL 40 X Xchar vaultflag[MAXLEVEL]; X XMONSTER bhit (); X X X X/* More various user do commands */ X X X X Xdozap () { X register OBJECT obj; X register MONSTER mtmp; X char zx, zy; X register num; X X if (!(obj = getobj ("/", "zap"))) { X nomove (); X return; X } X if (!obj -> spe) { X pline (NOTHIN); X return; X } X obj -> spe--; X if (obj -> otyp <= Z_CREATE_MON) { X switch (obj -> otyp) { X X case Z_LIGHT: X if (dlevel) X litroom (); X else X pline (NOTHIN); X break; X X case Z_DETEC: X if (!findit ()) X return; X break; X X case Z_CREATE_MON: X makemon (0); X mnexto (fmon); X break; X } X X if (oiden[obj -> otyp] & WANN) X return; X u.urexp += 10; X oiden[obj -> otyp] |= WANN; X return; X } X if (!getdir ()) { X obj -> spe++; X nomove (); X return; X } X if (obj -> otyp <= Z_TELEPORT) { X if (mtmp = bhit (dx, dy, rn1 (8, 6))) { X switch (obj -> otyp) { X X case Z_EXHAUST: X pline ("You fight and fight and fight......"); X home (); X flush (); X sleep (2); X flags.topl = 0; X u.uhp -= mtmp -> mhp; X if (u.uhp <= 0) { X pseebl ("You cannot beat %s", X mtmp -> data -> mname); X pline ("You die...."); X done (DIED); X } X else { X mtmp -> mhp = 0; X flags.dhp = 1; X killed (mtmp); X } X oiden[obj -> otyp] |= WANN; X break; X X case Z_SLOW_MON: X mtmp -> mspeed = MSLOW; X break; X X case Z_SPEED_MON: X mtmp -> mspeed = MFAST; X break; X X case Z_UND_TUR: X if (index (" WVZ&", mtmp -> data -> mlet)) { X mtmp -> mhp -= rnd (8); X if (alive (mtmp)) X mtmp -> mflee = 1; X } X break; X X case Z_POLYMORF: X if (mtmp -> ale && !cansee (mtmp -> mx, mtmp -> my)) X break; X if (mtmp == shopkeeper) X shkdead ();/* Michiel */ X unstuck (mtmp); X newcham (mtmp, &mon[rn2 (8)][rn2 (7)]); X oiden[obj -> otyp] |= WANN; X return; X X case Z_CAN: X mtmp -> mcan = 1; X break; X X case Z_TELEPORT: X unstuck (u.ustuck); X oiden[obj -> otyp] |= WANN; X if (mtmp == shopkeeper) X setangry ();/* FRED */ X else if (mtmp == vaultkeeper) X mtmp -> angry = 1; X rloc (mtmp); X break; X X } X } X return; X } X if (obj -> otyp == Z_CLOSING) { X PART * room; X X zx = u.ux + dx; X zy = u.uy + dy; X room = &levl[zx][zy]; X while (room -> typ >= CORR) { X zx += dx; X zy += dy; X room = &levl[zx][zy]; X } X if (room -> typ == DOOR || room -> typ == SDOOR) { X pline ("The %sdoor closes forever.", X room -> typ == SDOOR ? "secret " : ""); X oiden[obj -> otyp] |= WANN; X room -> typ = WALL; X newsym (zx, zy); X } X return; X } X if (obj -> otyp == Z_DIGGING) { X /* This is further improved by Michiel and Fred */ X PART * room; X int range = 1; X X zx = u.ux + dx; X zy = u.uy + dy; X num = ROOM; X for (;;) { X if (zx < 1 || zx > 78 || zy < 1 || zy > 21) { X zx -= dx; X zy -= dy; X break; X } X atl (zx, zy, '*'); X at (zx, zy, '*'); X ++range; X room = &levl[zx][zy]; X if (!xdnstair) { X if (zx < 3 || zx > 76 || zy < 3 || X zy > 18) X break; X if (room -> typ == WALL) { X room -> typ = ROOM; X break; X } X } X else if (room -> typ == POOL) X goto check; X else if (num == ROOM || num == 10) { X if (room -> typ) { X if (room -> typ == VAULT) X vaultinit (); X if (room -> typ != ROOM) { X if (room -> typ == VAULT) X room -> typ = ROOM; X else X if (room -> typ != CORR) X room -> typ = DOOR; X if (num == 10) X break; X num = 10; X } X } X else X room -> typ = CORR; X } X else { X if (room -> typ == VAULT) X vaultinit (); X if (room -> typ % 4) { X /* WALL,(S)DOOR,ROOM */ X room -> typ = DOOR; X break; X } X else X room -> typ = CORR; X } X check: X newsym (zx, zy); X zx += dx; X zy += dy; X } X while (--range) { X newsym (zx, zy); X if (mtmp = m_at (zx, zy)) X pmon (mtmp); X zx -= dx; X zy -= dy; X } X } X else X buzz (obj -> otyp, u.ux, u.uy, dx, dy); X oiden[obj -> otyp] |= WANN; X} X Xhit (str, mtmp) Xregister char *str; Xregister MONSTER mtmp; X{ X psee (THEIT2, mtmp -> mx, mtmp -> my, "%s hits %s", str, X mtmp -> data -> mname); X} X Xmiss (str, mtmp) Xregister char *str; Xregister MONSTER mtmp; X{ X psee (THEIT2, mtmp -> mx, mtmp -> my, "%s misses %s", str, X mtmp -> data -> mname); X} X Xfindit () { X char num, lx, hx, ly, hy; X register char zx, zy; X register GOLD_TRAP gtmp, gt1; X X for (lx = u.ux; levl[lx - 1][u.uy].typ % CORR; lx--);/* typ!=0 */ X /* WALL, SDOOR, DOOR, or ROOM (see hack.h) */ X X for (hx = u.ux; levl[hx + 1][u.uy].typ % 4; hx++); X for (ly = u.uy; levl[u.ux][ly - 1].typ % 4; ly--); X for (hy = u.uy; levl[u.ux][hy + 1].typ % 4; hy++); X num = 0; X for (zy = ly; zy <= hy; zy++) X for (zx = lx; zx <= hx; zx++) { X if (levl[zx][zy].typ == SDOOR) { X levl[zx][zy].typ = DOOR; X atl (zx, zy, '+'); X num++; X } X else if (gtmp = g_at (zx, zy, ftrap)) { X if (gtmp -> gflag == PIERC) { X mkmonat (PM_PIERC, zx, zy); X num++; X deltrap (gtmp); X } X else if (gtmp -> gflag == MIMIC) { X deltrap (gtmp); X M: X mkmonat (PM_MIMIC, zx, zy); X num++; X } X else if (!gtmp -> gflag & SEEN) { X gtmp -> gflag |= SEEN; X atl (zx, zy, '^'); X num++; X } X } X else if ((gtmp = g_at (zx, zy, fgold)) && X !gtmp -> gflag) { X if (gtmp == fgold) X fgold = gtmp -> ngen; X else { X for (gt1 = fgold; gt1 -> ngen != X gtmp; gt1 = gt1 -> ngen); X gt1 -> ngen = gtmp -> ngen; X } X free (gtmp); X goto M; X } X } X return (num); X} X X/* Sets dx,dy to the final position of the weapon thrown */ XMONSTER bhit (ddx, ddy, range) { X register MONSTER mtmp; X X dx = u.ux; X dy = u.uy; X if (u.uswallow) X return u.ustuck;/* a3 */ X while (range-- > 0) { X dx += ddx; X dy += ddy; X if (mtmp = m_at (dx, dy)) X return (mtmp); X if (levl[dx][dy].typ < CORR) { X dx -= ddx; X dy -= ddy; X return (0); X } X } X return (0); X} X Xbuzz (type, sx, sy, ddx, ddy) Xregister sx, sy; X{ X PART * lev; X register char range, let; X register MONSTER mtmp; X register wandeftype = type - 11; X X if (u.uswallow) { X pline ("The %s rips into the %s.", X wandeffect[wandeftype], X u.ustuck -> data -> mname); X zhit (u.ustuck, type); X alive (u.ustuck);/* a3 */ X return; X } X range = rn1 (7, 7); X if (ddx == ddy) X let = '\\'; X else if (ddx && ddy) X let = '/'; X else if (ddx) X let = '-'; X else X let = '|'; X while (range-- > 0) { X sx += ddx; X sy += ddy; X if ((lev = &levl[sx][sy]) -> typ) { X at (sx, sy, let); X on (sx, sy); X lev -> new = 1; X } X if (mtmp = m_at (sx, sy)) { X if (mtmp == vaultkeeper) X mtmp -> angry = 1; X if (rnd (20) < 18 + mtmp -> data -> ac) { X zhit (mtmp, type); X if (alive (mtmp)) X hit (wandeffect[wandeftype], X mtmp); X range -= 2; X } X else X miss (wandeffect[wandeftype], mtmp); X } X else if (sx == u.ux && sy == u.uy) { X if (rnd (20) < 18 + u.uac) { X range -= 2; X flags.dhp = 1;/* Michiel */ X pline ("The %s hits you!", X wandeffect[wandeftype]); X switch (type) { X case Z_MAG_MISSILE: X u.uhp -= d (2, 6); X break; X case Z_FIRE: X if (u.ufireres) { X pline ("You don't feel hot!"); X break; X } X u.uhp -= d (6, 6); X break; X case Z_SLEEP: X nomul (-rnd (25)); X break; X case Z_COLD: X if (u.ucoldres) { X pline ("You don't feel cold!"); X break; X } X u.uhp -= d (6, 6); X break; X case Z_DEATH: X u.uhp = 0; X break; X case Z_CONF_MON: X u.uconfused = d (4, 6); X } X if (u.uhp <= 0) X killer = wandeffect[wandeftype]; X } X else X pline ("The %s wizzes by you!", X wandeffect[wandeftype]); X } X if (lev -> typ <= DOOR || lev -> typ == VAULT) { X psee (0, sx, sy, "%s bounces!", X wandeffect[wandeftype], NULL); X ddx = -ddx; X ddy = -ddy; X range--; X } X } X} X Xzhit (mtmp, type) Xregister MONSTER mtmp; Xregister type; X{ X if (mtmp == shopkeeper) X setangry (); X switch (type) { X case Z_MAG_MISSILE: X mtmp -> mhp -= d (2, 6); X break; X case Z_FIRE: X if (index ("Dg", mtmp -> data -> mlet)) X return; X mtmp -> mhp -= d (6, 6); X if (mtmp -> data -> mlet == 'Y') X mtmp -> mhp -= 7; X break; X case Z_SLEEP: X mtmp -> mfroz = 1; X break; X case Z_COLD: X if (index ("Ygf", mtmp -> data -> mlet)) X return; X if (mtmp -> data -> mlet == 'D') X mtmp -> mhp -= 7; X mtmp -> mhp -= d (6, 6); X break; X case Z_DEATH: X if (index ("WVZ ", mtmp -> data -> mlet)) X return; X mtmp -> mhp = 0; X break; X case Z_CONF_MON: X if (mtmp == u.ustuck) X return; X mtmp -> mconf = 1; X break; X X } X} X Xdowhatis () { X register fd; X register char *str; X X X pline ("Specify what? "); X flags.topl = 0; X getlin (buf); X str = buf; X while (*str == ' ') X str++; X nomove (); X buf[52] = '\0'; X if (*(str + 1)) X pline ("One character please."); X else if ((fd = open (DATA, 0)) < 0) X pline ("Cannot open data file!"); X else { X lseek (fd, (long) (*str * 51), 0); X if (read (fd, buf, 51) > 0 && *buf != '\\') X pline (buf); X else X pline ("Unknown symbol."); X close (fd); X } X} X Xdoshow () { /* Michiel: Show everything you're wearing */ X nomove (); X show (uarm2); X show (uarm); X show (uwep); X show (uleft); X show (uright); X} X Xshow (otmp) Xregister OBJECT otmp; X{ X if (otmp) X prinv (otmp); X} X Xdosearch () { X register char x, y; X register GOLD_TRAP tgen; X X for (x = u.ux - 1; x < u.ux + 2; x++) X for (y = u.uy - 1; y < u.uy + 2; y++) X if (levl[x][y].typ == SDOOR && !rn2 (7)) { X levl[x][y].typ = DOOR; X atl (x, y, '+'); X nomul (0); X } X else { X for (tgen = ftrap; tgen; tgen = tgen -> ngen) X if (tgen -> gx == x && tgen -> gy == y && X (!rn2 (8) || ((!u.usearch) && X tgen -> gflag & SEEN))) { X nomul (0); X pline ("You find a%s", traps[tgen -> gflag & 037]); X if ((tgen -> gflag & 037) == X PIERC) { X deltrap (tgen); X mkmonat (PM_PIERC, x, y); X return; X } X if ((tgen -> gflag & 037) == X MIMIC) { X deltrap (tgen); X mkmonat (PM_MIMIC, x, y); X return; X } X if (!(tgen -> gflag & SEEN)) { X tgen -> gflag |= SEEN; X atl (x, y, '^'); X } X } X } X} X Xdoset () { X pline ("Give one inventory per line? "); X flush (); X flags.oneline = (getchar () == 'y'); X nomove (); X} X X X X/* X * The whole vault was implemented by Fred and Michiel X * X */ X X Xstruct permonst treasurer = { X "treasurer", '@', 15, 12, -1, 4, 8, 0 X}; X Xvaultinit () { X GOLD_TRAP gtmp; X X if (vaultflag[dlevel]) X return; X vaultflag[dlevel] = 1;; X makemon (&treasurer); X vaultkeeper = fmon; X for (gtmp = fgold; gtmp -> gflag < 10000; gtmp = gtmp -> ngen); X fmon -> mx = gtmp -> gx; X fmon -> my = gtmp -> gy; X if (!u.ublind) X pmon (fmon); X} / echo 'x - hack.mon.c' sed 's/^X//' > hack.mon.c << '/' X/* X * Hack.mon.c X */ X X/* Contains various monster routines */ X X#include "hack.h" X Xextern char WCLEV[], STOPGLOW[]; X Xdist (x, y) Xregister x, y; X{ X x -= u.ux; X y -= u.uy; X return (x * x + y * y); X} X Xr_free (x, y, mtmp) Xregister x, y; Xregister MONSTER mtmp; X{ X if (mtmp -> ale) X return (levl[x][y].typ == POOL); X else X return (levl[x][y].typ > SDOOR && X (x != u.ux || y != u.uy) && levl[x][y].typ < POOL); X /* DOOR,CORR,ROOM */ X} X X X/* Puts m next to u, or anywhere if there isn't room there */ Xmnexto (mtmp) XMONSTER mtmp; X{ X register x, y, z; X struct { X char zx, zy; X } foo[15], *tfoo; X int range; X X tfoo = foo; X range = 1; X do { /* Full kludge action */ X for (y = 0; y < 2; y++) X for (x = u.ux - range; x <= u.ux + range; x++) { X z = range; X if (!y) X z = -z; X if (test (x, z += u.uy)) { X tfoo -> zx = x; X tfoo++ -> zy = z; X if (tfoo == &foo[15]) X goto foofull; X } X } X for (x = 0; x < 2; x++) X for (y = u.uy + 1 - range; y < u.uy + range; X y++) { X z = range; X if (!x) X z = -z; X if (test (z += u.ux, y)) { X tfoo -> zx = z; X tfoo++ -> zy = y; X if (tfoo == &foo[15]) X goto foofull; X } X } X range++; X } while (tfoo == foo); Xfoofull: X tfoo = &foo[rn2 (tfoo - foo)]; X mtmp -> mx = tfoo -> zx; X mtmp -> my = tfoo -> zy; X pmon (mtmp); X if (mtmp -> data -> mlet == 'w') X initworm (mtmp); X} X Xrloc (mtmp) XMONSTER mtmp; X{ X register tx, ty; X register char ch = mtmp -> data -> mlet; X X if (ch == 'w' && mtmp -> mx) X return; /* Do not relocate worms */ X levlsym (mtmp -> mx, mtmp -> my, ch); X if (mtmp -> ale) { X do { X tx = rn1 (77, 2); X ty = rn2 (22); X /* until CORR,DORR,or ROOM; or... */ X } while (levl[tx][ty].typ != POOL || m_at (tx, ty) || X (tx == u.ux && ty == u.uy)); X } X else { X do { X tx = rn1 (77, 2); X ty = rn2 (22); X /* until CORR,DORR,or ROOM; or... */ X } while (levl[tx][ty].typ < DOOR || m_at (tx, ty) || X (tx == u.ux && ty == u.uy) X || levl[tx][ty].typ >= 7); X } X mtmp -> mx = tx; X mtmp -> my = ty; X pmon (mtmp); X if (ch == 'w') X initworm (mtmp); X} X Xtest (x, y) { X if (x <= 0 || x > 78 || y <= 0 || y > 20) X return 0; X if (m_at (x, y) || levl[x][y].typ < DOOR || levl[x][y].typ >= 7) X return 0; X return 1; X} X Xpoisoned (string, pname) Xregister char *string, *pname; X{ X pseebl ("%s was poisoned!", string); X if (u.upres) { X pline ("The poison doesn't seem to affect you."); X return; X } X X switch (rn2 (6)) { X case 0: X u.uhp = 0; X break; X case 1: X case 2: X case 3: X losestr (rn1 (3, 3)); X break; X case 4: X case 5: X losehp (rn1 (10, 6), pname); X return; X } X X if (u.uhp <= 0) X killer = pname; X} X Xsteal (mtmp) XMONSTER mtmp; X{ X register OBJECT otmp, ot1; X register tmp; X X for (otmp = invent, tmp = 0; otmp -> nobj; otmp = otmp -> nobj, tmp++); X X tmp = rn2 (tmp); X otmp = invent; X if (!tmp) X invent = invent -> nobj; X else { X for (; otmp && tmp; tmp--, otmp = otmp -> nobj); X ot1 = otmp -> nobj; X otmp -> nobj = ot1 -> nobj;/* rm obj from invent */ X otmp = ot1; X } X if (otmp == uarm || otmp == uarm2) { X u.uac += otmp -> spe; X if (otmp == uarm) X uarm = uarm2; X uarm2 = 0; X flags.dac = 1; X } X else if (otmp == uwep) X uwep = 0; X else if (otmp == uleft) { X uleft = 0; X doring (otmp, OFF); X } X else if (otmp == uright) { X uright = 0; X doring (otmp, OFF); X } X doname (otmp, buf); X pline ("She stole %s.", buf); X stlobj (mtmp, otmp); X} X Xstlobj (mtmp, otmp) Xregister MONSTER mtmp; Xregister OBJECT otmp; X{ X otmp -> nobj = 0; /* Michiel: dog and two objects? */ X if (mtmp -> mstole) { X otmp -> nobj = mtmp -> mstole -> sobj; X mtmp -> mstole -> sobj = otmp; X return; X } /* Michiel save stolen object */ X else { X mtmp -> mstole = newstole (); X mtmp -> mstole -> sobj = otmp; X mtmp -> mstole -> sgold = 0; X } X} X Xdelmon (mtmp) Xregister MONSTER mtmp; X{ X unstuck (mtmp); /* a3 */ X relmon (mtmp); X if (mtmp == shopkeeper) X shkdead (); X if (mtmp == vaultkeeper) { X mtmp -> data -> mmove = -1; X vaultkeeper = 0; X } X if (mtmp -> wormno) X wormdead (mtmp); X free (mtmp); X} X Xrelmon (mtmp) Xregister MONSTER mtmp; X{ X register MONSTER mtmp2; X X if (mtmp == fmon) X fmon = fmon -> nmon; X else { X for (mtmp2 = fmon; mtmp2 -> nmon != mtmp; mtmp2 = mtmp2 -> nmon); X mtmp2 -> nmon = mtmp -> nmon; X } X} X X/* Release the objects the killed animal has stolen */ Xrelobj (mtmp) Xregister MONSTER mtmp; X{ X register GOLD_TRAP gtmp; X register tmp = 0; X OBJECT otmp, otmp2; X X if (mtmp -> mstole) { /* Michiel drop stolen obj or gold */ X if (mtmp -> mstole -> sgold) X tmp = mtmp -> mstole -> sgold; X else { X otmp = mtmp -> mstole -> sobj; X do { X otmp -> ox = mtmp -> mx; X otmp -> oy = mtmp -> my; X otmp2 = otmp; X otmp = otmp -> nobj; X } while (otmp); X otmp2 -> nobj = fobj; X fobj = mtmp -> mstole -> sobj; X if (mtmp -> data -> mlet != 'd') X seeatl (otmp -> ox, otmp -> oy, otmp -> olet); X } X free (mtmp -> mstole); X mtmp -> mstole = NULL; X } X if (mtmp -> data -> mlet == 'L') { X gtmp = newgen (); X gtmp -> ngen = fgold; X gtmp -> gx = mtmp -> mx; X gtmp -> gy = mtmp -> my; X if (dlevel) X gtmp -> gflag = tmp + d (dlevel, 30); X else X gtmp -> gflag = tmp + d (maxdlevel, 30); X fgold = gtmp; X seeatl (mtmp -> mx, mtmp -> my, '$'); X } X} X X/* a3 */ Xunstuck (mtmp) Xregister MONSTER mtmp; X{ X if (mtmp == u.ustuck) { X if (u.uswallow) { X u.uswallow = 0; X u.uswldtim = 0; X docrt (); X setCon (SETC);/* Try a3 */ X } X u.ustuck = 0; X } X} X Xkilled (mtmp) Xregister MONSTER mtmp; X{ X register tmp; X X unstuck (mtmp); X levlsym (mtmp -> mx, mtmp -> my, mtmp -> data -> mlet); X if (mtmp -> cham) X mtmp -> data = (PM_CHAM); X pseebl ("You destroy %s!", mtmp -> data -> mname); X if (!u.ublind && u.umconf) { X pline (STOPGLOW); X u.umconf = 0; X } X tmp = mtmp -> data -> mhd; X tmp *= tmp; X ++tmp; X if (mtmp -> data -> ac < 3) X tmp += (7 - mtmp -> data -> ac) << 1; X if (index ("AcsSDXaeRTVWU&In:P", mtmp -> data -> mlet)) X tmp += mtmp -> data -> mhd << 1; X if (index ("DeV&P", mtmp -> data -> mlet)) X tmp += 7 * mtmp -> data -> mhd; X if (mtmp -> data -> mhd > 6) X tmp += 50; X if (mtmp -> ale) X tmp += 1000; X relobj (mtmp); X if ((index ("NTV&", mtmp -> data -> mlet) || !rn2 (5)) && !mtmp -> ale X && levl[mtmp -> mx][mtmp -> my].typ > SDOOR) { X /* Mimic in wall? */ X mkobj (0); X fobj -> ox = mtmp -> mx; X fobj -> oy = mtmp -> my; X if (!u.ublind) X atl (mtmp -> mx, mtmp -> my, fobj -> olet); X } X delmon (mtmp); X u.urexp += tmp << 2; X u.uexp += tmp; X flags.dexp = 1; X while (u.uexp >= 10L * pow (u.ulevel - 1)) { X pline (WCLEV, ++u.ulevel); X tmp = rnd (10); X if (tmp < 3) X tmp = rnd (10); X u.uhpmax += tmp; X u.uhp += tmp; X flags.dhp = 1; X flags.dhpmax = 1; X flags.dulev = 1; X } X} X X#define TBLIND 5 X#define NOTEST 6 X X/*VARARGS*/ Xpsee (mode, x, y, str, name, arg)/* Str bevat %s */ Xregister char *str, *name, *arg; X{ X char *a1, *a2; X X a1 = "the %s"; X a2 = "the %s"; X if (mode == TBLIND) { X if (u.ublind) X a1 = "it"; X } X else if (mode != NOTEST && !cansee (x, y)) X switch (mode) { X case IT1: X a1 = "it"; X break; X case THEIT2: X a2 = "it"; X break; X case 0: X return 0; X default: X pline ("Bad(%d) mode in psee", mode); X } X sprintf (buf, str, a1, a2); X if (*buf >= 'a' && *buf <= 'z') X *buf += 'A' - 'a'; X pline (buf, name, arg); X return 1; X} X X/*VARARGS*/ Xp2xthe (str, name, arg) Xregister char *str, *name, *arg; X{ X psee (NOTEST, 0, 0, str, name, arg); X} X Xpseebl (str, name) Xregister char *str, *name; X{ X psee (TBLIND, 0, 0, str, name, NULL); X} X Xrescham () { /* Force all chameleons to become normal */ X register MONSTER mtmp; X X for (mtmp = fmon; mtmp; mtmp = mtmp -> nmon) X if (mtmp -> cham) { X mtmp -> cham = 0; X if (u.uswallow && u.ustuck == mtmp) { X unstuck (mtmp); X mnexto (mtmp); X } X newcham (mtmp, PM_CHAM); X } X} X X/* Make a chameleon look like a new monster */ Xnewcham (mtmp, mdat) Xregister MONSTER mtmp; Xregister MONSTDATA mdat; X{ X register mhp, hpn, hpd; X X if (mdat == mtmp -> data) X return; /* Still the same monster */ X if (u.uswallow && mdat -> mlet == 'w') X return; X if (mtmp -> wormno) X wormdead (mtmp);/* Throw tail away */ X hpn = mtmp -> mhp; X hpd = mtmp -> data -> mhd << 3; X mtmp -> data = mdat; X mtmp -> invis = 0; X mtmp -> mtame = 0; X mhp = mdat -> mhd << 3; X/* New hp: same fraction of max as before */ X mtmp -> mhp = 2 + (hpn * mhp) / hpd; X hpn = mtmp -> orig_hp; X mtmp -> orig_hp = 2 + (hpn * mhp) / hpd; X if (mdat -> mlet == 'I') { X ++mtmp -> invis; X if (cansee (mtmp -> mx, mtmp -> my)) X prl (mtmp -> mx, mtmp -> my); X } X if (mdat -> mlet == 'w' && getwn (mtmp)) X initworm (mtmp); X if (u.uswallow && mtmp == u.ustuck && X !index (",'P", mdat -> mlet)) { X unstuck (mtmp); X mnexto (mtmp); X } X pmon (mtmp); X} X Xmakemon (ptr) Xregister MONSTDATA ptr; X{ X register MONSTER mtmp; X X if (!ptr) { X do X ptr = &mon[rn2 (dlevel / 3 + 1) % 8][rn2 (7)]; X while (index (genocided, ptr -> mlet)); X } X else { X if (index (genocided, ptr -> mlet)) { X if (!u.ublind) X p2xthe ("%s vanishes!", ptr -> mname); X return 1; X } X } X mtmp = newmonst (ptr -> pxlth); X mtmp -> nmon = fmon; X fmon = mtmp; X mtmp -> mstole = 0; X mtmp -> invis = 0; X mtmp -> cham = 0; X mtmp -> msleep = 0; X mtmp -> mfroz = 0; X mtmp -> mconf = 0; X mtmp -> mflee = 0; X mtmp -> mtame = 0; X mtmp -> mspeed = 0; X mtmp -> mcan = 0; X mtmp -> angry = 0; X mtmp -> mxlth = 0; X mtmp -> ale = 0; X mtmp -> data = ptr; X switch (ptr -> mlet) { X case 'I': X ++mtmp -> invis; X break; X case 'L': X mtmp -> msleep = u.uhcursed; X break; X case ':': X ++mtmp -> cham; X if (!u.ucham) X newcham (mtmp, &mon[rn1 (6, 2)][rn2 (7)]); X break; X case ';': X mtmp -> ale = 1; X break; X } X if (ptr -> mlet != 'w' || !getwn (mtmp)) X mtmp -> wormno = 0; X mtmp -> mhp = rnd (4); X if (ptr -> mhd) X mtmp -> mhp = d (ptr -> mhd, 8); X mtmp -> orig_hp = mtmp -> mhp; X return 0; X} X Xsomegold () { X return ((u.ugold < 100L) ? u.ugold : X (u.ugold > 10000L) ? rnd (10000) : rnd ((int) u.ugold)); X} X Xmkmonat (ptr, x, y) Xregister MONSTDATA ptr; Xregister x, y; X{ X if (makemon (ptr)) X return; X if (x == u.ux && y == u.uy) X mnexto (fmon); X else { X atl (x, y, ptr -> mlet); X fmon -> mx = x; X fmon -> my = y; X } X} / echo 'x - hack.move.c' sed 's/^X//' > hack.move.c << '/' X/* X * Hack.move.c X */ X X#include "hack.h" X Xextern char STOPGLOW[], UMISS[], *setan (); X X Xextern OBJECT addinv (); X Xchar seelx, seehx, seely, seehy;/* Corners of lit room */ X /* l for Low, h for High */ X X#define ZOO 1 X#define GRAVEYARD 2 X#define SWAMP 3 X#define FORT_KNOX 4 X X X/* Contains move commands */ X Xchar sdir[] = "hjklyubn"; Xshort xdir[8] = { X -1, 0, 0, 1, -1, 1, -1, 1 X} , X ydir[8] = { X 0, 1, -1, 0, -1, -1, 1, 1 X}; X Xmovecm (cmd) Xregister char *cmd; X{ X register char *dp; X X if (!(dp = index (sdir, *cmd))) X return 0; X dx = xdir[dp - sdir]; X dy = ydir[dp - sdir]; X return 1; X} X X Xdomove () { X char nx, ny, tmpx, tmpy, let; X register MONSTER mtmp; X register PART * tmpr, *ust; X GOLD_TRAP gold, trap, gtm1; X OBJECT otmp, obj; X X if (u.uswallow) { X nx = u.ux; X ny = u.uy; X goto M; X } X /* n is used for u.u + d */ X if (u.uconfused) { X do { X dx = rn2 (3); X dy = rn2 (3); X dx--; X dy--; X tmpr = &levl[u.ux + dx][u.uy + dy]; X } X while ((!dx && !dy) || tmpr -> typ < DOOR); X } X else X tmpr = &levl[u.ux + dx][u.uy + dy]; X ust = &levl[u.ux][u.uy]; X tmpx = u.ux; X tmpy = u.uy; X nx = u.ux + dx; X ny = u.uy + dy; X if (trap = g_at (nx, ny, ftrap)) { X if (trap -> gflag == MIMIC) { X nomul (0); X pline ("The door is actually a mimic."); X deltrap (trap); X if (makemon (PM_MIMIC)) { X newsym (nx, ny); X return; X } X if (m_at (nx, ny)) X mnexto (fmon); X else { X fmon -> mx = nx; X fmon -> my = ny; X } X if (!u.ustuck) X u.ustuck = fmon; X pmon (fmon); X return; X } X if (trap -> gflag & SEEN) X nomul (0); X } X if (u.ustuck && (nx != u.ustuck -> mx || ny != u.ustuck -> my)) { X pseebl ("You cannot escape from %s!", X u.ustuck -> data -> mname); X nomul (0); X return; X } XM: X if (mtmp = m_at (nx, ny)) { X/* Attack monster */ X char tmp; X register MONSTDATA mdat = mtmp -> data; X X tmp = u.ulevel - 1 + mdat -> ac + abon (); X if (uwep) { X tmp += uwep -> spe; X if (uwep -> otyp == W_TWOH_SWORD) X tmp--; X else if (uwep -> otyp == W_DAGGER) X tmp += 2; X else if (uwep -> otyp == W_SPEAR && index ("XDne", X mdat -> mlet)) X tmp += 2; X } X if (mtmp -> msleep) { X mtmp -> msleep = 0; X tmp += 2; X } X if (mtmp -> mfroz) { X tmp += 4; X if (!rn2 (10)) X mtmp -> mfroz = 0; X } X if (mtmp -> mflee) X tmp += 2; X if (u.utrap) X tmp -= 3; X if (mtmp == shopkeeper) X setangry (); X if (tmp < rnd (20) && !u.uswallow) X pseebl (UMISS, mdat -> mname); X else { X/* We hit the monster; but: it might die! */ X X if (hmon (mtmp, uwep)) { X /* 0-destroy,1-hit */ X if (!u.uswallow && !rn2 (25) && X mtmp -> mhp < mtmp -> orig_hp >> 1) { X/* You might be stucked at this point ! { FRED } */ X if (mtmp == u.ustuck) X unstuck (mtmp); X mtmp -> mflee = 1; X } X pseebl ("You hit %s!", mdat -> mname); X if (u.umconf && !u.uswallow) {/* a3 */ X if (!u.ublind) { X pline (STOPGLOW); X pseebl ("The %s appears confused.", mdat -> mname); X } X mtmp -> mconf = 1; X u.umconf = 0; X } X if (mtmp -> wormno) X cutworm (mtmp, nx, ny, X uwep -> otyp); X switch (mdat -> mlet) { X X case 'a': X if (rn2 (2)) { X pline ("You are splashed by the blob's acid!"); X losehp (rnd (6), mdat -> mname); X } X if (!rn2 (6) && uwep) { X pline ("Your %s corrodes!", X weapons[uwep -> otyp].wepnam); X --uwep -> spe; X } X break; X X case 'E': X if (!u.ublind && rn2 (2)) { X pline ("You are frozen by the floating eye's gaze!"); X nomul (rn1 (20, -20)); X return; X } X break; X } X } X } X nomul (0); X return; X } X X/* Not attacking an animal, so we try to move */ X if (u.utrap) { X pline ((u.upit) ? "You are still in a pit." : X "You are caught in a beartrap."); X if (u.upit || (dx && dy) || !rn2 (5)) X u.utrap--; X return; X } X if ((dx && dy && (tmpr -> typ == DOOR || ust -> typ == DOOR)) || X tmpr -> typ < DOOR || tmpr -> typ == VAULT) { X /* 0, WALL, or SDOOR */ X flags.move = 0; X nomul (0); X return; X } X u.ux = nx; /* u.ux+=dx; u.uy+=dy; */ X u.uy = ny; X nx += dx; X ny += dy; X if (flags.run) X if (tmpr -> typ == DOOR || X (xupstair == u.ux && yupstair == u.uy) || X (xdnstair == u.ux && ydnstair == u.uy)) X nomul (0); X if (tmpr -> typ >= 30 && tmpr -> typ <= 41) { X for (otmp = invent; otmp; otmp = otmp -> nobj) { X if (otmp -> otyp == tmpr -> typ && otmp -> olet == '_') { X pline ("The door opens."); X doname (otmp, buf); X pline ("The %s vanishes.", buf); X useup (otmp); X tmpr -> typ = DOOR; X break; X } X } X if (!otmp) { X if (rn2 (2)) X pline ("The door is locked!"); X else X pline ("You cannot unlock the door!"); X u.ux -= dx; X u.uy -= dy; X return; X } X } X if (ust -> scrsym == '@') { X newsym (tmpx, tmpy); X oldux = tmpx; X olduy = tmpy; X } X if (!u.ublind) { X if (ust -> lit) { X if (tmpr -> lit) { X if (tmpr -> typ == DOOR) X prl1 (nx, ny); X if (ust -> typ == DOOR) X nose1 (tmpx - dx, tmpy - dy); X } X else { X unCoff (UNC, 1); X prl1 (nx, ny); X } X } X else { X if (tmpr -> lit) X setCon (SETC); X else { X prl1 (nx, ny); X if (tmpr -> typ == DOOR) { X if (dy) { X prl (u.ux - 1, u.uy); X prl (u.ux + 1, u.uy); X } X else { X prl (u.ux, u.uy - 1); X prl (u.ux, u.uy + 1); X } X } X } X nose1 (tmpx - dx, tmpy - dy); X } X } X else X newunseen (tmpx, tmpy); X if (!multi) X pru (); X while (gold = g_at (u.ux, u.uy, fgold)) { X if (!gold -> gflag) { X pline ("The chest was a mimic!"); X if (!makemon (PM_MIMIC)) { X mnexto (fmon); X u.ustuck = fmon; X } X nomul (0); X } X else { X if (u.uhcursed) { X pline ("You cannot pick up the gold!"); X break; X } X if (gold -> gflag == 1) X gold -> gflag++;/* a3 */ X pline ("%u gold pieces", gold -> gflag); X u.ugold += gold -> gflag; X flags.dgold = 1; X } X if (gold == fgold) X fgold = fgold -> ngen; X else { X for (gtm1 = fgold; gtm1 -> ngen != gold; X gtm1 = gtm1 -> ngen); X gtm1 -> ngen = gold -> ngen; X } X free (gold); X if (flags.run) X nomul (0); X if (u.uinvis) X newsym (u.ux, u.uy); X } X while (obj = o_at (u.ux, u.uy)) { X for (otmp = invent, let = 0; otmp; otmp = otmp -> nobj) X let += weight (otmp); X let += weight (obj); X if (let > 85) { X pline ("You can't carry anything more."); X if (flags.run) X nomul (0); X break; X } X if (let > 80) X pline ("You have a little trouble lifting"); X if (!(obj -> cursed)) X obj -> cursed = u.uhcursed; X freeobj (obj); X addtobill (obj);/* Sets obj->unpaid if necessary */ X prinv (addinv (obj)); X /* Might merge it with other objects */ X if (u.uinvis) X newsym (u.ux, u.uy); X if (flags.run) X nomul (0); X } X if (trap) { X nomul (0); X if (trap -> gflag & SEEN && !rn2 (5)) X pline ("You escape a%s.", X traps[trap -> gflag & 037]); X else { X trap -> gflag |= SEEN; X switch (((trap -> gflag) & 037)) { X X case SLPTRP: X pline ("A cloud of gas puts you to sleep!"); X nomul (-rnd (25)); X break; X X case BEAR: X u.utrap = rn1 (4, 4); X u.upit = 0; X pline ("A bear trap closes on your foot!"); X break; X X case PIERC: X pline ("A piercer suddenly drops from the ceiling!"); X deltrap (trap); X if (!makemon (PM_PIERC)) { X mnexto (fmon); X hitu (3, d (4, 6), X "falling piercer"); X } X break; X X case ARROW: X pline ("An arrow shoots out at you!"); X hitu (8, rnd (6), "arrow"); X break; X X case TDOOR: X if (!xdnstair) { X pline ("A trap door in the ceiling opens and a rock falls on your head!"); X losehp (d (2, 10), X "falling rock"); X break; X } X pline ("A trap door opens up under you!"); X if (u.ufloat || u.ustuck) { X pline ("For some reason you don't fall in."); X break; X } X more (); X keepdogs (1); X unCoff (COFF, 1); X do { X dosavelev (); X dodown (); X levl[u.ux][u.uy].scrsym = '<'; X } while (!rn2 (4) && xdnstair); X land (); X losedogs (); X setCon (CON); X inshop ();/* a3:zie tele */ X break; X X case DART: X pline ("A little dart shoots out at you!"); X if (hitu (7, rnd (3), "little dart") && X !rn2 (6)) X poisoned ("dart", "poison dart"); X break; X X case TELE: X newsym (u.ux, u.uy); X tele (); X break; X X case PIT: X if (u.ufloat) { X pline ("A pit opens up under you!"); X pline ("You don't fall in!"); X break; X } X pline ("You fall into a pit!"); X u.utrap = rn1 (6, 2); X u.upit = 1; X losehp (rnd (6), "pit"); X break; X X default: X pline ("Bad(%d)trap", trap -> gflag); X impossible (); X } X } X } X if (tmpr -> typ == DOOR && dlevel) { X inshop (); X switch (rooms[inroom (u.ux, u.uy)].rtype) { X case ZOO: X if (!u.uinzoo) { X pline ("Welcome to the Zoo!"); X u.uinzoo++; X } X break; X case GRAVEYARD: X if (!u.uinyard) { X pline ("Welcome to the Graveyard!"); X u.uinyard++; X } X break; X case SWAMP: X if (!u.uinswamp) { X pline ("Welcome to the Swamp!"); X u.uinswamp++; X } X break; X case FORT_KNOX: X if (!u.uinknox) { X pline ("Welcome to Fort Knox!"); X u.uinknox++; X } X break; X default: X break;/* Who knows what more may come */ X } X } X if (tmpr -> typ == CORR) { X if (u.uinshop) X inshop ();/* Outside shop now */ X u.uinzoo = 0; /* You left the Zoo ?? */ X u.uinyard = 0; /* You left the Graveyard ?? */ X u.uinswamp = 0; /* You left the Swamp ?? */ X u.uinknox = 0; /* You left Fort Knox ?? */ X } X if (tmpr -> typ == POOL) X if (!u.ufloat) { X pline ("You fall into a pool!"); X pline ("You can't swim!"); X pline ("You drown..."); X more (); X killer = "Pool of water"; X done (DROWNED); X } X} X X/* Stop running if we see something interesting */ Xlookaround () { X register x, y, corrct = 0; X register MONSTER mtmp; X X if (u.ublind || flags.run < 2) X return; X for (x = u.ux - 1; x <= u.ux + 1; x++) X for (y = u.uy - 1; y <= u.uy + 1; y++) { X if (x == u.ux && y == u.uy) X continue; X/* Note: we cannot call r_free: perhaps a M is hidden in the wall */ X if (!levl[x][y].typ) X continue; X if (mtmp = m_at (x, y)) X if (!mtmp -> mtame || (x == u.ux + dx && X y == u.uy + dy)) { X nomul (0); X return; X } X if (x == u.ux - dx && y == u.uy - dy) X continue; X if (mtmp) X corrct++; X else X switch (levl[x][y].scrsym) { X case '+': X if (x == u.ux || y == u.uy) { X nomul (0); X return; X } X case '0': X multi = 0; X flags.run = 0; X return; X case '.': X case '|': X case '-': X break; X case '#': X corrct++; X break; X default: X nomul (0); X return; X } X } X if (corrct > 1 && flags.run == 2) X nomul (0); X} X Xnomul (nval) Xregister nval; X{ X if (multi < 0) X return; X if (flags.mv) X pru (); X multi = nval; X flags.mv = 0; X flags.run = 0; X} X Xchar * X parse () { X static char inline[80]; X register foo; X X oldux = 0; X olduy = 0; X flags.move = 1; X if (!u.uinvis) X curs (u.ux, u.uy + 2); X else X home (); X flush (); X while ((foo = getchar ()) >= '0' && foo <= '9') X multi += 10 * multi + foo - '0'; X if (multi) { X multi--; X save_cm = inline; X } X inline[0] = foo; X inline[1] = 0; X if (foo == 'f' || foo == 'F') { X inline[1] = getchar (); X inline[2] = 0; X } X if (flags.topl) { X home (); X cl_end (); X flags.topl = 0; X } X return (inline); X} X Xnomove () { X multi = 0; X flags.move = 0; X} / echo 'x - hack.shk.c' sed 's/^X//' > hack.shk.c << '/' X/* X * Hack.shk.c X */ X X#include "hack.h" X X#define BILLSZ 200 X#define ONBILL 1 X#define NOTONBILL 0 X#define GDIST(x, y) ((x - gx)*(x - gx) + (y - gy)*(y - gy) ) X Xstruct { X OBJECT op; Xunsigned useup: 1; Xunsigned bquan: 5; X unsigned price; X} bill[BILLSZ]; X XMONSTER shopkeeper; X Xstruct permonst shk_pm = { X "shopkeeper", '@', 10, 12, 0, 4, 8, 0 X}; X Xlong robbed = 0, total; X X/* X * shoproom = index in rooms; set by inshop() X * shlevel = last level we initialized shopkeeper X */ X Xchar billct = 0, shoproom, shlevel; Xchar *shopnam[] = { X "engagement ring", "walking cane", "antique weapon", X "delicatessen", "second hand book", "liquor", X "used armor", "assorted antiques" X}; X XCOORDINATES shk, shd; X /* Usual position shopkeeper;position shop door */ X X#define SHOP_NAME shopnam[rooms[shoproom].rtype - 8] X Xshkdead () { X shopkeeper = 0; X rooms[shoproom].rtype = 0; X setpaid (); X} X Xsetpaid () { X register tmp; X register OBJECT obj; X X for (obj = invent; obj; obj = obj -> nobj) X obj -> unpaid = 0; X for (tmp = 0; tmp < billct; tmp++) X if (bill[tmp].useup) X ofree (bill[tmp].op); X billct = 0; X} X Xaddupbill () { /* Delivers result in total */ X register ct = billct; X X total = 0; X while (ct--) X total += bill[ct].price; X} X Xinshproom (x, y) Xregister x, y; /* a3 */ X{ X return (inroom (x, y) == shoproom); X} X Xinshop () { X register tmp = inroom (u.ux, u.uy); X X if (tmp < 0 || rooms[tmp].rtype < 8) { X u.uinshop = 0; X if (billct) { X pline ("Somehow you escaped the shop without paying!"); X addupbill (); X pline ("You stole for a total worth of %U zorkmids.", total); X robbed += total; X setpaid (); X } X } X else { X shoproom = tmp; X if (shlevel != dlevel) X shopinit (); X if (!u.uinshop) { X pline ("%s to Dirk's %s shop!", X (shopkeeper -> angry) ? X "You're not that welcome" : "Welcome", X SHOP_NAME); X ++u.uinshop; X } X } X return (u.uinshop); X} X X/* Called by useup and dothrow only */ Xonbill (obj) Xregister OBJECT obj; X{ X register tmp; X X for (tmp = 0; tmp < billct; tmp++) X if (bill[tmp].op == obj) { X bill[tmp].useup = 1; X obj -> unpaid = 0;/* only for doinvbill */ X return (ONBILL); X } X return (NOTONBILL); X} X Xdopay () { X register unsigned tmp; X char buffer[BUFSZ]; X X multi = 0; X if (!inshop ()) { X flags.move = 0; X pline ("You are not in a shop."); X return; X } X X if (!shopkeeper || !inshproom (shopkeeper -> mx, X shopkeeper -> my)) { X pline ("There is nobody here to receive your payment."); X return; X } X if (!billct) { X pline ("You do not owe the shopkeeper anything."); X if (!u.ugold) { X pline ("Moreover, you have no money."); X return; X } X if (robbed) { X pline ("But since the shop has been robbed recently"); X pline ("You %srepay the shopkeeper's expenses.", (u.ugold < robbed) ? X "partially " : ""); X u.ugold -= robbed; X if (u.ugold < 0) X u.ugold = 0; X flags.dgold = 1; X robbed = 0; X return; X } X if (shopkeeper -> angry) { X pline ("But in order to appease the angry shopkeeper,"); X if (u.ugold >= 1000L) { X tmp = 1000; X pline ("You give him 1000 gold pieces."); X } X else { X tmp = (int) u.ugold; X pline ("You give him all your money."); X } X u.ugold -= (long) tmp; X flags.dgold = 1; X if (rn2 (3)) { X pline ("The shopkeeper calms down."); X shopkeeper -> angry = 0; X } X else X pline ("The shopkeeper is as angry as ever."); X } X return; X } X X while (billct) { X billct--; X bill[billct].op -> unpaid = 0; X doname (bill[billct].op, buffer); X tmp = bill[billct].price; X if (shopkeeper -> angry) X tmp += tmp / 3; X if (u.ugold < tmp) { X ++bill[billct].op -> unpaid; X billct++; X pline ("You don't have gold enough to pay %s.", X buffer); X return; X } X u.ugold -= tmp; X flags.dgold = 1; X pline ("You bought %s for %d gold pieces.", buffer, tmp); X if (bill[billct].useup) X ofree (bill[billct].op); X } X pline ("Thank you for shopping in Dirk's %s store!", X SHOP_NAME); X shopkeeper -> angry = 0; X} X Xpaybill () { /* Called after dying (or quitting) with X nonempty bill */ X if (shopkeeper) { X addupbill (); X if (total > u.ugold) { X u.ugold = 0; X if (invent) X pline ("The shopkeeper comes and takes all your possessions."); X } X else { X u.ugold -= total; X pline ("The shopkeeper comes and takes the %D zorkmids you owed him.", X total); X } X } X more (); X} X Xaddtobill (obj) Xregister OBJECT obj; X{ X if (!inshop ()) X return; X if (billct == BILLSZ) { X pline ("You got that for free!"); X return; X } X bill[billct].op = obj; X bill[billct].bquan = obj -> quan; X bill[billct].useup = 0; X bill[billct++].price = getprice (obj); X obj -> unpaid = 1; X} X Xsubfrombill (obj) Xregister OBJECT obj; X{ X register tmp; X register OBJECT otmp; X X if (!inshop ()) X return; X for (tmp = 0; tmp < billct; tmp++) X if (bill[tmp].op == obj) { X obj -> unpaid = 0; X if (bill[tmp].bquan != obj -> quan) { X bill[tmp].op = otmp = newobj (); X *otmp = *obj; X otmp -> quan = (bill[tmp].bquan -= X obj -> quan); X bill[tmp].price *= otmp -> quan; X bill[tmp].price /= (otmp -> quan + X obj -> quan); X bill[tmp].useup = 1; X return; X } X billct--; X bill[tmp] = bill[billct]; X return; X } X/* I dropped something of my own, wanting to sell it */ X if (shopkeeper -> msleep || shopkeeper -> mfroz || X !inshproom (shopkeeper -> mx, shopkeeper -> my) || X robbed || u.ux == shk.x && u.uy == shk.y || X u.ux == shd.x && u.uy == shd.y) X return; X tmp = getprice (obj); X if (shopkeeper -> angry) { X tmp /= 3; X shopkeeper -> angry = 0; X } X else X tmp >>= 1; X if (tmp < 2) X tmp = 2; X u.ugold += tmp; X flags.dgold = 1; X doname (obj, buf); X pline ("You sold %s and got %d gold pieces.", buf, tmp); X} X Xdoinvbill () { X register unsigned tmp, cnt = 0; X X for (tmp = 0; tmp < billct; tmp++) X if (bill[tmp].useup) { X if (!cnt && !flags.oneline) { X getret (); X cls (); X printf ("\n\nUnpaid articles already used up:\n\n"); X } X strcpy (buf, "* - "); X doname (bill[tmp].op, &buf[5]); X for (cnt = 0; buf[cnt]; cnt++); X while (cnt < 50) X buf[cnt++] = ' '; X sprintf (&buf[cnt], " %5d zorkmids", X bill[tmp].price); X if (flags.oneline) X pline (buf); X else X printf ("%s\n", buf); X if (!cnt % 20) X getret (); X } X} X Xgetprice (obj) Xregister OBJECT obj; X{ X register tmp, ac; X X switch (obj -> olet) { X case '"': X tmp = rnd (500); X break; X case '=': X case '/': X tmp = rnd (100); X break; X case '?': X case '!': X tmp = rnd (50); X break; X case '*': X tmp = rnd (6); X break; X case '%': X tmp = rnd (5 + 2000 / realhunger ()); X break; X case '[': X ac = obj -> spe; X tmp = (100 + ac * ac * rnd (10 + ac)) / 10; X break; X case ')': X if (obj -> otyp <= W_AMMUNITION) X tmp = rnd (10); X else if (obj -> otyp == W_LONG_SWORD || obj -> otyp == X W_TWOH_SWORD) X tmp = rnd (150); X else X tmp = rnd (75); X break; X case '_': X default: X tmp = 1000; X } X return (10 * obj -> quan * tmp); X} X Xrealhunger () { /* not completely foolproof (??) */ X register tmp = u.uhunger; X register OBJECT otmp = invent; X X while (otmp) { X if (otmp -> olet == '%' && !otmp -> unpaid) X tmp += foods[otmp -> otyp].nutrition; X otmp = otmp -> nobj; X } X return tmp; X} X Xshopinit () { X register MKROOM * sroom = &rooms[shoproom]; X register i, j, x, y; X X shlevel = dlevel; X shd = doors[sroom -> fdoor]; X shk.x = shd.x; X shk.y = shd.y; X if (shk.x == sroom -> lx - 1) X shk.x++; X else if (shk.x == sroom -> hx + 1) X shk.x--; X else if (shk.y == sroom -> ly - 1) X shk.y++; X else if (shk.y == sroom -> hy + 1) X shk.y--; X else { X sroom -> rtype = 0; X pline ("Where is shopdoor?"); X impossible (); X return; X } X if (shopkeeper) X return; /* We have been on this level before */ X if (makemon (&shk_pm)) X panic (CORE, "Cannot create shopkeeper?"); X shopkeeper = fmon; X shopkeeper -> angry = u.uhcursed; X if (m_at (shk.x, shk.y) || (shk.x == u.ux && shk.y == u.uy)) { X /* (a3)`mnexto(shopkeeper)' is fout gaan */ X prl (shk.x, shk.y); X for (i = -1; i < 2; i++) X for (j = -1; j < 2; j++) X if (levl[x = shk.x + i][y = shk.y + j].typ == X ROOM) X if (!m_at (x, y)) { X fmon -> mx = x; X fmon -> my = y; X pmon (shopkeeper); X return; X } X fmon -> mx = shk.x; X fmon -> my = shk.y; X return; /* bovenop een ander monster */ X } X else { X fmon -> mx = shk.x; X fmon -> my = shk.y; X } X pmon (shopkeeper); X} X Xsetangry () { X if (shopkeeper -> data -> mlet == '@' && !shopkeeper -> angry) { X pline ("The shopkeeper gets angry."); X ++shopkeeper -> angry; X } X} X Xshk_move () { X register MONSTER mtmp; X char gx, gy, omx, omy, cnt, appr, X nix, niy, ddx, ddy, zx, zy, num; X X omx = shopkeeper -> mx; X omy = shopkeeper -> my; X if (!u.uinshop && inshproom (omx, omy) && X levl[omx][omy].typ == ROOM) X return NOMOVE; X if (shopkeeper -> angry && dist (omx, omy) < 3) { X hitu (shk_pm.mhd, d (shk_pm.damn, shk_pm.damd), X shk_pm.mname); X return NOMOVE; X } X appr = 1; X if ((shopkeeper -> angry) && !u.uinvis) { X gx = u.ux; /* Fred */ X gy = u.uy; X } X else if (shk.x == omx && shk.y == omy && !billct && X !shopkeeper -> angry && X (!robbed || (u.ux == shd.x && u.uy == shd.y)) && X dist (omx, omy) < 3) { X appr = 0; X gx = 0; X gy = 0; X } X else { X gx = shk.x; X gy = shk.y; X } X cnt = 0; X if (omx == gx && omy == gy) X return NOMOVE; X if (shopkeeper -> mconf) X appr = 0; X nix = omx; X niy = omy; X for (ddx = -1; ddx <= 1; ddx++) X for (ddy = -1; ddy <= 1; ddy++) { X zx = omx + ddx; X zy = omy + ddy; X num = levl[zx][zy].typ;/* a3 */ X if ((ddx || ddy) && (num == ROOM || !inshproom (omx, omy) X && (num == CORR || num == DOOR)) && X (shopkeeper -> mconf || X ((zx != u.ux || zy != u.uy) && !m_at (zx, zy))) && X (!appr && !rn2 (++cnt) || appr && GDIST (zx, zy) < X GDIST (nix, niy))) { X nix = zx; X niy = zy; X } X } X if (nix != omx || niy != omy) { X if (shopkeeper -> mconf && (mtmp = m_at (nix, niy))) { X if (hitmm (shopkeeper, mtmp) == 1 && rn2 (3) X && hitmm (mtmp, shopkeeper) == DEAD) X return DEAD; X return NOMOVE; X } X shopkeeper -> mx = nix; X shopkeeper -> my = niy; X/* The shopkeeper might have been turned into an X */ X levlsym (omx, omy, shopkeeper -> data -> mlet); X pmon (shopkeeper); X return MOVE; X } X return NOMOVE; X} / echo 'x - mklev.svlev.c' sed 's/^X//' > mklev.svlev.c << '/' X/* X * Mklev.savelev.c X */ X Xsavelev () { X register int fd; X register MONSTER mtmp, mtmp2; X register GOLD_TRAP gtmp, gtmp2; X register OBJECT otmp, otmp2; X int minusone = -1; X X if ((fd = creat (tfile, 0644)) < 0) X panic ("Cannot create %s\n", tfile); X bwrite (fd, levl, sizeof (levl)); X bwrite (fd, nul, sizeof (unsigned)); X bwrite (fd, (char *) & xupstair, 1); X bwrite (fd, (char *) & yupstair, 1); X bwrite (fd, (char *) & xdnstair, 1); X bwrite (fd, (char *) & ydnstair, 1); X for (mtmp = fmon; mtmp; mtmp = mtmp2) { X mtmp2 = mtmp -> nmon; X bwrite (fd, &mtmp -> mxlth, sizeof (int)); X bwrite (fd, mtmp, mtmp -> mxlth + sizeof (struct monst)); X X/* Michiel save stolen objects */ X bwrite (fd, nul, sizeof (struct stole)); X } X bwrite (fd, &minusone, sizeof (int)); X for (gtmp = fgold; gtmp; gtmp = gtmp2) { X gtmp2 = gtmp -> ngen; X bwrite (fd, gtmp, sizeof (struct gen)); X free (gtmp); X } X bwrite (fd, nul, sizeof (struct gen)); X for (gtmp = ftrap; gtmp; gtmp = gtmp2) { X gtmp2 = gtmp -> ngen; X bwrite (fd, gtmp, sizeof (struct gen)); X free (gtmp); X } X bwrite (fd, nul, sizeof (struct gen)); X for (otmp = fobj; otmp; otmp = otmp2) { X otmp2 = otmp -> nobj; X bwrite (fd, otmp, sizeof (struct obj)); X free (otmp); X } X bwrite (fd, nul, sizeof (struct obj)); X bwrite (fd, rooms, sizeof (rooms)); X bwrite (fd, doors, sizeof (doors)); X fgold = TRAP_NULL; X ftrap = TRAP_NULL; X fmon = MON_NULL; X fobj = OBJ_NULL; X} X X/*NOSTRICT*/ Xbwrite (fd, loc, num) Xregister int fd, num; Xregister char *loc; X{ X if (write (fd, loc, num) != num) X panic ("Cannot write %d bytes to file #%d", num, fd); X} / echo 'Part 02 of Hack complete.' exit -- Michiel Huisjes. {seismo|decvax|philabs}!mcvax!vu44!ark!huisjes Brought to you by Super Global Mega Corp .com