📄 hack.shk.c
字号:
{ register struct obj *obj; register struct monst *mtmp; register unsigned id = bp->bo_id; if(bp->useup) obj = o_on(id, billobjs); else if(!(obj = o_on(id, invent)) && !(obj = o_on(id, fobj)) && !(obj = o_on(id, fcobj))) { for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(obj = o_on(id, mtmp->minvent)) break; for(mtmp = fallen_down; mtmp; mtmp = mtmp->nmon) if(obj = o_on(id, mtmp->minvent)) break; } return(obj);}static int getprice();/* called in hack.c when we pickup an object */addtobill(obj) register struct obj *obj; {register struct bill_x *bp; if(!inshop() || (u.ux == ESHK(shopkeeper)->shk.x && u.uy == ESHK(shopkeeper)->shk.y) || (u.ux == ESHK(shopkeeper)->shd.x && u.uy == ESHK(shopkeeper)->shd.y) || onbill(obj) /* perhaps we threw it away earlier */ ) return; if(ESHK(shopkeeper)->billct == BILLSZ){ pline("You got that for free!"); return; } bp = &bill[ESHK(shopkeeper)->billct]; bp->bo_id = obj->o_id; bp->bquan = obj->quan; bp->useup = 0; bp->price = getprice(obj); ESHK(shopkeeper)->billct++; obj->unpaid = 1;}splitbill(obj,otmp) register struct obj *obj, *otmp; { /* otmp has been split off from obj */register struct bill_x *bp;register int tmp; bp = onbill(obj); if(!bp) { impossible("splitbill: not on bill?"); return; } if(bp->bquan < otmp->quan) { impossible("Negative quantity on bill??"); } if(bp->bquan == otmp->quan) { impossible("Zero quantity on bill??"); } bp->bquan -= otmp->quan; /* addtobill(otmp); */ if(ESHK(shopkeeper)->billct == BILLSZ) otmp->unpaid = 0; else { tmp = bp->price; bp = &bill[ESHK(shopkeeper)->billct]; bp->bo_id = otmp->o_id; bp->bquan = otmp->quan; bp->useup = 0; bp->price = tmp; ESHK(shopkeeper)->billct++; }}subfrombill(obj) register struct obj *obj; {long ltmp;register int tmp;register struct obj *otmp;register struct bill_x *bp; if(!inshop() || (u.ux == ESHK(shopkeeper)->shk.x && u.uy == ESHK(shopkeeper)->shk.y) || (u.ux == ESHK(shopkeeper)->shd.x && u.uy == ESHK(shopkeeper)->shd.y)) return; if((bp = onbill(obj)) != 0){ obj->unpaid = 0; if(bp->bquan > obj->quan){ otmp = newobj(0); *otmp = *obj; bp->bo_id = otmp->o_id = flags.ident++; otmp->quan = (bp->bquan -= obj->quan); otmp->owt = 0; /* superfluous */ otmp->onamelth = 0; bp->useup = 1; otmp->nobj = billobjs; billobjs = otmp; return; } ESHK(shopkeeper)->billct--; *bp = bill[ESHK(shopkeeper)->billct]; return; } if(obj->unpaid){ pline("%s didn't notice.", Monnam(shopkeeper)); obj->unpaid = 0; return; /* %% */ } /* he dropped something of his own - probably wants to sell it */ if(shopkeeper->msleep || shopkeeper->mfroz || inroom(shopkeeper->mx,shopkeeper->my) != ESHK(shopkeeper)->shoproom) return; if(ESHK(shopkeeper)->billct == BILLSZ || ((tmp = shtypes[rooms[ESHK(shopkeeper)->shoproom].rtype-8]) && tmp != obj->olet) || index("_0", obj->olet)) { pline("%s seems not interested.", Monnam(shopkeeper)); return; } ltmp = getprice(obj) * obj->quan; if(ANGRY(shopkeeper)) { ltmp /= 3; NOTANGRY(shopkeeper) = 1; } else ltmp /= 2; if(ESHK(shopkeeper)->robbed){ if((ESHK(shopkeeper)->robbed -= ltmp) < 0) ESHK(shopkeeper)->robbed = 0;pline("Thank you for your contribution to restock this recently plundered shop."); return; } if(ltmp > shopkeeper->mgold) ltmp = shopkeeper->mgold; pay(-ltmp, shopkeeper); if(!ltmp) pline("%s gladly accepts %s but cannot pay you at present.", Monnam(shopkeeper), doname(obj)); else pline("You sold %s and got %ld gold piece%s.", doname(obj), ltmp, plur(ltmp));}doinvbill(mode)int mode; /* 0: deliver count 1: paged */{ register struct bill_x *bp; register struct obj *obj; long totused, thisused; char buf[BUFSZ]; if(mode == 0) { register int cnt = 0; if(shopkeeper) for(bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++) if(bp->useup || ((obj = bp_to_obj(bp)) && obj->quan < bp->bquan)) cnt++; return(cnt); } if(!shopkeeper) { impossible("doinvbill: no shopkeeper?"); return(0); } set_pager(0); if(page_line("Unpaid articles already used up:") || page_line("")) goto quit; totused = 0; for(bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++) { obj = bp_to_obj(bp); if(!obj) { impossible("Bad shopkeeper administration."); goto quit; } if(bp->useup || bp->bquan > obj->quan) { register int cnt, oquan, uquan; oquan = obj->quan; uquan = (bp->useup ? bp->bquan : bp->bquan - oquan); thisused = bp->price * uquan; totused += thisused; obj->quan = uquan; /* cheat doname */ (void) sprintf(buf, "x - %s", doname(obj)); obj->quan = oquan; /* restore value */ for(cnt = 0; buf[cnt]; cnt++); while(cnt < 50) buf[cnt++] = ' '; (void) sprintf(&buf[cnt], " %5ld zorkmids", thisused); if(page_line(buf)) goto quit; } } (void) sprintf(buf, "Total:%50ld zorkmids", totused); if(page_line("") || page_line(buf)) goto quit; set_pager(1); return(0);quit: set_pager(2); return(0);}staticgetprice(obj) register struct obj *obj; {register int tmp, ac; static int realhunger(); switch(obj->olet){ case AMULET_SYM: tmp = 10*rnd(500); break; case TOOL_SYM: tmp = 10*rnd((obj->otyp == EXPENSIVE_CAMERA) ? 150 : 30); break; case RING_SYM: tmp = 10*rnd(100); break; case WAND_SYM: tmp = 10*rnd(100); break; case SCROLL_SYM: tmp = 10*rnd(50);#ifdef MAIL if(obj->otyp == SCR_MAIL) tmp = rnd(5);#endif MAIL break; case POTION_SYM: tmp = 10*rnd(50); break; case FOOD_SYM: tmp = 10*rnd(5 + (2000/realhunger())); break; case GEM_SYM: tmp = 10*rnd(20); break; case ARMOR_SYM: ac = ARM_BONUS(obj); if(ac <= -10) /* probably impossible */ ac = -9; tmp = 100 + ac*ac*rnd(10+ac); break; case WEAPON_SYM: if(obj->otyp < BOOMERANG) tmp = 5*rnd(10); else if(obj->otyp == LONG_SWORD || obj->otyp == TWO_HANDED_SWORD) tmp = 10*rnd(150); else tmp = 10*rnd(75); break; case CHAIN_SYM: pline("Strange ..., carrying a chain?"); case BALL_SYM: tmp = 10; break; default: tmp = 10000; } return(tmp);}staticrealhunger(){ /* not completely foolproof */register tmp = u.uhunger;register struct obj *otmp = invent; while(otmp){ if(otmp->olet == FOOD_SYM && !otmp->unpaid) tmp += objects[otmp->otyp].nutrition; otmp = otmp->nobj; } return((tmp <= 0) ? 1 : tmp);}shkcatch(obj)register struct obj *obj;{ register struct monst *shkp = shopkeeper; if(u.uinshop && shkp && !shkp->mfroz && !shkp->msleep && u.dx && u.dy && inroom(u.ux+u.dx, u.uy+u.dy) + 1 == u.uinshop && shkp->mx == ESHK(shkp)->shk.x && shkp->my == ESHK(shkp)->shk.y && u.ux == ESHK(shkp)->shd.x && u.uy == ESHK(shkp)->shd.y) { pline("%s nimbly catches the %s.", Monnam(shkp), xname(obj)); obj->nobj = shkp->minvent; shkp->minvent = obj; return(1); } return(0);}/* * shk_move: return 1: he moved 0: he didnt -1: let m_move do it */shk_move(shkp)register struct monst *shkp;{ register struct monst *mtmp; register struct permonst *mdat = shkp->data; register xchar gx,gy,omx,omy,nx,ny,nix,niy; register schar appr,i; register int udist; int z; schar shkroom,chi,chcnt,cnt; boolean uondoor, satdoor, avoid, badinv; coord poss[9]; int info[9]; struct obj *ib = 0; omx = shkp->mx; omy = shkp->my; if((udist = dist(omx,omy)) < 3) { if(ANGRY(shkp)) { (void) hitu(shkp, d(mdat->damn, mdat->damd)+1); return(0); } if(ESHK(shkp)->following) { if(strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)){ pline("Hello %s! I was looking for %s.", plname, ESHK(shkp)->customer); ESHK(shkp)->following = 0; return(0); } if(!ESHK(shkp)->robbed) { /* impossible? */ ESHK(shkp)->following = 0; return(0); } if(moves > followmsg+4) { pline("Hello %s! Didn't you forget to pay?", plname); followmsg = moves; } if(udist < 2) return(0); } } shkroom = inroom(omx,omy); appr = 1; gx = ESHK(shkp)->shk.x; gy = ESHK(shkp)->shk.y; satdoor = (gx == omx && gy == omy); if(ESHK(shkp)->following || ((z = holetime()) >= 0 && z*z <= udist)){ gx = u.ux; gy = u.uy; if(shkroom < 0 || shkroom != inroom(u.ux,u.uy)) if(udist > 4) return(-1); /* leave it to m_move */ } else if(ANGRY(shkp)) { long saveBlind = Blind; Blind = 0; if(shkp->mcansee && !Invis && cansee(omx,omy)) { gx = u.ux; gy = u.uy; } Blind = saveBlind; avoid = FALSE; } else {#define GDIST(x,y) ((x-gx)*(x-gx)+(y-gy)*(y-gy)) if(Invis) avoid = FALSE; else { uondoor = (u.ux == ESHK(shkp)->shd.x && u.uy == ESHK(shkp)->shd.y); if(uondoor) { if(ESHK(shkp)->billct) pline("Hello %s! Will you please pay before leaving?", plname); badinv = (carrying(PICK_AXE) || carrying(ICE_BOX)); if(satdoor && badinv) return(0); avoid = !badinv; } else { avoid = (u.uinshop && dist(gx,gy) > 8); badinv = FALSE; } if(((!ESHK(shkp)->robbed && !ESHK(shkp)->billct) || avoid) && GDIST(omx,omy) < 3){ if(!badinv && !online(omx,omy)) return(0); if(satdoor) appr = gx = gy = 0; } } } if(omx == gx && omy == gy) return(0); if(shkp->mconf) { avoid = FALSE; appr = 0; } nix = omx; niy = omy; cnt = mfndpos(shkp,poss,info,ALLOW_SSM); if(avoid && uondoor) { /* perhaps we cannot avoid him */ for(i=0; i<cnt; i++) if(!(info[i] & NOTONL)) goto notonl_ok; avoid = FALSE; notonl_ok: ; } chi = -1; chcnt = 0; for(i=0; i<cnt; i++){ nx = poss[i].x; ny = poss[i].y; if(levl[nx][ny].typ == ROOM || shkroom != ESHK(shkp)->shoproom || ESHK(shkp)->following) {#ifdef STUPID /* cater for stupid compilers */ register int zz;#endif STUPID if(uondoor && (ib = sobj_at(ICE_BOX, nx, ny))) { nix = nx; niy = ny; chi = i; break; } if(avoid && (info[i] & NOTONL)) continue; if((!appr && !rn2(++chcnt)) ||#ifdef STUPID (appr && (zz = GDIST(nix,niy)) && zz > GDIST(nx,ny))#else (appr && GDIST(nx,ny) < GDIST(nix,niy))#endif STUPID ) { nix = nx; niy = ny; chi = i; } } } if(nix != omx || niy != omy){ if(info[chi] & ALLOW_M){ mtmp = m_at(nix,niy); if(hitmm(shkp,mtmp) == 1 && rn2(3) && hitmm(mtmp,shkp) == 2) return(2); return(0); } else if(info[chi] & ALLOW_U){ (void) hitu(shkp, d(mdat->damn, mdat->damd)+1); return(0); } shkp->mx = nix; shkp->my = niy; pmon(shkp); if(ib) { freeobj(ib); mpickobj(shkp, ib); } return(1); } return(0);}/* He is digging in the shop. */shopdig(fall)register int fall;{ if(!fall) { if(u.utraptype == TT_PIT) pline("\"Be careful, sir, or you might fall through the floor.\""); else pline("\"Please, do not damage the floor here.\""); } else if(dist(shopkeeper->mx, shopkeeper->my) < 3) { register struct obj *obj, *obj2; pline("%s grabs your backpack!", shkname(shopkeeper)); for(obj = invent; obj; obj = obj2) { obj2 = obj->nobj; if(obj->owornmask) continue; freeinv(obj); obj->nobj = shopkeeper->minvent; shopkeeper->minvent = obj; if(obj->unpaid) subfrombill(obj); } }}#endif QUESTonline(x,y) { return(x==u.ux || y==u.uy || (x-u.ux)*(x-u.ux) == (y-u.uy)*(y-u.uy));}/* Does this monster follow me downstairs? */follower(mtmp)register struct monst *mtmp;{ return( mtmp->mtame || index("1TVWZi&, ", mtmp->data->mlet)#ifndef QUEST || (mtmp->isshk && ESHK(mtmp)->following)#endif QUEST );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -