Hack sources for PDP11/44 and PDP11/45 (part 2 of 5)

0 views
Skip to first unread message

Michiel B. Huisjes

unread,
Feb 6, 1985, 1:47:31 AM2/6/85
to
#!/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<letter> is used for u.u<letter> + d<letter> */
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

Reply all
Reply to author
Forward
0 new messages