Amiga Hack Source (Part 8 of 13)

John A. Toebes, VIII jcz at ncsu.UUCP
Sun Feb 23 02:50:44 AEST 1986


#file hack.u_init.c
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */

#include "hack.h"
#include <stdio.h>
#include <signal.h>
#define   Strcat   (void) strcat
#define   UNDEF_TYP   0
#define   UNDEF_SPE   (-1)
extern struct obj *addinv();
extern char plname[];

char pl_character[PL_CSIZ];

struct trobj {
   uchar trotyp;
   schar trspe;
   char trolet;
   Bitfield(trquan,6);
   Bitfield(trknown,1);
};

#ifdef WIZARD
struct trobj Extra_objs[] = {
   { 0, 0, 0, 0, 0 },
   { 0, 0, 0, 0, 0 }
};
#endif WIZARD

struct trobj Cave_man[] = {
   { MACE, 1, WEAPON_SYM, 1, 1 },
   { BOW, 1, WEAPON_SYM, 1, 1 },
   { ARROW, 0, WEAPON_SYM, 25, 1 },   /* quan is variable */
   { LEATHER_ARMOR, 2, ARMOR_SYM, 1, 1 },
   { 0, 0, 0, 0, 0}
};

struct trobj Fighter[] = {
   { TWO_HANDED_SWORD, 0, WEAPON_SYM, 1, 1 },
   { RING_MAIL, 3, ARMOR_SYM, 1, 1 },
   { 0, 0, 0, 0, 0 }
};

struct trobj Knight[] = {
   { LONG_SWORD, 0, WEAPON_SYM, 1, 1 },
   { SPEAR, 2, WEAPON_SYM, 1, 1 },
   { RING_MAIL, 4, ARMOR_SYM, 1, 1 },
   { HELMET, 1, ARMOR_SYM, 1, 1 },
   { SHIELD, 1, ARMOR_SYM, 1, 1 },
   { PAIR_OF_GLOVES, 1, ARMOR_SYM, 1, 1 },
   { 0, 0, 0, 0, 0 }
};

struct trobj Speleologist[] = {
   { STUDDED_LEATHER_ARMOR, 3, ARMOR_SYM, 1, 1 },
   { UNDEF_TYP, 0, POTION_SYM, 2, 0 },
   { FOOD_RATION, 0, FOOD_SYM, 3, 1 },
   { ICE_BOX, 0, TOOL_SYM, 1, 0 },
   { 0, 0, 0, 0, 0}
};

struct trobj Tourist[] = {
   { UNDEF_TYP, 0, FOOD_SYM, 10, 1 },
   { POT_EXTRA_HEALING, 0, POTION_SYM, 2, 0 },
   { EXPENSIVE_CAMERA, 0, TOOL_SYM, 1, 1 },
   { DART, 2, WEAPON_SYM, 25, 1 },   /* quan is variable */
   { 0, 0, 0, 0, 0 }
};

struct trobj Wizard[] = {
   { ELVEN_CLOAK, 1, ARMOR_SYM, 1, 1 },
   { UNDEF_TYP, UNDEF_SPE, WAND_SYM, 2, 0 },
   { UNDEF_TYP, UNDEF_SPE, RING_SYM, 2, 0 },
   { UNDEF_TYP, UNDEF_SPE, POTION_SYM, 2, 0 },
   { UNDEF_TYP, UNDEF_SPE, SCROLL_SYM, 3, 0 },
   { 0, 0, 0, 0, 0 }
};

#ifdef NEWS
int u_in_infl;

u_in_intrup()
{
   u_in_infl++;
   (void) signal(SIGINT, u_in_intrup);
}
#endif NEWS

u_init(){
register int c,pc,i;
#ifdef NEWS
   /* It is not unlikely that we get an interrupt here
      intended to kill the news; unfortunately this would
      also kill (part of) the following question */
int (*prevsig)() = signal(SIGINT, u_in_intrup);
#endif NEWS
register char *cp;
char buf[256];
   if(pc = pl_character[0]) goto got_suffix;
   buf[0] = 0;
   Strcat(buf, "\nTell me what kind of character you are:\n");
   Strcat(buf, "Are you a Tourist, a Speleologist, a Fighter,\n");
   Strcat(buf, "        a Knight, a Cave-man or a Wizard? [TSFKCW] ");
intrup:
   for(cp = buf; *cp; cp++){
#ifdef NEWS
      if(u_in_infl){
         u_in_infl = 0;
         goto intrup;
      }
#endif NEWS
      (void) myputchar(*cp);
   }
loop:
   (void) myfflush(stdout);
   pc = 0;
   while((c = inchar()) != '\n') {
#ifndef AMIGA
      if(c == EOF) {
#ifdef NEWS
         if(u_in_infl) goto intrup;   /* %% */
#endif NEWS
         settty("\nEnd of input?\n");
         hackexit(0);
         }
      else
#endif !AMIGA
         if(pc && c==8)  /* backspace over it? */
         {
         myputchar(c);
         pc = 0;
         }
      else if (!pc)
         {
         pc = c;
         myputchar(c);
         }
   }
   if(!pc || !strchr("TSFKCWtsfkcw", pc)){
      myprintf("\nAnswer with T,S,F,K,C or W. What are you? ");
      goto loop;
   }
got_suffix:
   myputchar('\n');
   myfflush();
   if('a' <= pc && pc <= 'z') pc += 'A'-'a';

#ifdef NEWS
   (void) signal(SIGINT,prevsig);
#endif NEWS

   u.usym = '@';
   u.ulevel = 1;
   init_uhunger();
   u.uhpmax = u.uhp = 12;
   u.ustrmax = u.ustr = !rn2(20) ? 14 + rn2(7) : 16;
#ifdef QUEST
   u.uhorizon = 6;
#endif QUEST
   switch(pc) {
   case 'C':
      setpl_char("Cave-man");
      Cave_man[2].trquan = 12 + rnd(9)*rnd(9);
      u.uhp = u.uhpmax = 16;
      u.ustr = u.ustrmax = 18;
      ini_inv(Cave_man);
      break;
   case 'T':
      setpl_char("Tourist");
      Tourist[3].trquan = 20 + rnd(20);
      u.ugold = u.ugold0 = rnd(1000);
      u.uhp = u.uhpmax = 10;
      u.ustr = u.ustrmax = 8;
      ini_inv(Tourist);
      break;
   case 'W':
      setpl_char("Wizard");
      for(i=1; i<=4; i++) if(!rn2(5))
         Wizard[i].trquan += rn2(3) - 1;
      u.uhp = u.uhpmax = 15;
      u.ustr = u.ustrmax = 16;
      ini_inv(Wizard);
      break;
   case 'S':
      setpl_char("Speleologist");
      Fast = INTRINSIC;
      Stealth = INTRINSIC;
      u.uhp = u.uhpmax = 12;
      u.ustr = u.ustrmax = 10;
      ini_inv(Speleologist);
      break;
   case 'K':
      setpl_char("Knight");
      u.uhp = u.uhpmax = 12;
      u.ustr = u.ustrmax = 10;
      ini_inv(Knight);
      break;
   case 'F':
      setpl_char("Fighter");
      u.uhp = u.uhpmax = 14;
      u.ustr = u.ustrmax = 17;
      ini_inv(Fighter);
   }
   find_ac();
   /* make sure he can carry all he has - especially for T's */
   while(inv_weight() > 0 && u.ustr < 118)
      u.ustr++, u.ustrmax++;
#ifdef WIZARD
   if(wizard) wiz_inv();
#endif WIZARD
}

ini_inv(trop) register struct trobj *trop; {
register struct obj *obj;
extern struct obj *mkobj();
   while(trop->trolet) {
      obj = mkobj(trop->trolet);
      obj->known = trop->trknown;
      obj->cursed = 0;
      if(obj->olet == WEAPON_SYM){
         obj->quan = trop->trquan;
         trop->trquan = 1;
      }
      if(trop->trspe != UNDEF_SPE)
         obj->spe = trop->trspe;
      if(trop->trotyp != UNDEF_TYP)
         obj->otyp = trop->trotyp;
      obj->owt = weight(obj);   /* defined after setting otyp+quan */
      obj = addinv(obj);
      if(obj->olet == ARMOR_SYM){
         switch(obj->otyp){
         case SHIELD:
            if(!uarms) setworn(obj, W_ARMS);
            break;
         case HELMET:
            if(!uarmh) setworn(obj, W_ARMH);
            break;
         case PAIR_OF_GLOVES:
            if(!uarmg) setworn(obj, W_ARMG);
            break;
         case ELVEN_CLOAK:
            if(!uarm2)
               setworn(obj, W_ARM);
            break;
         default:
            if(!uarm) setworn(obj, W_ARM);
         }
      }
      if(obj->olet == WEAPON_SYM)
         if(!uwep) setuwep(obj);
      if(--trop->trquan) continue;   /* make a similar object */
      trop++;
   }
}

