⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hack.invent.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. *//* hack.invent.c - version 1.0.3 */#include	"hack.h"#include	<stdio.h>extern struct obj *splitobj();extern struct obj zeroobj;extern char morc;extern char quitchars[];static char *xprname();#ifndef NOWORM#include	"def.wseg.h"extern struct wseg *wsegs[32];#endif NOWORM#define	NOINVSYM	'#'static int lastinvnr = 51;	/* 0 ... 51 */staticassigninvlet(otmp)register struct obj *otmp;{	boolean inuse[52];	register int i;	register struct obj *obj;	for(i = 0; i < 52; i++) inuse[i] = FALSE;	for(obj = invent; obj; obj = obj->nobj) if(obj != otmp) {		i = obj->invlet;		if('a' <= i && i <= 'z') inuse[i - 'a'] = TRUE; else		if('A' <= i && i <= 'Z') inuse[i - 'A' + 26] = TRUE;		if(i == otmp->invlet) otmp->invlet = 0;	}	if((i = otmp->invlet) &&	    (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z')))		return;	for(i = lastinvnr+1; i != lastinvnr; i++) {		if(i == 52) { i = -1; continue; }		if(!inuse[i]) break;	}	otmp->invlet = (inuse[i] ? NOINVSYM :			(i < 26) ? ('a'+i) : ('A'+i-26));	lastinvnr = i;}struct obj *addinv(obj)register struct obj *obj;{	register struct obj *otmp;	/* merge or attach to end of chain */	if(!invent) {		invent = obj;		otmp = 0;	} else	for(otmp = invent; /* otmp */; otmp = otmp->nobj) {		if(merged(otmp, obj, 0))			return(otmp);		if(!otmp->nobj) {			otmp->nobj = obj;			break;		}	}	obj->nobj = 0;	if(flags.invlet_constant) {		assigninvlet(obj);		/*		 * The ordering of the chain is nowhere significant		 * so in case you prefer some other order than the		 * historical one, change the code below.		 */		if(otmp) {	/* find proper place in chain */			otmp->nobj = 0;			if((invent->invlet ^ 040) > (obj->invlet ^ 040)) {				obj->nobj = invent;				invent = obj;			} else			for(otmp = invent; ; otmp = otmp->nobj) {			    if(!otmp->nobj ||				(otmp->nobj->invlet ^ 040) > (obj->invlet ^ 040)){				obj->nobj = otmp->nobj;				otmp->nobj = obj;				break;			    }			}		}	}	return(obj);}useup(obj)register struct obj *obj;{	if(obj->quan > 1){		obj->quan--;		obj->owt = weight(obj);	} else {		setnotworn(obj);		freeinv(obj);		obfree(obj, (struct obj *) 0);	}}freeinv(obj)register struct obj *obj;{	register struct obj *otmp;	if(obj == invent)		invent = invent->nobj;	else {		for(otmp = invent; otmp->nobj != obj; otmp = otmp->nobj)			if(!otmp->nobj) panic("freeinv");		otmp->nobj = obj->nobj;	}}/* destroy object in fobj chain (if unpaid, it remains on the bill) */delobj(obj) register struct obj *obj; {	freeobj(obj);	unpobj(obj);	obfree(obj, (struct obj *) 0);}/* unlink obj from chain starting with fobj */freeobj(obj) register struct obj *obj; {	register struct obj *otmp;	if(obj == fobj) fobj = fobj->nobj;	else {		for(otmp = fobj; otmp->nobj != obj; otmp = otmp->nobj)			if(!otmp) panic("error in freeobj");		otmp->nobj = obj->nobj;	}}/* Note: freegold throws away its argument! */freegold(gold) register struct gold *gold; {	register struct gold *gtmp;	if(gold == fgold) fgold = gold->ngold;	else {		for(gtmp = fgold; gtmp->ngold != gold; gtmp = gtmp->ngold)			if(!gtmp) panic("error in freegold");		gtmp->ngold = gold->ngold;	}	free((char *) gold);}deltrap(trap)register struct trap *trap;{	register struct trap *ttmp;	if(trap == ftrap)		ftrap = ftrap->ntrap;	else {		for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ;		ttmp->ntrap = trap->ntrap;	}	free((char *) trap);}struct wseg *m_atseg;struct monst *m_at(x,y)register x,y;{	register struct monst *mtmp;#ifndef NOWORM	register struct wseg *wtmp;#endif NOWORM	m_atseg = 0;	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){		if(mtmp->mx == x && mtmp->my == y)			return(mtmp);#ifndef NOWORM		if(mtmp->wormno){		    for(wtmp = wsegs[mtmp->wormno]; wtmp; wtmp = wtmp->nseg)		    if(wtmp->wx == x && wtmp->wy == y){			m_atseg = wtmp;			return(mtmp);		    }		}#endif NOWORM	}	return(0);}struct obj *o_at(x,y)register x,y;{	register struct obj *otmp;	for(otmp = fobj; otmp; otmp = otmp->nobj)		if(otmp->ox == x && otmp->oy == y) return(otmp);	return(0);}struct obj *sobj_at(n,x,y)register n,x,y;{	register struct obj *otmp;	for(otmp = fobj; otmp; otmp = otmp->nobj)		if(otmp->ox == x && otmp->oy == y && otmp->otyp == n)			return(otmp);	return(0);}carried(obj) register struct obj *obj; {register struct obj *otmp;	for(otmp = invent; otmp; otmp = otmp->nobj)		if(otmp == obj) return(1);	return(0);}carrying(type)register int type;{	register struct obj *otmp;	for(otmp = invent; otmp; otmp = otmp->nobj)		if(otmp->otyp == type)			return(TRUE);	return(FALSE);}struct obj *o_on(id, objchn) unsigned int id; register struct obj *objchn; {	while(objchn) {		if(objchn->o_id == id) return(objchn);		objchn = objchn->nobj;	}	return((struct obj *) 0);}struct trap *t_at(x,y)register x,y;{	register struct trap *trap = ftrap;	while(trap) {		if(trap->tx == x && trap->ty == y) return(trap);		trap = trap->ntrap;	}	return(0);}struct gold *g_at(x,y)register x,y;{	register struct gold *gold = fgold;	while(gold) {		if(gold->gx == x && gold->gy == y) return(gold);		gold = gold->ngold;	}	return(0);}/* make dummy object structure containing gold - for temporary use only */struct obj *mkgoldobj(q)register long q;{	register struct obj *otmp;	otmp = newobj(0);	/* should set o_id etc. but otmp will be freed soon */	otmp->olet = '$';	u.ugold -= q;	OGOLD(otmp) = q;	flags.botl = 1;	return(otmp);}/* * getobj returns: *	struct obj *xxx:	object to do something with. *	(struct obj *) 0	error return: no object. *	&zeroobj		explicitly no object (as in w-). */struct obj *getobj(let,word)register char *let,*word;{	register struct obj *otmp;	register char ilet,ilet1,ilet2;	char buf[BUFSZ];	char lets[BUFSZ];	register int foo = 0, foo2;	register char *bp = buf;	xchar allowcnt = 0;	/* 0, 1 or 2 */	boolean allowgold = FALSE;	boolean allowall = FALSE;	boolean allownone = FALSE;	xchar foox = 0;	long cnt;	if(*let == '0') let++, allowcnt = 1;	if(*let == '$') let++, allowgold = TRUE;	if(*let == '#') let++, allowall = TRUE;	if(*let == '-') let++, allownone = TRUE;	if(allownone) *bp++ = '-';	if(allowgold) *bp++ = '$';	if(bp > buf && bp[-1] == '-') *bp++ = ' ';	ilet = 'a';	for(otmp = invent; otmp; otmp = otmp->nobj){	    if(!*let || index(let, otmp->olet)) {		bp[foo++] = flags.invlet_constant ? otmp->invlet : ilet;		/* ugly check: remove inappropriate things */		if((!strcmp(word, "take off") &&		    !(otmp->owornmask & (W_ARMOR - W_ARM2)))		|| (!strcmp(word, "wear") &&		    (otmp->owornmask & (W_ARMOR | W_RING)))		|| (!strcmp(word, "wield") &&		    (otmp->owornmask & W_WEP))) {			foo--;			foox++;		}	    }	    if(ilet == 'z') ilet = 'A'; else ilet++;	}	bp[foo] = 0;	if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0;	(void) strcpy(lets, bp);	/* necessary since we destroy buf */	if(foo > 5) {			/* compactify string */		foo = foo2 = 1;		ilet2 = bp[0];		ilet1 = bp[1];		while(ilet = bp[++foo2] = bp[++foo]){			if(ilet == ilet1+1){				if(ilet1 == ilet2+1)					bp[foo2 - 1] = ilet1 = '-';				else if(ilet2 == '-') {					bp[--foo2] = ++ilet1;					continue;				}			}			ilet2 = ilet1;			ilet1 = ilet;		}	}	if(!foo && !allowall && !allowgold && !allownone) {		pline("You don't have anything %sto %s.",			foox ? "else " : "", word);		return(0);	}	for(;;) {		if(!buf[0])			pline("What do you want to %s [*]? ", word);		else			pline("What do you want to %s [%s or ?*]? ",				word, buf);		cnt = 0;		ilet = readchar();		while(digit(ilet) && allowcnt) {			if (cnt < 100000000)			    cnt = 10*cnt + (ilet - '0');			else			    cnt = 999999999;			allowcnt = 2;	/* signal presence of cnt */			ilet = readchar();		}		if(digit(ilet)) {			pline("No count allowed with this command.");			continue;		}		if(index(quitchars,ilet))			return((struct obj *)0);		if(ilet == '-') {			return(allownone ? &zeroobj : (struct obj *) 0);		}		if(ilet == '$') {			if(!allowgold){				pline("You cannot %s gold.", word);				continue;			}			if(!(allowcnt == 2 && cnt < u.ugold))				cnt = u.ugold;			return(mkgoldobj(cnt));		}		if(ilet == '?') {			doinv(lets);			if(!(ilet = morc)) continue;			/* he typed a letter (not a space) to more() */		} else if(ilet == '*') {			doinv((char *) 0);			if(!(ilet = morc)) continue;			/* ... */		}		if(flags.invlet_constant) {			for(otmp = invent; otmp; otmp = otmp->nobj)				if(otmp->invlet == ilet) break;		} else {			if(ilet >= 'A' && ilet <= 'Z') ilet += 'z'-'A'+1;			ilet -= 'a';			for(otmp = invent; otmp && ilet;					ilet--, otmp = otmp->nobj) ;		}		if(!otmp) {			pline("You don't have that object.");			continue;		}		if(cnt < 0 || otmp->quan < cnt) {			pline("You don't have that many! [You have %u]"			, otmp->quan);			continue;		}		break;	}	if(!allowall && let && !index(let,otmp->olet)) {		pline("That is a silly thing to %s.",word);		return(0);	}	if(allowcnt == 2) {	/* cnt given */		if(cnt == 0) return(0);		if(cnt != otmp->quan) {			register struct obj *obj;			obj = splitobj(otmp, (int) cnt);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -