📄 hack.invent.c
字号:
/* 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 + -