#ifdef WIZARD
wiz_inv(){
register struct trobj *trop = &Extra_objs[0];
extern char *getenv();
register char *ep = getenv("INVENT");
register int type;
   while(ep && *ep) {
      type = atoi(ep);
      ep = strchr(ep, ',');
      if(ep) while(*ep == ',' || *ep == ' ') ep++;
      if(type <= 0 || type > NROFOBJECTS) continue;
      trop->trotyp = type;
      trop->trolet = objects[type].oc_olet;
      trop->trspe = 4;
      trop->trknown = 1;
      trop->trquan = 1;
      ini_inv(trop);
   }
   /* give him a wand of wishing by default */
   trop->trotyp = WAN_WISHING;
   trop->trolet = WAND_SYM;
   trop->trspe = 20;
   trop->trknown = 1;
   trop->trquan = 1;
   ini_inv(trop);
}
#endif WIZARD

setpl_char(plc) char *plc; {
   (void) strncpy(pl_character, plc, PL_CSIZ-1);
   pl_character[PL_CSIZ-1] = 0;
}

plnamesuffix() {
register char *p;
   if(p = strrchr(plname, '-')) {
      *p = 0;
      if(!plname[0]) {
         askname();
         plnamesuffix();
      }
      if(strchr("TSFKCWtsfkcw", p[1])) {
         pl_character[0] = p[1];
         pl_character[1] = 0;
      }
   }
}

#file hack.vault.c
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */

#include	"hack.h"
#ifdef QUEST
setgd(/* mtmp */) /* struct monst *mtmp; */ {}
gd_move() { return(2); }
gddead(mtmp) struct monst *mtmp; {}
invault(){}

#else


extern struct monst *makemon();
#define	VAULT	6
#define	FCSIZ	(ROWNO+COLNO)
struct fakecorr {
	xchar fx,fy,ftyp;
};

struct egd {
	int fcbeg, fcend;	/* fcend: first unused pos */
	xchar gdx, gdy;		/* goal of guard's walk */
	unsigned gddone:1;
	struct fakecorr fakecorr[FCSIZ];
};

struct permonst pm_guard =
	{ "guard", '@', 12, 12, -1, 4, 10, sizeof(struct egd) };

struct monst *guard;
int gdlevel;
#define	EGD	((struct egd *)(&(guard->mextra[0])))

restfakecorr(){
register int fcx,fcy,fcbeg;
register struct rm *crm;

	while((fcbeg = EGD->fcbeg) < EGD->fcend) {
		fcx = EGD->fakecorr[fcbeg].fx;
		fcy = EGD->fakecorr[fcbeg].fy;
		if((u.ux == fcx && u.uy == fcy) || cansee(fcx,fcy) ||
		   m_at(fcx,fcy))
			return;
		crm = &levl[fcx][fcy];
		crm->typ = EGD->fakecorr[fcbeg].ftyp;
		if(!crm->typ) crm->seen = 0;
		newsym(fcx,fcy);
		EGD->fcbeg++;
	}
	/* it seems he left the corridor - let the guard disappear */
	mondead(guard);
	guard = 0;
}

setgd(){
register struct monst *mtmp;
	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->isgd){
		guard = mtmp;
		gdlevel = dlevel;
		return;
	}
	guard = 0;
}

invault(){
register int tmp = inroom(u.ux, u.uy);
	if(tmp < 0 || rooms[tmp].rtype != VAULT) {
		u.uinvault = 0;
		return;
	}
	if(++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) {
	char buf[BUFSZ];
	register int x,y,dx,dy,gx,gy;

		/* first find the goal for the guard */
		for(dy = 0; dy < ROWNO; dy++)
		  for(y = u.uy-dy; y <= u.uy+dy; y++) {
		    if(y > u.uy-dy) y = u.uy+dy;
		    if(y < 0 || y > ROWNO-1) continue;
		    for(x = u.ux; x < COLNO; x++)
			if(levl[x][y].typ == CORR) goto fnd;
		    for(x = u.ux-1; x > 0; x--)
			if(levl[x][y].typ == CORR) goto fnd;
		}
		impossible();
		tele();
		return;
	fnd:
		gx = x; gy = y;

		/* next find a good place for a door in the wall */
		x = u.ux; y = u.uy;
		while(levl[x][y].typ > DOOR) {
			dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
			dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
			if(abs(gx-x) >= abs(gy-y)) x += dx;
			else y += dy;
		}

		/* make something interesting happen */
		if(!(guard = makemon(&pm_guard,x,y))) return;
		guard->isgd = guard->mpeaceful = 1;
		EGD->gddone = 0;
		gdlevel = dlevel;
		if(!cansee(guard->mx, guard->my)) {
			mondead(guard);
			guard = 0;
			return;
		}
		EGD->gdx = gx;
		EGD->gdy = gy;
		EGD->fcbeg = 0;
		EGD->fakecorr[0].fx = x;
		EGD->fakecorr[0].fy = y;
		EGD->fakecorr[0].ftyp = levl[x][y].typ;
		levl[x][y].typ = DOOR;
		EGD->fcend = 1;

		pline("Suddenly one of the Vault's guards enters!");
		pmon(guard);
		pline("\"Hello stranger, who are you?\" - ");
		getlin(buf);
		clrlin();
		pline("\"I don't know you.\"");
		if(!u.ugold) pline("\"Please follow me.\"");
		else {
		    pline("\"Most likely all that gold was stolen from this vault.\"");
		    pline("\"Please drop your gold (say d$ ) and follow me.\"");
		}
	}
}

gd_move(){
register int x,y,dx,dy,gx,gy,nx,ny,tmp;
register struct fakecorr *fcp;
register struct rm *crm;
	if(!guard || gdlevel != dlevel){
		pline("Where is the guard?");
		impossible();
		return(2);	/* died */
	}
	if(u.ugold || dist(guard->mx,guard->my) > 2 || EGD->gddone){
		restfakecorr();
		return(0);	/* didnt move */
	}
	x = guard->mx;
	y = guard->my;
	/* look around (hor & vert only) for accessible places */
	for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++)
	    if(nx == x || ny == y) if(nx != x || ny != y)
	    if(isok(nx,ny))
	    if((tmp = (crm = &levl[nx][ny])->typ) >= SDOOR) {
		register int i;
		for(i = EGD->fcbeg; i < EGD->fcend; i++)
			if(EGD->fakecorr[i].fx == nx &&
			   EGD->fakecorr[i].fy == ny)
				goto nextnxy;
		if((i = inroom(nx,ny)) >= 0 && rooms[i].rtype == VAULT)
			goto nextnxy;
		/* seems we found a good place to leave him alone */
		EGD->gddone = 1;
		if(tmp >= DOOR) goto newpos;
		crm->typ = (tmp == SCORR) ? CORR : DOOR;
		goto proceed;
	nextnxy:	;
	}
	nx = x;
	ny = y;
	gx = EGD->gdx;
	gy = EGD->gdy;
	dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
	dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
	if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy;

	while((tmp = (crm = &levl[nx][ny])->typ) != 0) {
	/* in view of the above we must have  tmp < SDOOR */
	/* must be a wall here */
		if(isok(nx+nx-x,ny+ny-y) && levl[nx+nx-x][ny+ny-y].typ > DOOR){
			crm->typ = DOOR;
			goto proceed;
		}
		if(dy && nx != x) {
			nx = x; ny = y+dy; dx = 0;
			continue;
		}
		if(dx && ny != y) {
			ny = y; nx = x+dx; dy = 0;
			continue;
		}
		/* I don't like this, but ... */
		crm->typ = DOOR;
		goto proceed;
	}
	crm->typ = CORR;
proceed:
	fcp = &(EGD->fakecorr[EGD->fcend]);
	if(EGD->fcend++ == FCSIZ) panic("fakecorr overflow");
	fcp->fx = nx;
	fcp->fy = ny;
	fcp->ftyp = tmp;
newpos:
	if(EGD->gddone) nx = ny = 0;
	guard->mx = nx;
	guard->my = ny;
	pmon(guard);
	restfakecorr();
	return(1);
}

gddead(){
	guard = 0;
}


#endif QUEST
#file hack.version.c
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */

#include	"date.h"

doversion(){
	pline("AMIGA %s 1.0.1 - last edit %s.",
#ifdef QUEST
		"Quest"
#else
		"Hack"
#endif QUEST
	, datestring);
	return(0);
}
#file hack.whatis.c
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* hack.whatis.c version 1.0.1 - whatis asks for one char only. */

#include	<stdio.h>
#include "hack.h"

dowhatis()
{
	FILE *fp;
	char bufr[BUFSZ];
	register char *ep, q;
	extern char readchar();

	if(!(fp = fopen("data","r")))
		pline("Cannot open data file!");
	else {
		pline("Specify what? ");
		q = readchar();
		while(fgets(bufr,BUFSZ,fp))
			if(*bufr == q) {
				ep = index(bufr, '\n');
				if(ep) *ep = 0;
				else impossible();
				pline(bufr);
				if(ep[-1] == ';') morewhat(fp);
				goto fnd;
			}
		pline("I've never heard of such things.");
	fnd:
		(void) fclose(fp);
	}
}

morewhat(fp) FILE *fp; {
char bufr[BUFSZ];
register char *ep;
	pline("More info? ");
	if(readchar() != 'y') return;
	cls();
	while(fgets(bufr,BUFSZ,fp) && *bufr == '\t'){
		ep = index(bufr, '\n');
		if(!ep) break;
		*ep = 0;
		myputs(bufr+1);
	}
	more();
	docrt();
}
#file hack.wield.c
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* hack.wield.c version 1.0.1 - evaporate%s */

#include	"hack.h"

setuwep(obj) register struct obj *obj; {
	setworn(obj, W_WEP);
}

dowield()
{
	register struct obj *wep;
	register int res = 0;

	multi = 0;
	if(!(wep = getobj("#-)", "wield"))) /* nothing */;
	else if(uwep == wep)
		pline("You are already wielding that!");
	else if(uwep && uwep->cursed)
		pline("The %s welded to your hand!",
			aobjnam(uwep, "are"));
	else if((int) wep == 1) {
		if(uwep == 0){
			pline("You are already empty handed.");
		} else {
			setuwep((struct obj *) 0);
			res++;
			pline("You are empty handed.");
		}
	} else if(uarms && wep->otyp == TWO_HANDED_SWORD)
	pline("You cannot wield a two-handed sword and wear a shield.");
	else if(wep->owornmask & (W_ARMOR | W_RING))
		pline("You cannot wield that!");
	else {
		setuwep(wep);
		res++;
		if(uwep->cursed) pline("The %s itself to your hand!",
			aobjnam(uwep, "weld"));
		else prinv(uwep);
	}
	return(res);
}

corrode_weapon(){
	if(!uwep || uwep->olet != WEAPON_SYM) return;	/* %% */
	if(uwep->rustfree)
		pline("Your %s not affected.", aobjnam(uwep, "are"));
	else {
		pline("Your %s!", aobjnam(uwep, "corrode"));
		uwep->spe--;
	}
}

chwepon(otmp,amount)
register struct obj *otmp;
register int amount;
{
register char *color = (amount < 0) ? "black" : "green";
register char *time;
	if(!uwep || uwep->olet != WEAPON_SYM) {
		strange_feeling(otmp);
		return(0);
	}

	if(uwep->otyp == WORM_TOOTH && amount > 0) {
		uwep->otyp = CRYSKNIFE;
		pline("Your weapon seems sharper now.");
		uwep->cursed = 0;
		return(1);
	}

	if(uwep->otyp == CRYSKNIFE && amount < 0) {
		uwep->otyp = WORM_TOOTH;
		pline("Your weapon looks duller now.");
		return(1);
	}

	/* there is a (soft) upper limit to uwep->spe */
	if(amount > 0 && uwep->spe > 5 && rn2(3)) {
	    pline("Your %s violently green for a while and then evaporate%s.",
		aobjnam(uwep, "glow"), (uwep->quan == 1) ? "s" : "");
	    useup(uwep);
	    return(1);
	}
	if(!rn2(6)) amount *= 2;
	time = (amount*amount == 1) ? "moment" : "while";
	pline("Your %s %s for a %s.",
		aobjnam(uwep, "glow"), color, time);
	uwep->spe += amount;
	if(amount > 0) uwep->cursed = 0;
	return(1);
}
#file hack.worm.c
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */

#include "hack.h"
#ifndef NOWORM
#include "def.wseg.h"

struct wseg *wsegs[32];	/* linked list, tail first */
struct wseg *wheads[32];
long wgrowtime[32];

getwn(mtmp) struct monst *mtmp; {
register int tmp;
	for(tmp=1; tmp<32; tmp++) if(!wsegs[tmp]) {
		mtmp->wormno = tmp;
		return(1);
	}
	return(0);	/* level infested with worms */
}

/* called to initialize a worm unless cut in half */
initworm(mtmp) struct monst *mtmp; {
register struct wseg *wtmp;
register int tmp = mtmp->wormno;
	if(!tmp) return;
	wheads[tmp] = wsegs[tmp] = wtmp = newseg();
	wgrowtime[tmp] = 0;
	wtmp->wx = mtmp->mx;
	wtmp->wy = mtmp->my;
/*	wtmp->wdispl = 0;*/
	wtmp->nseg = 0;
}

worm_move(mtmp) struct monst *mtmp; {
register struct wseg *wtmp, *whd;
register int tmp = mtmp->wormno;
	wtmp = newseg();
	wtmp->wx = mtmp->mx;
	wtmp->wy = mtmp->my;
	wtmp->nseg = 0;
/*	wtmp->wdispl = 0;*/
	(whd = wheads[tmp])->nseg = wtmp;
	wheads[tmp] = wtmp;
	if(cansee(whd->wx,whd->wy)){
		unpmon(mtmp);
		atl(whd->wx, whd->wy, '~');
		whd->wdispl = 1;
	} else	whd->wdispl = 0;
	if(wgrowtime[tmp] <= moves) {
		if(!wgrowtime[tmp]) wgrowtime[tmp] = moves + rnd(5);
		else wgrowtime[tmp] += 2+rnd(15);
		mtmp->orig_hp++;
		mtmp->mhp++;
		return;
	}
	whd = wsegs[tmp];
	wsegs[tmp] = whd->nseg;
	remseg(whd);
}

worm_nomove(mtmp) register struct monst *mtmp; {
register int tmp;
register struct wseg *wtmp;
	tmp = mtmp->wormno;
	wtmp = wsegs[tmp];
	if(wtmp == wheads[tmp]) return;
	if(wtmp == 0 || wtmp->nseg == 0) panic("worm_nomove?");
	wsegs[tmp] = wtmp->nseg;
	remseg(wtmp);
	mtmp->mhp--;	/* orig_hp not changed ! */
}

wormdead(mtmp) register struct monst *mtmp; {
register int tmp = mtmp->wormno;
register struct wseg *wtmp, *wtmp2;
	if(!tmp) return;
	mtmp->wormno = 0;
	for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){
		wtmp2 = wtmp->nseg;
		remseg(wtmp);
	}
	wsegs[tmp] = 0;
}

wormhit(mtmp) register struct monst *mtmp; {
register int tmp = mtmp->wormno;
register struct wseg *wtmp;
	if(!tmp) return;	/* worm without tail */
	for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg)
		(void) hitu(mtmp,1);
}

wormsee(tmp) register unsigned tmp; {
register struct wseg *wtmp = wsegs[tmp];
	if(!wtmp) panic("wormsee: wtmp==0");
	for(; wtmp->nseg; wtmp = wtmp->nseg)
		if(!cansee(wtmp->wx,wtmp->wy) && wtmp->wdispl){
			newsym(wtmp->wx, wtmp->wy);
			wtmp->wdispl = 0;
		}
}

pwseg(wtmp) register struct wseg *wtmp; {
	if(!wtmp->wdispl){
		atl(wtmp->wx, wtmp->wy, '~');
		wtmp->wdispl = 1;
	}
}

