1 /* SCCS Id: @(#)shk.c 3.4 2003/12/04 */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
12 #define PAY_CANT 0 /* too poor */
14 #define PAY_BROKE (-2)
17 STATIC_DCL void FDECL(makekops, (coord *));
18 STATIC_DCL void FDECL(call_kops, (struct monst *,BOOLEAN_P));
20 STATIC_DCL void FDECL(kops_gone, (BOOLEAN_P));
24 #define IS_SHOP(x) (rooms[x].rtype >= SHOPBASE)
26 extern const struct shclass shtypes[]; /* defined in shknam.c */
27 extern struct obj *thrownobj; /* defined in dothrow.c */
29 STATIC_VAR NEARDATA long int followmsg; /* last time of follow message */
31 STATIC_DCL void FDECL(setpaid, (struct monst *));
32 STATIC_DCL long FDECL(addupbill, (struct monst *));
33 STATIC_DCL void FDECL(pacify_shk, (struct monst *));
34 STATIC_DCL struct bill_x *FDECL(onbill, (struct obj *, struct monst *, BOOLEAN_P));
35 STATIC_DCL struct monst *FDECL(next_shkp, (struct monst *, BOOLEAN_P));
36 STATIC_DCL long FDECL(shop_debt, (struct eshk *));
37 STATIC_DCL char *FDECL(shk_owns, (char *,struct obj *));
38 STATIC_DCL char *FDECL(mon_owns, (char *,struct obj *));
39 STATIC_DCL void FDECL(clear_unpaid,(struct obj *));
40 STATIC_DCL long FDECL(check_credit, (long, struct monst *));
41 STATIC_DCL void FDECL(pay, (long, struct monst *));
42 STATIC_DCL long FDECL(get_cost, (struct obj *, struct monst *));
43 STATIC_DCL long FDECL(set_cost, (struct obj *, struct monst *));
44 STATIC_DCL const char *FDECL(shk_embellish, (struct obj *, long));
45 STATIC_DCL long FDECL(cost_per_charge, (struct monst *,struct obj *,BOOLEAN_P));
46 STATIC_DCL long FDECL(cheapest_item, (struct monst *));
47 STATIC_DCL int FDECL(dopayobj, (struct monst *, struct bill_x *,
48 struct obj **, int, BOOLEAN_P));
49 STATIC_DCL long FDECL(stolen_container, (struct obj *, struct monst *, long,
51 STATIC_DCL long FDECL(getprice, (struct obj *,BOOLEAN_P));
52 STATIC_DCL void FDECL(shk_names_obj,
53 (struct monst *,struct obj *,const char *,long,const char *));
54 STATIC_DCL struct obj *FDECL(bp_to_obj, (struct bill_x *));
55 STATIC_DCL boolean FDECL(inherits, (struct monst *,int,int));
56 STATIC_DCL void FDECL(set_repo_loc, (struct eshk *));
57 STATIC_DCL boolean NDECL(angry_shk_exists);
58 STATIC_DCL void FDECL(rile_shk, (struct monst *));
59 STATIC_DCL void FDECL(rouse_shk, (struct monst *,BOOLEAN_P));
60 STATIC_DCL void FDECL(remove_damage, (struct monst *, BOOLEAN_P));
61 STATIC_DCL void FDECL(sub_one_frombill, (struct obj *, struct monst *));
62 STATIC_DCL void FDECL(add_one_tobill, (struct obj *, BOOLEAN_P));
63 STATIC_DCL void FDECL(dropped_container, (struct obj *, struct monst *,
65 STATIC_DCL void FDECL(add_to_billobjs, (struct obj *));
66 STATIC_DCL void FDECL(bill_box_content, (struct obj *, BOOLEAN_P, BOOLEAN_P,
69 static boolean FDECL(rob_shop, (struct monst *));
74 invariants: obj->unpaid iff onbill(obj) [unless bp->useup]
75 obj->quan <= bp->bquan
81 Transfer money from inventory to monster when paying
82 shopkeepers, priests, oracle, succubus, & other demons.
83 Simple with only gold coins.
84 This routine will handle money changing when multiple
85 coin types is implemented, only appropriate
86 monsters will pay change. (Peaceful shopkeepers, priests
87 & the oracle try to maintain goodwill while selling
88 their wares or services. Angry monsters and all demons
89 will keep anything they get their hands on.
90 Returns the amount actually paid, so we can know
91 if the monster kept the change.
94 money2mon(mon, amount)
98 struct obj *ygold = findgold(invent);
101 impossible("%s payment in money2mon!", amount ? "negative" : "zero");
104 if (!ygold || ygold->quan < amount) {
105 impossible("Paying without %s money?", ygold ? "enough" : "");
109 if (ygold->quan > amount)
110 ygold = splitobj(ygold, amount);
111 else if (ygold->owornmask)
112 remove_worn_item(ygold, FALSE); /* quiver */
114 add_to_minv(mon, ygold);
121 Transfer money from monster to inventory.
122 Used when the shopkeeper pay for items, and when
123 the priest gives you money for an ale.
130 struct obj *mongold = findgold(mon->minvent);
133 impossible("%s payment in money2u!", amount ? "negative" : "zero");
136 if (!mongold || mongold->quan < amount) {
137 impossible("%s paying without %s money?", a_monnam(mon),
138 mongold ? "enough" : "");
142 if (mongold->quan > amount) mongold = splitobj(mongold, amount);
143 obj_extract_self(mongold);
145 if (!merge_choice(invent, mongold) && inv_cnt() >= 52) {
146 You("have no room for the money!");
156 STATIC_OVL struct monst *
157 next_shkp(shkp, withbill)
158 register struct monst *shkp;
159 register boolean withbill;
161 for (; shkp; shkp = shkp->nmon) {
162 if (DEADMONSTER(shkp)) continue;
163 if (shkp->isshk && (ESHK(shkp)->billct || !withbill)) break;
167 if (NOTANGRY(shkp)) {
168 if (ESHK(shkp)->surcharge) pacify_shk(shkp);
170 if (!ESHK(shkp)->surcharge) rile_shk(shkp);
177 shkname(mtmp) /* called in do_name.c */
178 register struct monst *mtmp;
180 return(ESHK(mtmp)->shknam);
184 shkgone(mtmp) /* called in mon.c */
187 struct eshk *eshk = ESHK(mtmp);
188 struct mkroom *sroom = &rooms[eshk->shoproom - ROOMOFFSET];
193 /* [BUG: some of this should be done on the shop level */
194 /* even when the shk dies on a different level.] */
195 if (on_level(&eshk->shoplevel, &u.uz)) {
196 remove_damage(mtmp, TRUE);
197 sroom->resident = (struct monst *)0;
198 if (!search_special(ANY_SHOP))
199 level.flags.has_shop = 0;
201 /* items on shop floor revert to ordinary objects */
202 for (sx = sroom->lx; sx <= sroom->hx; sx++)
203 for (sy = sroom->ly; sy <= sroom->hy; sy++)
204 for (otmp = level.objects[sx][sy]; otmp; otmp = otmp->nexthere)
207 /* Make sure bill is set only when the
208 dead shk is the resident shk. */
209 if ((p = index(u.ushops, eshk->shoproom)) != 0) {
211 eshk->bill_p = (struct bill_x *)0;
212 /* remove eshk->shoproom from u.ushops */
213 do { *p = *(p + 1); } while (*++p);
219 set_residency(shkp, zero_out)
220 register struct monst *shkp;
221 register boolean zero_out;
223 if (on_level(&(ESHK(shkp)->shoplevel), &u.uz))
224 rooms[ESHK(shkp)->shoproom - ROOMOFFSET].resident =
225 (zero_out)? (struct monst *)0 : shkp;
230 register struct monst *mtmp, *mtmp2;
232 rooms[ESHK(mtmp2)->shoproom - ROOMOFFSET].resident = mtmp2;
233 if (inhishop(mtmp) && *u.ushops == ESHK(mtmp)->shoproom) {
234 ESHK(mtmp2)->bill_p = &(ESHK(mtmp2)->bill[0]);
238 /* do shopkeeper specific structure munging -dlc */
240 restshk(shkp, ghostly)
245 struct eshk *eshkp = ESHK(shkp);
247 if (eshkp->bill_p != (struct bill_x *) -1000)
248 eshkp->bill_p = &eshkp->bill[0];
249 /* shoplevel can change as dungeons move around */
250 /* savebones guarantees that non-homed shk's will be gone */
252 assign_level(&eshkp->shoplevel, &u.uz);
253 if (ANGRY(shkp) && strncmpi(eshkp->customer, plname, PL_NSIZ))
262 /* Clear the unpaid bit on all of the objects in the list. */
265 register struct obj *list;
268 if (Has_contents(list)) clear_unpaid(list->cobj);
276 /* either you paid or left the shop or the shopkeeper died */
279 register struct monst *shkp;
281 register struct obj *obj;
282 register struct monst *mtmp;
284 /* FIXME: object handling should be limited to
285 items which are on this particular shk's bill */
287 clear_unpaid(invent);
289 clear_unpaid(level.buriedobjlist);
290 if (thrownobj) thrownobj->unpaid = 0;
291 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
292 clear_unpaid(mtmp->minvent);
293 for(mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon)
294 clear_unpaid(mtmp->minvent);
296 while ((obj = billobjs) != 0) {
297 obj_extract_self(obj);
301 ESHK(shkp)->billct = 0;
302 ESHK(shkp)->credit = 0L;
303 ESHK(shkp)->debit = 0L;
304 ESHK(shkp)->loan = 0L;
310 register struct monst *shkp;
312 register int ct = ESHK(shkp)->billct;
313 register struct bill_x *bp = ESHK(shkp)->bill_p;
314 register long total = 0L;
317 total += bp->price * bp->bquan;
328 call_kops(shkp, nearshop)
329 register struct monst *shkp;
330 register boolean nearshop;
332 /* Keystone Kops srt@ucla */
333 register boolean nokops;
338 pline("An alarm sounds!");
340 nokops = ((mvitals[PM_KEYSTONE_KOP].mvflags & G_GONE) &&
341 (mvitals[PM_KOP_SERGEANT].mvflags & G_GONE) &&
342 (mvitals[PM_KOP_LIEUTENANT].mvflags & G_GONE) &&
343 (mvitals[PM_KOP_KAPTAIN].mvflags & G_GONE));
345 if(!angry_guards(!flags.soundok) && nokops) {
346 if(flags.verbose && flags.soundok)
347 pline("But no one seems to respond to it.");
357 /* Create swarm around you, if you merely "stepped out" */
359 pline_The("Keystone Kops appear!");
366 pline_The("Keystone Kops are after you!");
367 /* Create swarm near down staircase (hinders return to level) */
371 /* Create swarm near shopkeeper (hinders return to shop) */
379 /* x,y is strictly inside shop */
386 rno = levl[x][y].roomno;
387 if ((rno < ROOMOFFSET) || levl[x][y].edge || !IS_SHOP(rno-ROOMOFFSET))
394 u_left_shop(leavestring, newlev)
403 * ((didn't leave outright) AND
404 * ((he is now strictly-inside the shop) OR
405 * (he wasn't strictly-inside last turn anyway)))
406 * THEN (there's nothing to do, so just return)
409 (!levl[u.ux][u.uy].edge || levl[u.ux0][u.uy0].edge))
412 shkp = shop_keeper(*u.ushops0);
413 if (!shkp || !inhishop(shkp))
414 return; /* shk died, teleported, changed levels... */
417 if (!eshkp->billct && !eshkp->debit) /* bill is settled */
420 if (!*leavestring && shkp->mcanmove && !shkp->msleeping) {
422 * Player just stepped onto shop-boundary (known from above logic).
423 * Try to intimidate him into paying his bill
425 verbalize(NOTANGRY(shkp) ?
426 "%s! Please pay before leaving." :
427 "%s! Don't you leave without paying!",
432 if (rob_shop(shkp)) {
434 call_kops(shkp, (!newlev && levl[u.ux0][u.uy0].edge));
436 (void) angry_guards(FALSE);
441 /* robbery from outside the shop via telekinesis or grappling hook */
443 remote_burglary(x, y)
449 shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
450 if (!shkp || !inhishop(shkp))
451 return; /* shk died, teleported, changed levels... */
454 if (!eshkp->billct && !eshkp->debit) /* bill is settled */
457 if (rob_shop(shkp)) {
459 /*[might want to set 2nd arg based on distance from shop doorway]*/
460 call_kops(shkp, FALSE);
462 (void) angry_guards(FALSE);
467 /* shop merchandise has been taken; pay for it with any credit available;
468 return false if the debt is fully covered by credit, true otherwise */
477 rouse_shk(shkp, TRUE);
478 total = (addupbill(shkp) + eshkp->debit);
479 if (eshkp->credit >= total) {
480 Your("credit of %ld %s is used to cover your shopping bill.",
481 eshkp->credit, currency(eshkp->credit));
482 total = 0L; /* credit gets cleared by setpaid() */
484 You("escaped the shop without paying!");
485 total -= eshkp->credit;
488 if (!total) return FALSE;
490 /* by this point, we know an actual robbery has taken place */
491 eshkp->robbed += total;
492 You("stole %ld %s worth of merchandise.",
493 total, currency(total));
494 if (!Role_if(PM_ROGUE)) /* stealing is unlawful */
495 adjalign(-sgn(u.ualign.type));
502 u_entered_shop(enterstring)
503 register char *enterstring;
507 register struct monst *shkp;
508 register struct eshk *eshkp;
509 static const char no_shk[] = "This shop appears to be deserted.";
510 static char empty_shops[5];
515 if(!(shkp = shop_keeper(*enterstring))) {
516 if (!index(empty_shops, *enterstring) &&
517 in_rooms(u.ux, u.uy, SHOPBASE) !=
518 in_rooms(u.ux0, u.uy0, SHOPBASE))
520 Strcpy(empty_shops, u.ushops);
527 if (!inhishop(shkp)) {
528 /* dump core when referenced */
529 eshkp->bill_p = (struct bill_x *) -1000;
530 if (!index(empty_shops, *enterstring))
532 Strcpy(empty_shops, u.ushops);
537 eshkp->bill_p = &(eshkp->bill[0]);
539 if ((!eshkp->visitct || *eshkp->customer) &&
540 strncmpi(eshkp->customer, plname, PL_NSIZ)) {
541 /* You seem to be new here */
543 eshkp->following = 0;
544 (void) strncpy(eshkp->customer,plname,PL_NSIZ);
548 if (shkp->msleeping || !shkp->mcanmove || eshkp->following)
549 return; /* no dialog */
552 pline("%s senses your presence.", shkname(shkp));
553 verbalize("Invisible customers are not welcome!");
557 rt = rooms[*enterstring - ROOMOFFSET].rtype;
560 verbalize("So, %s, you dare return to %s %s?!",
562 s_suffix(shkname(shkp)),
563 shtypes[rt - SHOPBASE].name);
564 } else if (eshkp->robbed) {
565 pline("%s mutters imprecations against shoplifters.", shkname(shkp));
567 verbalize("%s, %s! Welcome%s to %s %s!",
569 eshkp->visitct++ ? " again" : "",
570 s_suffix(shkname(shkp)),
571 shtypes[rt - SHOPBASE].name);
573 /* can't do anything about blocking if teleported in */
574 if (!inside_shop(u.ux, u.uy)) {
575 boolean should_block;
578 struct obj *pick = carrying(PICK_AXE),
579 *mattock = carrying(DWARVISH_MATTOCK);
581 if (pick || mattock) {
582 cnt = 1; /* so far */
583 if (pick && mattock) { /* carrying both types */
584 tool = "digging tool";
585 cnt = 2; /* `more than 1' is all that matters */
588 /* hack: `pick' already points somewhere into inventory */
589 while ((pick = pick->nobj) != 0)
590 if (pick->otyp == PICK_AXE) ++cnt;
591 } else { /* assert(mattock != 0) */
593 while ((mattock = mattock->nobj) != 0)
594 if (mattock->otyp == DWARVISH_MATTOCK) ++cnt;
595 /* [ALI] Shopkeeper identifies mattock(s) */
596 if (!Blind) makeknown(DWARVISH_MATTOCK);
598 verbalize(NOTANGRY(shkp) ?
599 "Will you please leave your %s%s outside?" :
600 "Leave the %s%s outside.",
604 } else if (u.usteed) {
605 verbalize(NOTANGRY(shkp) ?
606 "Will you please leave %s outside?" :
607 "Leave %s outside.", y_monnam(u.usteed));
611 should_block = (Fast && (sobj_at(PICK_AXE, u.ux, u.uy) ||
612 sobj_at(DWARVISH_MATTOCK, u.ux, u.uy)));
614 if (should_block) (void) dochug(shkp); /* shk gets extra move */
620 Decide whether two unpaid items are mergable; caller is responsible for
621 making sure they're unpaid and the same type of object; we check the price
622 quoted by the shopkeeper and also that they both belong to the same shk.
625 same_price(obj1, obj2)
626 struct obj *obj1, *obj2;
628 register struct monst *shkp1, *shkp2;
629 register struct bill_x *bp1 = 0, *bp2 = 0;
630 register boolean are_mergable = FALSE;
632 /* look up the first object by finding shk whose bill it's on */
633 for (shkp1 = next_shkp(fmon, TRUE); shkp1;
634 shkp1 = next_shkp(shkp1->nmon, TRUE))
635 if ((bp1 = onbill(obj1, shkp1, TRUE)) != 0) break;
636 /* second object is probably owned by same shk; if not, look harder */
637 if (shkp1 && (bp2 = onbill(obj2, shkp1, TRUE)) != 0) {
640 for (shkp2 = next_shkp(fmon, TRUE); shkp2;
641 shkp2 = next_shkp(shkp2->nmon, TRUE))
642 if ((bp2 = onbill(obj2, shkp2, TRUE)) != 0) break;
645 if (!bp1 || !bp2) impossible("same_price: object wasn't on any bill!");
646 else are_mergable = (shkp1 == shkp2 && bp1->price == bp2->price);
651 * Figure out how much is owed to a given shopkeeper.
652 * At present, we ignore any amount robbed from the shop, to avoid
653 * turning the `$' command into a way to discover that the current
654 * level is bones data which has a shk on the warpath.
662 long debt = eshkp->debit;
664 for (bp = eshkp->bill_p, ct = eshkp->billct; ct > 0; bp++, ct--)
665 debt += bp->price * bp->bquan;
669 /* called in response to the `$' command */
671 shopper_financial_report()
673 struct monst *shkp, *this_shkp = shop_keeper(inside_shop(u.ux, u.uy));
679 !(ESHK(this_shkp)->credit || shop_debt(ESHK(this_shkp)))) {
680 You("have no credit or debt in here.");
681 this_shkp = 0; /* skip first pass */
684 /* pass 0: report for the shop we're currently in, if any;
685 pass 1: report for all other shops on this level. */
686 for (pass = this_shkp ? 0 : 1; pass <= 1; pass++)
687 for (shkp = next_shkp(fmon, FALSE);
688 shkp; shkp = next_shkp(shkp->nmon, FALSE)) {
689 if ((shkp != this_shkp) ^ pass) continue;
691 if ((amt = eshkp->credit) != 0)
692 You("have %ld %s credit at %s %s.",
693 amt, currency(amt), s_suffix(shkname(shkp)),
694 shtypes[eshkp->shoptype - SHOPBASE].name);
695 else if (shkp == this_shkp)
696 You("have no credit in here.");
697 if ((amt = shop_debt(eshkp)) != 0)
698 You("owe %s %ld %s.",
699 shkname(shkp), amt, currency(amt));
700 else if (shkp == this_shkp)
701 You("don't owe any money here.");
710 register struct monst *mtmp;
712 return(index(in_rooms(mtmp->mx, mtmp->my, SHOPBASE),
713 ESHK(mtmp)->shoproom) &&
714 on_level(&(ESHK(mtmp)->shoplevel), &u.uz));
721 struct monst *shkp = rmno >= ROOMOFFSET ?
722 rooms[rmno - ROOMOFFSET].resident : 0;
725 if (NOTANGRY(shkp)) {
726 if (ESHK(shkp)->surcharge) pacify_shk(shkp);
728 if (!ESHK(shkp)->surcharge) rile_shk(shkp);
736 register struct mkroom *sroom;
738 register struct monst *mtmp = sroom->resident;
743 return((boolean)(inhishop(mtmp)));
746 STATIC_OVL struct bill_x *
747 onbill(obj, shkp, silent)
748 register struct obj *obj;
749 register struct monst *shkp;
750 register boolean silent;
753 register struct bill_x *bp = ESHK(shkp)->bill_p;
754 register int ct = ESHK(shkp)->billct;
757 if (bp->bo_id == obj->o_id) {
758 if (!obj->unpaid) pline("onbill: paid obj on bill?");
762 if(obj->unpaid & !silent) pline("onbill: unpaid obj not on bill?");
763 return (struct bill_x *)0;
766 /* Delete the contents of the given object. */
769 register struct obj *obj;
771 register struct obj *curr;
773 while ((curr = obj->cobj) != 0) {
774 obj_extract_self(curr);
775 obfree(curr, (struct obj *)0);
779 /* called with two args on merge */
782 register struct obj *obj, *merge;
784 register struct bill_x *bp;
785 register struct bill_x *bpm;
786 register struct monst *shkp;
788 if (obj->otyp == LEASH && obj->leashmon) o_unleash(obj);
789 if (obj->oclass == FOOD_CLASS) food_disappears(obj);
790 if (obj->oclass == SPBOOK_CLASS) book_disappears(obj);
791 if (Has_contents(obj)) delete_contents(obj);
795 /* look for a shopkeeper who owns this object */
796 for (shkp = next_shkp(fmon, TRUE); shkp;
797 shkp = next_shkp(shkp->nmon, TRUE))
798 if (onbill(obj, shkp, TRUE)) break;
800 /* sanity check, more or less */
801 if (!shkp) shkp = shop_keeper(*u.ushops);
803 * Note: `shkp = shop_keeper(*u.ushops)' used to be
804 * unconditional. But obfree() is used all over
805 * the place, so making its behavior be dependent
806 * upon player location doesn't make much sense.
809 if ((bp = onbill(obj, shkp, FALSE)) != 0) {
812 obj->unpaid = 0; /* only for doinvbill */
813 add_to_billobjs(obj);
816 bpm = onbill(merge, shkp, FALSE);
818 /* this used to be a rename */
819 impossible("obfree: not on bill??");
822 /* this was a merger */
823 bpm->bquan += bp->bquan;
824 ESHK(shkp)->billct--;
827 /* DRS/NS 2.2.6 messes up -- Peter Kendell */
828 int indx = ESHK(shkp)->billct;
829 *bp = ESHK(shkp)->bill_p[indx];
832 *bp = ESHK(shkp)->bill_p[ESHK(shkp)->billct];
842 check_credit(tmp, shkp)
844 register struct monst *shkp;
846 long credit = ESHK(shkp)->credit;
848 if(credit == 0L) return(tmp);
850 pline_The("price is deducted from your credit.");
851 ESHK(shkp)->credit -=tmp;
854 pline_The("price is partially covered by your credit.");
855 ESHK(shkp)->credit = 0L;
864 register struct monst *shkp;
866 long robbed = ESHK(shkp)->robbed;
867 long balance = ((tmp <= 0L) ? tmp : check_credit(tmp, shkp));
871 shkp->mgold += balance;
873 if (balance > 0) money2mon(shkp, balance);
874 else if (balance < 0) money2u(shkp, -balance);
879 if(robbed < 0) robbed = 0L;
880 ESHK(shkp)->robbed = robbed;
886 /* return shkp to home position */
888 home_shk(shkp, killkops)
889 register struct monst *shkp;
890 register boolean killkops;
892 register xchar x = ESHK(shkp)->shk.x, y = ESHK(shkp)->shk.y;
894 (void) mnearto(shkp, x, y, TRUE);
895 level.flags.has_shop = 1;
900 You_feel("vaguely apprehensive.");
904 after_shk_move(shkp);
910 register struct monst *shkp;
912 for (shkp = next_shkp(fmon, FALSE);
913 shkp; shkp = next_shkp(shkp->nmon, FALSE))
914 if (ANGRY(shkp)) return(TRUE);
918 /* remove previously applied surcharge from all billed items */
921 register struct monst *shkp;
923 NOTANGRY(shkp) = TRUE; /* make peaceful */
924 if (ESHK(shkp)->surcharge) {
925 register struct bill_x *bp = ESHK(shkp)->bill_p;
926 register int ct = ESHK(shkp)->billct;
928 ESHK(shkp)->surcharge = FALSE;
930 register long reduction = (bp->price + 3L) / 4L;
931 bp->price -= reduction; /* undo 33% increase */
937 /* add aggravation surcharge to all billed items */
940 register struct monst *shkp;
942 NOTANGRY(shkp) = FALSE; /* make angry */
943 if (!ESHK(shkp)->surcharge) {
944 register struct bill_x *bp = ESHK(shkp)->bill_p;
945 register int ct = ESHK(shkp)->billct;
947 ESHK(shkp)->surcharge = TRUE;
949 register long surcharge = (bp->price + 2L) / 3L;
950 bp->price += surcharge;
956 /* wakeup and/or unparalyze shopkeeper */
958 rouse_shk(shkp, verbosely)
962 if (!shkp->mcanmove || shkp->msleeping) {
963 /* greed induced recovery... */
964 if (verbosely && canspotmon(shkp))
965 pline("%s %s.", Monnam(shkp),
966 shkp->msleeping ? "wakes up" : "can move again");
974 make_happy_shk(shkp, silentkops)
975 register struct monst *shkp;
976 register boolean silentkops;
978 boolean wasmad = ANGRY(shkp);
979 struct eshk *eshkp = ESHK(shkp);
982 eshkp->following = 0;
984 if (!Role_if(PM_ROGUE))
985 adjalign(sgn(u.ualign.type));
986 if(!inhishop(shkp)) {
988 boolean vanished = canseemon(shkp);
990 Strcpy(shk_nam, mon_nam(shkp));
991 if (on_level(&eshkp->shoplevel, &u.uz)) {
992 home_shk(shkp, FALSE);
993 /* didn't disappear if shk can still be seen */
994 if (canseemon(shkp)) vanished = FALSE;
996 /* if sensed, does disappear regardless whether seen */
997 if (sensemon(shkp)) vanished = TRUE;
998 /* can't act as porter for the Amulet, even if shk
999 happens to be going farther down rather than up */
1000 mdrop_special_objs(shkp);
1001 /* arrive near shop's door */
1002 migrate_to_level(shkp, ledger_no(&eshkp->shoplevel),
1003 MIGR_APPROX_XY, &eshkp->shd);
1006 pline("Satisfied, %s suddenly disappears!", shk_nam);
1008 pline("%s calms down.", Monnam(shkp));
1010 if(!angry_shk_exists()) {
1012 kops_gone(silentkops);
1020 register struct monst *shkp;
1022 if(!shkp->isshk) return;
1025 (void) strncpy(ESHK(shkp)->customer, plname, PL_NSIZ);
1026 ESHK(shkp)->following = 1;
1029 /* used when the shkp is teleported or falls (ox == 0) out of his shop,
1030 * or when the player is not on a costly_spot and he
1031 * damages something inside the shop. these conditions
1032 * must be checked by the calling function.
1035 make_angry_shk(shkp, ox, oy)
1036 register struct monst *shkp;
1037 register xchar ox,oy;
1040 struct eshk *eshkp = ESHK(shkp);
1042 /* all pending shop transactions are now "past due" */
1043 if (eshkp->billct || eshkp->debit || eshkp->loan || eshkp->credit) {
1044 eshkp->robbed += (addupbill(shkp) + eshkp->debit + eshkp->loan);
1045 eshkp->robbed -= eshkp->credit;
1046 if (eshkp->robbed < 0L) eshkp->robbed = 0L;
1047 /* billct, debit, loan, and credit will be cleared by setpaid */
1051 /* If you just used a wand of teleportation to send the shk away, you
1052 might not be able to see her any more. Monnam would yield "it",
1053 which makes this message look pretty silly, so temporarily restore
1054 her original location during the call to Monnam. */
1055 sx = shkp->mx, sy = shkp->my;
1056 if (isok(ox, oy) && cansee(ox, oy) && !cansee(sx, sy))
1057 shkp->mx = ox, shkp->my = oy;
1058 pline("%s %s!", Monnam(shkp),
1059 !ANGRY(shkp) ? "gets angry" : "is furious");
1060 shkp->mx = sx, shkp->my = sy;
1064 STATIC_VAR const char no_money[] = "Moreover, you%s have no money.";
1065 STATIC_VAR const char not_enough_money[] =
1066 "Besides, you don't have enough to interest %s.";
1069 STATIC_VAR const char no_money[];
1070 STATIC_VAR const char not_enough_money[];
1076 cheapest_item(shkp) /* delivers the cheapest item on the list */
1077 register struct monst *shkp;
1079 register int ct = ESHK(shkp)->billct;
1080 register struct bill_x *bp = ESHK(shkp)->bill_p;
1081 register long gmin = (bp->price * bp->bquan);
1084 if(bp->price * bp->bquan < gmin)
1085 gmin = bp->price * bp->bquan;
1096 register struct eshk *eshkp;
1097 register struct monst *shkp;
1098 struct monst *nxtm, *resident;
1103 int pass, tmp, sk = 0, seensk = 0;
1104 boolean paid = FALSE, stashed_gold = (hidden_gold() > 0L);
1108 /* find how many shk's there are, how many are in */
1109 /* sight, and are you in a shop room with one. */
1110 nxtm = resident = 0;
1111 for (shkp = next_shkp(fmon, FALSE);
1112 shkp; shkp = next_shkp(shkp->nmon, FALSE)) {
1114 if (ANGRY(shkp) && distu(shkp->mx, shkp->my) <= 2) nxtm = shkp;
1115 if (canspotmon(shkp)) seensk++;
1116 if (inhishop(shkp) && (*u.ushops == ESHK(shkp)->shoproom))
1120 if (nxtm) { /* Player should always appease an */
1121 shkp = nxtm; /* irate shk standing next to them. */
1125 if ((!sk && (!Blind || Blind_telepat)) || (!Blind && !seensk)) {
1126 There("appears to be no shopkeeper here to receive your payment.");
1135 /* the usual case. allow paying at a distance when */
1136 /* inside a tended shop. should we change that? */
1137 if(sk == 1 && resident) {
1143 for (shkp = next_shkp(fmon, FALSE);
1144 shkp; shkp = next_shkp(shkp->nmon, FALSE))
1145 if (canspotmon(shkp)) break;
1146 if (shkp != resident && distu(shkp->mx, shkp->my) > 2) {
1147 pline("%s is not near enough to receive your payment.",
1159 if (getpos(&cc, TRUE, "the creature you want to pay") < 0)
1160 return 0; /* player pressed ESC */
1164 pline("Try again...");
1167 if(u.ux == cx && u.uy == cy) {
1168 You("are generous to yourself.");
1171 mtmp = m_at(cx, cy);
1173 There("is no one there to receive your payment.");
1177 pline("%s is not interested in your payment.",
1181 if (mtmp != resident && distu(mtmp->mx, mtmp->my) > 2) {
1182 pline("%s is too far to receive your payment.",
1191 pline("dopay: null shkp.");
1197 ltmp = eshkp->robbed;
1199 /* wake sleeping shk when someone who owes money offers payment */
1200 if (ltmp || eshkp->billct || eshkp->debit)
1201 rouse_shk(shkp, TRUE);
1203 if (!shkp->mcanmove || shkp->msleeping) { /* still asleep/paralyzed */
1204 pline("%s %s.", Monnam(shkp),
1205 rn2(2) ? "seems to be napping" : "doesn't respond");
1209 if(shkp != resident && NOTANGRY(shkp)) {
1211 umoney = money_cnt(invent);
1214 You("do not owe %s anything.", mon_nam(shkp));
1220 You("%shave no money.", stashed_gold ? "seem to " : "");
1222 pline("But you have some gold stashed away.");
1225 long ugold = u.ugold;
1230 You("give %s the %ld gold piece%s %s asked for.",
1231 mon_nam(shkp), ltmp, plur(ltmp), mhe(shkp));
1234 You("give %s all your%s gold.", mon_nam(shkp),
1235 stashed_gold ? " openly kept" : "");
1241 if (stashed_gold) pline("But you have hidden gold!");
1244 if((ugold < ltmp/2L) || (ugold < ltmp && stashed_gold))
1246 if((umoney < ltmp/2L) || (umoney < ltmp && stashed_gold))
1248 pline("Unfortunately, %s doesn't look satisfied.",
1251 make_happy_shk(shkp, FALSE);
1256 /* ltmp is still eshkp->robbed here */
1257 if (!eshkp->billct && !eshkp->debit) {
1259 umoney = money_cnt(invent);
1261 if(!ltmp && NOTANGRY(shkp)) {
1262 You("do not owe %s anything.", mon_nam(shkp));
1268 pline(no_money, stashed_gold ? " seem to" : "");
1270 pline("%s is after blood, not money!", Monnam(shkp));
1272 if(u.ugold < ltmp/2L ||
1273 (u.ugold < ltmp && stashed_gold)) {
1276 if(umoney < ltmp/2L ||
1277 (umoney < ltmp && stashed_gold)) {
1280 pline(no_money, stashed_gold ? " seem to" : "");
1281 else pline(not_enough_money, mhim(shkp));
1284 pline("But since %s shop has been robbed recently,",
1286 pline("you %scompensate %s for %s losses.",
1293 mon_nam(shkp), mhis(shkp));
1295 pay(u.ugold < ltmp ? u.ugold : ltmp, shkp);
1297 pay(umoney < ltmp ? umoney : ltmp, shkp);
1299 make_happy_shk(shkp, FALSE);
1301 /* shopkeeper is angry, but has not been robbed --
1302 * door broken, attacked, etc. */
1303 pline("%s is after your hide, not your money!",
1306 if(u.ugold < 1000L) {
1309 if(umoney < 1000L) {
1312 pline(no_money, stashed_gold ? " seem to" : "");
1313 else pline(not_enough_money, mhim(shkp));
1316 You("try to appease %s by giving %s 1000 gold pieces.",
1317 x_monnam(shkp, ARTICLE_THE, "angry", 0, FALSE),
1320 if (strncmp(eshkp->customer, plname, PL_NSIZ) || rn2(3))
1321 make_happy_shk(shkp, FALSE);
1323 pline("But %s is as angry as ever.", mon_nam(shkp));
1327 if(shkp != resident) {
1328 impossible("dopay: not to shopkeeper?");
1329 if(resident) setpaid(resident);
1332 /* pay debt, if any, first */
1334 long dtmp = eshkp->debit;
1335 long loan = eshkp->loan;
1338 umoney = money_cnt(invent);
1340 Sprintf(sbuf, "You owe %s %ld %s ",
1341 shkname(shkp), dtmp, currency(dtmp));
1344 Strcat(sbuf, "you picked up in the store.");
1346 "for gold picked up and the use of merchandise.");
1347 } else Strcat(sbuf, "for the use of merchandise.");
1350 if (u.ugold + eshkp->credit < dtmp) {
1352 if (umoney + eshkp->credit < dtmp) {
1354 pline("But you don't%s have enough gold%s.",
1355 stashed_gold ? " seem to" : "",
1356 eshkp->credit ? " or credit" : "");
1359 if (eshkp->credit >= dtmp) {
1360 eshkp->credit -= dtmp;
1363 Your("debt is covered by your credit.");
1364 } else if (!eshkp->credit) {
1367 shkp->mgold += dtmp;
1369 money2mon(shkp, dtmp);
1373 You("pay that debt.");
1376 dtmp -= eshkp->credit;
1380 shkp->mgold += dtmp;
1382 money2mon(shkp, dtmp);
1386 pline("That debt is partially offset by your credit.");
1387 You("pay the remainder.");
1393 /* now check items on bill */
1394 if (eshkp->billct) {
1395 register boolean itemize;
1397 if (!u.ugold && !eshkp->credit) {
1399 umoney = money_cnt(invent);
1400 if (!umoney && !eshkp->credit) {
1402 You("%shave no money or credit%s.",
1403 stashed_gold ? "seem to " : "",
1404 paid ? " left" : "");
1408 if ((u.ugold + eshkp->credit) < cheapest_item(shkp)) {
1410 if ((umoney + eshkp->credit) < cheapest_item(shkp)) {
1412 You("don't have enough money to buy%s the item%s you picked.",
1413 eshkp->billct > 1 ? " any of" : "", plur(eshkp->billct));
1415 pline("Maybe you have some gold stashed away?");
1419 /* this isn't quite right; it itemizes without asking if the
1420 * single item on the bill is partly used up and partly unpaid */
1421 itemize = (eshkp->billct > 1 ? yn("Itemized billing?") == 'y' : 1);
1423 for (pass = 0; pass <= 1; pass++) {
1425 while (tmp < eshkp->billct) {
1427 register struct bill_x *bp = &(eshkp->bill_p[tmp]);
1429 /* find the object on one of the lists */
1430 if ((otmp = bp_to_obj(bp)) != 0) {
1431 /* if completely used up, object quantity is stale;
1432 restoring it to its original value here avoids
1433 making the partly-used-up code more complicated */
1434 if (bp->useup) otmp->quan = bp->bquan;
1436 impossible("Shopkeeper administration out of order.");
1437 setpaid(shkp); /* be nice to the player */
1440 if (pass == bp->useup && otmp->quan == bp->bquan) {
1441 /* pay for used-up items on first pass and others
1442 * on second, so player will be stuck in the store
1443 * less often; things which are partly used up
1444 * are processed on both passes */
1447 switch (dopayobj(shkp, bp, &otmp, pass, itemize)) {
1452 goto thanks; /*break*/
1465 *bp = eshkp->bill_p[--eshkp->billct];
1471 update_inventory(); /* Done in dopayobj() if itemize. */
1473 if(!ANGRY(shkp) && paid)
1474 verbalize("Thank you for shopping in %s %s!",
1475 s_suffix(shkname(shkp)),
1476 shtypes[eshkp->shoptype - SHOPBASE].name);
1482 /* return 2 if used-up portion paid */
1483 /* 1 if paid successfully */
1484 /* 0 if not enough money */
1485 /* -1 if skip this object */
1486 /* -2 if no money/credit left */
1488 dopayobj(shkp, bp, obj_p, which, itemize)
1489 register struct monst *shkp;
1490 register struct bill_x *bp;
1492 int which; /* 0 => used-up item, 1 => other (unpaid or lost) */
1495 register struct obj *obj = *obj_p;
1496 long ltmp, quan, save_quan;
1498 long umoney = money_cnt(invent);
1501 boolean stashed_gold = (hidden_gold() > 0L),
1502 consumed = (which == 0);
1504 if(!obj->unpaid && !bp->useup){
1505 impossible("Paid object on bill??");
1509 if(itemize && u.ugold + ESHK(shkp)->credit == 0L){
1511 if(itemize && umoney + ESHK(shkp)->credit == 0L){
1513 You("%shave no money or credit left.",
1514 stashed_gold ? "seem to " : "");
1517 /* we may need to temporarily adjust the object, if part of the
1518 original quantity has been used up but part remains unpaid */
1519 save_quan = obj->quan;
1521 /* either completely used up (simple), or split needed */
1523 if (quan > obj->quan) /* difference is amount used up */
1526 /* dealing with ordinary unpaid item */
1529 obj->quan = quan; /* to be used by doname() */
1530 obj->unpaid = 0; /* ditto */
1531 ltmp = bp->price * quan;
1532 buy = PAY_BUY; /* flag; if changed then return early */
1536 Sprintf(qbuf,"%s for %ld %s. Pay?", quan == 1L ?
1537 Doname2(obj) : doname(obj), ltmp, currency(ltmp));
1538 if (yn(qbuf) == 'n') {
1539 buy = PAY_SKIP; /* don't want to buy */
1540 } else if (quan < bp->bquan && !consumed) { /* partly used goods */
1541 obj->quan = bp->bquan - save_quan; /* used up amount */
1542 verbalize("%s for the other %s before buying %s.",
1543 ANGRY(shkp) ? "Pay" : "Please pay", xname(obj),
1544 save_quan > 1L ? "these" : "this one");
1545 buy = PAY_SKIP; /* shk won't sell */
1549 if (buy == PAY_BUY && u.ugold + ESHK(shkp)->credit < ltmp) {
1551 if (buy == PAY_BUY && umoney + ESHK(shkp)->credit < ltmp) {
1553 You("don't%s have gold%s enough to pay for %s.",
1554 stashed_gold ? " seem to" : "",
1555 (ESHK(shkp)->credit > 0L) ? " or credit" : "",
1557 buy = itemize ? PAY_SKIP : PAY_CANT;
1560 if (buy != PAY_BUY) {
1561 /* restore unpaid object to original state */
1562 obj->quan = save_quan;
1568 shk_names_obj(shkp, obj, consumed ?
1569 "paid for %s at a cost of %ld gold piece%s.%s" :
1570 "bought %s for %ld gold piece%s.%s", ltmp, "");
1571 obj->quan = save_quan; /* restore original count */
1572 /* quan => amount just bought, save_quan => remaining unpaid count */
1574 if (quan != bp->bquan) {
1575 /* eliminate used-up portion; remainder is still unpaid */
1576 bp->bquan = obj->quan;
1580 } else { /* completely used-up, so get rid of it */
1581 obj_extract_self(obj);
1582 /* assert( obj == *obj_p ); */
1584 *obj_p = 0; /* destroy pointer to freed object */
1587 update_inventory(); /* Done just once in dopay() if !itemize. */
1593 static coord repo_location; /* repossession context */
1595 /* routine called after dying (or quitting) */
1598 int croaked; /* -1: escaped dungeon; 0: quit; 1: died */
1600 register struct monst *mtmp, *mtmp2, *resident= (struct monst *)0;
1601 register boolean taken = FALSE;
1602 register int numsk = 0;
1604 /* if we escaped from the dungeon, shopkeepers can't reach us;
1605 shops don't occur on level 1, but this could happen if hero
1606 level teleports out of the dungeon and manages not to die */
1607 if (croaked < 0) return FALSE;
1609 /* this is where inventory will end up if any shk takes it */
1610 repo_location.x = repo_location.y = 0;
1612 /* give shopkeeper first crack */
1613 if ((mtmp = shop_keeper(*u.ushops)) && inhishop(mtmp)) {
1616 taken = inherits(resident, numsk, croaked);
1618 for (mtmp = next_shkp(fmon, FALSE);
1619 mtmp; mtmp = next_shkp(mtmp2, FALSE)) {
1621 if (mtmp != resident) {
1622 /* for bones: we don't want a shopless shk around */
1623 if(!on_level(&(ESHK(mtmp)->shoplevel), &u.uz))
1627 taken |= inherits(mtmp, numsk, croaked);
1631 if(numsk == 0) return(FALSE);
1636 inherits(shkp, numsk, croaked)
1645 struct eshk *eshkp = ESHK(shkp);
1646 boolean take = FALSE, taken = FALSE;
1647 int roomno = *u.ushops;
1650 /* the simplifying principle is that first-come */
1651 /* already took everything you had. */
1653 if (cansee(shkp->mx, shkp->my && croaked))
1654 pline("%s %slooks at your corpse%s and %s.",
1656 (!shkp->mcanmove || shkp->msleeping) ? "wakes up, " : "",
1657 !rn2(2) ? (shkp->female ? ", shakes her head," :
1658 ", shakes his head,") : "",
1659 !inhishop(shkp) ? "disappears" : "sighs");
1660 rouse_shk(shkp, FALSE); /* wake shk for bones */
1661 taken = (roomno == eshkp->shoproom);
1665 /* get one case out of the way: you die in the shop, the */
1666 /* shopkeeper is peaceful, nothing stolen, nothing owed. */
1667 if(roomno == eshkp->shoproom && inhishop(shkp) &&
1668 !eshkp->billct && !eshkp->robbed && !eshkp->debit &&
1669 NOTANGRY(shkp) && !eshkp->following) {
1671 pline("%s gratefully inherits all your possessions.",
1673 set_repo_loc(eshkp);
1677 if (eshkp->billct || eshkp->debit || eshkp->robbed) {
1678 if (roomno == eshkp->shoproom && inhishop(shkp))
1679 loss = addupbill(shkp) + eshkp->debit;
1680 if (loss < eshkp->robbed) loss = eshkp->robbed;
1684 if (eshkp->following || ANGRY(shkp) || take) {
1686 if (!invent && !u.ugold) goto skip;
1688 if (!invent) goto skip;
1689 umoney = money_cnt(invent);
1692 if (!shkp->mcanmove || shkp->msleeping)
1693 Strcat(takes, "wakes up and ");
1694 if (distu(shkp->mx, shkp->my) > 2)
1695 Strcat(takes, "comes and ");
1696 Strcat(takes, "takes");
1699 if (loss > u.ugold || !loss || roomno == eshkp->shoproom) {
1700 eshkp->robbed -= u.ugold;
1701 if (eshkp->robbed < 0L) eshkp->robbed = 0L;
1702 shkp->mgold += u.ugold;
1705 if (loss > umoney || !loss || roomno == eshkp->shoproom) {
1706 eshkp->robbed -= umoney;
1707 if (eshkp->robbed < 0L) eshkp->robbed = 0L;
1708 if (umoney > 0) money2mon(shkp, umoney);
1711 pline("%s %s all your possessions.",
1712 shkname(shkp), takes);
1714 /* where to put player's invent (after disclosure) */
1715 set_repo_loc(eshkp);
1718 shkp->mgold += loss;
1721 money2mon(shkp, loss);
1724 pline("%s %s the %ld %s %sowed %s.",
1725 Monnam(shkp), takes,
1726 loss, currency(loss),
1727 strncmp(eshkp->customer, plname, PL_NSIZ) ?
1729 shkp->female ? "her" : "him");
1730 /* shopkeeper has now been paid in full */
1732 eshkp->following = 0;
1736 /* in case we create bones */
1737 rouse_shk(shkp, FALSE); /* wake up */
1738 if (!inhishop(shkp))
1739 home_shk(shkp, FALSE);
1750 register xchar ox, oy;
1752 /* if you're not in this shk's shop room, or if you're in its doorway
1753 or entry spot, then your gear gets dumped all the way inside */
1754 if (*u.ushops != eshkp->shoproom ||
1755 IS_DOOR(levl[u.ux][u.uy].typ) ||
1756 (u.ux == eshkp->shk.x && u.uy == eshkp->shk.y)) {
1757 /* shk.x,shk.y is the position immediately in
1758 * front of the door -- move in one more space
1762 ox += sgn(ox - eshkp->shd.x);
1763 oy += sgn(oy - eshkp->shd.y);
1764 } else { /* already inside this shk's shop */
1768 /* finish_paybill will deposit invent here */
1769 repo_location.x = ox;
1770 repo_location.y = oy;
1773 /* called at game exit, after inventory disclosure but before making bones */
1777 register struct obj *otmp;
1778 int ox = repo_location.x,
1779 oy = repo_location.y;
1781 #if 0 /* don't bother */
1782 if (ox == 0 && oy == 0) impossible("finish_paybill: no location");
1784 /* normally done by savebones(), but that's too late in this case */
1786 /* transfer all of the character's inventory to the shop floor */
1787 while ((otmp = invent) != 0) {
1788 otmp->owornmask = 0L; /* perhaps we should call setnotworn? */
1789 otmp->lamplit = 0; /* avoid "goes out" msg from freeinv */
1790 if (rn2(5)) curse(otmp); /* normal bones treatment for invent */
1791 obj_extract_self(otmp);
1792 place_object(otmp, ox, oy);
1796 /* find obj on one of the lists */
1797 STATIC_OVL struct obj *
1799 register struct bill_x *bp;
1801 register struct obj *obj;
1802 register unsigned int id = bp->bo_id;
1805 obj = o_on(id, billobjs);
1812 * Look for o_id on all lists but billobj. Return obj or NULL if not found.
1813 * Its OK for restore_timers() to call this function, there should not
1814 * be any timeouts on the billobjs chain.
1821 struct monst *mon, *mmtmp[3];
1824 /* first check various obj lists directly */
1825 if ((obj = o_on(id, invent)) != 0) return obj;
1826 if ((obj = o_on(id, fobj)) != 0) return obj;
1827 if ((obj = o_on(id, level.buriedobjlist)) != 0) return obj;
1828 if ((obj = o_on(id, migrating_objs)) != 0) return obj;
1830 /* not found yet; check inventory for members of various monst lists */
1832 mmtmp[1] = migrating_mons;
1833 mmtmp[2] = mydogs; /* for use during level changes */
1834 for (i = 0; i < 3; i++)
1835 for (mon = mmtmp[i]; mon; mon = mon->nmon)
1836 if ((obj = o_on(id, mon->minvent)) != 0) return obj;
1838 /* not found at all */
1839 return (struct obj *)0;
1844 /* calculate the value that the shk will charge for [one of] an object */
1847 register struct obj *obj;
1848 register struct monst *shkp; /* if angry, impose a surcharge */
1850 register long tmp = getprice(obj, FALSE);
1853 /* shopkeeper may notice if the player isn't very knowledgeable -
1854 especially when gem prices are concerned */
1855 if (!obj->dknown || !objects[obj->otyp].oc_name_known) {
1856 if (obj->oclass == GEM_CLASS &&
1857 objects[obj->otyp].oc_material == GLASS) {
1859 /* get a value that's 'random' from game to game, but the
1860 same within the same game */
1861 boolean pseudorand =
1862 (((int)u.ubirthday % obj->otyp) >= obj->otyp/2);
1864 /* all gems are priced high - real or not */
1865 switch(obj->otyp - LAST_GEM) {
1867 i = pseudorand ? DIAMOND : OPAL;
1870 i = pseudorand ? SAPPHIRE : AQUAMARINE;
1873 i = pseudorand ? RUBY : JASPER;
1875 case 4: /* yellowish brown */
1876 i = pseudorand ? AMBER : TOPAZ;
1878 case 5: /* orange */
1879 i = pseudorand ? JACINTH : AGATE;
1881 case 6: /* yellow */
1882 i = pseudorand ? CITRINE : CHRYSOBERYL;
1885 i = pseudorand ? BLACK_OPAL : JET;
1888 i = pseudorand ? EMERALD : JADE;
1890 case 9: /* violet */
1891 i = pseudorand ? AMETHYST : FLUORITE;
1893 default: impossible("bad glass gem %d?", obj->otyp);
1897 tmp = (long) objects[i].oc_cost;
1898 } else if (!(obj->o_id % 4)) /* arbitrarily impose surcharge */
1902 if ((Role_if(PM_TOURIST) && u.ulevel < (MAXULEV/2))
1903 || (uarmu && !uarm && !uarmc)) /* touristy shirt visible */
1907 if (uarmh && uarmh->otyp == DUNCE_CAP)
1910 if (ACURR(A_CHA) > 18) tmp /= 2L;
1911 else if (ACURR(A_CHA) > 17) tmp -= tmp / 3L;
1912 else if (ACURR(A_CHA) > 15) tmp -= tmp / 4L;
1913 else if (ACURR(A_CHA) < 6) tmp *= 2L;
1914 else if (ACURR(A_CHA) < 8) tmp += tmp / 2L;
1915 else if (ACURR(A_CHA) < 11) tmp += tmp / 3L;
1916 if (tmp <= 0L) tmp = 1L;
1917 else if (obj->oartifact) tmp *= 4L;
1918 /* anger surcharge should match rile_shk's */
1919 if (shkp && ESHK(shkp)->surcharge) tmp += (tmp + 2L) / 3L;
1925 /* returns the price of a container's content. the price
1926 * of the "top" container is added in the calling functions.
1927 * a different price quoted for selling as vs. buying.
1930 contained_cost(obj, shkp, price, usell, unpaid_only)
1931 register struct obj *obj;
1932 register struct monst *shkp;
1934 register boolean usell;
1935 register boolean unpaid_only;
1937 register struct obj *otmp;
1939 /* the price of contained objects */
1940 for (otmp = obj->cobj; otmp; otmp = otmp->nobj) {
1941 if (otmp->oclass == COIN_CLASS) continue;
1942 /* the "top" container is evaluated by caller */
1944 if (saleable(shkp, otmp) &&
1945 !otmp->unpaid && otmp->oclass != BALL_CLASS &&
1946 !(otmp->oclass == FOOD_CLASS && otmp->oeaten) &&
1947 !(Is_candle(otmp) && otmp->age <
1948 20L * (long)objects[otmp->otyp].oc_cost))
1949 price += set_cost(otmp, shkp);
1950 } else if (!otmp->no_charge &&
1951 (!unpaid_only || (unpaid_only && otmp->unpaid))) {
1952 price += get_cost(otmp, shkp) * otmp->quan;
1955 if (Has_contents(otmp))
1956 price += contained_cost(otmp, shkp, price, usell, unpaid_only);
1964 register struct obj *obj;
1966 register struct obj *otmp;
1967 register long value = 0L;
1969 /* accumulate contained gold */
1970 for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
1971 if (otmp->oclass == COIN_CLASS)
1972 value += otmp->quan;
1973 else if (Has_contents(otmp))
1974 value += contained_gold(otmp);
1980 dropped_container(obj, shkp, sale)
1981 register struct obj *obj;
1982 register struct monst *shkp;
1983 register boolean sale;
1985 register struct obj *otmp;
1987 /* the "top" container is treated in the calling fn */
1988 for (otmp = obj->cobj; otmp; otmp = otmp->nobj) {
1989 if (otmp->oclass == COIN_CLASS) continue;
1991 if (!otmp->unpaid && !(sale && saleable(shkp, otmp)))
1992 otmp->no_charge = 1;
1994 if (Has_contents(otmp))
1995 dropped_container(otmp, shkp, sale);
2000 picked_container(obj)
2001 register struct obj *obj;
2003 register struct obj *otmp;
2005 /* the "top" container is treated in the calling fn */
2006 for (otmp = obj->cobj; otmp; otmp = otmp->nobj) {
2007 if (otmp->oclass == COIN_CLASS) continue;
2009 if (otmp->no_charge)
2010 otmp->no_charge = 0;
2012 if (Has_contents(otmp))
2013 picked_container(otmp);
2019 /* calculate how much the shk will pay when buying [all of] an object */
2022 register struct obj *obj;
2023 register struct monst *shkp;
2025 long tmp = getprice(obj, TRUE) * obj->quan;
2028 if ((Role_if(PM_TOURIST) && u.ulevel < (MAXULEV/2))
2029 || (uarmu && !uarm && !uarmc)) /* touristy shirt visible */
2033 if (uarmh && uarmh->otyp == DUNCE_CAP)
2038 /* shopkeeper may notice if the player isn't very knowledgeable -
2039 especially when gem prices are concerned */
2040 if (!obj->dknown || !objects[obj->otyp].oc_name_known) {
2041 if (obj->oclass == GEM_CLASS) {
2042 /* different shop keepers give different prices */
2043 if (objects[obj->otyp].oc_material == GEMSTONE ||
2044 objects[obj->otyp].oc_material == GLASS) {
2045 tmp = (obj->otyp % (6 - shkp->m_id % 3));
2046 tmp = (tmp + 3) * obj->quan;
2048 } else if (tmp > 1L && !rn2(4))
2057 /* called from doinv(invent.c) for inventory of unpaid objects */
2059 unpaid_cost(unp_obj)
2060 register struct obj *unp_obj; /* known to be unpaid */
2062 register struct bill_x *bp = (struct bill_x *)0;
2063 register struct monst *shkp;
2065 for(shkp = next_shkp(fmon, TRUE); shkp;
2066 shkp = next_shkp(shkp->nmon, TRUE))
2067 if ((bp = onbill(unp_obj, shkp, TRUE)) != 0) break;
2069 /* onbill() gave no message if unexpected problem occurred */
2070 if(!bp) impossible("unpaid_cost: object wasn't on any bill!");
2072 return bp ? unp_obj->quan * bp->price : 0L;
2076 add_one_tobill(obj, dummy)
2077 register struct obj *obj;
2078 register boolean dummy;
2080 register struct monst *shkp;
2081 register struct bill_x *bp;
2083 register char roomno = *u.ushops;
2085 if (!roomno) return;
2086 if (!(shkp = shop_keeper(roomno))) return;
2087 if (!inhishop(shkp)) return;
2089 if (onbill(obj, shkp, FALSE) || /* perhaps thrown away earlier */
2090 (obj->oclass == FOOD_CLASS && obj->oeaten))
2093 if (ESHK(shkp)->billct == BILLSZ) {
2094 You("got that for free!");
2098 /* To recognize objects the shopkeeper is not interested in. -dgk
2100 if (obj->no_charge) {
2105 bct = ESHK(shkp)->billct;
2106 bp = &(ESHK(shkp)->bill_p[bct]);
2107 bp->bo_id = obj->o_id;
2108 bp->bquan = obj->quan;
2109 if(dummy) { /* a dummy object must be inserted into */
2110 bp->useup = 1; /* the billobjs chain here. crucial for */
2111 add_to_billobjs(obj); /* eating floorfood in shop. see eat.c */
2112 } else bp->useup = 0;
2113 bp->price = get_cost(obj, shkp);
2114 ESHK(shkp)->billct++;
2119 add_to_billobjs(obj)
2122 if (obj->where != OBJ_FREE)
2123 panic("add_to_billobjs: obj not free");
2125 obj_stop_timers(obj);
2127 obj->nobj = billobjs;
2129 obj->where = OBJ_ONBILL;
2132 /* recursive billing of objects within containers. */
2134 bill_box_content(obj, ininv, dummy, shkp)
2135 register struct obj *obj;
2136 register boolean ininv, dummy;
2137 register struct monst *shkp;
2139 register struct obj *otmp;
2141 for (otmp = obj->cobj; otmp; otmp = otmp->nobj) {
2142 if (otmp->oclass == COIN_CLASS) continue;
2144 /* the "top" box is added in addtobill() */
2145 if (!otmp->no_charge)
2146 add_one_tobill(otmp, dummy);
2147 if (Has_contents(otmp))
2148 bill_box_content(otmp, ininv, dummy, shkp);
2153 /* shopkeeper tells you what you bought or sold, sometimes partly IDing it */
2155 shk_names_obj(shkp, obj, fmt, amt, arg)
2158 const char *fmt; /* "%s %ld %s %s", doname(obj), amt, plur(amt), arg */
2162 char *obj_name, fmtbuf[BUFSZ];
2163 boolean was_unknown = !obj->dknown;
2166 /* Use real name for ordinary weapons/armor, and spell-less
2167 * scrolls/books (that is, blank and mail), but only if the
2168 * object is within the shk's area of interest/expertise.
2170 if (!objects[obj->otyp].oc_magic && saleable(shkp, obj) &&
2171 (obj->oclass == WEAPON_CLASS || obj->oclass == ARMOR_CLASS ||
2172 obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS ||
2173 obj->otyp == MIRROR)) {
2174 was_unknown |= !objects[obj->otyp].oc_name_known;
2175 makeknown(obj->otyp);
2177 obj_name = doname(obj);
2178 /* Use an alternate message when extra information is being provided */
2180 Sprintf(fmtbuf, "%%s; you %s", fmt);
2181 obj_name[0] = highc(obj_name[0]);
2182 pline(fmtbuf, obj_name, (obj->quan > 1) ? "them" : "it",
2183 amt, plur(amt), arg);
2185 You(fmt, obj_name, amt, plur(amt), arg);
2190 addtobill(obj, ininv, dummy, silent)
2191 register struct obj *obj;
2192 register boolean ininv, dummy, silent;
2194 register struct monst *shkp;
2195 register char roomno = *u.ushops;
2196 long ltmp = 0L, cltmp = 0L, gltmp = 0L;
2197 register boolean container = Has_contents(obj);
2199 if(!*u.ushops) return;
2201 if(!(shkp = shop_keeper(roomno))) return;
2203 if(!inhishop(shkp)) return;
2205 if(/* perhaps we threw it away earlier */
2206 onbill(obj, shkp, FALSE) ||
2207 (obj->oclass == FOOD_CLASS && obj->oeaten)
2210 if(ESHK(shkp)->billct == BILLSZ) {
2211 You("got that for free!");
2215 if(obj->oclass == COIN_CLASS) {
2216 costly_gold(obj->ox, obj->oy, obj->quan);
2221 ltmp = get_cost(obj, shkp);
2223 if (obj->no_charge && !container) {
2229 if(obj->cobj == (struct obj *)0) {
2230 if(obj->no_charge) {
2234 add_one_tobill(obj, dummy);
2238 cltmp += contained_cost(obj, shkp, cltmp, FALSE, FALSE);
2239 gltmp += contained_gold(obj);
2242 if(ltmp) add_one_tobill(obj, dummy);
2243 if(cltmp) bill_box_content(obj, ininv, dummy, shkp);
2244 picked_container(obj); /* reset contained obj->no_charge */
2249 costly_gold(obj->ox, obj->oy, gltmp);
2256 } else /* i.e., !container */
2257 add_one_tobill(obj, dummy);
2259 if (shkp->mcanmove && !shkp->msleeping && !silent) {
2263 pline("%s has no interest in %s.", Monnam(shkp),
2267 Strcpy(buf, "\"For you, ");
2268 if (ANGRY(shkp)) Strcat(buf, "scum ");
2270 static const char *honored[5] = {
2271 "good", "honored", "most gracious", "esteemed",
2272 "most renowned and sacred"
2274 Strcat(buf, honored[rn2(4) + u.uevent.udemigod]);
2275 if (!is_human(youmonst.data)) Strcat(buf, " creature");
2277 Strcat(buf, (flags.female) ? " lady" : " sir");
2280 long quan = obj->quan;
2281 obj->quan = 1L; /* fool xname() into giving singular */
2282 pline("%s; only %ld %s %s.\"", buf, ltmp,
2283 (quan > 1L) ? "per" : "for this", xname(obj));
2286 pline("%s will cost you %ld %s%s.",
2287 The(xname(obj)), ltmp, currency(ltmp),
2288 (obj->quan > 1L) ? " each" : "");
2289 } else if(!silent) {
2290 if(ltmp) pline_The("list price of %s is %ld %s%s.",
2291 the(xname(obj)), ltmp, currency(ltmp),
2292 (obj->quan > 1L) ? " each" : "");
2293 else pline("%s does not notice.", Monnam(shkp));
2298 splitbill(obj, otmp)
2299 register struct obj *obj, *otmp;
2301 /* otmp has been split off from obj */
2302 register struct bill_x *bp;
2304 register struct monst *shkp = shop_keeper(*u.ushops);
2306 if(!shkp || !inhishop(shkp)) {
2307 impossible("splitbill: no resident shopkeeper??");
2310 bp = onbill(obj, shkp, FALSE);
2312 impossible("splitbill: not on bill?");
2315 if(bp->bquan < otmp->quan) {
2316 impossible("Negative quantity on bill??");
2318 if(bp->bquan == otmp->quan) {
2319 impossible("Zero quantity on bill??");
2321 bp->bquan -= otmp->quan;
2323 if(ESHK(shkp)->billct == BILLSZ) otmp->unpaid = 0;
2326 bp = &(ESHK(shkp)->bill_p[ESHK(shkp)->billct]);
2327 bp->bo_id = otmp->o_id;
2328 bp->bquan = otmp->quan;
2331 ESHK(shkp)->billct++;
2336 sub_one_frombill(obj, shkp)
2337 register struct obj *obj;
2338 register struct monst *shkp;
2340 register struct bill_x *bp;
2342 if((bp = onbill(obj, shkp, FALSE)) != 0) {
2343 register struct obj *otmp;
2346 if(bp->bquan > obj->quan){
2349 bp->bo_id = otmp->o_id = flags.ident++;
2350 otmp->where = OBJ_FREE;
2351 otmp->quan = (bp->bquan -= obj->quan);
2352 otmp->owt = 0; /* superfluous */
2355 otmp->oattached = OATTACHED_NOTHING;
2357 add_to_billobjs(otmp);
2360 ESHK(shkp)->billct--;
2363 /* DRS/NS 2.2.6 messes up -- Peter Kendell */
2364 int indx = ESHK(shkp)->billct;
2365 *bp = ESHK(shkp)->bill_p[indx];
2368 *bp = ESHK(shkp)->bill_p[ESHK(shkp)->billct];
2371 } else if (obj->unpaid) {
2372 impossible("sub_one_frombill: unpaid object not on bill");
2377 /* recursive check of unpaid objects within nested containers. */
2379 subfrombill(obj, shkp)
2380 register struct obj *obj;
2381 register struct monst *shkp;
2383 register struct obj *otmp;
2385 sub_one_frombill(obj, shkp);
2387 if (Has_contents(obj))
2388 for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
2389 if(otmp->oclass == COIN_CLASS) continue;
2391 if (Has_contents(otmp))
2392 subfrombill(otmp, shkp);
2394 sub_one_frombill(otmp, shkp);
2402 stolen_container(obj, shkp, price, ininv)
2403 register struct obj *obj;
2404 register struct monst *shkp;
2406 register boolean ininv;
2408 register struct obj *otmp;
2410 if(ininv && obj->unpaid)
2411 price += get_cost(obj, shkp);
2414 price += get_cost(obj, shkp);
2418 /* the price of contained objects, if any */
2419 for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
2421 if(otmp->oclass == COIN_CLASS) continue;
2423 if (!Has_contents(otmp)) {
2426 price += otmp->quan * get_cost(otmp, shkp);
2428 if(!otmp->no_charge) {
2429 if(otmp->oclass != FOOD_CLASS || !otmp->oeaten)
2430 price += otmp->quan * get_cost(otmp, shkp);
2432 otmp->no_charge = 0;
2435 price += stolen_container(otmp, shkp, price, ininv);
2444 stolen_value(obj, x, y, peaceful, silent)
2445 register struct obj *obj;
2446 register xchar x, y;
2447 register boolean peaceful, silent;
2449 register long value = 0L, gvalue = 0L;
2450 register struct monst *shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
2452 if (!shkp || !inhishop(shkp))
2455 if(obj->oclass == COIN_CLASS) {
2456 gvalue += obj->quan;
2457 } else if (Has_contents(obj)) {
2458 register boolean ininv = !!count_unpaid(obj->cobj);
2460 value += stolen_container(obj, shkp, value, ininv);
2461 if(!ininv) gvalue += contained_gold(obj);
2462 } else if (!obj->no_charge && saleable(shkp, obj)) {
2463 value += get_cost(obj, shkp);
2466 if(gvalue + value == 0L) return(0L);
2471 boolean credit_use = !!ESHK(shkp)->credit;
2472 value = check_credit(value, shkp);
2473 /* 'peaceful' affects general treatment, but doesn't affect
2474 * the fact that other code expects that all charges after the
2475 * shopkeeper is angry are included in robbed, not debit */
2477 ESHK(shkp)->robbed += value;
2479 ESHK(shkp)->debit += value;
2482 const char *still = "";
2485 if (ESHK(shkp)->credit) {
2486 You("have %ld %s credit remaining.",
2487 ESHK(shkp)->credit, currency(ESHK(shkp)->credit));
2489 } else if (!value) {
2490 You("have no credit remaining.");
2495 if(obj->oclass == COIN_CLASS)
2496 You("%sowe %s %ld %s!", still,
2497 mon_nam(shkp), value, currency(value));
2499 You("%sowe %s %ld %s for %s!", still,
2500 mon_nam(shkp), value, currency(value),
2501 obj->quan > 1L ? "them" : "it");
2504 ESHK(shkp)->robbed += value;
2507 if(cansee(shkp->mx, shkp->my)) {
2508 Norep("%s booms: \"%s, you are a thief!\"",
2509 Monnam(shkp), plname);
2510 } else Norep("You hear a scream, \"Thief!\"");
2513 (void) angry_guards(FALSE);
2518 /* auto-response flag for/from "sell foo?" 'a' => 'y', 'q' => 'n' */
2519 static char sell_response = 'a';
2520 static int sell_how = SELL_NORMAL;
2521 /* can't just use sell_response='y' for auto_credit because the 'a' response
2522 shouldn't carry over from ordinary selling to credit selling */
2523 static boolean auto_credit = FALSE;
2526 sellobj_state(deliberate)
2529 /* If we're deliberately dropping something, there's no automatic
2530 response to the shopkeeper's "want to sell" query; however, if we
2531 accidentally drop anything, the shk will buy it/them without asking.
2532 This retains the old pre-query risk that slippery fingers while in
2533 shops entailed: you drop it, you've lost it.
2535 sell_response = (deliberate != SELL_NORMAL) ? '\0' : 'a';
2536 sell_how = deliberate;
2537 auto_credit = FALSE;
2542 register struct obj *obj;
2545 register struct monst *shkp;
2546 register struct eshk *eshkp;
2547 long ltmp = 0L, cltmp = 0L, gltmp = 0L, offer;
2548 boolean saleitem, cgold = FALSE, container = Has_contents(obj);
2549 boolean isgold = (obj->oclass == COIN_CLASS);
2550 boolean only_partially_your_contents = FALSE;
2552 if(!(shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) ||
2553 !inhishop(shkp)) return;
2554 if(!costly_spot(x, y)) return;
2555 if(!*u.ushops) return;
2557 if(obj->unpaid && !container && !isgold) {
2558 sub_one_frombill(obj, shkp);
2562 /* find the price of content before subfrombill */
2563 cltmp += contained_cost(obj, shkp, cltmp, TRUE, FALSE);
2564 /* find the value of contained gold */
2565 gltmp += contained_gold(obj);
2566 cgold = (gltmp > 0L);
2569 saleitem = saleable(shkp, obj);
2570 if(!isgold && !obj->unpaid && saleitem)
2571 ltmp = set_cost(obj, shkp);
2573 offer = ltmp + cltmp;
2575 /* get one case out of the way: nothing to sell, and no gold */
2577 ((offer + gltmp) == 0L || sell_how == SELL_DONTSELL)) {
2578 register boolean unpaid = (obj->unpaid ||
2579 (container && count_unpaid(obj->cobj)));
2582 dropped_container(obj, shkp, FALSE);
2583 if(!obj->unpaid && !saleitem)
2585 if(obj->unpaid || count_unpaid(obj->cobj))
2586 subfrombill(obj, shkp);
2587 } else obj->no_charge = 1;
2589 if(!unpaid && (sell_how != SELL_DONTSELL))
2590 pline("%s seems uninterested.", Monnam(shkp));
2594 /* you dropped something of your own - probably want to sell it */
2595 rouse_shk(shkp, TRUE); /* wake up sleeping or paralyzed shk */
2598 if (ANGRY(shkp)) { /* they become shop-objects, no pay */
2599 pline("Thank you, scum!");
2600 subfrombill(obj, shkp);
2604 if(eshkp->robbed) { /* shkp is not angry? */
2605 if(isgold) offer = obj->quan;
2606 else if(cgold) offer += cgold;
2607 if((eshkp->robbed -= offer < 0L))
2609 if(offer) verbalize(
2610 "Thank you for your contribution to restock this recently plundered shop.");
2611 subfrombill(obj, shkp);
2615 if(isgold || cgold) {
2616 if(!cgold) gltmp = obj->quan;
2618 if(eshkp->debit >= gltmp) {
2619 if(eshkp->loan) { /* you carry shop's gold */
2620 if(eshkp->loan >= gltmp)
2621 eshkp->loan -= gltmp;
2622 else eshkp->loan = 0L;
2624 eshkp->debit -= gltmp;
2625 Your("debt is %spaid off.",
2626 eshkp->debit ? "partially " : "");
2628 long delta = gltmp - eshkp->debit;
2630 eshkp->credit += delta;
2634 Your("debt is paid off.");
2636 pline("%ld %s %s added to your credit.",
2637 delta, currency(delta), delta > 1L ? "are" : "is");
2639 if(offer) goto move_on;
2643 dropped_container(obj, shkp, FALSE);
2644 if (!obj->unpaid && !saleitem) obj->no_charge = 1;
2645 subfrombill(obj, shkp);
2651 if((!saleitem && !(container && cltmp > 0L))
2652 || eshkp->billct == BILLSZ
2653 || obj->oclass == BALL_CLASS
2654 || obj->oclass == CHAIN_CLASS || offer == 0L
2655 || (obj->oclass == FOOD_CLASS && obj->oeaten)
2656 || (Is_candle(obj) &&
2657 obj->age < 20L * (long)objects[obj->otyp].oc_cost)) {
2658 pline("%s seems uninterested%s.", Monnam(shkp),
2659 cgold ? " in the rest" : "");
2661 dropped_container(obj, shkp, FALSE);
2669 if(!money_cnt(shkp->minvent)) {
2671 char c, qbuf[BUFSZ];
2672 long tmpcr = ((offer * 9L) / 10L) + (offer <= 1L);
2674 if (sell_how == SELL_NORMAL || auto_credit) {
2675 c = sell_response = 'y';
2676 } else if (sell_response != 'n') {
2677 pline("%s cannot pay you at present.", Monnam(shkp));
2679 "Will you accept %ld %s in credit for %s?",
2680 tmpcr, currency(tmpcr), doname(obj));
2681 /* won't accept 'a' response here */
2682 /* KLY - 3/2000 yes, we will, it's a damn nuisance
2683 to have to constantly hit 'y' to sell for credit */
2689 } else /* previously specified "quit" */
2693 shk_names_obj(shkp, obj, (sell_how != SELL_NORMAL) ?
2694 "traded %s for %ld zorkmid%s in %scredit." :
2695 "relinquish %s and acquire %ld zorkmid%s in %scredit.",
2697 (eshkp->credit > 0L) ? "additional " : "");
2698 eshkp->credit += tmpcr;
2699 subfrombill(obj, shkp);
2701 if (c == 'q') sell_response = 'n';
2703 dropped_container(obj, shkp, FALSE);
2704 if (!obj->unpaid) obj->no_charge = 1;
2705 subfrombill(obj, shkp);
2710 boolean short_funds = (offer > shkp->mgold);
2711 if (short_funds) offer = shkp->mgold;
2713 long shkmoney = money_cnt(shkp->minvent);
2714 boolean short_funds = (offer > shkmoney);
2715 if (short_funds) offer = shkmoney;
2717 if (!sell_response) {
2718 only_partially_your_contents =
2719 (contained_cost(obj, shkp, 0L, FALSE, FALSE) !=
2720 contained_cost(obj, shkp, 0L, FALSE, TRUE));
2722 "%s offers%s %ld gold piece%s for%s %s %s. Sell %s?",
2723 Monnam(shkp), short_funds ? " only" : "",
2725 (!ltmp && cltmp && only_partially_your_contents) ?
2726 " your items in" : (!ltmp && cltmp) ? " the contents of" : "",
2727 obj->unpaid ? "the" : "your", cxname(obj),
2729 !(!ltmp && cltmp && only_partially_your_contents)) ?
2731 } else qbuf[0] = '\0'; /* just to pacify lint */
2733 switch (sell_response ? sell_response : ynaq(qbuf)) {
2734 case 'q': sell_response = 'n';
2735 case 'n': if (container)
2736 dropped_container(obj, shkp, FALSE);
2737 if (!obj->unpaid) obj->no_charge = 1;
2738 subfrombill(obj, shkp);
2740 case 'a': sell_response = 'y';
2741 case 'y': if (container)
2742 dropped_container(obj, shkp, TRUE);
2743 if (!obj->unpaid && !saleitem) obj->no_charge = 1;
2744 subfrombill(obj, shkp);
2746 shk_names_obj(shkp, obj, (sell_how != SELL_NORMAL) ?
2747 (!ltmp && cltmp && only_partially_your_contents) ?
2748 "sold some items inside %s for %ld gold pieces%s.%s" :
2749 "sold %s for %ld gold piece%s.%s" :
2750 "relinquish %s and receive %ld gold piece%s in compensation.%s",
2753 default: impossible("invalid sell response");
2760 int mode; /* 0: deliver count 1: paged */
2763 void sasc_bug(struct obj *, unsigned);
2767 struct bill_x *bp, *end_bp;
2773 shkp = shop_keeper(*u.ushops);
2774 if (!shkp || !inhishop(shkp)) {
2775 if (mode != 0) impossible("doinvbill: no shopkeeper?");
2781 /* count expended items, so that the `I' command can decide
2782 whether to include 'x' in its prompt string */
2783 int cnt = !eshkp->debit ? 0 : 1;
2785 for (bp = eshkp->bill_p, end_bp = &eshkp->bill_p[eshkp->billct];
2788 ((obj = bp_to_obj(bp)) != 0 && obj->quan < bp->bquan))
2793 datawin = create_nhwindow(NHW_MENU);
2794 putstr(datawin, 0, "Unpaid articles already used up:");
2795 putstr(datawin, 0, "");
2798 for (bp = eshkp->bill_p, end_bp = &eshkp->bill_p[eshkp->billct];
2799 bp < end_bp; bp++) {
2800 obj = bp_to_obj(bp);
2802 impossible("Bad shopkeeper administration.");
2805 if(bp->useup || bp->bquan > obj->quan) {
2806 long oquan, uquan, thisused;
2807 unsigned save_unpaid;
2809 save_unpaid = obj->unpaid;
2811 uquan = (bp->useup ? bp->bquan : bp->bquan - oquan);
2812 thisused = bp->price * uquan;
2813 totused += thisused;
2814 obj->unpaid = 0; /* ditto */
2815 /* Why 'x'? To match `I x', more or less. */
2816 buf_p = xprname(obj, (char *)0, 'x', FALSE, thisused, uquan);
2818 /* SAS/C 6.2 can't cope for some reason */
2819 sasc_bug(obj,save_unpaid);
2821 obj->unpaid = save_unpaid;
2823 putstr(datawin, 0, buf_p);
2827 /* additional shop debt which has no itemization available */
2828 if (totused) putstr(datawin, 0, "");
2829 totused += eshkp->debit;
2830 buf_p = xprname((struct obj *)0,
2831 "usage charges and/or other fees",
2832 GOLD_SYM, FALSE, eshkp->debit, 0L);
2833 putstr(datawin, 0, buf_p);
2835 buf_p = xprname((struct obj *)0, "Total:", '*', FALSE, totused, 0L);
2836 putstr(datawin, 0, "");
2837 putstr(datawin, 0, buf_p);
2838 display_nhwindow(datawin, FALSE);
2840 destroy_nhwindow(datawin);
2847 getprice(obj, shk_buying)
2848 register struct obj *obj;
2851 register long tmp = (long) objects[obj->otyp].oc_cost;
2853 if (obj->oartifact) {
2854 tmp = arti_cost(obj);
2855 if (shk_buying) tmp /= 4;
2857 switch(obj->oclass) {
2859 /* simpler hunger check, (2-4)*cost */
2860 if (u.uhs >= HUNGRY && !shk_buying) tmp *= (long) u.uhs;
2861 if (obj->oeaten) tmp = 0L;
2864 if (obj->spe == -1) tmp = 0L;
2867 if (obj->otyp == POT_WATER && !obj->blessed && !obj->cursed)
2872 if (obj->spe > 0) tmp += 10L * (long) obj->spe;
2875 if (Is_candle(obj) &&
2876 obj->age < 20L * (long)objects[obj->otyp].oc_cost)
2883 /* shk catches thrown pick-axe */
2886 register struct obj *obj;
2887 register xchar x, y;
2889 register struct monst *shkp;
2891 if (!(shkp = shop_keeper(inside_shop(x, y))) ||
2892 !inhishop(shkp)) return(0);
2894 if (shkp->mcanmove && !shkp->msleeping &&
2895 (*u.ushops != ESHK(shkp)->shoproom || !inside_shop(u.ux, u.uy)) &&
2896 dist2(shkp->mx, shkp->my, x, y) < 3 &&
2897 /* if it is the shk's pos, you hit and anger him */
2898 (shkp->mx != x || shkp->my != y)) {
2899 if (mnearto(shkp, x, y, TRUE))
2900 verbalize("Out of my way, scum!");
2902 pline("%s nimbly%s catches %s.",
2904 (x == shkp->mx && y == shkp->my) ? "" : " reaches over and",
2906 if (!canspotmon(shkp))
2907 map_invisible(x, y);
2911 subfrombill(obj, shkp);
2912 (void) mpickobj(shkp, obj);
2915 return (struct monst *)0;
2919 add_damage(x, y, cost)
2920 register xchar x, y;
2923 struct damage *tmp_dam;
2926 if (IS_DOOR(levl[x][y].typ)) {
2929 /* Don't schedule for repair unless it's a real shop entrance */
2930 for (shops = in_rooms(x, y, SHOPBASE); *shops; shops++)
2931 if ((mtmp = shop_keeper(*shops)) != 0 &&
2932 x == ESHK(mtmp)->shd.x && y == ESHK(mtmp)->shd.y)
2934 if (!*shops) return;
2936 for (tmp_dam = level.damagelist; tmp_dam; tmp_dam = tmp_dam->next)
2937 if (tmp_dam->place.x == x && tmp_dam->place.y == y) {
2938 tmp_dam->cost += cost;
2941 tmp_dam = (struct damage *)alloc((unsigned)sizeof(struct damage));
2942 tmp_dam->when = monstermoves;
2943 tmp_dam->place.x = x;
2944 tmp_dam->place.y = y;
2945 tmp_dam->cost = cost;
2946 tmp_dam->typ = levl[x][y].typ;
2947 tmp_dam->next = level.damagelist;
2948 level.damagelist = tmp_dam;
2949 /* If player saw damage, display as a wall forever */
2951 levl[x][y].seenv = SVALL;
2958 * Do something about damage. Either (!croaked) try to repair it, or
2959 * (croaked) just discard damage structs for non-shared locations, since
2960 * they'll never get repaired. Assume that shared locations will get
2961 * repaired eventually by the other shopkeeper(s). This might be an erroneous
2962 * assumption (they might all be dead too), but we have no reasonable way of
2967 remove_damage(shkp, croaked)
2968 register struct monst *shkp;
2969 register boolean croaked;
2971 register struct damage *tmp_dam, *tmp2_dam;
2972 register boolean did_repair = FALSE, saw_door = FALSE;
2973 register boolean saw_floor = FALSE, stop_picking = FALSE;
2974 register boolean saw_untrap = FALSE;
2975 uchar saw_walls = 0;
2977 tmp_dam = level.damagelist;
2980 register xchar x = tmp_dam->place.x, y = tmp_dam->place.y;
2985 Strcpy(shops, in_rooms(x, y, SHOPBASE));
2986 if (index(shops, ESHK(shkp)->shoproom)) {
2988 disposition = (shops[1])? 0 : 1;
2989 else if (stop_picking)
2990 disposition = repair_damage(shkp, tmp_dam, FALSE);
2992 /* Defer the stop_occupation() until after repair msgs */
2993 if (closed_door(x, y))
2994 stop_picking = picking_at(x, y);
2995 disposition = repair_damage(shkp, tmp_dam, FALSE);
2997 stop_picking = FALSE;
3003 tmp_dam = tmp_dam->next;
3007 if (disposition > 1) {
3010 if (IS_WALL(levl[x][y].typ))
3012 else if (IS_DOOR(levl[x][y].typ))
3014 else if (disposition == 3) /* untrapped */
3021 tmp_dam = tmp_dam->next;
3023 free((genericptr_t)level.damagelist);
3024 level.damagelist = tmp_dam;
3026 free((genericptr_t)tmp2_dam->next);
3027 tmp2_dam->next = tmp_dam;
3033 pline("Suddenly, %s section%s of wall close%s up!",
3034 (saw_walls == 1) ? "a" : (saw_walls <= 3) ?
3036 (saw_walls == 1) ? "" : "s", (saw_walls == 1) ? "s" : "");
3038 pline_The("shop door reappears!");
3040 pline_The("floor is repaired!");
3043 pline("Suddenly, the shop door reappears!");
3045 pline("Suddenly, the floor damage is gone!");
3046 else if (saw_untrap)
3047 pline("Suddenly, the trap is removed from the floor!");
3048 else if (inside_shop(u.ux, u.uy) == ESHK(shkp)->shoproom)
3049 You_feel("more claustrophobic than before.");
3050 else if (flags.soundok && !rn2(10))
3051 Norep("The dungeon acoustics noticeably change.");
3058 * 0: repair postponed, 1: silent repair (no messages), 2: normal repair
3062 repair_damage(shkp, tmp_dam, catchup)
3063 register struct monst *shkp;
3064 register struct damage *tmp_dam;
3065 boolean catchup; /* restoring a level */
3067 register xchar x, y, i;
3069 register struct monst *mtmp;
3070 register struct obj *otmp;
3071 register struct trap *ttmp;
3073 if ((monstermoves - tmp_dam->when) < REPAIR_DELAY)
3075 if (shkp->msleeping || !shkp->mcanmove || ESHK(shkp)->following)
3077 x = tmp_dam->place.x;
3078 y = tmp_dam->place.y;
3079 if (!IS_ROOM(tmp_dam->typ)) {
3080 if (x == u.ux && y == u.uy)
3083 if (x == shkp->mx && y == shkp->my)
3085 if ((mtmp = m_at(x, y)) && (!passes_walls(mtmp->data)))
3088 if ((ttmp = t_at(x, y)) != 0) {
3089 if (x == u.ux && y == u.uy)
3092 if (ttmp->ttyp == LANDMINE || ttmp->ttyp == BEAR_TRAP) {
3093 /* convert to an object */
3094 otmp = mksobj((ttmp->ttyp == LANDMINE) ? LAND_MINE :
3095 BEARTRAP, TRUE, FALSE);
3097 otmp->owt = weight(otmp);
3098 (void) mpickobj(shkp, otmp);
3101 if(IS_DOOR(tmp_dam->typ)) {
3102 levl[x][y].doormask = D_CLOSED; /* arbitrary */
3104 } else if (IS_WALL(tmp_dam->typ)) {
3105 levl[x][y].typ = tmp_dam->typ;
3111 if (IS_ROOM(tmp_dam->typ)) {
3112 /* No messages, because player already filled trap door */
3115 if ((tmp_dam->typ == levl[x][y].typ) &&
3116 (!IS_DOOR(tmp_dam->typ) || (levl[x][y].doormask > D_BROKEN)))
3117 /* No messages if player already replaced shop door */
3119 levl[x][y].typ = tmp_dam->typ;
3120 (void) memset((genericptr_t)litter, 0, sizeof(litter));
3121 if ((otmp = level.objects[x][y]) != 0) {
3122 /* Scatter objects haphazardly into the shop */
3123 #define NEED_UPDATE 1
3126 #define horiz(i) ((i%3)-1)
3127 #define vert(i) ((i/3)-1)
3128 for (i = 0; i < 9; i++) {
3129 if ((i == 4) || (!ZAP_POS(levl[x+horiz(i)][y+vert(i)].typ)))
3132 if (inside_shop(x+horiz(i),
3133 y+vert(i)) == ESHK(shkp)->shoproom)
3134 litter[i] |= INSHOP;
3136 if (Punished && !u.uswallow &&
3137 ((uchain->ox == x && uchain->oy == y) ||
3138 (uball->ox == x && uball->oy == y))) {
3140 * Either the ball or chain is in the repair location.
3142 * Take the easy way out and put ball&chain under hero.
3144 verbalize("Get your junk out of my wall!");
3145 unplacebc(); /* pick 'em up */
3146 placebc(); /* put 'em down */
3148 while ((otmp = level.objects[x][y]) != 0)
3149 /* Don't mess w/ boulders -- just merge into wall */
3150 if ((otmp->otyp == BOULDER) || (otmp->otyp == ROCK)) {
3151 obj_extract_self(otmp);
3152 obfree(otmp, (struct obj *)0);
3154 while (!(litter[i = rn2(9)] & INSHOP));
3155 remove_object(otmp);
3156 place_object(otmp, x+horiz(i), y+vert(i));
3157 litter[i] |= NEED_UPDATE;
3160 if (catchup) return 1; /* repair occurred while off level */
3163 if(IS_DOOR(tmp_dam->typ)) {
3164 levl[x][y].doormask = D_CLOSED; /* arbitrary */
3167 /* don't set doormask - it is (hopefully) the same as it was */
3168 /* if not, perhaps save it with the damage array... */
3170 if (IS_WALL(tmp_dam->typ) && cansee(x, y)) {
3171 /* Player sees actual repair process, so they KNOW it's a wall */
3172 levl[x][y].seenv = SVALL;
3175 /* Mark this wall as "repaired". There currently is no code */
3176 /* to do anything about repaired walls, so don't do it. */
3178 for (i = 0; i < 9; i++)
3179 if (litter[i] & NEED_UPDATE)
3180 newsym(x+horiz(i), y+vert(i));
3191 * shk_move: return 1: moved 0: didn't -1: let m_move do it -2: died
3195 register struct monst *shkp;
3197 register xchar gx,gy,omx,omy;
3199 register schar appr;
3200 register struct eshk *eshkp = ESHK(shkp);
3202 boolean uondoor = FALSE, satdoor, avoid = FALSE, badinv;
3208 remove_damage(shkp, FALSE);
3210 if((udist = distu(omx,omy)) < 3 &&
3211 (shkp->data != &mons[PM_GRID_BUG] || (omx==u.ux || omy==u.uy))) {
3213 (Conflict && !resist(shkp, RING_CLASS, 0, 0))) {
3215 Your("displaced image doesn't fool %s!",
3217 (void) mattacku(shkp);
3220 if(eshkp->following) {
3221 if(strncmp(eshkp->customer, plname, PL_NSIZ)) {
3222 verbalize("%s, %s! I was looking for %s.",
3223 Hello(shkp), plname, eshkp->customer);
3224 eshkp->following = 0;
3227 if(moves > followmsg+4) {
3228 verbalize("%s, %s! Didn't you forget to pay?",
3229 Hello(shkp), plname);
3232 pline("%s doesn't like customers who don't pay.",
3245 satdoor = (gx == omx && gy == omy);
3246 if(eshkp->following || ((z = holetime()) >= 0 && z*z <= udist)){
3247 /* [This distance check used to apply regardless of
3248 whether the shk was following, but that resulted in
3249 m_move() sometimes taking the shk out of the shop if
3250 the player had fenced him in with boulders or traps.
3251 Such voluntary abandonment left unpaid objects in
3252 invent, triggering billing impossibilities on the
3253 next level once the character fell through the hole.] */
3254 if (udist > 4 && eshkp->following)
3255 return(-1); /* leave it to m_move */
3258 } else if(ANGRY(shkp)) {
3259 /* Move towards the hero if the shopkeeper can see him. */
3260 if(shkp->mcansee && m_canseeu(shkp)) {
3266 #define GDIST(x,y) (dist2(x,y,gx,gy))
3274 uondoor = (u.ux == eshkp->shd.x && u.uy == eshkp->shd.y);
3276 badinv = (carrying(PICK_AXE) || carrying(DWARVISH_MATTOCK) ||
3277 (Fast && (sobj_at(PICK_AXE, u.ux, u.uy) ||
3278 sobj_at(DWARVISH_MATTOCK, u.ux, u.uy))));
3279 if(satdoor && badinv)
3283 avoid = (*u.ushops && distu(gx,gy) > 8);
3287 if(((!eshkp->robbed && !eshkp->billct && !eshkp->debit)
3288 || avoid) && GDIST(omx,omy) < 3) {
3289 if (!badinv && !onlineu(omx,omy))
3297 z = move_special(shkp,inhishop(shkp),appr,uondoor,avoid,omx,omy,gx,gy);
3298 if (z > 0) after_shk_move(shkp);
3303 /* called after shopkeeper moves, in case the move causes re-entry into shop */
3305 after_shk_move(shkp)
3308 struct eshk *eshkp = ESHK(shkp);
3310 if (eshkp->bill_p == (struct bill_x *) -1000 && inhishop(shkp)) {
3311 /* reset bill_p, need to re-calc player's occupancy too */
3312 eshkp->bill_p = &eshkp->bill[0];
3313 check_special_room(FALSE);
3320 /* for use in levl_follower (mondata.c) */
3323 register struct monst *mtmp;
3325 return((boolean)(mtmp->isshk && ESHK(mtmp)->following));
3328 /* You are digging in the shop. */
3333 register struct monst *shkp = shop_keeper(*u.ushops);
3335 const char *grabs = "grabs";
3339 /* 0 == can't speak, 1 == makes animal noises, 2 == speaks */
3341 if (shkp->msleeping || !shkp->mcanmove || is_silent(shkp->data))
3342 ; /* lang stays 0 */
3343 else if (shkp->data->msound <= MS_ANIMAL)
3345 else if (shkp->data->msound >= MS_HUMANOID)
3348 if(!inhishop(shkp)) {
3349 if (Role_if(PM_KNIGHT)) {
3350 You_feel("like a common thief.");
3351 adjalign(-sgn(u.ualign.type));
3358 if(u.utraptype == TT_PIT)
3360 "Be careful, %s, or you might fall through the floor.",
3361 flags.female ? "madam" : "sir");
3363 verbalize("%s, do not damage the floor here!",
3364 flags.female ? "Madam" : "Sir");
3366 if (Role_if(PM_KNIGHT)) {
3367 You_feel("like a common thief.");
3368 adjalign(-sgn(u.ualign.type));
3370 } else if(!um_dist(shkp->mx, shkp->my, 5) &&
3371 !shkp->msleeping && shkp->mcanmove &&
3372 (ESHK(shkp)->billct || ESHK(shkp)->debit)) {
3373 register struct obj *obj, *obj2;
3374 if (nolimbs(shkp->data)) {
3375 grabs = "knocks off";
3377 /* This is what should happen, but for balance
3378 * reasons, it isn't currently.
3381 pline("%s curses %s inability to grab your backpack!",
3382 shkname(shkp), mhim(shkp));
3387 if (distu(shkp->mx, shkp->my) > 2) {
3389 /* for some reason the shopkeeper can't come next to you */
3390 if (distu(shkp->mx, shkp->my) > 2) {
3392 pline("%s curses you in anger and frustration!",
3397 pline("%s %s, and %s your backpack!",
3399 makeplural(locomotion(shkp->data,"leap")), grabs);
3401 pline("%s %s your backpack!", shkname(shkp), grabs);
3403 for(obj = invent; obj; obj = obj2) {
3405 if ((obj->owornmask & ~(W_SWAPWEP|W_QUIVER)) != 0 ||
3406 (obj == uswapwep && u.twoweap) ||
3407 (obj->otyp == LEASH && obj->leashmon)) continue;
3408 if (obj == current_wand) continue;
3411 subfrombill(obj, shkp);
3412 (void) add_to_minv(shkp, obj); /* may free obj */
3422 static const short k_mndx[4] = {
3423 PM_KEYSTONE_KOP, PM_KOP_SERGEANT, PM_KOP_LIEUTENANT, PM_KOP_KAPTAIN
3425 int k_cnt[4], cnt, mndx, k;
3427 k_cnt[0] = cnt = abs(depth(&u.uz)) + rnd(5);
3428 k_cnt[1] = (cnt / 3) + 1; /* at least one sarge */
3429 k_cnt[2] = (cnt / 6); /* maybe a lieutenant */
3430 k_cnt[3] = (cnt / 9); /* and maybe a kaptain */
3432 for (k = 0; k < 4; k++) {
3433 if ((cnt = k_cnt[k]) == 0) break;
3435 if (mvitals[mndx].mvflags & G_GONE) continue;
3438 if (enexto(mm, mm->x, mm->y, &mons[mndx]))
3439 (void) makemon(&mons[mndx], mm->x, mm->y, NO_MM_FLAGS);
3445 pay_for_damage(dmgstr, cant_mollify)
3447 boolean cant_mollify;
3449 register struct monst *shkp = (struct monst *)0;
3450 char shops_affected[5];
3451 register boolean uinshp = (*u.ushops != '\0');
3453 register xchar x, y;
3454 boolean dugwall = !strcmp(dmgstr, "dig into") || /* wand */
3455 !strcmp(dmgstr, "damage"); /* pick-axe */
3456 struct damage *tmp_dam, *appear_here = 0;
3457 /* any number >= (80*80)+(24*24) would do, actually */
3458 long cost_of_damage = 0L;
3459 unsigned int nearest_shk = 7000, nearest_damage = 7000;
3462 for (tmp_dam = level.damagelist;
3463 (tmp_dam && (tmp_dam->when == monstermoves));
3464 tmp_dam = tmp_dam->next) {
3469 cost_of_damage += tmp_dam->cost;
3470 Strcpy(shops_affected,
3471 in_rooms(tmp_dam->place.x, tmp_dam->place.y, SHOPBASE));
3472 for (shp = shops_affected; *shp; shp++) {
3473 struct monst *tmp_shk;
3474 unsigned int shk_distance;
3476 if (!(tmp_shk = shop_keeper(*shp)))
3478 if (tmp_shk == shkp) {
3479 unsigned int damage_distance =
3480 distu(tmp_dam->place.x, tmp_dam->place.y);
3482 if (damage_distance < nearest_damage) {
3483 nearest_damage = damage_distance;
3484 appear_here = tmp_dam;
3488 if (!inhishop(tmp_shk))
3490 shk_distance = distu(tmp_shk->mx, tmp_shk->my);
3491 if (shk_distance > nearest_shk)
3493 if ((shk_distance == nearest_shk) && picks) {
3499 nearest_shk = shk_distance;
3500 appear_here = tmp_dam;
3501 nearest_damage = distu(tmp_dam->place.x, tmp_dam->place.y);
3505 if (!cost_of_damage || !shkp)
3508 x = appear_here->place.x;
3509 y = appear_here->place.y;
3511 /* not the best introduction to the shk... */
3512 (void) strncpy(ESHK(shkp)->customer,plname,PL_NSIZ);
3514 /* if the shk is already on the war path, be sure it's all out */
3515 if(ANGRY(shkp) || ESHK(shkp)->following) {
3520 /* if the shk is not in their shop.. */
3521 if(!*in_rooms(shkp->mx,shkp->my,SHOPBASE)) {
3522 if(!cansee(shkp->mx, shkp->my))
3528 if(um_dist(shkp->mx, shkp->my, 1) &&
3529 !um_dist(shkp->mx, shkp->my, 3)) {
3530 pline("%s leaps towards you!", shkname(shkp));
3533 if(um_dist(shkp->mx, shkp->my, 1)) goto getcad;
3536 * Make shkp show up at the door. Effect: If there is a monster
3537 * in the doorway, have the hero hear the shopkeeper yell a bit,
3538 * pause, then have the shopkeeper appear at the door, having
3539 * yanked the hapless critter out of the way.
3543 You_hear("an angry voice:");
3544 verbalize("Out of my way, scum!");
3546 #if defined(UNIX) || defined(VMS)
3547 # if defined(SYSV) || defined(ULTRIX) || defined(VMS)
3554 (void) mnearto(shkp, x, y, TRUE);
3557 if((um_dist(x, y, 1) && !uinshp) || cant_mollify ||
3559 (u.ugold + ESHK(shkp)->credit) < cost_of_damage
3561 (money_cnt(invent) + ESHK(shkp)->credit) < cost_of_damage
3564 if(um_dist(x, y, 1) && !uinshp) {
3565 pline("%s shouts:", shkname(shkp));
3566 verbalize("Who dared %s my %s?", dmgstr,
3567 dugwall ? "shop" : "door");
3570 verbalize("How dare you %s my %s?", dmgstr,
3571 dugwall ? "shop" : "door");
3577 if (Invis) Your("invisibility does not fool %s!", shkname(shkp));
3578 Sprintf(qbuf,"\"Cad! You did %ld %s worth of damage!\" Pay? ",
3579 cost_of_damage, currency(cost_of_damage));
3580 if(yn(qbuf) != 'n') {
3581 cost_of_damage = check_credit(cost_of_damage, shkp);
3583 u.ugold -= cost_of_damage;
3584 shkp->mgold += cost_of_damage;
3586 money2mon(shkp, cost_of_damage);
3589 pline("Mollified, %s accepts your restitution.",
3591 /* move shk back to his home loc */
3592 home_shk(shkp, FALSE);
3595 verbalize("Oh, yes! You'll pay!");
3597 adjalign(-sgn(u.ualign.type));
3602 /* called in dokick.c when we kick an object that might be in a store */
3605 register xchar x, y;
3607 register struct monst *shkp;
3609 if (!level.flags.has_shop) return FALSE;
3610 shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
3611 if(!shkp || !inhishop(shkp)) return(FALSE);
3613 return((boolean)(inside_shop(x, y) &&
3614 !(x == ESHK(shkp)->shk.x &&
3615 y == ESHK(shkp)->shk.y)));
3620 /* called by dotalk(sounds.c) when #chatting; returns obj if location
3621 contains shop goods and shopkeeper is willing & able to speak */
3624 register xchar x, y;
3626 register struct obj *otmp;
3627 register struct monst *shkp;
3629 if(!(shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) || !inhishop(shkp))
3630 return(struct obj *)0;
3632 for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
3633 if (otmp->oclass != COIN_CLASS)
3635 /* note: otmp might have ->no_charge set, but that's ok */
3636 return (otmp && costly_spot(x, y) && NOTANGRY(shkp)
3637 && shkp->mcanmove && !shkp->msleeping)
3638 ? otmp : (struct obj *)0;
3641 /* give price quotes for all objects linked to this one (ie, on this spot) */
3643 price_quote(first_obj)
3644 register struct obj *first_obj;
3646 register struct obj *otmp;
3647 char buf[BUFSZ], price[40];
3651 struct monst *shkp = shop_keeper(inside_shop(u.ux, u.uy));
3653 tmpwin = create_nhwindow(NHW_MENU);
3654 putstr(tmpwin, 0, "Fine goods for sale:");
3655 putstr(tmpwin, 0, "");
3656 for (otmp = first_obj; otmp; otmp = otmp->nexthere) {
3657 if (otmp->oclass == COIN_CLASS) continue;
3658 cost = (otmp->no_charge || otmp == uball || otmp == uchain) ? 0L :
3659 get_cost(otmp, (struct monst *)0);
3660 if (Has_contents(otmp))
3661 cost += contained_cost(otmp, shkp, 0L, FALSE, FALSE);
3663 Strcpy(price, "no charge");
3665 Sprintf(price, "%ld %s%s", cost, currency(cost),
3666 otmp->quan > 1L ? " each" : "");
3668 Sprintf(buf, "%s, %s", doname(otmp), price);
3669 putstr(tmpwin, 0, buf), cnt++;
3672 display_nhwindow(tmpwin, TRUE);
3673 } else if (cnt == 1) {
3674 if (first_obj->no_charge || first_obj == uball || first_obj == uchain){
3675 pline("%s!", buf); /* buf still contains the string */
3677 /* print cost in slightly different format, so can't reuse buf */
3678 cost = get_cost(first_obj, (struct monst *)0);
3679 if (Has_contents(first_obj))
3680 cost += contained_cost(first_obj, shkp, 0L, FALSE, FALSE);
3681 pline("%s, price %ld %s%s%s", doname(first_obj),
3682 cost, currency(cost), first_obj->quan > 1L ? " each" : "",
3683 shk_embellish(first_obj, cost));
3686 destroy_nhwindow(tmpwin);
3691 STATIC_OVL const char *
3692 shk_embellish(itm, cost)
3693 register struct obj *itm;
3697 register int o, choice = rn2(5);
3698 if (choice == 0) choice = (cost < 100L ? 1 : cost < 500L ? 2 : 3);
3701 if (cost < 10L) break; else o = itm->oclass;
3702 if (o == FOOD_CLASS) return ", gourmets' delight!";
3703 if (objects[itm->otyp].oc_name_known
3704 ? objects[itm->otyp].oc_magic
3705 : (o == AMULET_CLASS || o == RING_CLASS ||
3706 o == WAND_CLASS || o == POTION_CLASS ||
3707 o == SCROLL_CLASS || o == SPBOOK_CLASS))
3708 return ", painstakingly developed!";
3709 return ", superb craftsmanship!";
3710 case 3: return ", finest quality.";
3711 case 2: return ", an excellent choice.";
3712 case 1: return ", a real bargain.";
3715 } else if (itm->oartifact) {
3716 return ", one of a kind!";
3723 /* First 4 supplied by Ronen and Tamar, remainder by development team */
3724 const char *Izchak_speaks[]={
3725 "%s says: 'These shopping malls give me a headache.'",
3726 "%s says: 'Slow down. Think clearly.'",
3727 "%s says: 'You need to take things one at a time.'",
3728 "%s says: 'I don't like poofy coffee... give me Columbian Supremo.'",
3729 "%s says that getting the devteam's agreement on anything is difficult.",
3730 "%s says that he has noticed those who serve their deity will prosper.",
3731 "%s says: 'Don't try to steal from me - I have friends in high places!'",
3732 "%s says: 'You may well need something from this shop in the future.'",
3733 "%s comments about the Valley of the Dead as being a gateway."
3745 /* The monster type is shopkeeper, but this monster is
3746 not actually a shk, which could happen if someone
3747 wishes for a shopkeeper statue and then animates it.
3748 (Note: shkname() would be "" in a case like this.) */
3749 pline("%s asks whether you've seen any untended shops recently.",
3751 /* [Perhaps we ought to check whether this conversation
3752 is taking place inside an untended shop, but a shopless
3753 shk can probably be expected to be rather disoriented.] */
3759 pline("%s mentions how much %s dislikes %s customers.",
3760 shkname(shkp), mhe(shkp),
3761 eshk->robbed ? "non-paying" : "rude");
3762 else if (eshk->following) {
3763 if (strncmp(eshk->customer, plname, PL_NSIZ)) {
3764 verbalize("%s %s! I was looking for %s.",
3765 Hello(shkp), plname, eshk->customer);
3766 eshk->following = 0;
3768 verbalize("%s %s! Didn't you forget to pay?",
3769 Hello(shkp), plname);
3771 } else if (eshk->billct) {
3772 register long total = addupbill(shkp) + eshk->debit;
3773 pline("%s says that your bill comes to %ld %s.",
3774 shkname(shkp), total, currency(total));
3775 } else if (eshk->debit)
3776 pline("%s reminds you that you owe %s %ld %s.",
3777 shkname(shkp), mhim(shkp),
3778 eshk->debit, currency(eshk->debit));
3779 else if (eshk->credit)
3780 pline("%s encourages you to use your %ld %s of credit.",
3781 shkname(shkp), eshk->credit, currency(eshk->credit));
3782 else if (eshk->robbed)
3783 pline("%s complains about a recent robbery.", shkname(shkp));
3785 else if (shkp->mgold < 50)
3787 else if ((shkmoney = money_cnt(shkp->minvent)) < 50)
3789 pline("%s complains that business is bad.", shkname(shkp));
3791 else if (shkp->mgold > 4000)
3793 else if (shkmoney > 4000)
3795 pline("%s says that business is good.", shkname(shkp));
3796 else if (strcmp(shkname(shkp), "Izchak") == 0)
3797 pline(Izchak_speaks[rn2(SIZE(Izchak_speaks))],shkname(shkp));
3799 pline("%s talks about the problem of shoplifters.",shkname(shkp));
3805 register boolean silent;
3807 register int cnt = 0;
3808 register struct monst *mtmp, *mtmp2;
3810 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
3812 if (mtmp->data->mlet == S_KOP) {
3813 if (canspotmon(mtmp)) cnt++;
3818 pline_The("Kop%s (disappointed) vanish%s into thin air.",
3819 plur(cnt), cnt == 1 ? "es" : "");
3827 cost_per_charge(shkp, otmp, altusage)
3830 boolean altusage; /* some items have an "alternate" use with different cost */
3834 if(!shkp || !inhishop(shkp)) return(0L); /* insurance */
3835 tmp = get_cost(otmp, shkp);
3837 /* The idea is to make the exhaustive use of */
3838 /* an unpaid item more expensive than buying */
3840 if(otmp->otyp == MAGIC_LAMP) { /* 1 */
3841 /* normal use (ie, as light source) of a magic lamp never
3842 degrades its value, but not charging anything would make
3843 identifcation too easy; charge an amount comparable to
3844 what is charged for an ordinary lamp (don't bother with
3845 angry shk surchage) */
3846 if (!altusage) tmp = (long) objects[OIL_LAMP].oc_cost;
3847 else tmp += tmp / 3L; /* djinni is being released */
3848 } else if(otmp->otyp == MAGIC_MARKER) { /* 70 - 100 */
3849 /* no way to determine in advance */
3850 /* how many charges will be wasted. */
3851 /* so, arbitrarily, one half of the */
3852 /* price per use. */
3854 } else if(otmp->otyp == BAG_OF_TRICKS || /* 1 - 20 */
3855 otmp->otyp == HORN_OF_PLENTY) {
3857 } else if(otmp->otyp == CRYSTAL_BALL || /* 1 - 5 */
3858 otmp->otyp == OIL_LAMP || /* 1 - 10 */
3859 otmp->otyp == BRASS_LANTERN ||
3860 (otmp->otyp >= MAGIC_FLUTE &&
3861 otmp->otyp <= DRUM_OF_EARTHQUAKE) || /* 5 - 9 */
3862 otmp->oclass == WAND_CLASS) { /* 3 - 11 */
3863 if (otmp->spe > 1) tmp /= 4L;
3864 } else if (otmp->oclass == SPBOOK_CLASS) {
3866 } else if (otmp->otyp == CAN_OF_GREASE ||
3867 otmp->otyp == TINNING_KIT
3869 || otmp->otyp == EXPENSIVE_CAMERA
3873 } else if (otmp->otyp == POT_OIL) {
3881 /* Charge the player for partial use of an unpaid object.
3883 * Note that bill_dummy_object() should be used instead
3884 * when an object is completely used.
3887 check_unpaid_usage(otmp, altusage)
3892 const char *fmt, *arg1, *arg2;
3895 if (!otmp->unpaid || !*u.ushops ||
3896 (otmp->spe <= 0 && objects[otmp->otyp].oc_charged))
3898 if (!(shkp = shop_keeper(*u.ushops)) || !inhishop(shkp))
3900 if ((tmp = cost_per_charge(shkp, otmp, altusage)) == 0L)
3904 if (otmp->oclass == SPBOOK_CLASS) {
3905 fmt = "%sYou owe%s %ld %s.";
3906 arg1 = rn2(2) ? "This is no free library, cad! " : "";
3907 arg2 = ESHK(shkp)->debit > 0L ? " an additional" : "";
3908 } else if (otmp->otyp == POT_OIL) {
3909 fmt = "%s%sThat will cost you %ld %s (Yendorian Fuel Tax).";
3911 fmt = "%s%sUsage fee, %ld %s.";
3912 if (!rn2(3)) arg1 = "Hey! ";
3913 if (!rn2(3)) arg2 = "Ahem. ";
3916 if (shkp->mcanmove || !shkp->msleeping)
3917 verbalize(fmt, arg1, arg2, tmp, currency(tmp));
3918 ESHK(shkp)->debit += tmp;
3919 exercise(A_WIS, TRUE); /* you just got info */
3922 /* for using charges of unpaid objects "used in the normal manner" */
3927 check_unpaid_usage(otmp, FALSE); /* normal item use */
3931 costly_gold(x, y, amount)
3932 register xchar x, y;
3933 register long amount;
3935 register long delta;
3936 register struct monst *shkp;
3937 register struct eshk *eshkp;
3939 if(!costly_spot(x, y)) return;
3940 /* shkp now guaranteed to exist by costly_spot() */
3941 shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
3944 if(eshkp->credit >= amount) {
3945 if(eshkp->credit > amount)
3946 Your("credit is reduced by %ld %s.",
3947 amount, currency(amount));
3948 else Your("credit is erased.");
3949 eshkp->credit -= amount;
3951 delta = amount - eshkp->credit;
3953 Your("credit is erased.");
3955 Your("debt increases by %ld %s.",
3956 delta, currency(delta));
3957 else You("owe %s %ld %s.",
3958 shkname(shkp), delta, currency(delta));
3959 eshkp->debit += delta;
3960 eshkp->loan += delta;
3965 /* used in domove to block diagonal shop-exit */
3966 /* x,y should always be a door */
3969 register xchar x, y;
3971 register int roomno = *in_rooms(x, y, SHOPBASE);
3972 register struct monst *shkp;
3974 if(roomno < 0 || !IS_SHOP(roomno)) return(FALSE);
3975 if(!IS_DOOR(levl[x][y].typ)) return(FALSE);
3976 if(roomno != *u.ushops) return(FALSE);
3978 if(!(shkp = shop_keeper((char)roomno)) || !inhishop(shkp))
3981 if(shkp->mx == ESHK(shkp)->shk.x && shkp->my == ESHK(shkp)->shk.y
3982 /* Actually, the shk should be made to block _any_
3983 * door, including a door the player digs, if the
3984 * shk is within a 'jumping' distance.
3986 && ESHK(shkp)->shd.x == x && ESHK(shkp)->shd.y == y
3987 && shkp->mcanmove && !shkp->msleeping
3988 && (ESHK(shkp)->debit || ESHK(shkp)->billct ||
3989 ESHK(shkp)->robbed)) {
3990 pline("%s%s blocks your way!", shkname(shkp),
3991 Invis ? " senses your motion and" : "");
3997 /* used in domove to block diagonal shop-entry */
3998 /* u.ux, u.uy should always be a door */
4001 register xchar x, y;
4003 register xchar sx, sy;
4004 register int roomno;
4005 register struct monst *shkp;
4007 if(!(IS_DOOR(levl[u.ux][u.uy].typ) &&
4008 levl[u.ux][u.uy].doormask == D_BROKEN)) return(FALSE);
4010 roomno = *in_rooms(x, y, SHOPBASE);
4011 if(roomno < 0 || !IS_SHOP(roomno)) return(FALSE);
4012 if(!(shkp = shop_keeper((char)roomno)) || !inhishop(shkp))
4015 if(ESHK(shkp)->shd.x != u.ux || ESHK(shkp)->shd.y != u.uy)
4018 sx = ESHK(shkp)->shk.x;
4019 sy = ESHK(shkp)->shk.y;
4021 if(shkp->mx == sx && shkp->my == sy
4022 && shkp->mcanmove && !shkp->msleeping
4023 && (x == sx-1 || x == sx+1 || y == sy-1 || y == sy+1)
4024 && (Invis || carrying(PICK_AXE) || carrying(DWARVISH_MATTOCK)
4029 pline("%s%s blocks your way!", shkname(shkp),
4030 Invis ? " senses your motion and" : "");
4044 if (!shk_owns(buf, obj) && !mon_owns(buf, obj))
4045 Strcpy(buf, carried(obj) ? "your" : "the");
4054 (void) shk_your(buf, obj);
4067 if (get_obj_location(obj, &x, &y, 0) &&
4069 (obj->where==OBJ_FLOOR && !obj->no_charge && costly_spot(x,y)))) {
4070 shkp = shop_keeper(inside_shop(x, y));
4071 return strcpy(buf, shkp ? s_suffix(shkname(shkp)) : "the");
4081 if (obj->where == OBJ_MINVENT)
4082 return strcpy(buf, s_suffix(mon_nam(obj->ocarry)));
4091 sasc_bug(struct obj *op, unsigned x){