From 75bfdaf4b0ca61af280a2f3342e1b7db652b6533 Mon Sep 17 00:00:00 2001 From: CSRG Date: Thu, 25 Jul 1985 17:18:53 -0800 Subject: [PATCH] BSD 4_3_Tahoe development Work on file usr/src/games/hack/hack.zap.c Work on file usr/src/games/hack/help Work on file usr/src/games/hack/hh Synthesized-from: CSRG/cd2/4.3tahoe --- usr/src/games/hack/hack.zap.c | 642 ++++++++++++++++++++++++++++++++++ usr/src/games/hack/help | 132 +++++++ usr/src/games/hack/hh | 55 +++ 3 files changed, 829 insertions(+) create mode 100644 usr/src/games/hack/hack.zap.c create mode 100644 usr/src/games/hack/help create mode 100644 usr/src/games/hack/hh diff --git a/usr/src/games/hack/hack.zap.c b/usr/src/games/hack/hack.zap.c new file mode 100644 index 0000000000..e1472b5690 --- /dev/null +++ b/usr/src/games/hack/hack.zap.c @@ -0,0 +1,642 @@ +/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ +/* hack.zap.c - version 1.0.3 */ + +#include "hack.h" + +extern struct obj *mkobj_at(); +extern struct monst *makemon(), *mkmon_at(), youmonst; +struct monst *bhit(); +char *exclam(); + +char *fl[]= { + "magic missile", + "bolt of fire", + "sleep ray", + "bolt of cold", + "death ray" +}; + +/* Routines for IMMEDIATE wands. */ +/* bhitm: monster mtmp was hit by the effect of wand otmp */ +bhitm(mtmp, otmp) +register struct monst *mtmp; +register struct obj *otmp; +{ + wakeup(mtmp); + switch(otmp->otyp) { + case WAN_STRIKING: + if(u.uswallow || rnd(20) < 10+mtmp->data->ac) { + register int tmp = d(2,12); + hit("wand", mtmp, exclam(tmp)); + mtmp->mhp -= tmp; + if(mtmp->mhp < 1) killed(mtmp); + } else miss("wand", mtmp); + break; + case WAN_SLOW_MONSTER: + mtmp->mspeed = MSLOW; + break; + case WAN_SPEED_MONSTER: + mtmp->mspeed = MFAST; + break; + case WAN_UNDEAD_TURNING: + if(index(UNDEAD,mtmp->data->mlet)) { + mtmp->mhp -= rnd(8); + if(mtmp->mhp < 1) killed(mtmp); + else mtmp->mflee = 1; + } + break; + case WAN_POLYMORPH: + if( newcham(mtmp,&mons[rn2(CMNUM)]) ) + objects[otmp->otyp].oc_name_known = 1; + break; + case WAN_CANCELLATION: + mtmp->mcan = 1; + break; + case WAN_TELEPORTATION: + rloc(mtmp); + break; + case WAN_MAKE_INVISIBLE: + mtmp->minvis = 1; + break; +#ifdef WAN_PROBING + case WAN_PROBING: + mstatusline(mtmp); + break; +#endif WAN_PROBING + default: + impossible("What an interesting wand (%u)", otmp->otyp); + } +} + +bhito(obj, otmp) /* object obj was hit by the effect of wand otmp */ +register struct obj *obj, *otmp; /* returns TRUE if sth was done */ +{ + register int res = TRUE; + + if(obj == uball || obj == uchain) + res = FALSE; + else + switch(otmp->otyp) { + case WAN_POLYMORPH: + /* preserve symbol and quantity, but turn rocks into gems */ + mkobj_at((obj->otyp == ROCK || obj->otyp == ENORMOUS_ROCK) + ? GEM_SYM : obj->olet, + obj->ox, obj->oy) -> quan = obj->quan; + delobj(obj); + break; + case WAN_STRIKING: + if(obj->otyp == ENORMOUS_ROCK) + fracture_rock(obj); + else + res = FALSE; + break; + case WAN_CANCELLATION: + if(obj->spe && obj->olet != AMULET_SYM) { + obj->known = 0; + obj->spe = 0; + } + break; + case WAN_TELEPORTATION: + rloco(obj); + break; + case WAN_MAKE_INVISIBLE: + obj->oinvis = 1; + break; + case WAN_UNDEAD_TURNING: + res = revive(obj); + break; + case WAN_SLOW_MONSTER: /* no effect on objects */ + case WAN_SPEED_MONSTER: +#ifdef WAN_PROBING + case WAN_PROBING: +#endif WAN_PROBING + res = FALSE; + break; + default: + impossible("What an interesting wand (%u)", otmp->otyp); + } + return(res); +} + +dozap() +{ + register struct obj *obj; + xchar zx,zy; + + obj = getobj("/", "zap"); + if(!obj) return(0); + if(obj->spe < 0 || (obj->spe == 0 && rn2(121))) { + pline("Nothing Happens."); + return(1); + } + if(obj->spe == 0) + pline("You wrest one more spell from the worn-out wand."); + if(!(objects[obj->otyp].bits & NODIR) && !getdir(1)) + return(1); /* make him pay for knowing !NODIR */ + obj->spe--; + if(objects[obj->otyp].bits & IMMEDIATE) { + if(u.uswallow) + bhitm(u.ustuck, obj); + else if(u.dz) { + if(u.dz > 0) { + register struct obj *otmp = o_at(u.ux, u.uy); + if(otmp) + (void) bhito(otmp, obj); + } + } else + (void) bhit(u.dx,u.dy,rn1(8,6),0,bhitm,bhito,obj); + } else { + switch(obj->otyp){ + case WAN_LIGHT: + litroom(TRUE); + break; + case WAN_SECRET_DOOR_DETECTION: + if(!findit()) return(1); + break; + case WAN_CREATE_MONSTER: + { register int cnt = 1; + if(!rn2(23)) cnt += rn2(7) + 1; + while(cnt--) + (void) makemon((struct permonst *) 0, u.ux, u.uy); + } + break; + case WAN_WISHING: + { char buf[BUFSZ]; + register struct obj *otmp; + extern struct obj *readobjnam(), *addinv(); + if(u.uluck + rn2(5) < 0) { + pline("Unfortunately, nothing happens."); + break; + } + pline("You may wish for an object. What do you want? "); + getlin(buf); + if(buf[0] == '\033') buf[0] = 0; + otmp = readobjnam(buf); + otmp = addinv(otmp); + prinv(otmp); + break; + } + case WAN_DIGGING: + /* Original effect (approximately): + * from CORR: dig until we pierce a wall + * from ROOM: piece wall and dig until we reach + * an ACCESSIBLE place. + * Currently: dig for digdepth positions; + * also down on request of Lennart Augustsson. + */ + { register struct rm *room; + register int digdepth; + if(u.uswallow) { + register struct monst *mtmp = u.ustuck; + + pline("You pierce %s's stomach wall!", + monnam(mtmp)); + mtmp->mhp = 1; /* almost dead */ + unstuck(mtmp); + mnexto(mtmp); + break; + } + if(u.dz) { + if(u.dz < 0) { + pline("You loosen a rock from the ceiling."); + pline("It falls on your head!"); + losehp(1, "falling rock"); + mksobj_at(ROCK, u.ux, u.uy); + fobj->quan = 1; + stackobj(fobj); + if(Invisible) newsym(u.ux, u.uy); + } else { + dighole(); + } + break; + } + zx = u.ux+u.dx; + zy = u.uy+u.dy; + digdepth = 8 + rn2(18); + Tmp_at(-1, '*'); /* open call */ + while(--digdepth >= 0) { + if(!isok(zx,zy)) break; + room = &levl[zx][zy]; + Tmp_at(zx,zy); + if(!xdnstair){ + if(zx < 3 || zx > COLNO-3 || + zy < 3 || zy > ROWNO-3) + break; + if(room->typ == HWALL || + room->typ == VWALL){ + room->typ = ROOM; + break; + } + } else + if(room->typ == HWALL || room->typ == VWALL || + room->typ == SDOOR || room->typ == LDOOR){ + room->typ = DOOR; + digdepth -= 2; + } else + if(room->typ == SCORR || !room->typ) { + room->typ = CORR; + digdepth--; + } + mnewsym(zx,zy); + zx += u.dx; + zy += u.dy; + } + mnewsym(zx,zy); /* not always necessary */ + Tmp_at(-1,-1); /* closing call */ + break; + } + default: + buzz((int) obj->otyp - WAN_MAGIC_MISSILE, + u.ux, u.uy, u.dx, u.dy); + break; + } + if(!objects[obj->otyp].oc_name_known) { + objects[obj->otyp].oc_name_known = 1; + more_experienced(0,10); + } + } + return(1); +} + +char * +exclam(force) +register int force; +{ + /* force == 0 occurs e.g. with sleep ray */ + /* note that large force is usual with wands so that !! would + require information about hand/weapon/wand */ + return( (force < 0) ? "?" : (force <= 4) ? "." : "!" ); +} + +hit(str,mtmp,force) +register char *str; +register struct monst *mtmp; +register char *force; /* usually either "." or "!" */ +{ + if(!cansee(mtmp->mx,mtmp->my)) pline("The %s hits it.", str); + else pline("The %s hits %s%s", str, monnam(mtmp), force); +} + +miss(str,mtmp) +register char *str; +register struct monst *mtmp; +{ + if(!cansee(mtmp->mx,mtmp->my)) pline("The %s misses it.",str); + else pline("The %s misses %s.",str,monnam(mtmp)); +} + +/* bhit: called when a weapon is thrown (sym = obj->olet) or when an + IMMEDIATE wand is zapped (sym = 0); the weapon falls down at end of + range or when a monster is hit; the monster is returned, and bhitpos + is set to the final position of the weapon thrown; the ray of a wand + may affect several objects and monsters on its path - for each of + these an argument function is called. */ +/* check !u.uswallow before calling bhit() */ + +struct monst * +bhit(ddx,ddy,range,sym,fhitm,fhito,obj) +register int ddx,ddy,range; /* direction and range */ +char sym; /* symbol displayed on path */ +int (*fhitm)(), (*fhito)(); /* fns called when mon/obj hit */ +struct obj *obj; /* 2nd arg to fhitm/fhito */ +{ + register struct monst *mtmp; + register struct obj *otmp; + register int typ; + + bhitpos.x = u.ux; + bhitpos.y = u.uy; + + if(sym) tmp_at(-1, sym); /* open call */ + while(range-- > 0) { + bhitpos.x += ddx; + bhitpos.y += ddy; + typ = levl[bhitpos.x][bhitpos.y].typ; + if(mtmp = m_at(bhitpos.x,bhitpos.y)){ + if(sym) { + tmp_at(-1, -1); /* close call */ + return(mtmp); + } + (*fhitm)(mtmp, obj); + range -= 3; + } + if(fhito && (otmp = o_at(bhitpos.x,bhitpos.y))){ + if((*fhito)(otmp, obj)) + range--; + } + if(!ZAP_POS(typ)) { + bhitpos.x -= ddx; + bhitpos.y -= ddy; + break; + } + if(sym) tmp_at(bhitpos.x, bhitpos.y); + } + + /* leave last symbol unless in a pool */ + if(sym) + tmp_at(-1, (levl[bhitpos.x][bhitpos.y].typ == POOL) ? -1 : 0); + return(0); +} + +struct monst * +boomhit(dx,dy) { + register int i, ct; + register struct monst *mtmp; + char sym = ')'; + extern schar xdir[], ydir[]; + + bhitpos.x = u.ux; + bhitpos.y = u.uy; + + for(i=0; i<8; i++) if(xdir[i] == dx && ydir[i] == dy) break; + tmp_at(-1, sym); /* open call */ + for(ct=0; ct<10; ct++) { + if(i == 8) i = 0; + sym = ')' + '(' - sym; + tmp_at(-2, sym); /* change let call */ + dx = xdir[i]; + dy = ydir[i]; + bhitpos.x += dx; + bhitpos.y += dy; + if(mtmp = m_at(bhitpos.x, bhitpos.y)){ + tmp_at(-1,-1); + return(mtmp); + } + if(!ZAP_POS(levl[bhitpos.x][bhitpos.y].typ)) { + bhitpos.x -= dx; + bhitpos.y -= dy; + break; + } + if(bhitpos.x == u.ux && bhitpos.y == u.uy) { /* ct == 9 */ + if(rn2(20) >= 10+u.ulevel){ /* we hit ourselves */ + (void) thitu(10, rnd(10), "boomerang"); + break; + } else { /* we catch it */ + tmp_at(-1,-1); + pline("Skillfully, you catch the boomerang."); + return(&youmonst); + } + } + tmp_at(bhitpos.x, bhitpos.y); + if(ct % 5 != 0) i++; + } + tmp_at(-1, -1); /* do not leave last symbol */ + return(0); +} + +char +dirlet(dx,dy) register dx,dy; { + return + (dx == dy) ? '\\' : (dx && dy) ? '/' : dx ? '-' : '|'; +} + +/* type == -1: monster spitting fire at you */ +/* type == -1,-2,-3: bolts sent out by wizard */ +/* called with dx = dy = 0 with vertical bolts */ +buzz(type,sx,sy,dx,dy) +register int type; +register xchar sx,sy; +register int dx,dy; +{ + int abstype = abs(type); + register char *fltxt = (type == -1) ? "blaze of fire" : fl[abstype]; + struct rm *lev; + xchar range; + struct monst *mon; + + if(u.uswallow) { + register int tmp; + + if(type < 0) return; + tmp = zhit(u.ustuck, type); + pline("The %s rips into %s%s", + fltxt, monnam(u.ustuck), exclam(tmp)); + return; + } + if(type < 0) pru(); + range = rn1(7,7); + Tmp_at(-1, dirlet(dx,dy)); /* open call */ + while(range-- > 0) { + sx += dx; + sy += dy; + if((lev = &levl[sx][sy])->typ) Tmp_at(sx,sy); + else { + int bounce = 0; + if(cansee(sx-dx,sy-dy)) + pline("The %s bounces!", fltxt); + if(ZAP_POS(levl[sx][sy-dy].typ)) + bounce = 1; + if(ZAP_POS(levl[sx-dx][sy].typ)) { + if(!bounce || rn2(2)) bounce = 2; + } + switch(bounce){ + case 0: + dx = -dx; + dy = -dy; + continue; + case 1: + dy = -dy; + sx -= dx; + break; + case 2: + dx = -dx; + sy -= dy; + break; + } + Tmp_at(-2,dirlet(dx,dy)); + continue; + } + if(lev->typ == POOL && abstype == 1 /* fire */) { + range -= 3; + lev->typ = ROOM; + if(cansee(sx,sy)) { + mnewsym(sx,sy); + pline("The water evaporates."); + } else + pline("You hear a hissing sound."); + } + if((mon = m_at(sx,sy)) && + (type != -1 || mon->data->mlet != 'D')) { + wakeup(mon); + if(rnd(20) < 18 + mon->data->ac) { + register int tmp = zhit(mon,abstype); + if(mon->mhp < 1) { + if(type < 0) { + if(cansee(mon->mx,mon->my)) + pline("%s is killed by the %s!", + Monnam(mon), fltxt); + mondied(mon); + } else + killed(mon); + } else + hit(fltxt, mon, exclam(tmp)); + range -= 2; + } else + miss(fltxt,mon); + } else if(sx == u.ux && sy == u.uy) { + nomul(0); + if(rnd(20) < 18+u.uac) { + register int dam = 0; + range -= 2; + pline("The %s hits you!",fltxt); + switch(abstype) { + case 0: + dam = d(2,6); + break; + case 1: + if(Fire_resistance) + pline("You don't feel hot!"); + else dam = d(6,6); + if(!rn2(3)) + burn_scrolls(); + break; + case 2: + nomul(-rnd(25)); /* sleep ray */ + break; + case 3: + if(Cold_resistance) + pline("You don't feel cold!"); + else dam = d(6,6); + break; + case 4: + u.uhp = -1; + } + losehp(dam,fltxt); + } else pline("The %s whizzes by you!",fltxt); + stop_occupation(); + } + if(!ZAP_POS(lev->typ)) { + int bounce = 0, rmn; + if(cansee(sx,sy)) pline("The %s bounces!",fltxt); + range--; + if(!dx || !dy || !rn2(20)){ + dx = -dx; + dy = -dy; + } else { + if(ZAP_POS(rmn = levl[sx][sy-dy].typ) && + (IS_ROOM(rmn) || ZAP_POS(levl[sx+dx][sy-dy].typ))) + bounce = 1; + if(ZAP_POS(rmn = levl[sx-dx][sy].typ) && + (IS_ROOM(rmn) || ZAP_POS(levl[sx-dx][sy+dy].typ))) + if(!bounce || rn2(2)) + bounce = 2; + + switch(bounce){ + case 0: + dy = -dy; + dx = -dx; + break; + case 1: + dy = -dy; + break; + case 2: + dx = -dx; + break; + } + Tmp_at(-2, dirlet(dx,dy)); + } + } + } + Tmp_at(-1,-1); +} + +zhit(mon,type) /* returns damage to mon */ +register struct monst *mon; +register type; +{ + register int tmp = 0; + + switch(type) { + case 0: /* magic missile */ + tmp = d(2,6); + break; + case -1: /* Dragon blazing fire */ + case 1: /* fire */ + if(index("Dg", mon->data->mlet)) break; + tmp = d(6,6); + if(index("YF", mon->data->mlet)) tmp += 7; + break; + case 2: /* sleep*/ + mon->mfroz = 1; + break; + case 3: /* cold */ + if(index("YFgf", mon->data->mlet)) break; + tmp = d(6,6); + if(mon->data->mlet == 'D') tmp += 7; + break; + case 4: /* death*/ + if(index(UNDEAD, mon->data->mlet)) break; + tmp = mon->mhp+1; + break; + } + mon->mhp -= tmp; + return(tmp); +} + +#define CORPSE_I_TO_C(otyp) (char) ((otyp >= DEAD_ACID_BLOB)\ + ? 'a' + (otyp - DEAD_ACID_BLOB)\ + : '@' + (otyp - DEAD_HUMAN)) +revive(obj) +register struct obj *obj; +{ + register struct monst *mtmp; + + if(obj->olet == FOOD_SYM && obj->otyp > CORPSE) { + /* do not (yet) revive shopkeepers */ + /* Note: this might conceivably produce two monsters + at the same position - strange, but harmless */ + mtmp = mkmon_at(CORPSE_I_TO_C(obj->otyp),obj->ox,obj->oy); + delobj(obj); + } + return(!!mtmp); /* TRUE if some monster created */ +} + +rloco(obj) +register struct obj *obj; +{ + register tx,ty,otx,oty; + + otx = obj->ox; + oty = obj->oy; + do { + tx = rn1(COLNO-3,2); + ty = rn2(ROWNO); + } while(!goodpos(tx,ty)); + obj->ox = tx; + obj->oy = ty; + if(cansee(otx,oty)) + newsym(otx,oty); +} + +fracture_rock(obj) /* fractured by pick-axe or wand of striking */ +register struct obj *obj; /* no texts here! */ +{ + /* unpobj(obj); */ + obj->otyp = ROCK; + obj->quan = 7 + rn2(60); + obj->owt = weight(obj); + obj->olet = WEAPON_SYM; + if(cansee(obj->ox,obj->oy)) + prl(obj->ox,obj->oy); +} + +burn_scrolls() +{ + register struct obj *obj, *obj2; + register int cnt = 0; + + for(obj = invent; obj; obj = obj2) { + obj2 = obj->nobj; + if(obj->olet == SCROLL_SYM) { + cnt++; + useup(obj); + } + } + if(cnt > 1) { + pline("Your scrolls catch fire!"); + losehp(cnt, "burning scrolls"); + } else if(cnt) { + pline("Your scroll catches fire!"); + losehp(1, "burning scroll"); + } +} diff --git a/usr/src/games/hack/help b/usr/src/games/hack/help new file mode 100644 index 0000000000..24b22a5d41 --- /dev/null +++ b/usr/src/games/hack/help @@ -0,0 +1,132 @@ + Welcome to HACK! ( description of version 1.0.3 ) + + Hack is a Dungeons and Dragons like game where you (the adventurer) +descend into the depths of the dungeon in search of the Amulet of Yendor +(reputed to be hidden on the twentieth level). You are accompanied by a +little dog that can help you in many ways and can be trained to do all +sorts of things. On the way you will find useful (or useless) items, (quite +possibly with magic properties) and assorted monsters. You attack a monster +by trying to move into the space a monster is in (but often it is much +wiser to leave it alone). + + Unlike most adventure games, which give you a verbal description of +your location, hack gives you a visual image of the dungeon level you are on. + + Hack uses the following symbols: + A to Z and a to z: monsters. You can find out what a letter +represents by saying "/ (letter)", as in "/A", which will tell you that 'A' +is a giant ant. + - and | These form the walls of a room (or maze). + . this is the floor of a room. + # this is a corridor. + > this is the staircase to the next level. + < the staircase to the previous level. + ` A large boulder. + @ You (usually). + ^ A trap. + ) A weapon of some sort. + ( Some other useful object (key, rope, dynamite, camera, ...) + [ A suit of armor. + % A piece of food (not necessarily healthy ...). + / A wand. + = A ring. + ? A scroll. + ! A magic potion. + $ A pile or pot of gold. + +Commands: + Hack knows the following commands: + ? help: print this list. + Q Quit the game. + S Save the game. + ! Escape to a shell. + ^Z Suspend the game. + < up: go up the staircase (if you are standing on it). + > down: go down (just like up). + kjhlyubn - go one step in the direction indicated. + k: north (i.e., to the top of the screen), + j: south, h: west, l: east, y: ne, u: nw, b: se, n: sw. + KJHLYUBN - Go in that direction until you hit a wall or run + into something. + m (followed by one of kjhlyubn): move without picking up + any objects. + M (followed by one of KJHLYUBN): Move far, no pickup. + f (followed by one of kjhlyubn): move until something + interesting is found. + F (followed by one of KJHLYUBN): as previous, but forking + of corridors is not considered interesting. + i print your inventory. + I print selected parts of your inventory, like in + I* - print all gems in inventory; + IU - print all unpaid items; + IX - print all used up items that are on your shopping bill; + I$ - count your money. + s search for secret doors and traps around you. + ^ ask for the type of a trap you found earlier. + ) ask for current wielded weapon. + [ ask for current armor. + = ask for current rings. + $ count how many gold pieces you are carrying. + . rest, do nothing. + , pick up some things. + : look at what is here. + ^T teleport. + ^R redraw the screen. + ^P repeat last message + (subsequent ^P's repeat earlier messages). + / (followed by any symbol): tell what this symbol represents. + \ tell what has been discovered. + e eat food. + w wield weapon. w- means: wield nothing, use bare hands. + q drink (quaff) a potion. + r read a scroll. + T Takeoff armor. + R Remove Ring. + W Wear armor. + P Put on a ring. + z zap a wand. + t throw an object or shoot an arrow. + p pay your shopping bill. + d drop something. d7a: drop seven items of object a. + D Drop several things. + In answer to the question "What kinds of things do you + want to drop? [!%= au]" you should give zero or more + object symbols possibly followed by 'a' and/or 'u'. + 'a' means: drop all such objects, without asking for + confirmation. + 'u' means: drop only unpaid objects (when in a shop). + a use, apply - Generic command for using a key to lock + or unlock a door, using a camera, using a rope, etc. + c call: name a certain object or class of objects. + C Call: Name an individual monster. + E Engrave: Write a message in the dust on the floor. + E- means: use fingers for writing. + O Set options. You will be asked to enter an option line. + If this is empty, the current options are reported. + Otherwise it should be a list of options separated by commas. + Possible boolean options are: oneline, time, news, tombstone, + rest_on_space, fixinvlet, beginner, male, female. + They can be negated by prefixing them with '!' or "no". + A string option is name; it supplies the answer to the question + "Who are you?"; it may have a suffix. + A compound option is endgame; it is followed by a description + of what parts of the list of topscorers should be printed + when the game is finished. + Usually one will not want to use the 'O' command, but instead + put a HACKOPTIONS="...." line in one's environment. + v print version number. + + You can put a number before a command to repeat it that many times, + as in "20s" or "40.". + + At present, some information is displayed on the bottom line. + (It is expected that this information will go away in future versions.) + You see on what dungeon level you are, how many hit points you have + now (and will have when fully recovered), what your armor class is + (the lower the better), your strength, experience level and the + state of your stomach. + + Have Fun, and Good Hacking! + + + diff --git a/usr/src/games/hack/hh b/usr/src/games/hack/hh new file mode 100644 index 0000000000..d777102dae --- /dev/null +++ b/usr/src/games/hack/hh @@ -0,0 +1,55 @@ +y k u Move commands: + \|/ hykulnjb: single move in specified direction +h-+-l HYKULNJB: repeated move in specified direction + /|\ (until stopped by e.g. a wall) +b j n f: fast movement in direction + (until something interesting is seen) + m: move without picking up objects + +Meta commands: +Q quit leave the game +S save save the game (to be continued later) +! sh escape to some SHELL +^Z suspend suspend the game (independent of your current suspend char) +O set set options +? help print information +/ whatis give name (and sometimes more info) of specified monster +\ known print list of what's been discovered +v version print version number +^R redraw redraw the screen (^R denotes the symbol CTRL/R) +^P print repeat last message (subsequent ^P's repeat earlier messages) +# introduces a long command; not really implemented + +Game commands: +^T teleport teleport +a apply, use use something (a key, camera, etc.) +c call give a name to a class of objects +d drop drop an object. d7a: drop seven items of object a. +e eat eat something +i invent list the inventory (all objects you are carrying) +I invent list selected parts of the inventory + IU: list unpaid objects + IX: list unpaid but used up items + I$: count your money +p pay pay your bill +q drink quaff a potion +r read read a scroll +s search search for secret doors, hidden traps and monsters +t throw throw or shoot a weapon +w wield wield a weapon (w- wield nothing) +z zap zap a wand +C name name an individual monster (e.g., baptize your dog) +D Drop drop several things +E Engrave write a message in the dust on the floor (E- use fingers) +P wear put on a ring +R remove remove a ring +T remove take off some armor +W wear put on some armor +< up go up the stairs +> down go down the stairs +^ trap_id identify a previously found trap +),[,= ask for current weapon, armor, rings, respectively +$ gold count your gold +. rest wait a moment +, pickup pick up all you can carry +: look look at what is here -- 2.20.1