cutworm(mtmp,x,y,weptyp)
register struct monst *mtmp;
register xchar x,y;
register uchar weptyp;		/* uwep->otyp or 0 */
{
	register struct wseg *wtmp, *wtmp2;
	register struct monst *mtmp2;
	register int tmp,tmp2;
	if(mtmp->mx == x && mtmp->my == y) return;	/* hit headon */

	/* cutting goes best with axe or sword */
	tmp = rnd(20);
	if(weptyp == LONG_SWORD || weptyp == TWO_HANDED_SWORD ||
		weptyp == AXE) tmp += 5;
	if(tmp < 12) return;

	/* if tail then worm just loses a tail segment */
	tmp = mtmp->wormno;
	wtmp = wsegs[tmp];
	if(wtmp->wx == x && wtmp->wy == y){
		wsegs[tmp] = wtmp->nseg;
		remseg(wtmp);
		return;
	}

	/* cut the worm in two halves */
	mtmp2 = newmonst(0);
	*mtmp2 = *mtmp;
	mtmp2->mxlth = mtmp2->mnamelth = 0;

	/* sometimes the tail end dies */
	if(rn2(3) || !getwn(mtmp2)){
		monfree(mtmp2);
		tmp2 = 0;
	} else {
		tmp2 = mtmp2->wormno;
		wsegs[tmp2] = wsegs[tmp];
		wgrowtime[tmp2] = 0;
	}
	do {
		if(wtmp->nseg->wx == x && wtmp->nseg->wy == y){
			if(tmp2) wheads[tmp2] = wtmp;
			wsegs[tmp] = wtmp->nseg->nseg;
			remseg(wtmp->nseg);
			wtmp->nseg = 0;
			if(tmp2){
				pline("You cut the worm in half.");
				mtmp2->orig_hp = mtmp2->mhp =
					d(mtmp2->data->mlevel, 8);
				mtmp2->mx = wtmp->wx;
				mtmp2->my = wtmp->wy;
				mtmp2->nmon = fmon;
				fmon = mtmp2;
				pmon(mtmp2);
			} else {
				pline("You cut off part of the worm's tail.");
				remseg(wtmp);
			}
			mtmp->mhp /= 2;
			return;
		}
		wtmp2 = wtmp->nseg;
		if(!tmp2) remseg(wtmp);
		wtmp = wtmp2;
	} while(wtmp->nseg);
	panic("Cannot find worm segment");
}

remseg(wtmp) register struct wseg *wtmp; {
	if(wtmp->wdispl)
		newsym(wtmp->wx, wtmp->wy);
	free((char *) wtmp);
}
#endif NOWORM
#file hack.worn.c
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */



#include "hack.h"



struct worn {

	long w_mask;

	struct obj **w_obj;

} worn[] = {

	{ W_ARM, &uarm },

	{ W_ARM2, &uarm2 },

	{ W_ARMH, &uarmh },

	{ W_ARMS, &uarms },

	{ W_ARMG, &uarmg },

	{ W_RINGL, &uleft },

	{ W_RINGR, &uright },

	{ W_WEP, &uwep },

	{ W_BALL, &uball },

	{ W_CHAIN, &uchain },

	{ 0, 0 }

};



setworn(obj, mask)

register struct obj *obj;

long mask;

{

	register struct worn *wp;

	register struct obj *oobj;



	for(wp = worn; wp->w_mask; wp++) if(wp->w_mask & mask) {

		oobj = *(wp->w_obj);

		if(oobj && !(oobj->owornmask & wp->w_mask)){

			pline("Setworn: mask = %d.", wp->w_mask);

			impossible();

		}

		if(oobj) oobj->owornmask &= ~wp->w_mask;

		if(obj && oobj && wp->w_mask == W_ARM){

			if(uarm2) {

				pline("Setworn: uarm2 set?");

				impossible();

			} else

				setworn(uarm, W_ARM2);

		}

		*(wp->w_obj) = obj;

		if(obj) obj->owornmask |= wp->w_mask;

	}

	if(uarm2 && !uarm) {

		uarm = uarm2;

		uarm2 = 0;

		uarm->owornmask ^= (W_ARM | W_ARM2);

	}

}



/* called e.g. when obj is destroyed */

setnotworn(obj) register struct obj *obj; {

	register struct worn *wp;



	for(wp = worn; wp->w_mask; wp++)

		if(obj == *(wp->w_obj)) {

			*(wp->w_obj) = 0;

			obj->owornmask &= ~wp->w_mask;

		}

	if(uarm2 && !uarm) {

		uarm = uarm2;

		uarm2 = 0;

		uarm->owornmask ^= (W_ARM | W_ARM2);

	}

}



More information about the Comp.sources.unix mailing list