Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!tektronix!tekgen!tekred!games-request
From: games-request@tekred.TEK.COM
Newsgroups: comp.sources.games
Subject: v03i011: NetHack2.2 - display oriented dungeons and dragons, Part11/20
Message-ID: <1897@tekred.TEK.COM>
Date: Wed, 2-Dec-87 12:02:23 EST
Article-I.D.: tekred.1897
Posted: Wed Dec 2 12:02:23 1987
Date-Received: Sun, 6-Dec-87 06:00:33 EST
Sender: billr@tekred.TEK.COM
Lines: 2335
Approved: billr@tekred.TEK.COM
Submitted by: mike@genat.UUCP (Mike Stephenson)
Comp.sources.games: Volume 3, Issue 11
Archive-name: nethack2.2/Part11
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh engrave.c <<'END_OF_engrave.c'
X/* SCCS Id: @(#)engrave.c 2.0 87/09/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X#include "hack.h"
X
Xextern char *nomovemsg;
Xextern char nul[];
Xextern struct obj zeroobj;
X#ifdef KAA
Xextern char *xname();
X#endif
Xstruct engr {
X struct engr *nxt_engr;
X char *engr_txt;
X xchar engr_x, engr_y;
X unsigned engr_lth; /* for save & restore; not length of text */
X long engr_time; /* moment engraving was (will be) finished */
X xchar engr_type;
X#define DUST 1
X#define ENGRAVE 2
X#define BURN 3
X#ifdef MARKER
X#define MARK 4
X#define POLY 5 /* temporary type - for polymorphing engraving */
X#else
X#define POLY 4 /* temporary type - for polymorphing engraving */
X#endif
X} *head_engr;
X
X/* random engravings */
X#ifdef KAA
Xchar *random_engr[] =
X#else
Xchar random_engr[][30] =
X#endif
X {"Elbereth", "ad ae?ar um",
X#ifdef NEWCLASS
X "?la? ?as he??",
X#endif
X /* more added by Eric Backus */
X "?ilroy wa? h?re", "?ala??iel", "Aba?don H?pe...",
X "Fo? a ?ood time c?ll 6?6-4311"};
X#ifdef NEWCLASS
X#define RAND_ENGRS 7
X#else
X#define RAND_ENGRS 6
X#endif
X
Xstruct engr *
Xengr_at(x,y) register xchar x,y; {
Xregister struct engr *ep = head_engr;
X while(ep) {
X if(x == ep->engr_x && y == ep->engr_y)
X return(ep);
X ep = ep->nxt_engr;
X }
X return((struct engr *) 0);
X}
X
Xsengr_at(s,x,y) register char *s; register xchar x,y; {
Xregister struct engr *ep = engr_at(x,y);
Xregister char *t;
Xregister int n;
X if(ep && ep->engr_time <= moves) {
X t = ep->engr_txt;
X/*
X if(!strcmp(s,t)) return(1);
X*/
X n = strlen(s);
X while(*t) {
X if(!strncmp(s,t,n)) return(1);
X t++;
X }
X }
X return(0);
X}
X
Xu_wipe_engr(cnt)
Xregister int cnt;
X{
X if(!u.uswallow && !Levitation)
X wipe_engr_at(u.ux, u.uy, cnt);
X}
X
Xwipe_engr_at(x,y,cnt) register xchar x,y,cnt; {
Xregister struct engr *ep = engr_at(x,y);
Xregister int lth,pos;
Xchar ch;
X if(ep){
X if(ep->engr_type != BURN) {
X if(ep->engr_type != DUST) {
X cnt = rn2(1 + 50/(cnt+1)) ? 0 : 1;
X }
X lth = strlen(ep->engr_txt);
X if(lth && cnt > 0 ) {
X while(cnt--) {
X pos = rn2(lth);
X if((ch = ep->engr_txt[pos]) == ' ')
X continue;
X ep->engr_txt[pos] = (ch != '?') ? '?' : ' ';
X }
X }
X while(lth && ep->engr_txt[lth-1] == ' ')
X ep->engr_txt[--lth] = 0;
X while(ep->engr_txt[0] == ' ')
X ep->engr_txt++;
X if(!ep->engr_txt[0]) del_engr(ep);
X }
X }
X}
X
Xread_engr_at(x,y) register int x,y; {
Xregister struct engr *ep = engr_at(x,y);
Xregister int canfeel;
X if(ep && ep->engr_txt[0]) {
X switch(ep->engr_type) {
X case DUST:
X if(!Blind) pline("Something is written here in the dust.");
X canfeel = 0;
X break;
X case ENGRAVE:
X pline("Something is engraved here on the floor.");
X canfeel = 1;
X break;
X case BURN:
X pline("Some text has been burned here in the floor.");
X canfeel = 1;
X break;
X#ifdef MARKER
X case MARK:
X if(!Blind) pline("There's some graffiti here on the floor.");
X canfeel = 0;
X break;
X#endif
X default:
X impossible("Something is written in a very strange way.");
X canfeel = 1;
X }
X if (canfeel || !Blind)
X pline("You %s: \"%s\".",
X (Blind) ? "feel the words" : "read", ep->engr_txt);
X }
X}
X
Xmake_engr_at(x,y,s)
Xregister int x,y;
Xregister char *s;
X{
X register struct engr *ep;
X
X if(ep = engr_at(x,y))
X del_engr(ep);
X ep = (struct engr *)
X alloc((unsigned)(sizeof(struct engr) + strlen(s) + 1));
X ep->nxt_engr = head_engr;
X head_engr = ep;
X ep->engr_x = x;
X ep->engr_y = y;
X ep->engr_txt = (char *)(ep + 1);
X (void) strcpy(ep->engr_txt, s);
X ep->engr_time = 0;
X ep->engr_type = DUST;
X ep->engr_lth = strlen(s) + 1;
X}
X/*
X * freehand - returns true if player has a free hand
X */
Xint
Xfreehand(){
X
X return(!uwep ||
X !uwep->cursed ||
X (uwep->otyp != TWO_HANDED_SWORD && (!uarms || !uarms->cursed)));
X/* if ((uwep && uwep->otyp == TWO_HANDED_SWORD) ||
X (uwep && uarms))
X return(0);
X else
X return(1);*/
X}
X
X
X
Xdoengrave(){
Xregister int len, tmp;
Xregister char *sp, *sptmp;
Xregister struct engr *ep, *oep = engr_at(u.ux,u.uy);
Xchar buf[BUFSZ];
Xxchar type;
Xint spct; /* number of leading spaces */
Xregister struct obj *otmp;
X multi = 0;
X
X if(u.uswallow) {
X pline("You're joking. Hahaha!"); /* riv05!a3 */
X return(0);
X }
X
X /* one may write with finger, weapon or wand */
X /* edited by GAN 10/20/86 so as not to change
X * weapon wielded.
X */
X otmp = getobj("#-()/", "write with");
X if(!otmp) return(0);
X
X#ifdef FREEHAND /* There's no reason you should be able to write with a wand
X * while both your hands are tied up. Also, it's necessary to
X * prevent engraving with "worn" objects other than weapons.
X */
X if (!freehand() && otmp != uwep) {
X#else
X /* added by GAN 10/20/86 to require you to need a hand to
X write with.
X */
X if(!(otmp->owornmask || otmp->olet == WAND_SYM) && !freehand()) {
X#endif
X pline("You have no free hand to write with!");
X return(0);
X }
X#ifdef KAA
X if (cantwield(u.usym)) {
X pline("You can't even hold anything!");
X return(0);
X }
X if(otmp != &zeroobj && index("][0`",otmp->olet)) {
X pline("You can't engrave with such a large object!");
X return(1);
X }
X#endif
X
X if(Levitation && otmp->olet != WAND_SYM){ /* riv05!a3 */
X pline("You can't reach the floor!");
X return(0);
X }
X
X if(otmp == &zeroobj) {
X pline("You write in the dust with your fingers.");
X type = DUST;
X } else if(otmp->olet == WAND_SYM && zappable(otmp)) {
X /* changed so any wand gets zapped out, but fire
X * wands become known.
X */
X if((objects[otmp->otyp].bits & NODIR)) {
X zapnodir(otmp);
X type = DUST;
X } else {
X switch(otmp->otyp) {
X case WAN_FIRE:
X if(!objects[otmp->otyp].oc_name_known) {
X pline("The %s is a wand of fire!",
X xname(otmp));
X objects[otmp->otyp].oc_name_known = 1;
X more_experienced(0,10);
X }
X type = BURN;
X break;
X case WAN_DIGGING:
X if(!objects[otmp->otyp].oc_name_known) {
X pline("The %s is a wand of digging!",
X xname(otmp));
X objects[otmp->otyp].oc_name_known = 1;
X more_experienced(0,10);
X }
X type = ENGRAVE;
X break;
X case WAN_POLYMORPH:
X if(oep) {
X del_engr(oep);
X oep = 0;
X type = POLY;
X } else
X type = DUST;
X break;
X case WAN_COLD:
X type = DUST;
X if(!oep || (oep->engr_type != BURN))
X break;
X case WAN_CANCELLATION:
X case WAN_MAKE_INVISIBLE:
X if(!oep) { /* Eric Backus */
X type = DUST;
X break;
X }
X del_engr(oep);
X pline("The engraving on the floor vanishes!");
X return(1);
X break;
X case WAN_TELEPORTATION:
X if(!oep)
X type = DUST;
X else {
X register tx,ty;
X
X do {
X tx = rn1(COLNO-3,2);
X ty = rn2(ROWNO);
X } while(!goodpos(tx,ty));
X oep->engr_x = tx;
X oep->engr_y = ty;
X pline("The engraving on the floor vanishes!");
X return(1);
X }
X break;
X default:
X type = DUST;
X }
X }
X if(type == DUST)
X pline("You write in the dust with %s.",
X doname(otmp));
X
X } else {
X if(otmp->otyp == DAGGER || otmp->otyp == TWO_HANDED_SWORD ||
X otmp->otyp == CRYSKNIFE || otmp->otyp == KATANA ||
X otmp->otyp == SCIMITAR || otmp->otyp == BROAD_SWORD ||
X otmp->otyp == SHORT_SWORD ||
X otmp->otyp == LONG_SWORD || otmp->otyp == AXE) {
X type = ENGRAVE;
X if((int)otmp->spe <= -3) {
X pline("Your %s too dull for engraving.",
X aobjnam(otmp, "are"));
X type = DUST;
X /* following messaged added 10/20/86 - GAN */
X pline("You write in the dust with %s.",
X doname(otmp));
X } else
X pline("You engrave with %s.", doname(otmp));
X#ifdef MARKER
X } else if(otmp->otyp == MAGIC_MARKER) {
X if(otmp->spe <= 0) {
X pline("Your marker is dried out.");
X pline("You write in the dust with the marker.");
X type = DUST;
X } else {
X pline("You write with %s.", doname(otmp));
X type = MARK;
X }
X#endif
X } else {
X pline("You write in the dust with %s.",
X doname(otmp));
X type = DUST;
X }
X }
X
X if(type != POLY && oep && oep->engr_type == DUST){
X pline("You wipe out the message that was written here.");
X del_engr(oep);
X oep = 0;
X }
X if(type == DUST && oep){
X pline("You cannot wipe out the message that is %s in the rock.",
X (oep->engr_type == BURN) ? "burned" : (oep->engr_type == ENGRAVE)? "engraved" : "scribbled");
X return(1);
X }
X if(type == POLY) {
X#ifdef MARKER
X type = rnd(4);
X#else
X type = rnd(3);
X#endif
X strcpy(buf,random_engr[rn2(RAND_ENGRS)]);
X switch(type){
X case DUST:
X pline("\"%s\" is now written on the ground.",buf);
X break;
X case ENGRAVE:
X pline("\"%s\" is now engraved in the rock.",buf);
X break;
X case BURN:
X pline("\"%s\" is now burned in the rock.",buf);
X break;
X#ifdef MARKER
X case MARK:
X pline("\"%s\" is now scribbled on the rock.",buf);
X break;
X#endif
X default:
X impossible("\"%s\" is now written in a very strange way.",
X buf);
X }
X } else {
X pline("What do you want to %s on the floor here? ",
X (type == ENGRAVE) ? "engrave" : (type == BURN) ? "burn" : "write");
X getlin(buf);
X clrlin();
X }
X spct = 0;
X sp = buf;
X while(*sp == ' ') spct++, sp++;
X len = strlen(sp);
X if(!len || *buf == '\033') {
X /* changed by GAN 11/01/86 to not recharge wand */
X if(type == BURN)
X pline("A few sparks fly from the wand of fire.");
X else
X if(otmp->otyp == WAN_DIGGING)
X pline("Gravel flies up from the floor.");
X return(1);
X }
X /* kludge by stewr 870708 */
X for (sptmp = sp, tmp=0; !(tmp == len); sptmp++,tmp++) {
X if (((type == DUST) && !rn2(25))
X || (Blind && !rn2(12))
X || (Confusion && !rn2(3))) {
X *sptmp = '!' + rn2(93); /* ASCII-code only */
X }
X }
X
X switch(type) {
X case DUST:
X case BURN:
X if(len > 15) {
X multi = -(len/10);
X nomovemsg = "You finished writing.";
X }
X break;
X case ENGRAVE:
X#ifdef MARKER
X case MARK:
X { int len2;
X
X if(type == ENGRAVE)
X len2 = (otmp->spe + 3) * 2 + 1;
X else
X len2 = (otmp->spe) * 2;
X nomovemsg = "You finished writing.";
X if(type != MARK)
X#else
X { int len2 = (otmp->spe + 3) * 2 + 1;
X#endif
X nomovemsg = "You finished engraving.";
X if(otmp->olet != WAND_SYM) {
X if(otmp->olet == WEAPON_SYM)
X pline("Your %s dull.",
X aobjnam(otmp, "get"));
X if(len2 < len) {
X len = len2;
X sp[len] = 0;
X if(type == ENGRAVE) {
X otmp->spe = -3;
X } else {
X pline("Your marker dries out!");
X otmp->spe = 0;
X }
X /* next line added by GAN 10/20/86 */
X pline("You only write \"%s\".", sp);
X nomovemsg = "You cannot write more.";
X } else
X otmp->spe -= len/2;
X#ifdef MARKER
X if(type == MARK)
X multi = -(len/10);
X else
X#endif
X multi = -len;
X } else
X multi = -(len/10);
X }
X break;
X }
X if(oep) len += strlen(oep->engr_txt) + spct;
X ep = (struct engr *) alloc((unsigned)(sizeof(struct engr) + len + 1));
X ep->nxt_engr = head_engr;
X head_engr = ep;
X ep->engr_x = u.ux;
X ep->engr_y = u.uy;
X sp = (char *)(ep + 1); /* (char *)ep + sizeof(struct engr) */
X ep->engr_txt = sp;
X if(oep) {
X (void) strcpy(sp, oep->engr_txt);
X (void) strcat(sp, buf);
X del_engr(oep);
X } else
X (void) strcpy(sp, buf);
X ep->engr_lth = len+1;
X ep->engr_type = type;
X ep->engr_time = moves-multi;
X
X /* kludge to protect pline against excessively long texts */
X if(len > BUFSZ-20) sp[BUFSZ-20] = 0;
X
X /* cute messages for odd wands */
X switch(otmp->otyp) {
X case WAN_SLOW_MONSTER:
X pline("The bugs on the ground slow down!");
X break;
X case WAN_SPEED_MONSTER:
X pline("The bugs on the ground speed up!");
X break;
X case WAN_MAGIC_MISSILE:
X pline("The ground is riddled by bullet holes!");
X break;
X case WAN_SLEEP:
X case WAN_DEATH: /* can't tell sleep from death - Eric Backus */
X pline("The bugs on the ground stop moving!");
X break;
X case WAN_COLD:
X pline("A few ice cubes drop from your %s.",xname(otmp));
X break;
X case WAN_STRIKING:
X pline("The %s unsuccessfully fights your attempt to write!",xname(otmp));
X }
X
X return(1);
X}
X
Xsave_engravings(fd) int fd; {
Xregister struct engr *ep = head_engr;
X while(ep) {
X if(!ep->engr_lth || !ep->engr_txt[0]){
X ep = ep->nxt_engr;
X continue;
X }
X bwrite(fd, (char *) & (ep->engr_lth), sizeof(ep->engr_lth));
X bwrite(fd, (char *) ep, sizeof(struct engr) + ep->engr_lth);
X ep = ep->nxt_engr;
X }
X bwrite(fd, (char *) nul, sizeof(unsigned));
X#ifdef DGK
X if (!count_only)
X#endif
X head_engr = 0;
X}
X
Xrest_engravings(fd) int fd; {
Xregister struct engr *ep;
Xunsigned lth;
X head_engr = 0;
X while(1) {
X mread(fd, (char *) <h, sizeof(unsigned));
X if(lth == 0) return;
X ep = (struct engr *) alloc(sizeof(struct engr) + lth);
X mread(fd, (char *) ep, sizeof(struct engr) + lth);
X ep->nxt_engr = head_engr;
X ep->engr_txt = (char *) (ep + 1); /* Andreas Bormann */
X head_engr = ep;
X }
X}
X
Xdel_engr(ep) register struct engr *ep; {
Xregister struct engr *ept;
X if(ep == head_engr)
X head_engr = ep->nxt_engr;
X else {
X for(ept = head_engr; ept; ept = ept->nxt_engr) {
X if(ept->nxt_engr == ep) {
X ept->nxt_engr = ep->nxt_engr;
X goto fnd;
X }
X }
X impossible("Error in del_engr?");
X return;
X fnd: ;
X }
X free((char *) ep);
X}
END_OF_engrave.c
if test 12939 -ne `wc -c gen.h <<'END_OF_gen.h'
X/* SCCS Id: @(#)gen.h 1.4 87/08/08
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* gen.h version 1.0.1: added ONCE flag */
X
Xstruct gen {
X struct gen *ngen;
X xchar gx,gy;
X unsigned gflag; /* 037: trap type; 040: SEEN flag */
X /* 0100: ONCE only */
X#define TRAPTYPE 037
X#define SEEN 040
X#define ONCE 0100
X};
Xextern struct gen *fgold, *ftrap;
Xstruct gen *g_at();
X#define newgen() (struct gen *) alloc(sizeof(struct gen))
END_OF_gen.h
if test 446 -ne `wc -c monmove.c <<'END_OF_monmove.c'
X/* SCCS Id: @(#)monmove.c 2.1 87/10/18
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X#include "hack.h"
X#include "mfndpos.h"
X#define NULL (char *) 0
X
Xextern int warnlevel; /* defined in mon.c */
X
Xdochugw(mtmp) register struct monst *mtmp; {
Xregister x = mtmp->mx;
Xregister y = mtmp->my;
Xregister d = dochug(mtmp);
Xregister dd;
X if(!d) /* monster still alive */
X if(Warning)
X if(!mtmp->mpeaceful)
X if(mtmp->data->mlevel > warnlevel)
X if((dd = dist(mtmp->mx,mtmp->my)) < dist(x,y))
X if(dd < 100)
X if(!canseemon(mtmp))
X warnlevel = mtmp->data->mlevel;
X return(d);
X}
X
X/* returns 1 if monster died moving, 0 otherwise */
Xdochug(mtmp)
Xregister struct monst *mtmp;
X{
X register struct permonst *mdat;
X register tmp, nearby, scared, onscary;
X
X if(mtmp->cham && !rn2(6))
X (void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
X mdat = mtmp->data;
X if(mdat->mlevel < 0)
X panic("bad monster %c (%d)",mdat->mlet,mdat->mlevel);
X
X /* regenerate monsters */
X if((!(moves%20) || index(MREGEN, mdat->mlet)) &&
X mtmp->mhp < mtmp->mhpmax)
X mtmp->mhp++;
X
X if(mtmp->mfroz) {
X if (Hallucination) pmon(mtmp);
X return(0); /* frozen monsters don't do anything */
X }
X
X if(mtmp->msleep) /* there is a chance we will wake it */
X if(!disturb(mtmp)) return(0);
X
X /* not frozen or sleeping: wipe out texts written in the dust */
X wipe_engr_at(mtmp->mx, mtmp->my, 1);
X
X /* confused monsters get unconfused with small probability */
X if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0;
X
X /* some monsters teleport */
X if(mtmp->mflee && index("tNL", mdat->mlet) && !rn2(40)){
X rloc(mtmp);
X return(0);
X }
X if(mdat->mmove < rnd(6)) return(0);
X
X /* fleeing monsters might regain courage */
X if(mtmp->mflee && !mtmp->mfleetim
X && mtmp->mhp == mtmp->mhpmax && !rn2(25))
X mtmp->mflee = 0;
X
X nearby = (dist(mtmp->mx, mtmp->my) < 3);
X onscary = (sengr_at("Elbereth", u.ux, u.uy) ||
X sobj_at(SCR_SCARE_MONSTER, u.ux, u.uy));
X scared = (nearby && onscary && !mtmp->mtame && mtmp->mcansee)
X && (mdat->mlet != '1'); /* RPH: the wiz is never scared */
X if(scared && !mtmp->mflee) {
X mtmp->mflee = 1;
X mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));
X }
X
X if(!nearby ||
X mtmp->mflee || scared ||
X mtmp->mconf ||
X (mtmp->minvis && !rn2(3)) ||
X#ifndef KOPS
X (index("BIuy", mdat->mlet) && !rn2(4)) ||
X#else
X (index("KBIuy", mdat->mlet) && !rn2(4)) ||
X#endif
X (mdat->mlet == 'L' && !u.ugold && (mtmp->mgold || rn2(2))) ||
X (!mtmp->mcansee && !rn2(4)) ||
X mtmp->mpeaceful
X ) {
X tmp = m_move(mtmp,0); /* 2: monster died moving */
X if(tmp == 2 || (tmp && mdat->mmove <= 12))
X return(tmp == 2);
X
X if(Hallucination && tmp==0) pmon(mtmp);
X/* If 0, this means the monster didn't move. During hallucination, its
X appearance should still change. */
X
X#ifdef HARD
X /* Without this line, fast monsters don't hit you when they've
X * caught up to you. -dgk
X */
X nearby = (dist(mtmp->mx, mtmp->my) < 3);
X scared = (nearby && onscary);
X if(scared && !mtmp->mflee) {
X mtmp->mflee = 1;
X mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));
X }
X#endif
X }
X#ifdef HARD /* Demonic Blackmail!!! */
X if(mdat->mlet == '&' && mtmp->mpeaceful && !mtmp->mtame)
X if(demon_talk(mtmp))
X return(1); /* you paid it off */
X#endif
X if(!index("Ea", mdat->mlet) && nearby &&
X !mtmp->mpeaceful && u.uhp > 0 && !scared) {
X if(mhitu(mtmp))
X return(1); /* monster died (e.g. 'y' or 'F') */
X }
X /* extra movement for fast monsters */
X if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp,1);
X return(tmp == 2);
X}
X
Xm_move(mtmp,after)
Xregister struct monst *mtmp;
X{
X#ifndef REGBUG
X register
X#endif
X struct monst *mtmp2;
X#ifndef REGBUG
X register
X#endif
X int nx,ny,omx,omy,appr,nearer,cnt,i,j;
X xchar gx,gy,nix,niy,chcnt;
X schar chi;
X boolean likegold, likegems, likeobjs;
X#ifdef KAA
X boolean likerock;
X#endif
X char msym = mtmp->data->mlet;
X schar mmoved = 0; /* not strictly nec.: chi >= 0 will do */
X coord poss[9];
X long info[9];
X
X if(mtmp->mfroz || mtmp->msleep)
X return(0);
X if(mtmp->mtrapped) {
X i = mintrap(mtmp);
X if(i == 2) return(2); /* he died */
X if(i == 1) return(0); /* still in trap, so didnt move */
X }
X if(mtmp->mhide && o_at(mtmp->mx,mtmp->my) && rn2(10))
X return(0); /* do not leave hiding place */
X
X#ifndef NOWORM
X if(mtmp->wormno)
X goto not_special;
X#endif
X
X /* my dog gets a special treatment */
X if(mtmp->mtame) {
X return( dog_move(mtmp, after) );
X }
X
X /* likewise for shopkeeper */
X if(mtmp->isshk) {
X mmoved = shk_move(mtmp);
X if(mmoved >= 0)
X goto postmov;
X mmoved = 0; /* follow player outside shop */
X }
X
X /* and for the guard */
X if(mtmp->isgd) {
X mmoved = gd_move();
X goto postmov;
X }
X
X/* teleport if that lies in our nature ('t') or when badly wounded ('1') */
X if((msym == 't' && !rn2(5))
X || (msym == '1' && (mtmp->mhp < 7 || (!xdnstair && !rn2(5))
X || levl[u.ux][u.uy].typ == STAIRS))) {
X if(mtmp->mhp < 7 || (msym == 't' && rn2(2)))
X rloc(mtmp);
X else
X mnexto(mtmp);
X mmoved = 1;
X goto postmov;
X }
X
X /* spit fire ('D') or use a wand ('1') when appropriate */
X#ifdef DGKMOD
X /* Add arrow and bolt throwing monsters */
X if (index(
X# ifdef KAA
X# ifdef KOPS
X "D1OKC9",
X# else
X "D1KC9",
X# endif
X# else
X# ifdef KOPS
X "D1OKC",
X# else
X "D1KC",
X# endif
X# endif
X msym))
X
X if (!inrange(mtmp)) /* inrange returns 1 if OK for mon */
X return(0); /* to move after it zaps or throws */
X#else
X if(index("D1", msym))
X inrange(mtmp);
X#endif
X
X if(msym == 'U' && !mtmp->mcan && canseemon(mtmp) &&
X mtmp->mcansee && rn2(5)) {
X if(!Confusion)
X pline("%s's gaze has confused you!", Monnam(mtmp));
X else
X pline("You are getting more and more confused.");
X if(rn2(3)) mtmp->mcan = 1;
X HConfusion += d(3,4); /* timeout */
X }
X#ifdef RPH
X if (msym == '8' && canseemon(mtmp)) {
X if (mtmp->mcan)
X pline ("You notice that %s isn't all that ugly.",monnam(mtmp));
X else if (rn2(3))
X pline ("You see the ugly back of %s.", monnam(mtmp));
X else {
X pline ("You look upon %s.", monnam(mtmp));
X pline ("You turn to stone.");
X done_in_by(mtmp);
X }
X }
X#endif
Xnot_special:
X if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1);
X appr = 1;
X if(mtmp->mflee) appr = -1;
X if(mtmp->mconf || Invis || !mtmp->mcansee ||
X (index("BIy", msym) && !rn2(3)))
X appr = 0;
X omx = mtmp->mx;
X omy = mtmp->my;
X gx = u.ux;
X gy = u.uy;
X if(msym == 'L' && appr == 1 && mtmp->mgold > u.ugold)
X appr = -1;
X
X /* random criterion for 'smell' or track finding ability
X should use mtmp->msmell or sth
X */
X if(msym == '@' ||
X#ifdef RPH
X uwep && !strcmp(ONAME(uwep), "Excalibur") ||
X#endif
X ('a' <= msym && msym <= 'z')) {
X extern coord *gettrack();
X register coord *cp;
X schar mroom;
X mroom = inroom(omx,omy);
X if(mroom < 0 || mroom != inroom(u.ux,u.uy)){
X cp = gettrack(omx,omy);
X if(cp){
X gx = cp->x;
X gy = cp->y;
X }
X }
X }
X
X /* look for gold or jewels nearby */
X#ifdef ROCKMOLE
X likegold = (index("LODr", msym) != NULL);
X likegems = (index("ODu", msym) != NULL);
X# ifdef KJSMODS
X likeobjs = (mtmp->mhide || (msym == 'r' && dlevel > 3));
X# else
X likeobjs = (mtmp->mhide || msym == 'r');
X# endif
X#else
X likegold = (index("LOD", msym) != NULL);
X likegems = (index("ODu", msym) != NULL);
X likeobjs = mtmp->mhide;
X#endif
X#ifdef KAA
X likerock = (msym == '9');
X#endif
X#define SRCHRADIUS 25
X { xchar mind = SRCHRADIUS; /* not too far away */
X register int dd;
X if(likegold){
X register struct gold *gold;
X for(gold = fgold; gold; gold = gold->ngold)
X if((dd = DIST(omx,omy,gold->gx,gold->gy)) < mind){
X mind = dd;
X gx = gold->gx;
X gy = gold->gy;
X }
X }
X if(likegems || likeobjs
X#ifdef KAA
X || likerock
X#endif
X ) {
X register struct obj *otmp;
X for(otmp = fobj; otmp; otmp = otmp->nobj)
X if(likeobjs
X || (likegems && otmp->olet == GEM_SYM)
X#ifdef KAA
X || (likerock && otmp->olet == ROCK_SYM)
X#endif
X ) {
X if(msym != 'u' || objects[otmp->otyp].g_val != 0)
X if((dd = DIST(omx,omy,otmp->ox,otmp->oy)) < mind){
X mind = dd;
X gx = otmp->ox;
X gy = otmp->oy;
X }
X }
X }
X if(mind < SRCHRADIUS && appr == -1) {
X if(dist(omx,omy) < 10) {
X gx = u.ux;
X gy = u.uy;
X } else
X appr = 1;
X }
X }
X nix = omx;
X niy = omy;
X cnt = mfndpos(mtmp,poss,info,
X msym == 'u' ? NOTONL :
X#ifdef ROCKMOLE
X# ifdef KJSMODS
X (msym == 'r' && dlevel > 3) ? ALLOW_WALL :
X# else
X msym == 'r' ? ALLOW_WALL :
X# endif
X#endif
X (msym == '@' || msym == '1') ? (ALLOW_SSM | ALLOW_TRAPS) :
X index(UNDEAD, msym) ? NOGARLIC :
X#ifdef KAA
X (msym == '9') ? (ALLOW_ROCK | ALLOW_TRAPS) : ALLOW_TRAPS);
X#else
X ALLOW_TRAPS);
X#endif
X chcnt = 0;
X chi = -1;
X for(i=0; imtrack[j].x && ny == mtmp->mtrack[j].y)
X if(rn2(4*(cnt-j))) goto nxti;
X#ifdef STUPID
X /* some stupid compilers think that this is too complicated */
X { int d1 = DIST(nx,ny,gx,gy);
X int d2 = DIST(nix,niy,gx,gy);
X nearer = (d1 < d2);
X }
X#else
X nearer = (DIST(nx,ny,gx,gy) < DIST(nix,niy,gx,gy));
X#endif
X if((appr == 1 && nearer) || (appr == -1 && !nearer) ||
X !mmoved ||
X (!appr && !rn2(++chcnt))){
X nix = nx;
X niy = ny;
X chi = i;
X mmoved = 1;
X }
X nxti: ;
X }
X if(mmoved){
X if(info[chi] & ALLOW_M){
X mtmp2 = m_at(nix,niy);
X if(hitmm(mtmp,mtmp2) == 1 && rn2(4) &&
X hitmm(mtmp2,mtmp) == 2) return(2);
X return(0);
X }
X if(info[chi] & ALLOW_U){
X (void) hitu(mtmp, d(mtmp->data->damn, mtmp->data->damd)+1);
X return(0);
X }
X mtmp->mx = nix;
X mtmp->my = niy;
X for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1];
X mtmp->mtrack[0].x = omx;
X mtmp->mtrack[0].y = omy;
X#ifndef NOWORM
X if(mtmp->wormno) worm_move(mtmp);
X#endif
X } else {
X if(msym == 'u' && rn2(2)){
X rloc(mtmp);
X return(0);
X }
X#ifndef NOWORM
X if(mtmp->wormno) worm_nomove(mtmp);
X#endif
X }
Xpostmov:
X if(mmoved == 1) {
X if(mintrap(mtmp) == 2) /* he died */
X return(2);
X#ifdef ROCKMOLE
X /* Maybe a rock mole just ate something? */
X if(msym == 'r'
X# ifdef KJSMODS
X && dlevel > 3
X#endif
X && IS_ROCK(levl[mtmp->mx][mtmp->my].typ) &&
X levl[mtmp->mx][mtmp->my].typ != POOL){
X register int pile = rnd(25);
X /* Just ate something. */
X if(levl[mtmp->mx][mtmp->my].typ == 0)
X levl[mtmp->mx][mtmp->my].typ = CORR;
X else if(IS_WALL(levl[mtmp->mx][mtmp->my].typ))
X levl[mtmp->mx][mtmp->my].typ = DOOR;
X mnewsym(mtmp->mx,mtmp->my);
X /* Left behind a pile? */
X if(pile < 5) {
X if(pile == 1)
X mksobj_at(ENORMOUS_ROCK, mtmp->mx, mtmp->my);
X else
X mksobj_at(ROCK, mtmp->mx, mtmp->my);
X }
X if(cansee(mtmp->mx, mtmp->my))
X if(fobj) atl(mtmp->mx,mtmp->my,fobj->olet);
X }
X /* Maybe a rock mole just ate some gold or armor? */
X if(msym == 'r') meatgold(mtmp);
X#endif /* ROCKMOLE /**/
X if(likegold) mpickgold(mtmp);
X#ifdef KAA
X if(likerock || likegems) mpickgems(mtmp);
X#else
X if(likegems) mpickgems(mtmp);
X#endif
X if(mtmp->mhide) mtmp->mundetected = 1;
X }
X pmon(mtmp);
X return(mmoved);
X}
X
END_OF_monmove.c
if test 11002 -ne `wc -c objnam.c <<'END_OF_objnam.c'
X/* SCCS Id: @(#)objnam.c 2.1 87/09/28
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X#include "hack.h"
X#define Sprintf (void) sprintf
X#define Strcat (void) strcat
X#define Strcpy (void) strcpy
X#define PREFIX 15
Xextern char *eos();
Xextern int bases[];
X
Xchar *
Xstrprepend(s,pref) register char *s, *pref; {
Xregister int i = strlen(pref);
X if(i > PREFIX) {
X pline("WARNING: prefix too short.");
X return(s);
X }
X s -= i;
X (void) strncpy(s, pref, i); /* do not copy trailing 0 */
X return(s);
X}
X
Xchar *
Xsitoa(a) int a; {
Xstatic char buf[13];
X Sprintf(buf, (a < 0) ? "%d" : "+%d", a);
X return(buf);
X}
X
Xchar *
Xtypename(otyp)
Xregister int otyp;
X{
Xstatic char buf[BUFSZ];
Xregister struct objclass *ocl = &objects[otyp];
Xregister char *an = ocl->oc_name;
Xregister char *dn = ocl->oc_descr;
Xregister char *un = ocl->oc_uname;
Xregister int nn = ocl->oc_name_known;
X switch(ocl->oc_olet) {
X case POTION_SYM:
X Strcpy(buf, "potion");
X break;
X case SCROLL_SYM:
X Strcpy(buf, "scroll");
X break;
X case WAND_SYM:
X Strcpy(buf, "wand");
X break;
X#ifdef SPELLS
X case SPBOOK_SYM:
X Strcpy(buf, "spellbook");
X break;
X#endif
X case RING_SYM:
X Strcpy(buf, "ring");
X break;
X default:
X if(nn) {
X Strcpy(buf, an);
X if(otyp >= TURQUOISE && otyp <= JADE)
X Strcat(buf, " stone");
X if(un)
X Sprintf(eos(buf), " called %s", un);
X if(dn)
X Sprintf(eos(buf), " (%s)", dn);
X } else {
X Strcpy(buf, dn ? dn : an);
X if(ocl->oc_olet == GEM_SYM)
X Strcat(buf, " gem");
X if(un)
X Sprintf(eos(buf), " called %s", un);
X }
X return(buf);
X }
X /* here for ring/scroll/potion/wand */
X if(nn)
X Sprintf(eos(buf), " of %s", an);
X if(un)
X Sprintf(eos(buf), " called %s", un);
X if(dn)
X Sprintf(eos(buf), " (%s)", dn);
X return(buf);
X}
X
Xchar *
Xxname(obj)
Xregister struct obj *obj;
X{
Xstatic char bufr[BUFSZ];
Xregister char *buf = &(bufr[PREFIX]); /* leave room for "17 -3 " */
Xregister int nn = objects[obj->otyp].oc_name_known;
Xregister char *an = objects[obj->otyp].oc_name;
Xregister char *dn = objects[obj->otyp].oc_descr;
Xregister char *un = objects[obj->otyp].oc_uname;
Xregister int pl = (obj->quan != 1);
X#ifdef KAA
X if(!obj->dknown && !Blind && obj->olet != WEAPON_SYM) obj->dknown=1;
X#else
X if(!obj->dknown && !Blind) obj->dknown = 1; /* %% doesnt belong here */
X#endif
X switch(obj->olet) {
X case AMULET_SYM:
X Strcpy(buf, (obj->spe < 0 && obj->known)
X ? "cheap plastic imitation of the " : "");
X Strcat(buf,"Amulet of Yendor");
X break;
X case TOOL_SYM:
X if(!nn) {
X Strcpy(buf, dn);
X break;
X }
X Strcpy(buf,an);
X break;
X case FOOD_SYM:
X if(obj->otyp == DEAD_HOMUNCULUS && pl) {
X pl = 0;
X Strcpy(buf, "dead homunculi");
X break;
X }
X /* fungis ? */
X#ifdef KAA /* The fungus mistake was a D&D holdover. */
X if(obj->otyp == DEAD_VIOLET_FUNGUS && pl) {
X pl = 0;
X Strcpy(buf, "dead violet fungi");
X break;
X }
X#endif
X /* fall into next case */
X case WEAPON_SYM:
X if(obj->otyp == WORM_TOOTH && pl) {
X pl = 0;
X Strcpy(buf, "worm teeth");
X break;
X }
X if(obj->otyp == CRYSKNIFE && pl) {
X pl = 0;
X Strcpy(buf, "crysknives");
X break;
X }
X /* fall into next case */
X case ARMOR_SYM:
X case CHAIN_SYM:
X case ROCK_SYM:
X Strcpy(buf,an);
X break;
X case BALL_SYM:
X Sprintf(buf, "%sheavy iron ball",
X (obj->owt > objects[obj->otyp].oc_weight) ? "very " : "");
X break;
X case POTION_SYM:
X if(nn || un || !obj->dknown) {
X Strcpy(buf, "potion");
X if(pl) {
X pl = 0;
X Strcat(buf, "s");
X }
X if(!obj->dknown) break;
X if(un) {
X Strcat(buf, " called ");
X Strcat(buf, un);
X } else {
X Strcat(buf, " of ");
X Strcat(buf, an);
X }
X } else {
X Strcpy(buf, dn);
X Strcat(buf, " potion");
X }
X break;
X case SCROLL_SYM:
X Strcpy(buf, "scroll");
X if(pl) {
X pl = 0;
X Strcat(buf, "s");
X }
X if(!obj->dknown) break;
X if(nn) {
X Strcat(buf, " of ");
X Strcat(buf, an);
X } else if(un) {
X Strcat(buf, " called ");
X Strcat(buf, un);
X } else {
X Strcat(buf, " labeled ");
X Strcat(buf, dn);
X }
X break;
X case WAND_SYM:
X if(!obj->dknown)
X Sprintf(buf, "wand");
X else if(nn)
X Sprintf(buf, "wand of %s", an);
X else if(un)
X Sprintf(buf, "wand called %s", un);
X else
X Sprintf(buf, "%s wand", dn);
X break;
X#ifdef SPELLS
X case SPBOOK_SYM:
X if(!obj->dknown)
X Sprintf(buf, "spellbook");
X else if(nn)
X Sprintf(buf, "spellbook of %s", an);
X else if(un)
X Sprintf(buf, "spellbook called %s", un);
X else
X Sprintf(buf, "%s spellbook", dn);
X break;
X#endif
X case RING_SYM:
X if(!obj->dknown)
X Sprintf(buf, "ring");
X else if(nn)
X Sprintf(buf, "ring of %s", an);
X else if(un)
X Sprintf(buf, "ring called %s", un);
X else
X Sprintf(buf, "%s ring", dn);
X break;
X case GEM_SYM:
X if(!obj->dknown) {
X Strcpy(buf, "gem");
X break;
X }
X if(!nn) {
X#ifdef KAA
X if(un) {
X if (!pl) Sprintf(buf,"gem called %s",un);
X else Sprintf(buf,"gems called %s",un);
X pl=0;
X } else
X#endif
X Sprintf(buf, "%s gem", dn);
X break;
X }
X Strcpy(buf, an);
X if(obj->otyp >= TURQUOISE && obj->otyp <= JADE)
X Strcat(buf, " stone");
X break;
X default:
X Sprintf(buf,"glorkum %c (0%o) %u %d",
X obj->olet,obj->olet,obj->otyp,obj->spe);
X }
X if(pl) {
X register char *p;
X
X for(p = buf; *p; p++) {
X if(!strncmp(" of ", p, 4)) {
X /* pieces of, cloves of, lumps of */
X register int c1, c2 = 's';
X
X do {
X c1 = c2; c2 = *p; *p++ = c1;
X } while(c1);
X goto nopl;
X }
X }
X p = eos(buf)-1;
X if(*p == 's' || *p == 'z' || *p == 'x' ||
X (*p == 'h' && p[-1] == 's'))
X Strcat(buf, "es"); /* boxes */
X else if(*p == 'y' && !index(vowels, p[-1]))
X Strcpy(p, "ies"); /* rubies, zruties */
X else
X Strcat(buf, "s");
X }
Xnopl:
X if(obj->onamelth) {
X Strcat(buf, " named ");
X Strcat(buf, ONAME(obj));
X }
X return(buf);
X}
X
Xchar *
Xdoname(obj)
Xregister struct obj *obj;
X{
Xchar prefix[PREFIX];
Xregister char *bp = xname(obj);
X if(obj->quan != 1)
X Sprintf(prefix, "%u ", obj->quan);
X else
X Strcpy(prefix, "a ");
X switch(obj->olet) {
X case AMULET_SYM:
X if(strncmp(bp, "cheap ", 6))
X Strcpy(prefix, "the ");
X break;
X case ARMOR_SYM:
X if(obj->owornmask & W_ARMOR)
X Strcat(bp, " (being worn)");
X /* fall into next case */
X case WEAPON_SYM:
X if(obj->known) {
X#ifdef KAA
X /* dknown is special for weapons */
X if(obj->dknown && obj->olet == WEAPON_SYM)
X Strcat(prefix,"blessed ");
X#endif
X Strcat(prefix, sitoa(obj->spe));
X Strcat(prefix, " ");
X }
X break;
X#ifdef MARKER
X case TOOL_SYM: /* temp. hack by GAN 11/18/86 */
X if(obj->otyp != MAGIC_MARKER) break;
X#endif
X case WAND_SYM:
X if(obj->known)
X Sprintf(eos(bp), " (%d)", obj->spe);
X break;
X case RING_SYM:
X if(obj->owornmask & W_RINGR) Strcat(bp, " (on right hand)");
X if(obj->owornmask & W_RINGL) Strcat(bp, " (on left hand)");
X if(obj->known && (objects[obj->otyp].bits & SPEC)) {
X Strcat(prefix, sitoa(obj->spe));
X Strcat(prefix, " ");
X }
X break;
X }
X if(obj->owornmask & W_WEP)
X Strcat(bp, " (weapon in hand)");
X if(obj->unpaid)
X Strcat(bp, " (unpaid)");
X if(!strcmp(prefix, "a ") && index(vowels, *bp))
X Strcpy(prefix, "an ");
X bp = strprepend(bp, prefix);
X return(bp);
X}
X
X/* used only in fight.c (thitu) */
Xsetan(str,buf)
Xregister char *str,*buf;
X{
X if(index(vowels,*str))
X Sprintf(buf, "an %s", str);
X else
X Sprintf(buf, "a %s", str);
X}
X
Xchar *
Xaobjnam(otmp,verb) register struct obj *otmp; register char *verb; {
Xregister char *bp = xname(otmp);
Xchar prefix[PREFIX];
X if(otmp->quan != 1) {
X Sprintf(prefix, "%u ", otmp->quan);
X bp = strprepend(bp, prefix);
X }
X
X if(verb) {
X /* verb is given in plural (i.e., without trailing s) */
X Strcat(bp, " ");
X if(otmp->quan != 1)
X Strcat(bp, verb);
X else if(!strcmp(verb, "are"))
X Strcat(bp, "is");
X else {
X Strcat(bp, verb);
X Strcat(bp, "s");
X }
X }
X return(bp);
X}
X
Xchar *
XDoname(obj)
Xregister struct obj *obj;
X{
X register char *s = doname(obj);
X
X if('a' <= *s && *s <= 'z') *s -= ('a' - 'A');
X return(s);
X}
X
Xchar *wrp[] = { "wand", "ring", "potion", "scroll", "gem"
X#ifdef SPELLS
X , "spellbook"
X#endif
X };
Xchar wrpsym[] = { WAND_SYM, RING_SYM, POTION_SYM, SCROLL_SYM, GEM_SYM
X#ifdef SPELLS
X , SPBOOK_SYM
X#endif
X };
X
Xstruct obj *
Xreadobjnam(bp) register char *bp; {
Xregister char *p;
Xregister int i;
Xint cnt, spe, spesgn, typ, heavy;
Xchar let;
Xchar *un, *dn, *an;
X#ifdef KAA
Xint blessed=0;
X#endif
X/* int the = 0; char *oname = 0; */
X cnt = spe = spesgn = typ = heavy = 0;
X let = 0;
X an = dn = un = 0;
X for(p = bp; *p; p++) /* set the string to lower case */
X if('A' <= *p && *p <= 'Z') *p += 'a'-'A';
X if(!strncmp(bp, "the ", 4)){
X/* the = 1; */
X bp += 4;
X } else if(!strncmp(bp, "an ", 3)){
X cnt = 1;
X bp += 3;
X } else if(!strncmp(bp, "a ", 2)){
X cnt = 1;
X bp += 2;
X }
X#ifdef KAA
X if(!strncmp(bp,"blessed ",8)) {
X blessed=1;
X bp += 8;
X }
X#endif
X if(!cnt && digit(*bp)){
X cnt = atoi(bp);
X while(digit(*bp)) bp++;
X while(*bp == ' ') bp++;
X }
X if(!cnt) cnt = 1; /* %% what with "gems" etc. ? */
X
X if(*bp == '+' || *bp == '-'){
X spesgn = (*bp++ == '+') ? 1 : -1;
X spe = atoi(bp);
X while(digit(*bp)) bp++;
X while(*bp == ' ') bp++;
X } else {
X p = rindex(bp, '(');
X if(p) {
X if(p > bp && p[-1] == ' ') p[-1] = 0;
X else *p = 0;
X p++;
X spe = atoi(p);
X while(digit(*p)) p++;
X if(strcmp(p, ")")) spe = 0;
X else spesgn = 1;
X }
X }
X /* now we have the actual name, as delivered by xname, say
X green potions called whisky
X scrolls labeled "QWERTY"
X egg
X dead zruties
X fortune cookies
X very heavy iron ball named hoei
X wand of wishing
X elven cloak
X */
X for(p = bp; *p; p++) if(!strncmp(p, " named ", 7)) {
X *p = 0;
X/* oname = p+7; */
X }
X for(p = bp; *p; p++) if(!strncmp(p, " called ", 8)) {
X *p = 0;
X un = p+8;
X }
X for(p = bp; *p; p++) if(!strncmp(p, " labeled ", 9)) {
X *p = 0;
X dn = p+9;
X }
X
X /* first change to singular if necessary */
X if(cnt != 1) {
X /* find "cloves of garlic", "worthless pieces of blue glass" */
X for(p = bp; *p; p++) if(!strncmp(p, "s of ", 5)){
X while(*p = p[1]) p++;
X goto sing;
X }
X /* remove -s or -es (boxes) or -ies (rubies, zruties) */
X p = eos(bp);
X if(p[-1] == 's') {
X if(p[-2] == 'e') {
X if(p[-3] == 'i') {
X#ifdef KAA
X if(!strcmp(p-7, "cookies") || !strcmp(p-4, "pies"))
X#else
X if(!strcmp(p-7, "cookies"))
X#endif
X goto mins;
X Strcpy(p-3, "y");
X goto sing;
X }
X
X /* note: cloves / knives from clove / knife */
X if(!strcmp(p-6, "knives")) {
X Strcpy(p-3, "fe");
X goto sing;
X }
X
X /* note: nurses, axes but boxes */
X if(!strcmp(p-5, "boxes")) {
X p[-2] = 0;
X goto sing;
X }
X }
X mins:
X p[-1] = 0;
X } else {
X if(!strcmp(p-9, "homunculi")
X#ifdef KAA
X || !strcmp(p-5, "fungi")
X#endif
X ) {
X Strcpy(p-1, "us"); /* !! makes string longer */
X goto sing;
X }
X if(!strcmp(p-5, "teeth")) {
X Strcpy(p-5, "tooth");
X goto sing;
X }
X /* here we cannot find the plural suffix */
X }
X }
Xsing:
X if(!strcmp(bp, "amulet of yendor")) {
X typ = AMULET_OF_YENDOR;
X goto typfnd;
X }
X if(!strcmp(bp, "ring mail")){ /* Note: ring mail is not a ring ! */
X let = ARMOR_SYM;
X an = bp;
X goto srch;
X }
X
X p = eos(bp);
X#if defined(KOPS) && !defined(KJSMODS)
X if (!strcmp(p-3, "kop")) {
X *(p-3) = 'K';
X an = bp;
X goto srch;
X }
X#endif
X for(i = 0; i < sizeof(wrpsym); i++) {
X register int j = strlen(wrp[i]);
X if(!strncmp(bp, wrp[i], j)){
X let = wrpsym[i];
X bp += j;
X if(!strncmp(bp, " of ", 4)) an = bp+4;
X /* else if(*bp) ?? */
X goto srch;
X }
X if(!strcmp(p-j, wrp[i])){
X let = wrpsym[i];
X p -= j;
X *p = 0;
X if(p[-1] == ' ') p[-1] = 0;
X dn = bp;
X goto srch;
X }
X }
X if(!strcmp(p-6, " stone")){
X p[-6] = 0;
X let = GEM_SYM;
X an = bp;
X goto srch;
X }
X#ifdef KAA
X if(!strcmp(p-10, "gold piece") || !strcmp(p-7, "zorkmid")) {
X if (cnt > 5000) cnt=5000;
X if (cnt < 1) cnt=1;
X pline("%d gold piece%s.", cnt, cnt==1 ? "" : "s");
X u.ugold += cnt;
X flags.botl=1;
X return(0);
X }
X#endif
X if(!strcmp(bp, "very heavy iron ball")){
X heavy = 1;
X typ = HEAVY_IRON_BALL;
X goto typfnd;
X }
X an = bp;
Xsrch:
X if(!an && !dn && !un)
X goto any;
X i = 1;
X if(let) i = bases[letindex(let)];
X while(i <= NROFOBJECTS && (!let || objects[i].oc_olet == let)){
X register char *zn = objects[i].oc_name;
X
X if(!zn) goto nxti;
X if(an && strcmp(an, zn))
X goto nxti;
X if(dn && (!(zn = objects[i].oc_descr) || strcmp(dn, zn)))
X goto nxti;
X if(un && (!(zn = objects[i].oc_uname) || strcmp(un, zn)))
X goto nxti;
X typ = i;
X goto typfnd;
X nxti:
X i++;
X }
Xany:
X if(!let) let = wrpsym[rn2(sizeof(wrpsym))];
X typ = probtype(let);
Xtypfnd:
X { register struct obj *otmp;
X extern struct obj *mksobj();
X let = objects[typ].oc_olet;
X otmp = mksobj(typ);
X if(heavy) otmp->owt += 15;
X
X if(cnt > 0 && index("%?!*)", let) &&
X (cnt < 4 ||
X#ifdef WIZARD
X wizard ||
X#endif
X#ifdef KAA
X (let == WEAPON_SYM && typ <= ROCK && cnt <= 20)
X#else
X (let == WEAPON_SYM && typ <= ROCK && cnt < 20)
X#endif
X )) otmp->quan = cnt;
X
X if(spe > 3 && spe > otmp->spe) {
X#ifdef WIZARD
X if(!wizard)
X#endif
X spe = 0;
X } else if(let == WAND_SYM)
X spe = otmp->spe;
X#ifdef KAA
X if(let==WEAPON_SYM && blessed) {
X if(u.uluck < 0) otmp->cursed=1;
X else otmp->dknown=1;
X }
X#endif
X if(spe == 3 && u.uluck < 0)
X spesgn = -1;
X if(let != WAND_SYM && spesgn == -1)
X spe = -spe;
X if(let == BALL_SYM)
X spe = 0;
X else if(let == AMULET_SYM)
X spe = -1;
X else if(typ == WAN_WISHING && rn2(10))
X spe = (rn2(10) ? -1 : 0);
X#ifdef MARKER
X else if(typ == MAGIC_MARKER)
X spe = rn1(50,50);
X#endif
X otmp->spe = spe;
X
X if(spesgn == -1)
X otmp->cursed = 1;
X
X return(otmp);
X }
X}
END_OF_objnam.c
if test 13433 -ne `wc -c u_init.c <<'END_OF_u_init.c'
X/* SCCS Id: @(#)u_init.c 2.0 87/09/15
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X#include
X#include
X#include "hack.h"
X#ifdef GENIX
X#define void int
X#endif
X
X#define Strcpy (void) strcpy
X#define Strcat (void) strcat
X#define UNDEF_TYP 0
X#define UNDEF_SPE '\177'
Xextern struct obj *addinv();
Xextern char *eos();
Xextern char plname[];
X#define IS_MAGIC(x) ((x)->olet == WAND_SYM || (x)->olet == POTION_SYM || \
X (x)->olet == RING_SYM || (x)->olet == SCROLL_SYM || \
X (x)->olet == SPBOOK_SYM)
X
Xstruct you zerou;
Xchar pl_character[PL_CSIZ];
Xchar *(roles[]) = { /* must all have distinct first letter */
X /* roles[4] & [7] may be changed for females */
X "Archeologist", "Tourist", "Barbarian", "Knight", "Cave-man",
X#ifdef NEWCLASS
X "Samurai", "Ninja", "Priest",
X#endif
X#ifdef KAA
X "Valkyrie", "Elf", "Healer",
X#endif
X "Wizard"
X};
X#define NR_OF_ROLES SIZE(roles)
Xchar rolesyms[NR_OF_ROLES + 1]; /* filled by u_init() */
X
Xstruct trobj {
X unsigned short trotyp;
X schar trspe;
X char trolet;
X Bitfield(trquan,6);
X Bitfield(trknown,1);
X};
X
X#ifdef WIZARD
Xstruct trobj Extra_objs[] = {
X { 0, 0, 0, 0, 0 },
X { 0, 0, 0, 0, 0 }
X};
X#endif
X
Xstruct trobj Cave_man[] = {
X#define C_ARROWS 2
X { CLUB, 1, WEAPON_SYM, 1, 1 },
X { BOW, 1, WEAPON_SYM, 1, 1 },
X { ARROW, 0, WEAPON_SYM, 25, 1 }, /* quan is variable */
X { LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1 },
X { 0, 0, 0, 0, 0}
X};
X
Xstruct trobj Barbarian[] = {
X { TWO_HANDED_SWORD, 0, WEAPON_SYM, 1, 1 },
X { RING_MAIL, 0, ARMOR_SYM, 1, 1 },
X { 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Knight[] = {
X { LONG_SWORD, 0, WEAPON_SYM, 1, 1 },
X { SPEAR, 2, WEAPON_SYM, 1, 1 },
X { RING_MAIL, 1, ARMOR_SYM, 1, 1 },
X { HELMET, 0, ARMOR_SYM, 1, 1 },
X { SHIELD, 0, ARMOR_SYM, 1, 1 },
X { PAIR_OF_GLOVES, 0, ARMOR_SYM, 1, 1 },
X { 0, 0, 0, 0, 0 }
X};
X
X#ifdef KAA
Xstruct trobj Elf[] = {
X#define E_ARROWS 2
X#define E_ARMOR 3
X { SHORT_SWORD, 0, WEAPON_SYM, 1, 1 },
X { BOW, 0, WEAPON_SYM, 1, 1 },
X { ARROW, 0, WEAPON_SYM, 25, 1 },
X { UNDEF_TYP, 0, ARMOR_SYM, 1, 1 },
X { 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Valkyrie[] = {
X { LONG_SWORD, 1, WEAPON_SYM, 1, 1 },
X { SHIELD, 3, ARMOR_SYM, 1, 1 },
X { FOOD_RATION, 0, FOOD_SYM, 1, 1 },
X { 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Healer[] = {
X { STETHOSCOPE, 0, TOOL_SYM, 1, 0 },
X { POT_HEALING, 0, POTION_SYM, 4, 1 },
X { POT_EXTRA_HEALING, 0, POTION_SYM, 4, 1 },
X { APPLE, 0, FOOD_SYM, 5, 0 },
X { 0, 0, 0, 0, 0}
X};
X#endif /* KAA /**/
X
Xstruct trobj Archeologist[] = {
X { STUDDED_LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1 },
X { UNDEF_TYP, 0, POTION_SYM, 2, 0 },
X { FOOD_RATION, 0, FOOD_SYM, 3, 1 },
X { PICK_AXE, UNDEF_SPE, TOOL_SYM, 1, 0 },
X { ICE_BOX, 0, TOOL_SYM, 1, 0 },
X { 0, 0, 0, 0, 0}
X};
X
Xstruct trobj Tinopener[] = {
X { CAN_OPENER, 0, TOOL_SYM, 1, 1 },
X { 0, 0, 0, 0, 0 }
X};
X
X#ifdef MARKER
Xstruct trobj Magicmarker[] = {
X { MAGIC_MARKER, 50, TOOL_SYM, 1, 0 },
X { 0, 0, 0, 0, 0 }
X};
X#endif
X
X#ifdef WALKIES
Xstruct trobj Leash[] = {
X { LEASH, 0, TOOL_SYM, 1, 0 },
X { 0, 0, 0, 0, 0 }
X};
X#endif
X
Xstruct trobj Blindfold[] = {
X { BLINDFOLD, 0, TOOL_SYM, 1, 0 },
X { 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Tourist[] = {
X#define T_DARTS 3
X { UNDEF_TYP, 0, FOOD_SYM, 10, 1 },
X { POT_EXTRA_HEALING, 0, POTION_SYM, 2, 0 },
X { EXPENSIVE_CAMERA, 0, TOOL_SYM, 1, 1 },
X { DART, 2, WEAPON_SYM, 25, 1 }, /* quan is variable */
X { 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Wizard[] = {
X#define W_MULTSTART 2
X#define W_MULTEND 6
X { ELVEN_CLOAK, 0, ARMOR_SYM, 1, 1 },
X { DAGGER, 0, WEAPON_SYM, 1, 1 }, /* for dealing with ghosts */
X { UNDEF_TYP, UNDEF_SPE, WAND_SYM, 2, 1 },
X { UNDEF_TYP, UNDEF_SPE, RING_SYM, 2, 1 },
X { UNDEF_TYP, UNDEF_SPE, POTION_SYM, 2, 1 },
X { UNDEF_TYP, UNDEF_SPE, SCROLL_SYM, 3, 1 },
X#ifdef SPELLS
X { UNDEF_TYP, UNDEF_SPE, SPBOOK_SYM, 3, 1 },
X#endif
X { 0, 0, 0, 0, 0 }
X};
X
X#ifdef NEWCLASS
Xstruct trobj Samurai[] = {
X#define S_ARROWS 3
X { KATANA, 0, WEAPON_SYM, 1, 1 },
X { SHORT_SWORD, 0, WEAPON_SYM, 1, 1 }, /* the wakizashi */
X { BOW, 1, WEAPON_SYM, 1, 1 },
X { ARROW, 0, WEAPON_SYM, 25, 1 }, /* quan is variable */
X { SPLINT_MAIL, 0, ARMOR_SYM, 1, 1},
X { 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Ninja[] = {
X#define N_SHURIKEN 1
X { KATANA, 0, WEAPON_SYM, 1, 1 },
X { SHURIKEN, 0, WEAPON_SYM, 25, 1 }, /* quan is variable */
X { LEATHER_ARMOR, 1, ARMOR_SYM, 1, 1},
X { 0, 0, 0, 0, 0 }
X};
X
Xstruct trobj Priest[] = {
X { CHAIN_MAIL, 0, ARMOR_SYM, 1, 1 },
X { SHIELD, 0, ARMOR_SYM, 1, 1 },
X { MACE, 1, WEAPON_SYM, 1, 1 },
X { POT_HOLY_WATER, 0, POTION_SYM, 4, 1 },
X#ifdef SPELLS
X { UNDEF_TYP, UNDEF_SPE, SPBOOK_SYM, 2, 0 },
X#endif
X { 0, 0, 0, 0, 0 }
X};
X#endif /* NEWCLASS /**/
X
Xu_init(){
Xregister int i;
Xchar exper = 'y', pc;
Xextern char readchar();
X if(flags.female) { /* should have been set in HACKOPTIONS */
X roles[4] = "Cave-woman";
X#ifdef NEWCLASS
X roles[7] = "Priestess";
X#endif
X }
X for(i = 0; i < NR_OF_ROLES; i++)
X rolesyms[i] = roles[i][0];
X rolesyms[i] = 0;
X
X if(pc = pl_character[0]) {
X if('a' <= pc && pc <= 'z') pc += 'A'-'a';
X if((i = role_index(pc)) >= 0)
X goto got_suffix; /* implies experienced */
X printf("\nUnknown role: %c\n", pc);
X pl_character[0] = pc = 0;
X }
X
X printf("\nShall I pick a character for you (yes, no, or quit) ? [ynq] ");
X
X while(!index("yYnNqQ", (exper = readchar()))) bell();
X
X printf("%c\n", exper); /* echo */
X
X if (index("qQ", exper)) {
X clearlocks();
X settty((char *) 0);
X exit(0);
X }
X
X if(index("Yy", exper)) {
X exper = 0;
X goto beginner;
X }
X
X printf("\n Tell me what kind of character you are:\n");
X printf(" Are you");
X for(i = 0; i < NR_OF_ROLES; i++) {
X printf(" %s %s", index("AEIOU",roles[i][0]) ? "an" : "a", roles[i]);
X if((((i + 1) % 4) == 0) && (i != NR_OF_ROLES -1)) printf(",\n ");
X else if(i < NR_OF_ROLES - 2) printf(",");
X if(i == NR_OF_ROLES - 2) printf(" or");
X }
X printf("? [%s or q(quit)] ", rolesyms);
X
X while(pc = readchar()) {
X if (pc == 'q' || pc == 'Q') {
X
X clearlocks();
X settty((char *) 0);
X exit(0);
X }
X if('a' <= pc && pc <= 'z') pc += 'A'-'a';
X if((i = role_index(pc)) >= 0) {
X printf("%c\n", pc); /* echo */
X (void) fflush(stdout); /* should be seen */
X break;
X }
X if(pc == '\n') break;
X bell();
X }
X if(pc == '\n') pc = 0;
X
Xbeginner:
X if(!pc) {
X i = rn2(NR_OF_ROLES);
X pc = rolesyms[i];
X printf("\nThis game you will be %s %s%s.\n",
X (exper || index("AEIOU", roles[i][0])) ? "an" : "a",
X exper ? "experienced " : "", roles[i]);
X getret();
X /* give him some feedback in case mklev takes much time */
X (void) putchar('\n');
X (void) fflush(stdout);
X }
X if(exper) {
X roles[i][0] = pc;
X }
X
Xgot_suffix:
X
X (void) strncpy(pl_character, roles[i], PL_CSIZ-1);
X pl_character[PL_CSIZ-1] = 0;
X flags.beginner = 1;
X u = zerou;
X u.usym = '@';
X u.ulevel = 1;
X init_uhunger();
X uarm = uarm2 = uarmh = uarms = uarmg = uwep =
X uball = uchain = uleft = uright = 0;
X
X#ifdef SPELLS
X u.uen = u.uenmax = 1;
X for (i = 0; i <= MAXSPELL; i++) spl_book[i].sp_id = NO_SPELL;
X#endif
X#ifdef PRAYERS
X u.ublesscnt = 300; /* no prayers just yet */
X u.ublessed = 0; /* not worthy yet */
X u.ugangr = 0; /* gods not angry */
X#endif
X#ifdef HARD
X u.udemigod = u.udg_cnt = 0; /* not a demi-god yet... */
X#endif
X#ifdef KAA
X u.mh = u.mhmax = u.umonnum = u.mtimedone = 0;
X#endif
X#ifdef QUEST
X u.uhorizon = 6;
X#endif
X switch(pc) {
X case 'c':
X case 'C':
X Cave_man[C_ARROWS].trquan = 12 + rnd(9)*rnd(9);
X u.uhp = u.uhpmax = 16;
X u.ustr = u.ustrmax = 18;
X ini_inv(Cave_man);
X break;
X case 't':
X case 'T':
X#ifdef KAA
X objects[POT_EXTRA_HEALING].oc_name_known=1;
X#endif
X Tourist[T_DARTS].trquan = 20 + rnd(20);
X u.ugold = u.ugold0 = rnd(1000);
X u.uhp = u.uhpmax = 10;
X u.ustr = u.ustrmax = 8;
X ini_inv(Tourist);
X if(!rn2(25)) ini_inv(Tinopener);
X#ifdef MARKER
X else if(!rn2(25)) ini_inv(Magicmarker);
X#endif
X#ifdef WALKIES
X else if(!rn2(25)) ini_inv(Leash);
X#endif
X break;
X case 'w':
X case 'W':
X for(i = W_MULTSTART; i <= W_MULTEND; i++)
X if(!rn2(5))
X Wizard[i].trquan += rn2(3) - 1;
X u.uhp = u.uhpmax = 15;
X u.ustr = u.ustrmax = 16;
X#ifdef SPELLS
X u.uen = u.uenmax += rn2(4);
X#endif
X ini_inv(Wizard);
X#ifdef MARKER
X if(!rn2(5)) ini_inv(Magicmarker);
X#endif
X if(!rn2(5)) ini_inv(Blindfold);
X break;
X case 'a':
X case 'A':
X Fast = INTRINSIC;
X Stealth = INTRINSIC;
X u.uhp = u.uhpmax = 12;
X u.ustr = u.ustrmax = 10;
X ini_inv(Archeologist);
X if(!rn2(10)) ini_inv(Tinopener);
X#ifdef MARKER
X else if(!rn2(10)) ini_inv(Magicmarker);
X#endif
X break;
X#ifdef KAA
X case 'e':
X case 'E':
X Elf[E_ARROWS].trquan = 15+rnd(20);
X Elf[E_ARMOR].trotyp = (rn2(2) ? ELFIN_CHAIN_MAIL : ELVEN_CLOAK);
X Fast = INTRINSIC;
X HSee_invisible = INTRINSIC;
X u.uhp = u.uhpmax = 16;
X u.ustr = u.ustrmax = 16;
X ini_inv(Elf);
X if(!rn2(5)) ini_inv(Blindfold);
X break;
X case 'v':
X case 'V':
X Stealth = INTRINSIC;
X HCold_resistance = INTRINSIC;
X flags.female = TRUE;
X u.uhp = u.uhpmax = 16;
X u.ustr = u.ustrmax = 17;
X ini_inv(Valkyrie);
X break;
X case 'h':
X case 'H':
X objects[POT_HEALING].oc_name_known=1;
X objects[POT_EXTRA_HEALING].oc_name_known=1;
X HPoison_resistance = INTRINSIC;
X u.uhp = u.uhpmax = 16;
X u.ustr = u.ustrmax = 15;
X ini_inv(Healer);
X break;
X#endif
X case 'k':
X case 'K':
X u.uhp = u.uhpmax = 12;
X u.ustr = u.ustrmax = 10;
X ini_inv(Knight);
X break;
X case 'b':
X case 'B':
X u.uhp = u.uhpmax = 14;
X u.ustr = u.ustrmax = 17;
X ini_inv(Barbarian);
X break;
X#ifdef NEWCLASS
X case 's':
X case 'S':
X Fast = INTRINSIC;
X u.uhp = u.uhpmax = 16;
X u.ustr = u.ustrmax = 16;
X Samurai[S_ARROWS].trquan = 12 + rnd(9)*rnd(9);
X ini_inv(Samurai);
X break;
X case 'n':
X case 'N':
X Fast = INTRINSIC;
X Stealth = INTRINSIC;
X u.uhp = u.uhpmax = 15;
X u.ustr = u.ustrmax = 10;
X Ninja[N_SHURIKEN].trquan = 12 + rnd(9)*rnd(9);
X ini_inv(Ninja);
X if(!rn2(5)) ini_inv(Blindfold);
X break;
X case 'p':
X case 'P':
X u.uhp = u.uhpmax = 13;
X u.ustr = u.ustrmax = 15;
X# ifdef SPELLS
X u.uen = u.uenmax += rn2(4);
X# endif
X ini_inv(Priest);
X# ifdef KAA
X uwep->dknown = 1; /* bless his primary weapon */
X# endif
X# ifdef MARKER
X if(!rn2(10)) ini_inv(Magicmarker);
X# endif
X objects[POT_HOLY_WATER].oc_name_known = 1;
X break;
X#endif /* NEWCLASS /**/
X default: /* impossible */
X u.uhp = u.uhpmax = 12;
X u.ustr = u.ustrmax = 16;
X }
X find_ac();
X if(!rn2(20)) {
X register int d = rn2(7) - 2; /* biased variation */
X u.ustr += d;
X u.ustrmax += d;
X }
X
X#ifdef WIZARD
X wiz_inv();
X#endif
X /* make sure he can carry all he has - especially for T's */
X while(inv_weight() > 0 && u.ustr < 118)
X u.ustr++, u.ustrmax++;
X}
X
Xini_inv(trop) register struct trobj *trop; {
Xregister struct obj *obj;
Xextern struct obj *mkobj();
X while(trop->trolet) {
X obj = mkobj(trop->trolet);
X obj->known = trop->trknown;
X /* not obj->dknown = 1; - let him look at it at least once */
X obj->cursed = 0;
X if(obj->olet == WEAPON_SYM){
X obj->quan = trop->trquan;
X trop->trquan = 1;
X }
X if(trop->trspe != UNDEF_SPE)
X obj->spe = trop->trspe;
X if(trop->trotyp != UNDEF_TYP)
X obj->otyp = trop->trotyp;
X else
X if(obj->otyp == WAN_WISHING) /* gitpyr!robert */
X obj->otyp = WAN_DEATH;
X obj->owt = weight(obj); /* defined after setting otyp+quan */
X obj = addinv(obj);
X
X /*
X * if a magic item's 'known' bit is on, set its name known
X */
X if (IS_MAGIC(obj) && obj->known)
X objects[obj->otyp].oc_name_known=1;
X
X if(obj->olet == ARMOR_SYM){
X switch(obj->otyp){
X case SHIELD:
X if(!uarms) setworn(obj, W_ARMS);
X break;
X case HELMET:
X if(!uarmh) setworn(obj, W_ARMH);
X break;
X case PAIR_OF_GLOVES:
X if(!uarmg) setworn(obj, W_ARMG);
X break;
X case ELVEN_CLOAK:
X if(!uarm2)
X setworn(obj, W_ARM);
X break;
X default:
X if(!uarm) setworn(obj, W_ARM);
X }
X }
X /* below changed by GAN 01/09/87 to allow wielding of
X * pick-axe or can-opener if there is no weapon
X */
X if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE ||
X obj->otyp == CAN_OPENER)
X if(!uwep) setuwep(obj);
X#ifndef PYRAMID_BUG
X if(--trop->trquan) continue; /* make a similar object */
X#else
X if(trop->trquan) { /* check if zero first */
X --trop->trquan;
X if(trop->trquan)
X continue; /* make a similar object */
X }
X#endif
X trop++;
X }
X}
X
X#ifdef WIZARD
Xwiz_inv(){
Xregister struct trobj *trop = &Extra_objs[0];
Xextern char *getenv();
Xregister char *ep = getenv("INVENT");
Xregister int type;
X while(ep && *ep) {
X type = atoi(ep);
X ep = index(ep, ',');
X if(ep) while(*ep == ',' || *ep == ' ') ep++;
X if(type <= 0 || type > NROFOBJECTS) continue;
X trop->trotyp = type;
X trop->trolet = objects[type].oc_olet;
X trop->trspe = 4;
X trop->trknown = 1;
X trop->trquan = 1;
X ini_inv(trop);
X }
X}
X#endif /* WIZARD /**/
X
Xplnamesuffix() {
Xregister char *p;
X if(p = rindex(plname, '-')) {
X *p = 0;
X pl_character[0] = p[1];
X pl_character[1] = 0;
X if(!plname[0]) {
X askname();
X plnamesuffix();
X }
X }
X}
X
Xrole_index(pc)
Xchar pc;
X{ /* must be called only from u_init() */
X /* so that rolesyms[] is defined */
X register char *cp;
X
X if(cp = index(rolesyms, pc))
X return(cp - rolesyms);
X return(-1);
X}
END_OF_u_init.c
if test 12871 -ne `wc -c