1 /* NetHack 3.6 shk.c $NHDT-Date: 1446854234 2015/11/06 23:57:14 $ $NHDT-Branch: master $:$NHDT-Revision: 1.116 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
9 #define PAY_CANT 0 /* too poor */
11 #define PAY_BROKE (-2)
13 STATIC_DCL void FDECL(makekops, (coord *));
14 STATIC_DCL void FDECL(call_kops, (struct monst *, BOOLEAN_P));
15 STATIC_DCL void FDECL(kops_gone, (BOOLEAN_P));
17 #define NOTANGRY(mon) ((mon)->mpeaceful)
18 #define ANGRY(mon) (!NOTANGRY(mon))
19 #define IS_SHOP(x) (rooms[x].rtype >= SHOPBASE)
21 #define muteshk(shkp) \
22 ((shkp)->msleeping || !(shkp)->mcanmove \
23 || (shkp)->data->msound <= MS_ANIMAL)
25 extern const struct shclass shtypes[]; /* defined in shknam.c */
27 STATIC_VAR NEARDATA long int followmsg; /* last time of follow message */
28 STATIC_VAR const char and_its_contents[] = " and its contents";
29 STATIC_VAR const char the_contents_of[] = "the contents of ";
31 STATIC_DCL void FDECL(append_honorific, (char *));
32 STATIC_DCL void FDECL(setpaid, (struct monst *));
33 STATIC_DCL long FDECL(addupbill, (struct monst *));
34 STATIC_DCL void FDECL(pacify_shk, (struct monst *));
35 STATIC_DCL struct bill_x *FDECL(onbill, (struct obj *, struct monst *,
37 STATIC_DCL struct monst *FDECL(next_shkp, (struct monst *, BOOLEAN_P));
38 STATIC_DCL long FDECL(shop_debt, (struct eshk *));
39 STATIC_DCL char *FDECL(shk_owns, (char *, struct obj *));
40 STATIC_DCL char *FDECL(mon_owns, (char *, struct obj *));
41 STATIC_DCL void FDECL(clear_unpaid, (struct obj *));
42 STATIC_DCL long FDECL(check_credit, (long, struct monst *));
43 STATIC_DCL void FDECL(pay, (long, struct monst *));
44 STATIC_DCL long FDECL(get_cost, (struct obj *, struct monst *));
45 STATIC_DCL long FDECL(set_cost, (struct obj *, struct monst *));
46 STATIC_DCL const char *FDECL(shk_embellish, (struct obj *, long));
47 STATIC_DCL long FDECL(cost_per_charge, (struct monst *, struct obj *,
49 STATIC_DCL long FDECL(cheapest_item, (struct monst *));
50 STATIC_DCL int FDECL(dopayobj, (struct monst *, struct bill_x *,
51 struct obj **, int, BOOLEAN_P));
52 STATIC_DCL long FDECL(stolen_container, (struct obj *, struct monst *,
54 STATIC_DCL long FDECL(getprice, (struct obj *, BOOLEAN_P));
55 STATIC_DCL void FDECL(shk_names_obj, (struct monst *, struct obj *,
56 const char *, long, const char *));
57 STATIC_DCL struct obj *FDECL(bp_to_obj, (struct bill_x *));
58 STATIC_DCL boolean FDECL(inherits, (struct monst *, int, int));
59 STATIC_DCL void FDECL(set_repo_loc, (struct monst *));
60 STATIC_DCL boolean NDECL(angry_shk_exists);
61 STATIC_DCL void FDECL(rile_shk, (struct monst *));
62 STATIC_DCL void FDECL(rouse_shk, (struct monst *, BOOLEAN_P));
63 STATIC_DCL void FDECL(remove_damage, (struct monst *, BOOLEAN_P));
64 STATIC_DCL void FDECL(sub_one_frombill, (struct obj *, struct monst *));
65 STATIC_DCL void FDECL(add_one_tobill, (struct obj *, BOOLEAN_P,
67 STATIC_DCL void FDECL(dropped_container, (struct obj *, struct monst *,
69 STATIC_DCL void FDECL(add_to_billobjs, (struct obj *));
70 STATIC_DCL void FDECL(bill_box_content, (struct obj *, BOOLEAN_P, BOOLEAN_P,
72 STATIC_DCL boolean FDECL(rob_shop, (struct monst *));
73 STATIC_DCL void FDECL(deserted_shop, (char *));
74 STATIC_DCL boolean FDECL(special_stock, (struct obj *, struct monst *,
76 STATIC_DCL const char *FDECL(cad, (BOOLEAN_P));
79 invariants: obj->unpaid iff onbill(obj) [unless bp->useup]
80 obj->quan <= bp->bquan
84 * Transfer money from inventory to monster when paying
85 * shopkeepers, priests, oracle, succubus, and other demons.
86 * Simple with only gold coins.
87 * This routine will handle money changing when multiple
88 * coin types is implemented, only appropriate
89 * monsters will pay change. (Peaceful shopkeepers, priests
90 * and the oracle try to maintain goodwill while selling
91 * their wares or services. Angry monsters and all demons
92 * will keep anything they get their hands on.
93 * Returns the amount actually paid, so we can know
94 * if the monster kept the change.
97 money2mon(mon, amount)
101 struct obj *ygold = findgold(invent);
104 impossible("%s payment in money2mon!", amount ? "negative" : "zero");
107 if (!ygold || ygold->quan < amount) {
108 impossible("Paying without %s money?", ygold ? "enough" : "");
112 if (ygold->quan > amount)
113 ygold = splitobj(ygold, amount);
114 else if (ygold->owornmask)
115 remove_worn_item(ygold, FALSE); /* quiver */
117 add_to_minv(mon, ygold);
123 * Transfer money from monster to inventory.
124 * Used when the shopkeeper pay for items, and when
125 * the priest gives you money for an ale.
132 struct obj *mongold = findgold(mon->minvent);
135 impossible("%s payment in money2u!", amount ? "negative" : "zero");
138 if (!mongold || mongold->quan < amount) {
139 impossible("%s paying without %s money?", a_monnam(mon),
140 mongold ? "enough" : "");
144 if (mongold->quan > amount)
145 mongold = splitobj(mongold, amount);
146 obj_extract_self(mongold);
148 if (!merge_choice(invent, mongold) && inv_cnt(FALSE) >= 52) {
149 You("have no room for the money!");
157 STATIC_OVL struct monst *
158 next_shkp(shkp, withbill)
159 register struct monst *shkp;
160 register boolean withbill;
162 for (; shkp; shkp = shkp->nmon) {
163 if (DEADMONSTER(shkp))
165 if (shkp->isshk && (ESHK(shkp)->billct || !withbill))
170 if (NOTANGRY(shkp)) {
171 if (ESHK(shkp)->surcharge)
174 if (!ESHK(shkp)->surcharge)
181 /* called in mon.c */
186 struct eshk *eshk = ESHK(mtmp);
187 struct mkroom *sroom = &rooms[eshk->shoproom - ROOMOFFSET];
192 /* [BUG: some of this should be done on the shop level */
193 /* even when the shk dies on a different level.] */
194 if (on_level(&eshk->shoplevel, &u.uz)) {
195 remove_damage(mtmp, TRUE);
196 sroom->resident = (struct monst *) 0;
197 if (!search_special(ANY_SHOP))
198 level.flags.has_shop = 0;
200 /* items on shop floor revert to ordinary objects */
201 for (sx = sroom->lx; sx <= sroom->hx; sx++)
202 for (sy = sroom->ly; sy <= sroom->hy; sy++)
203 for (otmp = level.objects[sx][sy]; otmp;
204 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 */
221 set_residency(shkp, zero_out)
222 register struct monst *shkp;
223 register boolean zero_out;
225 if (on_level(&(ESHK(shkp)->shoplevel), &u.uz))
226 rooms[ESHK(shkp)->shoproom - ROOMOFFSET].resident =
227 (zero_out) ? (struct monst *) 0 : shkp;
232 register struct monst *mtmp, *mtmp2;
234 rooms[ESHK(mtmp2)->shoproom - ROOMOFFSET].resident = mtmp2;
235 if (inhishop(mtmp) && *u.ushops == ESHK(mtmp)->shoproom) {
236 ESHK(mtmp2)->bill_p = &(ESHK(mtmp2)->bill[0]);
240 /* do shopkeeper specific structure munging -dlc */
242 restshk(shkp, ghostly)
247 struct eshk *eshkp = ESHK(shkp);
249 if (eshkp->bill_p != (struct bill_x *) -1000)
250 eshkp->bill_p = &eshkp->bill[0];
251 /* shoplevel can change as dungeons move around */
252 /* savebones guarantees that non-homed shk's will be gone */
254 assign_level(&eshkp->shoplevel, &u.uz);
255 if (ANGRY(shkp) && strncmpi(eshkp->customer, plname, PL_NSIZ))
261 /* Clear the unpaid bit on all of the objects in the list. */
264 register struct obj *list;
267 if (Has_contents(list))
268 clear_unpaid(list->cobj);
274 /* either you paid or left the shop or the shopkeeper died */
277 register struct monst *shkp;
279 register struct obj *obj;
280 register struct monst *mtmp;
282 /* FIXME: object handling should be limited to
283 items which are on this particular shk's bill */
285 clear_unpaid(invent);
287 clear_unpaid(level.buriedobjlist);
289 thrownobj->unpaid = 0;
291 kickedobj->unpaid = 0;
292 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
293 clear_unpaid(mtmp->minvent);
294 for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon)
295 clear_unpaid(mtmp->minvent);
297 while ((obj = billobjs) != 0) {
298 obj_extract_self(obj);
302 ESHK(shkp)->billct = 0;
303 ESHK(shkp)->credit = 0L;
304 ESHK(shkp)->debit = 0L;
305 ESHK(shkp)->loan = 0L;
311 register struct monst *shkp;
313 register int ct = ESHK(shkp)->billct;
314 register struct bill_x *bp = ESHK(shkp)->bill_p;
315 register long total = 0L;
318 total += bp->price * bp->bquan;
325 call_kops(shkp, nearshop)
326 register struct monst *shkp;
327 register boolean nearshop;
329 /* Keystone Kops srt@ucla */
330 register boolean nokops;
336 pline("An alarm sounds!");
338 nokops = ((mvitals[PM_KEYSTONE_KOP].mvflags & G_GONE)
339 && (mvitals[PM_KOP_SERGEANT].mvflags & G_GONE)
340 && (mvitals[PM_KOP_LIEUTENANT].mvflags & G_GONE)
341 && (mvitals[PM_KOP_KAPTAIN].mvflags & G_GONE));
343 if (!angry_guards(!!Deaf) && nokops) {
344 if (flags.verbose && !Deaf)
345 pline("But no one seems to respond to it.");
356 /* Create swarm around you, if you merely "stepped out" */
358 pline_The("Keystone Kops appear!");
365 pline_The("Keystone Kops are after you!");
366 /* Create swarm near down staircase (hinders return to level) */
370 /* Create swarm near shopkeeper (hinders return to shop) */
377 /* x,y is strictly inside shop */
384 rno = levl[x][y].roomno;
385 if ((rno < ROOMOFFSET) || levl[x][y].edge || !IS_SHOP(rno - ROOMOFFSET))
392 u_left_shop(leavestring, newlev)
401 * ((didn't leave outright) AND
402 * ((he is now strictly-inside the shop) OR
403 * (he wasn't strictly-inside last turn anyway)))
404 * THEN (there's nothing to do, so just return)
406 if (!*leavestring && (!levl[u.ux][u.uy].edge || levl[u.ux0][u.uy0].edge))
409 shkp = shop_keeper(*u.ushops0);
410 if (!shkp || !inhishop(shkp))
411 return; /* shk died, teleported, changed levels... */
414 if (!eshkp->billct && !eshkp->debit) /* bill is settled */
417 if (!*leavestring && !muteshk(shkp)) {
419 * Player just stepped onto shop-boundary (known from above logic).
420 * Try to intimidate him into paying his bill
422 verbalize(NOTANGRY(shkp) ? "%s! Please pay before leaving."
423 : "%s! Don't you leave without paying!",
428 if (rob_shop(shkp)) {
429 call_kops(shkp, (!newlev && levl[u.ux0][u.uy0].edge));
433 /* robbery from outside the shop via telekinesis or grappling hook */
435 remote_burglary(x, y)
441 shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
442 if (!shkp || !inhishop(shkp))
443 return; /* shk died, teleported, changed levels... */
446 if (!eshkp->billct && !eshkp->debit) /* bill is settled */
449 if (rob_shop(shkp)) {
450 /*[might want to set 2nd arg based on distance from shop doorway]*/
451 call_kops(shkp, FALSE);
455 /* shop merchandise has been taken; pay for it with any credit available;
456 return false if the debt is fully covered by credit, true otherwise */
465 rouse_shk(shkp, TRUE);
466 total = (addupbill(shkp) + eshkp->debit);
467 if (eshkp->credit >= total) {
468 Your("credit of %ld %s is used to cover your shopping bill.",
469 eshkp->credit, currency(eshkp->credit));
470 total = 0L; /* credit gets cleared by setpaid() */
472 You("escaped the shop without paying!");
473 total -= eshkp->credit;
479 /* by this point, we know an actual robbery has taken place */
480 eshkp->robbed += total;
481 You("stole %ld %s worth of merchandise.", total, currency(total));
482 if (!Role_if(PM_ROGUE)) /* stealing is unlawful */
483 adjalign(-sgn(u.ualign.type));
489 /* give a message when entering an untended shop (caller has verified that) */
491 deserted_shop(enterstring)
492 /*const*/ char *enterstring;
495 struct mkroom *r = &rooms[(int) *enterstring - ROOMOFFSET];
496 int x, y, m = 0, n = 0;
498 for (x = r->lx; x <= r->hx; ++x)
499 for (y = r->ly; y <= r->hy; ++y) {
500 if (x == u.ux && y == u.uy)
502 if ((mtmp = m_at(x, y)) != 0) {
504 if (sensemon(mtmp) || ((mtmp->m_ap_type == M_AP_NOTHING
505 || mtmp->m_ap_type == M_AP_MONSTER)
511 if (Blind && !(Blind_telepat || Detect_monsters))
512 ++n; /* force feedback to be less specific */
514 pline("This shop %s %s.", (m < n) ? "seems to be" : "is",
515 !n ? "deserted" : "untended");
519 u_entered_shop(enterstring)
523 register struct monst *shkp;
524 register struct eshk *eshkp;
525 static char empty_shops[5];
530 if (!(shkp = shop_keeper(*enterstring))) {
531 if (!index(empty_shops, *enterstring)
532 && in_rooms(u.ux, u.uy, SHOPBASE)
533 != in_rooms(u.ux0, u.uy0, SHOPBASE))
534 deserted_shop(enterstring);
535 Strcpy(empty_shops, u.ushops);
542 if (!inhishop(shkp)) {
543 /* dump core when referenced */
544 eshkp->bill_p = (struct bill_x *) -1000;
545 if (!index(empty_shops, *enterstring))
546 deserted_shop(enterstring);
547 Strcpy(empty_shops, u.ushops);
552 eshkp->bill_p = &(eshkp->bill[0]);
554 if ((!eshkp->visitct || *eshkp->customer)
555 && strncmpi(eshkp->customer, plname, PL_NSIZ)) {
556 /* You seem to be new here */
558 eshkp->following = 0;
559 (void) strncpy(eshkp->customer, plname, PL_NSIZ);
563 if (muteshk(shkp) || eshkp->following)
564 return; /* no dialog */
567 pline("%s senses your presence.", shkname(shkp));
568 verbalize("Invisible customers are not welcome!");
572 rt = rooms[*enterstring - ROOMOFFSET].rtype;
575 verbalize("So, %s, you dare return to %s %s?!", plname,
576 s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name);
577 } else if (eshkp->robbed) {
578 pline("%s mutters imprecations against shoplifters.", shkname(shkp));
580 verbalize("%s, %s! Welcome%s to %s %s!", Hello(shkp), plname,
581 eshkp->visitct++ ? " again" : "", s_suffix(shkname(shkp)),
582 shtypes[rt - SHOPBASE].name);
584 /* can't do anything about blocking if teleported in */
585 if (!inside_shop(u.ux, u.uy)) {
586 boolean should_block;
589 struct obj *pick = carrying(PICK_AXE),
590 *mattock = carrying(DWARVISH_MATTOCK);
592 if (pick || mattock) {
593 cnt = 1; /* so far */
594 if (pick && mattock) { /* carrying both types */
595 tool = "digging tool";
596 cnt = 2; /* `more than 1' is all that matters */
599 /* hack: `pick' already points somewhere into inventory */
600 while ((pick = pick->nobj) != 0)
601 if (pick->otyp == PICK_AXE)
603 } else { /* assert(mattock != 0) */
605 while ((mattock = mattock->nobj) != 0)
606 if (mattock->otyp == DWARVISH_MATTOCK)
608 /* [ALI] Shopkeeper identifies mattock(s) */
610 makeknown(DWARVISH_MATTOCK);
612 verbalize(NOTANGRY(shkp)
613 ? "Will you please leave your %s%s outside?"
614 : "Leave the %s%s outside.",
617 } else if (u.usteed) {
618 verbalize(NOTANGRY(shkp) ? "Will you please leave %s outside?"
619 : "Leave %s outside.",
624 (Fast && (sobj_at(PICK_AXE, u.ux, u.uy)
625 || sobj_at(DWARVISH_MATTOCK, u.ux, u.uy)));
628 (void) dochug(shkp); /* shk gets extra move */
633 /* called when removing a pick-axe or mattock from a container */
640 if (obj->unpaid || !is_pick(obj))
642 shkp = shop_keeper(*u.ushops);
643 if (shkp && inhishop(shkp) && !muteshk(shkp)) {
644 static NEARDATA long pickmovetime = 0L;
646 /* if you bring a sack of N picks into a shop to sell,
647 don't repeat this N times when they're taken out */
648 if (moves != pickmovetime)
649 verbalize("You sneaky %s! Get out of here with that pick!",
651 pickmovetime = moves;
656 Decide whether two unpaid items are mergable; caller is responsible for
657 making sure they're unpaid and the same type of object; we check the price
658 quoted by the shopkeeper and also that they both belong to the same shk.
661 same_price(obj1, obj2)
662 struct obj *obj1, *obj2;
664 register struct monst *shkp1, *shkp2;
665 struct bill_x *bp1 = 0, *bp2 = 0;
666 boolean are_mergable = FALSE;
668 /* look up the first object by finding shk whose bill it's on */
669 for (shkp1 = next_shkp(fmon, TRUE); shkp1;
670 shkp1 = next_shkp(shkp1->nmon, TRUE))
671 if ((bp1 = onbill(obj1, shkp1, TRUE)) != 0)
673 /* second object is probably owned by same shk; if not, look harder */
674 if (shkp1 && (bp2 = onbill(obj2, shkp1, TRUE)) != 0) {
677 for (shkp2 = next_shkp(fmon, TRUE); shkp2;
678 shkp2 = next_shkp(shkp2->nmon, TRUE))
679 if ((bp2 = onbill(obj2, shkp2, TRUE)) != 0)
684 impossible("same_price: object wasn't on any bill!");
686 are_mergable = (shkp1 == shkp2 && bp1->price == bp2->price);
691 * Figure out how much is owed to a given shopkeeper.
692 * At present, we ignore any amount robbed from the shop, to avoid
693 * turning the `$' command into a way to discover that the current
694 * level is bones data which has a shk on the warpath.
702 long debt = eshkp->debit;
704 for (bp = eshkp->bill_p, ct = eshkp->billct; ct > 0; bp++, ct--)
705 debt += bp->price * bp->bquan;
709 /* called in response to the `$' command */
711 shopper_financial_report()
713 struct monst *shkp, *this_shkp = shop_keeper(inside_shop(u.ux, u.uy));
718 eshkp = this_shkp ? ESHK(this_shkp) : 0;
719 if (eshkp && !(eshkp->credit || shop_debt(eshkp))) {
720 You("have no credit or debt in here.");
721 this_shkp = 0; /* skip first pass */
724 /* pass 0: report for the shop we're currently in, if any;
725 pass 1: report for all other shops on this level. */
726 for (pass = this_shkp ? 0 : 1; pass <= 1; pass++)
727 for (shkp = next_shkp(fmon, FALSE); shkp;
728 shkp = next_shkp(shkp->nmon, FALSE)) {
729 if ((shkp != this_shkp) ^ pass)
732 if ((amt = eshkp->credit) != 0)
733 You("have %ld %s credit at %s %s.", amt, currency(amt),
734 s_suffix(shkname(shkp)),
735 shtypes[eshkp->shoptype - SHOPBASE].name);
736 else if (shkp == this_shkp)
737 You("have no credit in here.");
738 if ((amt = shop_debt(eshkp)) != 0)
739 You("owe %s %ld %s.", shkname(shkp), amt, currency(amt));
740 else if (shkp == this_shkp)
741 You("don't owe any money here.");
747 register struct monst *mtmp;
749 struct eshk *eshkp = ESHK(mtmp);
751 return (index(in_rooms(mtmp->mx, mtmp->my, SHOPBASE), eshkp->shoproom)
752 && on_level(&eshkp->shoplevel, &u.uz));
760 rmno >= ROOMOFFSET ? rooms[rmno - ROOMOFFSET].resident : 0;
763 if (NOTANGRY(shkp)) {
764 if (ESHK(shkp)->surcharge)
767 if (!ESHK(shkp)->surcharge)
776 register struct mkroom *sroom;
778 register struct monst *mtmp = sroom->resident;
783 return (boolean) inhishop(mtmp);
786 STATIC_OVL struct bill_x *
787 onbill(obj, shkp, silent)
788 register struct obj *obj;
789 register struct monst *shkp;
790 register boolean silent;
793 register struct bill_x *bp = ESHK(shkp)->bill_p;
794 register int ct = ESHK(shkp)->billct;
797 if (bp->bo_id == obj->o_id) {
799 pline("onbill: paid obj on bill?");
804 if (obj->unpaid & !silent)
805 pline("onbill: unpaid obj not on bill?");
806 return (struct bill_x *) 0;
809 /* check whether an object or any of its contents belongs to a shop */
814 return (boolean) (obj->unpaid
815 || (Has_contents(obj) && count_unpaid(obj->cobj)));
818 /* Delete the contents of the given object. */
821 register struct obj *obj;
823 register struct obj *curr;
825 while ((curr = obj->cobj) != 0) {
826 obj_extract_self(curr);
827 obfree(curr, (struct obj *) 0);
831 /* called with two args on merge */
834 register struct obj *obj, *merge;
836 register struct bill_x *bp;
837 register struct bill_x *bpm;
838 register struct monst *shkp;
840 if (obj->otyp == LEASH && obj->leashmon)
842 if (obj->oclass == FOOD_CLASS)
843 food_disappears(obj);
844 if (obj->oclass == SPBOOK_CLASS)
845 book_disappears(obj);
846 if (Has_contents(obj))
847 delete_contents(obj);
851 /* look for a shopkeeper who owns this object */
852 for (shkp = next_shkp(fmon, TRUE); shkp;
853 shkp = next_shkp(shkp->nmon, TRUE))
854 if (onbill(obj, shkp, TRUE))
857 /* sanity check, more or less */
859 shkp = shop_keeper(*u.ushops);
861 * Note: `shkp = shop_keeper(*u.ushops)' used to be
862 * unconditional. But obfree() is used all over
863 * the place, so making its behavior be dependent
864 * upon player location doesn't make much sense.
867 if ((bp = onbill(obj, shkp, FALSE)) != 0) {
870 obj->unpaid = 0; /* only for doinvbill */
871 add_to_billobjs(obj);
874 bpm = onbill(merge, shkp, FALSE);
876 /* this used to be a rename */
877 impossible("obfree: not on bill??");
880 /* this was a merger */
881 bpm->bquan += bp->bquan;
882 ESHK(shkp)->billct--;
885 /* DRS/NS 2.2.6 messes up -- Peter Kendell */
886 int indx = ESHK(shkp)->billct;
888 *bp = ESHK(shkp)->bill_p[indx];
891 *bp = ESHK(shkp)->bill_p[ESHK(shkp)->billct];
895 if (obj->owornmask) {
896 impossible("obfree: deleting worn obj (%d: %ld)", obj->otyp,
898 /* unfortunately at this point we don't know whether worn mask
899 applied to hero or a monster or perhaps something bogus, so
900 can't call remove_worn_item() to get <X>_off() side-effects */
907 check_credit(tmp, shkp)
909 register struct monst *shkp;
911 long credit = ESHK(shkp)->credit;
914 ; /* nothing to do; just 'return tmp;' */
915 } else if (credit >= tmp) {
916 pline_The("price is deducted from your credit.");
917 ESHK(shkp)->credit -= tmp;
920 pline_The("price is partially covered by your credit.");
921 ESHK(shkp)->credit = 0L;
930 register struct monst *shkp;
932 long robbed = ESHK(shkp)->robbed;
933 long balance = ((tmp <= 0L) ? tmp : check_credit(tmp, shkp));
936 money2mon(shkp, balance);
937 else if (balance < 0)
938 money2u(shkp, -balance);
944 ESHK(shkp)->robbed = robbed;
948 /* return shkp to home position */
950 home_shk(shkp, killkops)
951 register struct monst *shkp;
952 register boolean killkops;
954 register xchar x = ESHK(shkp)->shk.x, y = ESHK(shkp)->shk.y;
956 (void) mnearto(shkp, x, y, TRUE);
957 level.flags.has_shop = 1;
962 after_shk_move(shkp);
968 register struct monst *shkp;
970 for (shkp = next_shkp(fmon, FALSE); shkp;
971 shkp = next_shkp(shkp->nmon, FALSE))
977 /* remove previously applied surcharge from all billed items */
980 register struct monst *shkp;
982 NOTANGRY(shkp) = TRUE; /* make peaceful */
983 if (ESHK(shkp)->surcharge) {
984 register struct bill_x *bp = ESHK(shkp)->bill_p;
985 register int ct = ESHK(shkp)->billct;
987 ESHK(shkp)->surcharge = FALSE;
989 register long reduction = (bp->price + 3L) / 4L;
990 bp->price -= reduction; /* undo 33% increase */
996 /* add aggravation surcharge to all billed items */
999 register struct monst *shkp;
1001 NOTANGRY(shkp) = FALSE; /* make angry */
1002 if (!ESHK(shkp)->surcharge) {
1003 register struct bill_x *bp = ESHK(shkp)->bill_p;
1004 register int ct = ESHK(shkp)->billct;
1006 ESHK(shkp)->surcharge = TRUE;
1008 register long surcharge = (bp->price + 2L) / 3L;
1009 bp->price += surcharge;
1015 /* wakeup and/or unparalyze shopkeeper */
1017 rouse_shk(shkp, verbosely)
1021 if (!shkp->mcanmove || shkp->msleeping) {
1022 /* greed induced recovery... */
1023 if (verbosely && canspotmon(shkp))
1024 pline("%s %s.", Monnam(shkp),
1025 shkp->msleeping ? "wakes up" : "can move again");
1026 shkp->msleeping = 0;
1033 make_happy_shk(shkp, silentkops)
1034 register struct monst *shkp;
1035 register boolean silentkops;
1037 boolean wasmad = ANGRY(shkp);
1038 struct eshk *eshkp = ESHK(shkp);
1041 eshkp->following = 0;
1043 if (!Role_if(PM_ROGUE))
1044 adjalign(sgn(u.ualign.type));
1045 if (!inhishop(shkp)) {
1046 char shk_nam[BUFSZ];
1047 boolean vanished = canseemon(shkp);
1049 Strcpy(shk_nam, mon_nam(shkp));
1050 if (on_level(&eshkp->shoplevel, &u.uz)) {
1051 home_shk(shkp, FALSE);
1052 /* didn't disappear if shk can still be seen */
1053 if (canseemon(shkp))
1056 /* if sensed, does disappear regardless whether seen */
1059 /* can't act as porter for the Amulet, even if shk
1060 happens to be going farther down rather than up */
1061 mdrop_special_objs(shkp);
1062 /* arrive near shop's door */
1063 migrate_to_level(shkp, ledger_no(&eshkp->shoplevel),
1064 MIGR_APPROX_XY, &eshkp->shd);
1065 /* dismiss kops on that level when shk arrives */
1066 eshkp->dismiss_kops = TRUE;
1069 pline("Satisfied, %s suddenly disappears!", shk_nam);
1071 pline("%s calms down.", Monnam(shkp));
1073 make_happy_shoppers(silentkops);
1076 /* called by make_happy_shk() and also by losedogs() for migrating shk */
1078 make_happy_shoppers(silentkops)
1081 if (!angry_shk_exists()) {
1082 kops_gone(silentkops);
1089 register struct monst *shkp;
1095 (void) strncpy(ESHK(shkp)->customer, plname, PL_NSIZ);
1096 ESHK(shkp)->following = 1;
1099 /* used when the shkp is teleported or falls (ox == 0) out of his shop,
1100 * or when the player is not on a costly_spot and he
1101 * damages something inside the shop. these conditions
1102 * must be checked by the calling function.
1105 make_angry_shk(shkp, ox, oy)
1106 register struct monst *shkp;
1107 register xchar ox, oy;
1110 struct eshk *eshkp = ESHK(shkp);
1112 /* all pending shop transactions are now "past due" */
1113 if (eshkp->billct || eshkp->debit || eshkp->loan || eshkp->credit) {
1114 eshkp->robbed += (addupbill(shkp) + eshkp->debit + eshkp->loan);
1115 eshkp->robbed -= eshkp->credit;
1116 if (eshkp->robbed < 0L)
1118 /* billct, debit, loan, and credit will be cleared by setpaid */
1122 /* If you just used a wand of teleportation to send the shk away, you
1123 might not be able to see her any more. Monnam would yield "it",
1124 which makes this message look pretty silly, so temporarily restore
1125 her original location during the call to Monnam. */
1126 sx = shkp->mx, sy = shkp->my;
1127 if (isok(ox, oy) && cansee(ox, oy) && !cansee(sx, sy))
1128 shkp->mx = ox, shkp->my = oy;
1129 pline("%s %s!", Monnam(shkp), !ANGRY(shkp) ? "gets angry" : "is furious");
1130 shkp->mx = sx, shkp->my = sy;
1134 STATIC_VAR const char no_money[] = "Moreover, you%s have no money.";
1135 STATIC_VAR const char not_enough_money[] =
1136 "Besides, you don't have enough to interest %s.";
1139 cheapest_item(shkp) /* delivers the cheapest item on the list */
1140 register struct monst *shkp;
1142 register int ct = ESHK(shkp)->billct;
1143 register struct bill_x *bp = ESHK(shkp)->bill_p;
1144 register long gmin = (bp->price * bp->bquan);
1147 if (bp->price * bp->bquan < gmin)
1148 gmin = bp->price * bp->bquan;
1157 register struct eshk *eshkp;
1158 register struct monst *shkp;
1159 struct monst *nxtm, *resident;
1162 int pass, tmp, sk = 0, seensk = 0;
1163 boolean paid = FALSE, stashed_gold = (hidden_gold() > 0L);
1167 /* Find how many shk's there are, how many are in
1168 * sight, and are you in a shop room with one.
1170 nxtm = resident = 0;
1171 for (shkp = next_shkp(fmon, FALSE); shkp;
1172 shkp = next_shkp(shkp->nmon, FALSE)) {
1174 if (ANGRY(shkp) && distu(shkp->mx, shkp->my) <= 2)
1176 if (canspotmon(shkp))
1178 if (inhishop(shkp) && (*u.ushops == ESHK(shkp)->shoproom))
1182 if (nxtm) { /* Player should always appease an */
1183 shkp = nxtm; /* irate shk standing next to them. */
1187 if ((!sk && (!Blind || Blind_telepat)) || (!Blind && !seensk)) {
1188 There("appears to be no shopkeeper here to receive your payment.");
1197 /* The usual case. Allow paying at a distance when
1198 * inside a tended shop. Should we change that?
1200 if (sk == 1 && resident) {
1206 for (shkp = next_shkp(fmon, FALSE); shkp;
1207 shkp = next_shkp(shkp->nmon, FALSE))
1208 if (canspotmon(shkp))
1210 if (shkp != resident && distu(shkp->mx, shkp->my) > 2) {
1211 pline("%s is not near enough to receive your payment.",
1223 if (getpos(&cc, TRUE, "the creature you want to pay") < 0)
1224 return 0; /* player pressed ESC */
1228 pline("Try again...");
1231 if (u.ux == cx && u.uy == cy) {
1232 You("are generous to yourself.");
1235 mtmp = m_at(cx, cy);
1237 There("is no one there to receive your payment.");
1241 pline("%s is not interested in your payment.", Monnam(mtmp));
1244 if (mtmp != resident && distu(mtmp->mx, mtmp->my) > 2) {
1245 pline("%s is too far to receive your payment.", Monnam(mtmp));
1252 debugpline0("dopay: null shkp.");
1257 ltmp = eshkp->robbed;
1259 /* wake sleeping shk when someone who owes money offers payment */
1260 if (ltmp || eshkp->billct || eshkp->debit)
1261 rouse_shk(shkp, TRUE);
1263 if (!shkp->mcanmove || shkp->msleeping) { /* still asleep/paralyzed */
1264 pline("%s %s.", Monnam(shkp),
1265 rn2(2) ? "seems to be napping" : "doesn't respond");
1269 if (shkp != resident && NOTANGRY(shkp)) {
1270 umoney = money_cnt(invent);
1272 You("do not owe %s anything.", mon_nam(shkp));
1274 You("%shave no money.", stashed_gold ? "seem to " : "");
1276 pline("But you have some gold stashed away.");
1278 if (umoney > ltmp) {
1279 You("give %s the %ld gold piece%s %s asked for.",
1280 shkname(shkp), ltmp, plur(ltmp), mhe(shkp));
1283 You("give %s all your%s gold.", shkname(shkp),
1284 stashed_gold ? " openly kept" : "");
1287 pline("But you have hidden gold!");
1289 if ((umoney < ltmp / 2L) || (umoney < ltmp && stashed_gold))
1290 pline("Unfortunately, %s doesn't look satisfied.", mhe(shkp));
1292 make_happy_shk(shkp, FALSE);
1297 /* ltmp is still eshkp->robbed here */
1298 if (!eshkp->billct && !eshkp->debit) {
1299 umoney = money_cnt(invent);
1300 if (!ltmp && NOTANGRY(shkp)) {
1301 You("do not owe %s anything.", shkname(shkp));
1303 pline(no_money, stashed_gold ? " seem to" : "");
1305 pline("%s is after blood, not money!", shkname(shkp));
1306 if (umoney < ltmp / 2L || (umoney < ltmp && stashed_gold)) {
1308 pline(no_money, stashed_gold ? " seem to" : "");
1310 pline(not_enough_money, mhim(shkp));
1313 pline("But since %s shop has been robbed recently,", mhis(shkp));
1314 pline("you %scompensate %s for %s losses.",
1315 (umoney < ltmp) ? "partially " : "", shkname(shkp),
1317 pay(umoney < ltmp ? umoney : ltmp, shkp);
1318 make_happy_shk(shkp, FALSE);
1320 /* shopkeeper is angry, but has not been robbed --
1321 * door broken, attacked, etc. */
1322 pline("%s is after your hide, not your money!", Monnam(shkp));
1323 if (umoney < 1000L) {
1325 pline(no_money, stashed_gold ? " seem to" : "");
1327 pline(not_enough_money, mhim(shkp));
1330 You("try to appease %s by giving %s 1000 gold pieces.",
1331 x_monnam(shkp, ARTICLE_THE, "angry", 0, FALSE), mhim(shkp));
1333 if (strncmp(eshkp->customer, plname, PL_NSIZ) || rn2(3))
1334 make_happy_shk(shkp, FALSE);
1336 pline("But %s is as angry as ever.", shkname(shkp));
1340 if (shkp != resident) {
1341 impossible("dopay: not to shopkeeper?");
1346 /* pay debt, if any, first */
1348 long dtmp = eshkp->debit;
1349 long loan = eshkp->loan;
1351 umoney = money_cnt(invent);
1352 Sprintf(sbuf, "You owe %s %ld %s ", shkname(shkp), dtmp,
1356 Strcat(sbuf, "you picked up in the store.");
1359 "for gold picked up and the use of merchandise.");
1361 Strcat(sbuf, "for the use of merchandise.");
1363 if (umoney + eshkp->credit < dtmp) {
1364 pline("But you don't%s have enough gold%s.",
1365 stashed_gold ? " seem to" : "",
1366 eshkp->credit ? " or credit" : "");
1369 if (eshkp->credit >= dtmp) {
1370 eshkp->credit -= dtmp;
1373 Your("debt is covered by your credit.");
1374 } else if (!eshkp->credit) {
1375 money2mon(shkp, dtmp);
1378 You("pay that debt.");
1381 dtmp -= eshkp->credit;
1383 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 umoney = money_cnt(invent);
1398 if (!umoney && !eshkp->credit) {
1399 You("%shave no money or credit%s.",
1400 stashed_gold ? "seem to " : "", paid ? " left" : "");
1403 if ((umoney + eshkp->credit) < cheapest_item(shkp)) {
1404 You("don't have enough money to buy%s the item%s you picked.",
1405 eshkp->billct > 1 ? " any of" : "", plur(eshkp->billct));
1407 pline("Maybe you have some gold stashed away?");
1411 /* this isn't quite right; it itemizes without asking if the
1412 * single item on the bill is partly used up and partly unpaid */
1413 iprompt = (eshkp->billct > 1 ? ynq("Itemized billing?") : 'y');
1414 itemize = (iprompt == 'y');
1418 for (pass = 0; pass <= 1; pass++) {
1420 while (tmp < eshkp->billct) {
1422 register struct bill_x *bp = &(eshkp->bill_p[tmp]);
1424 /* find the object on one of the lists */
1425 if ((otmp = bp_to_obj(bp)) != 0) {
1426 /* if completely used up, object quantity is stale;
1427 restoring it to its original value here avoids
1428 making the partly-used-up code more complicated */
1430 otmp->quan = bp->bquan;
1432 impossible("Shopkeeper administration out of order.");
1433 setpaid(shkp); /* be nice to the player */
1436 if (pass == bp->useup && otmp->quan == bp->bquan) {
1437 /* pay for used-up items on first pass and others
1438 * on second, so player will be stuck in the store
1439 * less often; things which are partly used up
1440 * are processed on both passes */
1443 switch (dopayobj(shkp, bp, &otmp, pass, itemize)) {
1448 goto thanks; /*break*/
1463 *bp = eshkp->bill_p[--eshkp->billct];
1469 update_inventory(); /* Done in dopayobj() if itemize. */
1471 if (!ANGRY(shkp) && paid && !muteshk(shkp))
1472 verbalize("Thank you for shopping in %s %s!", s_suffix(shkname(shkp)),
1473 shtypes[eshkp->shoptype - SHOPBASE].name);
1477 /* return 2 if used-up portion paid
1478 * 1 if paid successfully
1479 * 0 if not enough money
1480 * -1 if skip this object
1481 * -2 if no money/credit left
1484 dopayobj(shkp, bp, obj_p, which, itemize)
1485 register struct monst *shkp;
1486 register struct bill_x *bp;
1488 int which; /* 0 => used-up item, 1 => other (unpaid or lost) */
1491 register struct obj *obj = *obj_p;
1492 long ltmp, quan, save_quan;
1493 long umoney = money_cnt(invent);
1495 boolean stashed_gold = (hidden_gold() > 0L), consumed = (which == 0);
1497 if (!obj->unpaid && !bp->useup) {
1498 impossible("Paid object on bill??");
1501 if (itemize && umoney + ESHK(shkp)->credit == 0L) {
1502 You("%shave no money or credit left.",
1503 stashed_gold ? "seem to " : "");
1506 /* we may need to temporarily adjust the object, if part of the
1507 original quantity has been used up but part remains unpaid */
1508 save_quan = obj->quan;
1510 /* either completely used up (simple), or split needed */
1512 if (quan > obj->quan) /* difference is amount used up */
1515 /* dealing with ordinary unpaid item */
1518 obj->quan = quan; /* to be used by doname() */
1519 obj->unpaid = 0; /* ditto */
1520 iflags.suppress_price++; /* affects containers */
1521 ltmp = bp->price * quan;
1522 buy = PAY_BUY; /* flag; if changed then return early */
1525 char qbuf[BUFSZ], qsfx[BUFSZ];
1527 Sprintf(qsfx, " for %ld %s. Pay?", ltmp, currency(ltmp));
1528 (void) safe_qbuf(qbuf, (char *) 0, qsfx, obj,
1529 (quan == 1L) ? Doname2 : doname, ansimpleoname,
1530 (quan == 1L) ? "that" : "those");
1531 if (yn(qbuf) == 'n') {
1532 buy = PAY_SKIP; /* don't want to buy */
1533 } else if (quan < bp->bquan && !consumed) { /* partly used goods */
1534 obj->quan = bp->bquan - save_quan; /* used up amount */
1535 verbalize("%s for the other %s before buying %s.",
1536 ANGRY(shkp) ? "Pay" : "Please pay",
1537 simpleonames(obj), /* short name suffices */
1538 save_quan > 1L ? "these" : "this one");
1539 buy = PAY_SKIP; /* shk won't sell */
1542 if (buy == PAY_BUY && umoney + ESHK(shkp)->credit < ltmp) {
1543 You("don't%s have gold%s enough to pay for %s.",
1544 stashed_gold ? " seem to" : "",
1545 (ESHK(shkp)->credit > 0L) ? " or credit" : "",
1546 thesimpleoname(obj));
1547 buy = itemize ? PAY_SKIP : PAY_CANT;
1550 if (buy != PAY_BUY) {
1551 /* restore unpaid object to original state */
1552 obj->quan = save_quan;
1554 iflags.suppress_price--;
1559 shk_names_obj(shkp, obj,
1560 consumed ? "paid for %s at a cost of %ld gold piece%s.%s"
1561 : "bought %s for %ld gold piece%s.%s",
1563 obj->quan = save_quan; /* restore original count */
1564 /* quan => amount just bought, save_quan => remaining unpaid count */
1566 if (quan != bp->bquan) {
1567 /* eliminate used-up portion; remainder is still unpaid */
1568 bp->bquan = obj->quan;
1572 } else { /* completely used-up, so get rid of it */
1573 obj_extract_self(obj);
1574 /* assert( obj == *obj_p ); */
1576 *obj_p = 0; /* destroy pointer to freed object */
1579 update_inventory(); /* Done just once in dopay() if !itemize. */
1580 iflags.suppress_price--;
1584 static struct repo { /* repossession context */
1585 struct monst *shopkeeper;
1589 /* routine called after dying (or quitting) */
1592 int croaked; /* -1: escaped dungeon; 0: quit; 1: died */
1594 struct monst *mtmp, *mtmp2, *firstshk, *resident, *creditor, *hostile,
1597 boolean taken = FALSE, local;
1600 /* if we escaped from the dungeon, shopkeepers can't reach us;
1601 shops don't occur on level 1, but this could happen if hero
1602 level teleports out of the dungeon and manages not to die */
1605 /* [should probably also return false when dead hero has been
1606 petrified since shk shouldn't be able to grab inventory
1607 which has been shut inside a statue] */
1609 /* this is where inventory will end up if any shk takes it */
1610 repo.location.x = repo.location.y = 0;
1611 repo.shopkeeper = 0;
1614 * Scan all shopkeepers on the level, to prioritize them:
1615 * 1) keeper of shop hero is inside and who is owed money,
1616 * 2) keeper of shop hero is inside who isn't owed any money,
1617 * 3) other shk who is owed money, 4) other shk who is angry,
1618 * 5) any shk local to this level, and if none is found,
1619 * 6) first shk on monster list (last resort; unlikely, since
1620 * any nonlocal shk will probably be in the owed category
1621 * and almost certainly be in the angry category).
1623 resident = creditor = hostile = localshk = (struct monst *) 0;
1624 for (mtmp = next_shkp(fmon, FALSE); mtmp;
1625 mtmp = next_shkp(mtmp2, FALSE)) {
1628 local = on_level(&eshkp->shoplevel, &u.uz);
1629 if (local && index(u.ushops, eshkp->shoproom)) {
1630 /* inside this shk's shop [there might be more than one
1631 resident shk if hero is standing in a breech of a shared
1632 wall, so give priority to one who's also owed money] */
1633 if (!resident || eshkp->billct || eshkp->debit || eshkp->robbed)
1635 } else if (eshkp->billct || eshkp->debit || eshkp->robbed) {
1636 /* owe this shopkeeper money (might also owe others) */
1639 } else if (eshkp->following || ANGRY(mtmp)) {
1640 /* this shopkeeper is antagonistic (others might be too) */
1644 /* this shopkeeper's shop is on current level */
1650 /* give highest priority shopkeeper first crack */
1651 firstshk = resident ? resident
1652 : creditor ? creditor
1657 taken = inherits(firstshk, numsk, croaked);
1660 /* now handle the rest */
1661 for (mtmp = next_shkp(fmon, FALSE); mtmp;
1662 mtmp = next_shkp(mtmp2, FALSE)) {
1665 local = on_level(&eshkp->shoplevel, &u.uz);
1666 if (mtmp != firstshk) {
1668 taken |= inherits(mtmp, numsk, croaked);
1670 /* for bones: we don't want a shopless shk around */
1678 inherits(shkp, numsk, croaked)
1685 struct eshk *eshkp = ESHK(shkp);
1686 boolean take = FALSE, taken = FALSE;
1687 unsigned save_minvis = shkp->minvis;
1688 int roomno = *u.ushops;
1692 /* The simplifying principle is that first-come
1693 already took everything you had. */
1695 if (cansee(shkp->mx, shkp->my) && croaked) {
1697 if (has_head(shkp->data) && !rn2(2))
1698 Sprintf(takes, ", shakes %s %s,", mhis(shkp),
1699 mbodypart(shkp, HEAD));
1700 pline("%s %slooks at your corpse%s and %s.", Monnam(shkp),
1701 (!shkp->mcanmove || shkp->msleeping) ? "wakes up, " : "",
1702 takes, !inhishop(shkp) ? "disappears" : "sighs");
1704 rouse_shk(shkp, FALSE); /* wake shk for bones */
1705 taken = (roomno == eshkp->shoproom);
1709 /* get one case out of the way: you die in the shop, the */
1710 /* shopkeeper is peaceful, nothing stolen, nothing owed. */
1711 if (roomno == eshkp->shoproom && inhishop(shkp) && !eshkp->billct
1712 && !eshkp->robbed && !eshkp->debit && NOTANGRY(shkp)
1713 && !eshkp->following) {
1714 taken = (invent != 0);
1716 pline("%s gratefully inherits all your possessions.",
1722 if (eshkp->billct || eshkp->debit || eshkp->robbed) {
1723 if (roomno == eshkp->shoproom && inhishop(shkp))
1724 loss = addupbill(shkp) + eshkp->debit;
1725 if (loss < eshkp->robbed)
1726 loss = eshkp->robbed;
1730 if (eshkp->following || ANGRY(shkp) || take) {
1733 umoney = money_cnt(invent);
1735 if (!shkp->mcanmove || shkp->msleeping)
1736 Strcat(takes, "wakes up and ");
1737 if (distu(shkp->mx, shkp->my) > 2)
1738 Strcat(takes, "comes and ");
1739 Strcat(takes, "takes");
1741 if (loss > umoney || !loss || roomno == eshkp->shoproom) {
1742 eshkp->robbed -= umoney;
1743 if (eshkp->robbed < 0L)
1746 money2mon(shkp, umoney);
1748 pline("%s %s all your possessions.", shkname(shkp), takes);
1750 /* where to put player's invent (after disclosure) */
1753 money2mon(shkp, loss);
1755 pline("%s %s the %ld %s %sowed %s.", Monnam(shkp), takes, loss,
1757 strncmp(eshkp->customer, plname, PL_NSIZ) ? "" : "you ",
1758 shkp->female ? "her" : "him");
1759 /* shopkeeper has now been paid in full */
1761 eshkp->following = 0;
1765 /* in case we create bones */
1766 rouse_shk(shkp, FALSE); /* wake up */
1767 if (!inhishop(shkp))
1768 home_shk(shkp, FALSE);
1771 shkp->minvis = save_minvis;
1780 register xchar ox, oy;
1781 struct eshk *eshkp = ESHK(shkp);
1783 /* if you're not in this shk's shop room, or if you're in its doorway
1784 or entry spot, then your gear gets dumped all the way inside */
1785 if (*u.ushops != eshkp->shoproom || IS_DOOR(levl[u.ux][u.uy].typ)
1786 || (u.ux == eshkp->shk.x && u.uy == eshkp->shk.y)) {
1787 /* shk.x,shk.y is the position immediately in
1788 * front of the door -- move in one more space
1792 ox += sgn(ox - eshkp->shd.x);
1793 oy += sgn(oy - eshkp->shd.y);
1794 } else { /* already inside this shk's shop */
1798 /* finish_paybill will deposit invent here */
1799 repo.location.x = ox;
1800 repo.location.y = oy;
1801 repo.shopkeeper = shkp;
1804 /* called at game exit, after inventory disclosure but before making bones */
1808 struct monst *shkp = repo.shopkeeper;
1809 int ox = repo.location.x, oy = repo.location.y;
1811 #if 0 /* don't bother */
1812 if (ox == 0 && oy == 0)
1813 impossible("finish_paybill: no location");
1815 /* normally done by savebones(), but that's too late in this case */
1817 /* if hero has any gold left, take it into shopkeeper's possession */
1819 long umoney = money_cnt(invent);
1822 money2mon(shkp, umoney);
1824 /* transfer rest of the character's inventory to the shop floor */
1825 drop_upon_death((struct monst *) 0, (struct obj *) 0, ox, oy);
1828 /* find obj on one of the lists */
1829 STATIC_OVL struct obj *
1831 register struct bill_x *bp;
1833 register struct obj *obj;
1834 register unsigned int id = bp->bo_id;
1837 obj = o_on(id, billobjs);
1844 * Look for o_id on all lists but billobj. Return obj or NULL if not found.
1845 * Its OK for restore_timers() to call this function, there should not
1846 * be any timeouts on the billobjs chain.
1853 struct monst *mon, *mmtmp[3];
1856 /* first check various obj lists directly */
1857 if ((obj = o_on(id, invent)) != 0)
1859 if ((obj = o_on(id, fobj)) != 0)
1861 if ((obj = o_on(id, level.buriedobjlist)) != 0)
1863 if ((obj = o_on(id, migrating_objs)) != 0)
1866 /* not found yet; check inventory for members of various monst lists */
1868 mmtmp[1] = migrating_mons;
1869 mmtmp[2] = mydogs; /* for use during level changes */
1870 for (i = 0; i < 3; i++)
1871 for (mon = mmtmp[i]; mon; mon = mon->nmon)
1872 if ((obj = o_on(id, mon->minvent)) != 0)
1875 /* not found at all */
1876 return (struct obj *) 0;
1879 /* Returns the price of an arbitrary item in the shop.
1880 Returns 0 if the item doesn't belong to a shopkeeper. */
1882 get_cost_of_shop_item(obj)
1883 register struct obj *obj;
1890 && obj->oclass != COIN_CLASS
1891 && obj != uball && obj != uchain
1892 && get_obj_location(obj, &x, &y, 0)
1894 || (obj->where == OBJ_FLOOR
1895 && !obj->no_charge && costly_spot(x, y)))
1896 && (shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0
1897 && inhishop(shkp)) {
1898 cost = obj->quan * get_cost(obj, shkp);
1899 if (Has_contents(obj))
1900 cost += contained_cost(obj, shkp, 0L, FALSE, FALSE);
1905 /* calculate the value that the shk will charge for [one of] an object */
1908 register struct obj *obj;
1909 register struct monst *shkp; /* if angry, impose a surcharge */
1911 long tmp = getprice(obj, FALSE),
1912 /* used to perform a single calculation even when multiple
1913 adjustments (unID'd, dunce/tourist, charisma) are made */
1914 multiplier = 1L, divisor = 1L;
1918 /* shopkeeper may notice if the player isn't very knowledgeable -
1919 especially when gem prices are concerned */
1920 if (!obj->dknown || !objects[obj->otyp].oc_name_known) {
1921 if (obj->oclass == GEM_CLASS
1922 && objects[obj->otyp].oc_material == GLASS) {
1924 /* get a value that's 'random' from game to game, but the
1925 same within the same game */
1926 boolean pseudorand =
1927 (((int) ubirthday % obj->otyp) >= obj->otyp / 2);
1929 /* all gems are priced high - real or not */
1930 switch (obj->otyp - LAST_GEM) {
1932 i = pseudorand ? DIAMOND : OPAL;
1935 i = pseudorand ? SAPPHIRE : AQUAMARINE;
1938 i = pseudorand ? RUBY : JASPER;
1940 case 4: /* yellowish brown */
1941 i = pseudorand ? AMBER : TOPAZ;
1943 case 5: /* orange */
1944 i = pseudorand ? JACINTH : AGATE;
1946 case 6: /* yellow */
1947 i = pseudorand ? CITRINE : CHRYSOBERYL;
1950 i = pseudorand ? BLACK_OPAL : JET;
1953 i = pseudorand ? EMERALD : JADE;
1955 case 9: /* violet */
1956 i = pseudorand ? AMETHYST : FLUORITE;
1959 impossible("bad glass gem %d?", obj->otyp);
1963 tmp = (long) objects[i].oc_cost;
1964 } else if (!(obj->o_id % 4)) {
1965 /* unid'd, arbitrarily impose surcharge: tmp *= 4/3 */
1970 if (uarmh && uarmh->otyp == DUNCE_CAP)
1971 multiplier *= 4L, divisor *= 3L;
1972 else if ((Role_if(PM_TOURIST) && u.ulevel < (MAXULEV / 2))
1973 || (uarmu && !uarm && !uarmc)) /* touristy shirt visible */
1974 multiplier *= 4L, divisor *= 3L;
1976 if (ACURR(A_CHA) > 18)
1978 else if (ACURR(A_CHA) == 18)
1979 multiplier *= 2L, divisor *= 3L;
1980 else if (ACURR(A_CHA) >= 16)
1981 multiplier *= 3L, divisor *= 4L;
1982 else if (ACURR(A_CHA) <= 5)
1984 else if (ACURR(A_CHA) <= 7)
1985 multiplier *= 3L, divisor *= 2L;
1986 else if (ACURR(A_CHA) <= 10)
1987 multiplier *= 4L, divisor *= 3L;
1989 /* tmp = (tmp * multiplier) / divisor [with roundoff tweak] */
1992 /* tmp = (((tmp * 10) / divisor) + 5) / 10 */
2001 /* the artifact prices in artilist[] are also used as a score bonus;
2002 inflate their shop price here without affecting score calculation */
2006 /* anger surcharge should match rile_shk's, so we do it separately
2007 from the multiplier/divisor calculation */
2008 if (shkp && ESHK(shkp)->surcharge)
2009 tmp += (tmp + 2L) / 3L;
2013 /* returns the price of a container's content. the price
2014 * of the "top" container is added in the calling functions.
2015 * a different price quoted for selling as vs. buying.
2018 contained_cost(obj, shkp, price, usell, unpaid_only)
2023 boolean unpaid_only;
2025 register struct obj *otmp;
2027 /* price of contained objects; "top" container handled by caller */
2028 for (otmp = obj->cobj; otmp; otmp = otmp->nobj) {
2029 if (otmp->oclass == COIN_CLASS)
2033 if (saleable(shkp, otmp) && !otmp->unpaid
2034 && otmp->oclass != BALL_CLASS
2035 && !(otmp->oclass == FOOD_CLASS && otmp->oeaten)
2036 && !(Is_candle(otmp)
2037 && otmp->age < 20L * (long) objects[otmp->otyp].oc_cost))
2038 price += set_cost(otmp, shkp);
2039 } else if (!otmp->no_charge && (otmp->unpaid || !unpaid_only)) {
2040 price += get_cost(otmp, shkp) * otmp->quan;
2043 if (Has_contents(otmp))
2044 price = contained_cost(otmp, shkp, price, usell, unpaid_only);
2052 register struct obj *obj;
2054 register struct obj *otmp;
2055 register long value = 0L;
2057 /* accumulate contained gold */
2058 for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
2059 if (otmp->oclass == COIN_CLASS)
2060 value += otmp->quan;
2061 else if (Has_contents(otmp))
2062 value += contained_gold(otmp);
2068 dropped_container(obj, shkp, sale)
2069 register struct obj *obj;
2070 register struct monst *shkp;
2071 register boolean sale;
2073 register struct obj *otmp;
2075 /* the "top" container is treated in the calling fn */
2076 for (otmp = obj->cobj; otmp; otmp = otmp->nobj) {
2077 if (otmp->oclass == COIN_CLASS)
2080 if (!otmp->unpaid && !(sale && saleable(shkp, otmp)))
2081 otmp->no_charge = 1;
2083 if (Has_contents(otmp))
2084 dropped_container(otmp, shkp, sale);
2089 picked_container(obj)
2090 register struct obj *obj;
2092 register struct obj *otmp;
2094 /* the "top" container is treated in the calling fn */
2095 for (otmp = obj->cobj; otmp; otmp = otmp->nobj) {
2096 if (otmp->oclass == COIN_CLASS)
2099 if (otmp->no_charge)
2100 otmp->no_charge = 0;
2102 if (Has_contents(otmp))
2103 picked_container(otmp);
2108 special_stock(obj, shkp, quietly)
2113 /* for unique situations */
2114 if (ESHK(shkp)->shoptype == CANDLESHOP
2115 && obj->otyp == CANDELABRUM_OF_INVOCATION) {
2117 if (is_izchak(shkp, TRUE) && !u.uevent.invoked) {
2118 verbalize("No thanks, I'd hang onto that if I were you.");
2121 "You'll need %d%s candle%s to go along with it.",
2122 (7 - obj->spe), (obj->spe > 0) ? " more" : "",
2123 plur(7 - obj->spe));
2124 /* [what if hero is already carrying enough candles?
2125 should Izchak explain how to attach them instead] */
2127 verbalize("I won't stock that. Take it out of here!");
2135 /* calculate how much the shk will pay when buying [all of] an object */
2138 register struct obj *obj;
2139 register struct monst *shkp;
2141 long tmp = getprice(obj, TRUE) * obj->quan, multiplier = 1L, divisor = 1L;
2143 if (uarmh && uarmh->otyp == DUNCE_CAP)
2145 else if ((Role_if(PM_TOURIST) && u.ulevel < (MAXULEV / 2))
2146 || (uarmu && !uarm && !uarmc)) /* touristy shirt visible */
2151 /* shopkeeper may notice if the player isn't very knowledgeable -
2152 especially when gem prices are concerned */
2153 if (!obj->dknown || !objects[obj->otyp].oc_name_known) {
2154 if (obj->oclass == GEM_CLASS) {
2155 /* different shop keepers give different prices */
2156 if (objects[obj->otyp].oc_material == GEMSTONE
2157 || objects[obj->otyp].oc_material == GLASS) {
2158 tmp = (obj->otyp % (6 - shkp->m_id % 3));
2159 tmp = (tmp + 3) * obj->quan;
2161 } else if (tmp > 1L && !rn2(4))
2162 multiplier *= 3L, divisor *= 4L;
2166 /* [see get_cost()] */
2174 /* avoid adjusting nonzero to zero */
2179 /* (no adjustment for angry shk here) */
2183 /* called when an item's value has been enhanced; if it happens to be
2184 on any shop bill, update that bill to reflect the new higher price
2185 [if the new price drops for some reason, keep the old one in place] */
2187 alter_cost(obj, amt)
2189 long amt; /* if 0, use regular shop pricing, otherwise force amount;
2190 if negative, use abs(amt) even if it's less than old cost */
2192 struct bill_x *bp = 0;
2196 for (shkp = next_shkp(fmon, TRUE); shkp; shkp = next_shkp(shkp, TRUE))
2197 if ((bp = onbill(obj, shkp, TRUE)) != 0) {
2198 new_price = !amt ? get_cost(obj, shkp) : (amt < 0L) ? -amt : amt;
2199 if (new_price > bp->price || amt < 0L) {
2200 bp->price = new_price;
2208 /* called from doinv(invent.c) for inventory of unpaid objects */
2210 unpaid_cost(unp_obj, include_contents)
2211 struct obj *unp_obj; /* known to be unpaid or contain unpaid */
2212 boolean include_contents;
2214 struct bill_x *bp = (struct bill_x *) 0;
2219 if (!get_obj_location(unp_obj, &ox, &oy, BURIED_TOO | CONTAINED_TOO))
2220 ox = u.ux, oy = u.uy; /* (shouldn't happen) */
2221 if ((shkp = shop_keeper(*in_rooms(ox, oy, SHOPBASE))) != 0) {
2222 bp = onbill(unp_obj, shkp, TRUE);
2224 /* didn't find shk? try searching bills */
2225 for (shkp = next_shkp(fmon, TRUE); shkp;
2226 shkp = next_shkp(shkp->nmon, TRUE))
2227 if ((bp = onbill(unp_obj, shkp, TRUE)) != 0)
2231 /* onbill() gave no message if unexpected problem occurred */
2232 if (!shkp || (unp_obj->unpaid && !bp)) {
2233 impossible("unpaid_cost: object wasn't on any bill.");
2236 amt = unp_obj->quan * bp->price;
2237 if (include_contents && Has_contents(unp_obj))
2238 amt = contained_cost(unp_obj, shkp, amt, FALSE, TRUE);
2244 add_one_tobill(obj, dummy, shkp)
2253 if (!billable(&shkp, obj, *u.ushops, TRUE))
2257 if (eshkp->billct == BILLSZ) {
2258 You("got that for free!");
2262 bct = eshkp->billct;
2263 bp = &(eshkp->bill_p[bct]);
2264 bp->bo_id = obj->o_id;
2265 bp->bquan = obj->quan;
2266 if (dummy) { /* a dummy object must be inserted into */
2267 bp->useup = 1; /* the billobjs chain here. crucial for */
2268 add_to_billobjs(obj); /* eating floorfood in shop. see eat.c */
2271 bp->price = get_cost(obj, shkp);
2277 add_to_billobjs(obj)
2280 if (obj->where != OBJ_FREE)
2281 panic("add_to_billobjs: obj not free");
2283 obj_stop_timers(obj);
2285 obj->nobj = billobjs;
2287 obj->where = OBJ_ONBILL;
2290 /* recursive billing of objects within containers. */
2292 bill_box_content(obj, ininv, dummy, shkp)
2293 register struct obj *obj;
2294 register boolean ininv, dummy;
2295 register struct monst *shkp;
2297 register struct obj *otmp;
2299 for (otmp = obj->cobj; otmp; otmp = otmp->nobj) {
2300 if (otmp->oclass == COIN_CLASS)
2303 /* the "top" box is added in addtobill() */
2304 if (!otmp->no_charge)
2305 add_one_tobill(otmp, dummy, shkp);
2306 if (Has_contents(otmp))
2307 bill_box_content(otmp, ininv, dummy, shkp);
2311 /* shopkeeper tells you what you bought or sold, sometimes partly IDing it */
2313 shk_names_obj(shkp, obj, fmt, amt, arg)
2316 const char *fmt; /* "%s %ld %s %s", doname(obj), amt, plur(amt), arg */
2320 char *obj_name, fmtbuf[BUFSZ];
2321 boolean was_unknown = !obj->dknown;
2324 /* Use real name for ordinary weapons/armor, and spell-less
2325 * scrolls/books (that is, blank and mail), but only if the
2326 * object is within the shk's area of interest/expertise.
2328 if (!objects[obj->otyp].oc_magic && saleable(shkp, obj)
2329 && (obj->oclass == WEAPON_CLASS || obj->oclass == ARMOR_CLASS
2330 || obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS
2331 || obj->otyp == MIRROR)) {
2332 was_unknown |= !objects[obj->otyp].oc_name_known;
2333 makeknown(obj->otyp);
2335 obj_name = doname(obj);
2336 /* Use an alternate message when extra information is being provided */
2338 Sprintf(fmtbuf, "%%s; you %s", fmt);
2339 obj_name[0] = highc(obj_name[0]);
2340 pline(fmtbuf, obj_name, (obj->quan > 1L) ? "them" : "it", amt,
2343 You(fmt, obj_name, amt, plur(amt), arg);
2347 /* decide whether a shopkeeper thinks an item belongs to her */
2349 billable(shkpp, obj, roomno, reset_nocharge)
2350 struct monst **shkpp; /* in: non-null if shk has been validated; out: shk */
2353 boolean reset_nocharge;
2355 struct monst *shkp = *shkpp;
2357 /* if caller hasn't supplied a shopkeeper, look one up now */
2361 shkp = shop_keeper(roomno);
2362 if (!shkp || !inhishop(shkp))
2366 /* perhaps we threw it away earlier */
2367 if (onbill(obj, shkp, FALSE)
2368 || (obj->oclass == FOOD_CLASS && obj->oeaten))
2370 /* outer container might be marked no_charge but still have contents
2371 which should be charged for; clear no_charge when picking things up */
2372 if (obj->no_charge) {
2373 if (!Has_contents(obj) || (contained_gold(obj) == 0L
2374 && contained_cost(obj, shkp, 0L, FALSE,
2375 !reset_nocharge) == 0L))
2376 shkp = 0; /* not billable */
2377 if (reset_nocharge && !shkp && obj->oclass != COIN_CLASS) {
2379 if (Has_contents(obj))
2380 picked_container(obj); /* clear no_charge */
2383 return shkp ? TRUE : FALSE;
2387 addtobill(obj, ininv, dummy, silent)
2389 boolean ininv, dummy, silent;
2391 struct monst *shkp = 0;
2392 long ltmp, cltmp, gltmp;
2396 if (!billable(&shkp, obj, *u.ushops, TRUE))
2399 if (obj->oclass == COIN_CLASS) {
2400 costly_gold(obj->ox, obj->oy, obj->quan);
2402 } else if (ESHK(shkp)->billct == BILLSZ) {
2404 You("got that for free!");
2408 ltmp = cltmp = gltmp = 0L;
2409 container = Has_contents(obj);
2411 if (!obj->no_charge)
2412 ltmp = get_cost(obj, shkp);
2414 if (obj->no_charge && !container) {
2420 cltmp = contained_cost(obj, shkp, cltmp, FALSE, FALSE);
2421 gltmp = contained_gold(obj);
2424 add_one_tobill(obj, dummy, shkp);
2426 bill_box_content(obj, ininv, dummy, shkp);
2427 picked_container(obj); /* reset contained obj->no_charge */
2432 costly_gold(obj->ox, obj->oy, gltmp);
2439 contentscount = count_unpaid(obj->cobj);
2440 } else { /* !container */
2441 add_one_tobill(obj, dummy, shkp);
2445 if (!muteshk(shkp) && !silent) {
2449 pline("%s has no interest in %s.", Monnam(shkp), the(xname(obj)));
2453 pline("%s will cost you %ld %s%s.", The(xname(obj)), ltmp,
2454 currency(ltmp), (obj->quan > 1L) ? " each" : "");
2456 long save_quan = obj->quan;
2458 Strcpy(buf, "\"For you, ");
2460 Strcat(buf, "scum;");
2462 append_honorific(buf);
2463 Strcat(buf, "; only");
2465 obj->quan = 1L; /* fool xname() into giving singular */
2466 pline("%s %ld %s %s %s%s.\"", buf, ltmp, currency(ltmp),
2467 (save_quan > 1L) ? "per" : (contentscount && !obj->unpaid)
2468 ? "for the contents of this"
2471 (contentscount && obj->unpaid) ? and_its_contents : "");
2472 obj->quan = save_quan;
2474 } else if (!silent) {
2476 pline_The("list price of %s%s%s is %ld %s%s.",
2477 (contentscount && !obj->unpaid) ? the_contents_of : "",
2479 (contentscount && obj->unpaid) ? and_its_contents : "",
2480 ltmp, currency(ltmp), (obj->quan > 1L) ? " each" : "");
2482 pline("%s does not notice.", Monnam(shkp));
2487 append_honorific(buf)
2490 /* (chooses among [0]..[3] normally; [1]..[4] after the
2491 Wizard has been killed or invocation ritual performed) */
2492 static const char *const honored[] = { "good", "honored", "most gracious",
2494 "most renowned and sacred" };
2495 Strcat(buf, honored[rn2(SIZE(honored) - 1) + u.uevent.udemigod]);
2496 if (is_vampire(youmonst.data))
2497 Strcat(buf, (flags.female) ? " dark lady" : " dark lord");
2498 else if (is_elf(youmonst.data))
2499 Strcat(buf, (flags.female) ? " hiril" : " hir");
2501 Strcat(buf, !is_human(youmonst.data) ? " creature" : (flags.female)
2507 splitbill(obj, otmp)
2508 register struct obj *obj, *otmp;
2510 /* otmp has been split off from obj */
2511 register struct bill_x *bp;
2513 register struct monst *shkp = shop_keeper(*u.ushops);
2515 if (!shkp || !inhishop(shkp)) {
2516 impossible("splitbill: no resident shopkeeper??");
2519 bp = onbill(obj, shkp, FALSE);
2521 impossible("splitbill: not on bill?");
2524 if (bp->bquan < otmp->quan) {
2525 impossible("Negative quantity on bill??");
2527 if (bp->bquan == otmp->quan) {
2528 impossible("Zero quantity on bill??");
2530 bp->bquan -= otmp->quan;
2532 if (ESHK(shkp)->billct == BILLSZ)
2536 bp = &(ESHK(shkp)->bill_p[ESHK(shkp)->billct]);
2537 bp->bo_id = otmp->o_id;
2538 bp->bquan = otmp->quan;
2541 ESHK(shkp)->billct++;
2546 sub_one_frombill(obj, shkp)
2547 register struct obj *obj;
2548 register struct monst *shkp;
2550 register struct bill_x *bp;
2552 if ((bp = onbill(obj, shkp, FALSE)) != 0) {
2553 register struct obj *otmp;
2556 if (bp->bquan > obj->quan) {
2559 otmp->oextra = (struct oextra *) 0;
2560 bp->bo_id = otmp->o_id = context.ident++;
2561 otmp->where = OBJ_FREE;
2562 otmp->quan = (bp->bquan -= obj->quan);
2563 otmp->owt = 0; /* superfluous */
2565 add_to_billobjs(otmp);
2568 ESHK(shkp)->billct--;
2571 /* DRS/NS 2.2.6 messes up -- Peter Kendell */
2572 int indx = ESHK(shkp)->billct;
2574 *bp = ESHK(shkp)->bill_p[indx];
2577 *bp = ESHK(shkp)->bill_p[ESHK(shkp)->billct];
2580 } else if (obj->unpaid) {
2581 impossible("sub_one_frombill: unpaid object not on bill");
2586 /* recursive check of unpaid objects within nested containers. */
2588 subfrombill(obj, shkp)
2589 register struct obj *obj;
2590 register struct monst *shkp;
2592 register struct obj *otmp;
2594 sub_one_frombill(obj, shkp);
2596 if (Has_contents(obj))
2597 for (otmp = obj->cobj; otmp; otmp = otmp->nobj) {
2598 if (otmp->oclass == COIN_CLASS)
2601 if (Has_contents(otmp))
2602 subfrombill(otmp, shkp);
2604 sub_one_frombill(otmp, shkp);
2609 stolen_container(obj, shkp, price, ininv)
2619 /* the price of contained objects; caller handles top container */
2620 for (otmp = obj->cobj; otmp; otmp = otmp->nobj) {
2621 if (otmp->oclass == COIN_CLASS)
2624 if (!billable(&shkp, otmp, ESHK(shkp)->shoproom, TRUE)) {
2625 /* billable() returns false for objects already on bill */
2626 if ((bp = onbill(otmp, shkp, FALSE)) == 0)
2628 /* this assumes that we're being called by stolen_value()
2629 (or by a recursive call to self on behalf of it) where
2630 the cost of this object is about to be added to shop
2631 debt in place of having it remain on the current bill */
2632 billamt = bp->bquan * bp->price;
2633 sub_one_frombill(otmp, shkp); /* avoid double billing */
2638 else if (ininv ? otmp->unpaid : !otmp->no_charge)
2639 price += otmp->quan * get_cost(otmp, shkp);
2641 if (Has_contents(otmp))
2642 price = stolen_container(otmp, shkp, price, ininv);
2649 stolen_value(obj, x, y, peaceful, silent)
2652 boolean peaceful, silent;
2654 long value = 0L, gvalue = 0L, billamt = 0L;
2655 char roomno = *in_rooms(x, y, SHOPBASE);
2657 struct monst *shkp = 0;
2659 if (!billable(&shkp, obj, roomno, FALSE)) {
2660 /* things already on the bill yield a not-billable result, so
2661 we need to check bill before deciding that shk doesn't care */
2662 if ((bp = onbill(obj, shkp, FALSE)) == 0)
2664 /* shk does care; take obj off bill to avoid double billing */
2665 billamt = bp->bquan * bp->price;
2666 sub_one_frombill(obj, shkp);
2669 if (obj->oclass == COIN_CLASS) {
2670 gvalue += obj->quan;
2674 else if (!obj->no_charge)
2675 value += obj->quan * get_cost(obj, shkp);
2677 if (Has_contents(obj)) {
2679 (obj->where == OBJ_INVENT || obj->where == OBJ_FREE);
2681 value += stolen_container(obj, shkp, 0L, ininv);
2683 gvalue += contained_gold(obj);
2687 if (gvalue + value == 0L)
2693 boolean credit_use = !!ESHK(shkp)->credit;
2694 value = check_credit(value, shkp);
2695 /* 'peaceful' affects general treatment, but doesn't affect
2696 * the fact that other code expects that all charges after the
2697 * shopkeeper is angry are included in robbed, not debit */
2699 ESHK(shkp)->robbed += value;
2701 ESHK(shkp)->debit += value;
2704 const char *still = "";
2707 if (ESHK(shkp)->credit) {
2708 You("have %ld %s credit remaining.", ESHK(shkp)->credit,
2709 currency(ESHK(shkp)->credit));
2711 } else if (!value) {
2712 You("have no credit remaining.");
2717 if (obj->oclass == COIN_CLASS)
2718 You("%sowe %s %ld %s!", still, mon_nam(shkp), value,
2721 You("%sowe %s %ld %s for %s!", still, mon_nam(shkp), value,
2722 currency(value), obj->quan > 1L ? "them" : "it");
2725 ESHK(shkp)->robbed += value;
2728 if (cansee(shkp->mx, shkp->my)) {
2729 Norep("%s booms: \"%s, you are a thief!\"", Monnam(shkp),
2732 Norep("You hear a scream, \"Thief!\"");
2735 (void) angry_guards(FALSE);
2740 /* auto-response flag for/from "sell foo?" 'a' => 'y', 'q' => 'n' */
2741 static char sell_response = 'a';
2742 static int sell_how = SELL_NORMAL;
2743 /* can't just use sell_response='y' for auto_credit because the 'a' response
2744 shouldn't carry over from ordinary selling to credit selling */
2745 static boolean auto_credit = FALSE;
2748 sellobj_state(deliberate)
2751 /* If we're deliberately dropping something, there's no automatic
2752 response to the shopkeeper's "want to sell" query; however, if we
2753 accidentally drop anything, the shk will buy it/them without asking.
2754 This retains the old pre-query risk that slippery fingers while in
2755 shops entailed: you drop it, you've lost it.
2757 sell_response = (deliberate != SELL_NORMAL) ? '\0' : 'a';
2758 sell_how = deliberate;
2759 auto_credit = FALSE;
2764 register struct obj *obj;
2767 register struct monst *shkp;
2768 register struct eshk *eshkp;
2769 long ltmp = 0L, cltmp = 0L, gltmp = 0L, offer, shkmoney;
2770 boolean saleitem, cgold = FALSE, container = Has_contents(obj);
2771 boolean isgold = (obj->oclass == COIN_CLASS);
2772 boolean only_partially_your_contents = FALSE;
2774 if (!(shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) || !inhishop(shkp))
2776 if (!costly_spot(x, y))
2781 if (obj->unpaid && !container && !isgold) {
2782 sub_one_frombill(obj, shkp);
2786 /* find the price of content before subfrombill */
2787 cltmp = contained_cost(obj, shkp, cltmp, TRUE, FALSE);
2788 /* find the value of contained gold */
2789 gltmp += contained_gold(obj);
2790 cgold = (gltmp > 0L);
2793 saleitem = saleable(shkp, obj);
2794 if (!isgold && !obj->unpaid && saleitem)
2795 ltmp = set_cost(obj, shkp);
2797 offer = ltmp + cltmp;
2799 /* get one case out of the way: nothing to sell, and no gold */
2800 if (!isgold && ((offer + gltmp) == 0L || sell_how == SELL_DONTSELL)) {
2801 boolean unpaid = is_unpaid(obj);
2804 dropped_container(obj, shkp, FALSE);
2805 if (!obj->unpaid && !saleitem)
2808 subfrombill(obj, shkp);
2812 if (!unpaid && (sell_how != SELL_DONTSELL)
2813 && !special_stock(obj, shkp, FALSE))
2814 pline("%s seems uninterested.", Monnam(shkp));
2818 /* you dropped something of your own - probably want to sell it */
2819 rouse_shk(shkp, TRUE); /* wake up sleeping or paralyzed shk */
2822 if (ANGRY(shkp)) { /* they become shop-objects, no pay */
2824 verbalize("Thank you, scum!");
2825 subfrombill(obj, shkp);
2829 if (eshkp->robbed) { /* shkp is not angry? */
2834 if ((eshkp->robbed -= offer < 0L))
2836 if (offer && !muteshk(shkp))
2838 "Thank you for your contribution to restock this recently plundered shop.");
2839 subfrombill(obj, shkp);
2843 if (isgold || cgold) {
2847 if (eshkp->debit >= gltmp) {
2848 if (eshkp->loan) { /* you carry shop's gold */
2849 if (eshkp->loan >= gltmp)
2850 eshkp->loan -= gltmp;
2854 eshkp->debit -= gltmp;
2855 Your("debt is %spaid off.", eshkp->debit ? "partially " : "");
2857 long delta = gltmp - eshkp->debit;
2859 eshkp->credit += delta;
2863 Your("debt is paid off.");
2865 if (eshkp->credit == delta)
2866 You("have established %ld %s credit.", delta,
2869 pline("%ld %s added to your credit; total is now %ld %s.",
2870 delta, currency(delta), eshkp->credit,
2871 currency(eshkp->credit));
2877 dropped_container(obj, shkp, FALSE);
2878 if (!obj->unpaid && !saleitem)
2880 subfrombill(obj, shkp);
2886 if ((!saleitem && !(container && cltmp > 0L)) || eshkp->billct == BILLSZ
2887 || obj->oclass == BALL_CLASS || obj->oclass == CHAIN_CLASS
2888 || offer == 0L || (obj->oclass == FOOD_CLASS && obj->oeaten)
2890 && obj->age < 20L * (long) objects[obj->otyp].oc_cost)) {
2891 pline("%s seems uninterested%s.", Monnam(shkp),
2892 cgold ? " in the rest" : "");
2894 dropped_container(obj, shkp, FALSE);
2899 shkmoney = money_cnt(shkp->minvent);
2901 char c, qbuf[BUFSZ];
2902 long tmpcr = ((offer * 9L) / 10L) + (offer <= 1L);
2904 if (sell_how == SELL_NORMAL || auto_credit) {
2905 c = sell_response = 'y';
2906 } else if (sell_response != 'n') {
2907 pline("%s cannot pay you at present.", shkname(shkp));
2908 Sprintf(qbuf, "Will you accept %ld %s in credit for ", tmpcr,
2910 c = ynaq(safe_qbuf(qbuf, qbuf, "?", obj, doname, thesimpleoname,
2911 (obj->quan == 1L) ? "that" : "those"));
2916 } else /* previously specified "quit" */
2922 (sell_how != SELL_NORMAL)
2923 ? "traded %s for %ld zorkmid%s in %scredit."
2924 : "relinquish %s and acquire %ld zorkmid%s in %scredit.",
2925 tmpcr, (eshkp->credit > 0L) ? "additional " : "");
2926 eshkp->credit += tmpcr;
2927 subfrombill(obj, shkp);
2930 sell_response = 'n';
2932 dropped_container(obj, shkp, FALSE);
2935 subfrombill(obj, shkp);
2938 char qbuf[BUFSZ], qsfx[BUFSZ];
2939 boolean short_funds = (offer > shkmoney), one;
2943 if (!sell_response) {
2944 long yourc = 0L, shksc;
2947 /* number of items owned by shk */
2948 shksc = count_contents(obj, TRUE, TRUE, FALSE);
2949 /* number of items owned by you (total - shksc) */
2950 yourc = count_contents(obj, TRUE, TRUE, TRUE) - shksc;
2951 only_partially_your_contents = shksc && yourc;
2954 "<shk> offers * for ..." query formatting.
2956 "... your <object>. Sell it?"
2957 "... your <objects>. Sell them?"
2958 A container is either owned by the hero, or already
2959 owned by the shk (!ltmp), or the shk isn't interested
2960 in buying it (also !ltmp). It's either empty (!cltmp)
2961 or it has contents owned by the hero or it has some
2962 contents owned by the hero and others by the shk.
2963 (The case where it has contents already entirely owned
2964 by the shk is treated the same was if it were empty
2965 since the hero isn't selling any of those contents.)
2967 "... your <empty bag>. Sell it?"
2968 "... your <bag> and its contents. Sell them?"
2969 "... your <bag> and item inside. Sell them?"
2970 "... your <bag> and items inside. Sell them?"
2972 "... your item in the <bag>. Sell it?"
2973 "... your items in the <bag>. Sell them?"
2975 Sprintf(qbuf, "%s offers%s %ld gold piece%s for %s%s ",
2976 shkname(shkp), short_funds ? " only" : "", offer,
2979 ? ((yourc == 1L) ? "your item in " : "your items in ")
2981 obj->unpaid ? "the" : "your");
2982 one = obj->unpaid ? (yourc == 1L) : (obj->quan == 1L && !cltmp);
2983 Sprintf(qsfx, "%s. Sell %s?",
2985 ? (only_partially_your_contents
2986 ? ((yourc == 1L) ? " and item inside"
2987 : " and items inside")
2990 one ? "it" : "them");
2991 (void) safe_qbuf(qbuf, qbuf, qsfx, obj, xname, simpleonames,
2992 one ? "that" : "those");
2994 qbuf[0] = '\0'; /* just to pacify lint */
2996 switch (sell_response ? sell_response : ynaq(qbuf)) {
2998 sell_response = 'n';
3001 dropped_container(obj, shkp, FALSE);
3004 subfrombill(obj, shkp);
3007 sell_response = 'y';
3010 dropped_container(obj, shkp, TRUE);
3011 if (!obj->unpaid && !saleitem)
3013 subfrombill(obj, shkp);
3015 shk_names_obj(shkp, obj,
3016 (sell_how != SELL_NORMAL)
3017 ? ((!ltmp && cltmp && only_partially_your_contents)
3018 ? "sold some items inside %s for %ld gold piece%s.%s"
3019 : "sold %s for %ld gold piece%s.%s")
3020 : "relinquish %s and receive %ld gold piece%s in compensation.%s",
3024 impossible("invalid sell response");
3031 int mode; /* 0: deliver count 1: paged */
3034 void sasc_bug(struct obj *, unsigned);
3038 struct bill_x *bp, *end_bp;
3044 shkp = shop_keeper(*u.ushops);
3045 if (!shkp || !inhishop(shkp)) {
3047 impossible("doinvbill: no shopkeeper?");
3053 /* count expended items, so that the `I' command can decide
3054 whether to include 'x' in its prompt string */
3055 int cnt = !eshkp->debit ? 0 : 1;
3057 for (bp = eshkp->bill_p, end_bp = &eshkp->bill_p[eshkp->billct];
3060 || ((obj = bp_to_obj(bp)) != 0 && obj->quan < bp->bquan))
3065 datawin = create_nhwindow(NHW_MENU);
3066 putstr(datawin, 0, "Unpaid articles already used up:");
3067 putstr(datawin, 0, "");
3070 for (bp = eshkp->bill_p, end_bp = &eshkp->bill_p[eshkp->billct];
3071 bp < end_bp; bp++) {
3072 obj = bp_to_obj(bp);
3074 impossible("Bad shopkeeper administration.");
3077 if (bp->useup || bp->bquan > obj->quan) {
3078 long oquan, uquan, thisused;
3081 uquan = (bp->useup ? bp->bquan : bp->bquan - oquan);
3082 thisused = bp->price * uquan;
3083 totused += thisused;
3084 iflags.suppress_price++; /* suppress "(unpaid)" suffix */
3085 /* Why 'x'? To match `I x', more or less. */
3086 buf_p = xprname(obj, (char *) 0, 'x', FALSE, thisused, uquan);
3087 iflags.suppress_price--;
3088 putstr(datawin, 0, buf_p);
3092 /* additional shop debt which has no itemization available */
3094 putstr(datawin, 0, "");
3095 totused += eshkp->debit;
3096 buf_p = xprname((struct obj *) 0, "usage charges and/or other fees",
3097 GOLD_SYM, FALSE, eshkp->debit, 0L);
3098 putstr(datawin, 0, buf_p);
3100 buf_p = xprname((struct obj *) 0, "Total:", '*', FALSE, totused, 0L);
3101 putstr(datawin, 0, "");
3102 putstr(datawin, 0, buf_p);
3103 display_nhwindow(datawin, FALSE);
3105 destroy_nhwindow(datawin);
3112 getprice(obj, shk_buying)
3113 register struct obj *obj;
3116 register long tmp = (long) objects[obj->otyp].oc_cost;
3118 if (obj->oartifact) {
3119 tmp = arti_cost(obj);
3123 switch (obj->oclass) {
3125 /* simpler hunger check, (2-4)*cost */
3126 if (u.uhs >= HUNGRY && !shk_buying)
3127 tmp *= (long) u.uhs;
3136 if (obj->otyp == POT_WATER && !obj->blessed && !obj->cursed)
3142 tmp += 10L * (long) obj->spe;
3146 && obj->age < 20L * (long) objects[obj->otyp].oc_cost)
3153 /* shk catches thrown pick-axe */
3156 register struct obj *obj;
3157 register xchar x, y;
3159 register struct monst *shkp;
3161 if (!(shkp = shop_keeper(inside_shop(x, y))) || !inhishop(shkp))
3164 if (shkp->mcanmove && !shkp->msleeping
3165 && (*u.ushops != ESHK(shkp)->shoproom || !inside_shop(u.ux, u.uy))
3166 && dist2(shkp->mx, shkp->my, x, y) < 3
3167 /* if it is the shk's pos, you hit and anger him */
3168 && (shkp->mx != x || shkp->my != y)) {
3169 if (mnearto(shkp, x, y, TRUE) && !muteshk(shkp))
3170 verbalize("Out of my way, scum!");
3172 pline("%s nimbly%s catches %s.", Monnam(shkp),
3173 (x == shkp->mx && y == shkp->my) ? "" : " reaches over and",
3175 if (!canspotmon(shkp))
3176 map_invisible(x, y);
3180 subfrombill(obj, shkp);
3181 (void) mpickobj(shkp, obj);
3184 return (struct monst *) 0;
3188 add_damage(x, y, cost)
3189 register xchar x, y;
3192 struct damage *tmp_dam;
3195 if (IS_DOOR(levl[x][y].typ)) {
3198 /* Don't schedule for repair unless it's a real shop entrance */
3199 for (shops = in_rooms(x, y, SHOPBASE); *shops; shops++)
3200 if ((mtmp = shop_keeper(*shops)) != 0 && x == ESHK(mtmp)->shd.x
3201 && y == ESHK(mtmp)->shd.y)
3206 for (tmp_dam = level.damagelist; tmp_dam; tmp_dam = tmp_dam->next)
3207 if (tmp_dam->place.x == x && tmp_dam->place.y == y) {
3208 tmp_dam->cost += cost;
3211 tmp_dam = (struct damage *) alloc((unsigned) sizeof(struct damage));
3212 tmp_dam->when = monstermoves;
3213 tmp_dam->place.x = x;
3214 tmp_dam->place.y = y;
3215 tmp_dam->cost = cost;
3216 tmp_dam->typ = levl[x][y].typ;
3217 tmp_dam->next = level.damagelist;
3218 level.damagelist = tmp_dam;
3219 /* If player saw damage, display as a wall forever */
3221 levl[x][y].seenv = SVALL;
3225 * Do something about damage. Either (!croaked) try to repair it, or
3226 * (croaked) just discard damage structs for non-shared locations, since
3227 * they'll never get repaired. Assume that shared locations will get
3228 * repaired eventually by the other shopkeeper(s). This might be an erroneous
3229 * assumption (they might all be dead too), but we have no reasonable way of
3234 remove_damage(shkp, croaked)
3238 struct damage *tmp_dam, *tmp2_dam;
3239 boolean did_repair = FALSE, saw_door = FALSE, saw_floor = FALSE,
3240 stop_picking = FALSE, doorway_trap = FALSE;
3241 int saw_walls = 0, saw_untrap = 0;
3242 char trapmsg[BUFSZ];
3244 tmp_dam = level.damagelist;
3247 register xchar x = tmp_dam->place.x, y = tmp_dam->place.y;
3250 unsigned old_doormask = 0;
3253 Strcpy(shops, in_rooms(x, y, SHOPBASE));
3254 if (index(shops, ESHK(shkp)->shoproom)) {
3255 if (IS_DOOR(levl[x][y].typ))
3256 old_doormask = levl[x][y].doormask;
3259 disposition = (shops[1]) ? 0 : 1;
3260 else if (stop_picking)
3261 disposition = repair_damage(shkp, tmp_dam, FALSE);
3263 /* Defer the stop_occupation() until after repair msgs */
3264 if (closed_door(x, y))
3265 stop_picking = picking_at(x, y);
3266 disposition = repair_damage(shkp, tmp_dam, FALSE);
3268 stop_picking = FALSE;
3274 tmp_dam = tmp_dam->next;
3278 if (disposition > 1) {
3281 if (IS_WALL(levl[x][y].typ)) {
3283 } else if (IS_DOOR(levl[x][y].typ)
3284 /* an existing door here implies trap removal */
3285 && !(old_doormask & (D_ISOPEN | D_CLOSED))) {
3287 } else if (disposition == 3) { /* untrapped */
3289 if (IS_DOOR(levl[x][y].typ))
3290 doorway_trap = TRUE;
3297 tmp_dam = tmp_dam->next;
3299 free((genericptr_t) level.damagelist);
3300 level.damagelist = tmp_dam;
3302 free((genericptr_t) tmp2_dam->next);
3303 tmp2_dam->next = tmp_dam;
3310 Sprintf(trapmsg, "%s trap%s",
3311 (saw_untrap > 3) ? "several" : (saw_untrap > 1) ? "some"
3314 Sprintf(eos(trapmsg), " %s", vtense(trapmsg, "are"));
3315 Sprintf(eos(trapmsg), " removed from the %s",
3316 (doorway_trap && saw_untrap == 1) ? "doorway" : "floor");
3318 trapmsg[0] = '\0'; /* not just lint suppression... */
3321 char wallbuf[BUFSZ];
3323 Sprintf(wallbuf, "section%s", plur(saw_walls));
3324 pline("Suddenly, %s %s of wall %s up!",
3325 (saw_walls == 1) ? "a" : (saw_walls <= 3) ? "some" : "several",
3326 wallbuf, vtense(wallbuf, "close"));
3329 pline_The("shop door reappears!");
3331 pline_The("floor is repaired!");
3333 pline("%s!", upstart(trapmsg));
3335 if (saw_door || saw_floor || saw_untrap)
3336 pline("Suddenly, %s%s%s%s%s!",
3337 saw_door ? "the shop door reappears" : "",
3338 (saw_door && saw_floor) ? " and " : "",
3339 saw_floor ? "the floor damage is gone" : "",
3340 ((saw_door || saw_floor) && *trapmsg) ? " and " : "",
3342 else if (inside_shop(u.ux, u.uy) == ESHK(shkp)->shoproom)
3343 You_feel("more claustrophobic than before.");
3344 else if (!Deaf && !rn2(10))
3345 Norep("The dungeon acoustics noticeably change.");
3352 * 0: repair postponed, 1: silent repair (no messages), 2: normal repair
3356 repair_damage(shkp, tmp_dam, catchup)
3357 register struct monst *shkp;
3358 register struct damage *tmp_dam;
3359 boolean catchup; /* restoring a level */
3361 register xchar x, y, i;
3363 register struct monst *mtmp;
3364 register struct obj *otmp;
3365 register struct trap *ttmp;
3367 if ((monstermoves - tmp_dam->when) < REPAIR_DELAY)
3369 if (shkp->msleeping || !shkp->mcanmove || ESHK(shkp)->following)
3371 x = tmp_dam->place.x;
3372 y = tmp_dam->place.y;
3373 if (!IS_ROOM(tmp_dam->typ)) {
3374 if (x == u.ux && y == u.uy)
3377 if (x == shkp->mx && y == shkp->my)
3379 if ((mtmp = m_at(x, y)) && (!passes_walls(mtmp->data)))
3382 if ((ttmp = t_at(x, y)) != 0) {
3383 if (x == u.ux && y == u.uy)
3386 if (ttmp->ttyp == LANDMINE || ttmp->ttyp == BEAR_TRAP) {
3387 /* convert to an object */
3388 otmp = mksobj((ttmp->ttyp == LANDMINE) ? LAND_MINE : BEARTRAP,
3391 otmp->owt = weight(otmp);
3392 (void) mpickobj(shkp, otmp);
3395 if (IS_DOOR(tmp_dam->typ) && !(levl[x][y].doormask & D_ISOPEN)) {
3396 levl[x][y].doormask = D_CLOSED;
3398 } else if (IS_WALL(tmp_dam->typ)) {
3399 levl[x][y].typ = tmp_dam->typ;
3405 if (IS_ROOM(tmp_dam->typ)) {
3406 /* No messages, because player already filled trap door */
3409 if ((tmp_dam->typ == levl[x][y].typ)
3410 && (!IS_DOOR(tmp_dam->typ) || (levl[x][y].doormask > D_BROKEN)))
3411 /* No messages if player already replaced shop door */
3413 levl[x][y].typ = tmp_dam->typ;
3414 (void) memset((genericptr_t) litter, 0, sizeof(litter));
3415 if ((otmp = level.objects[x][y]) != 0) {
3416 /* Scatter objects haphazardly into the shop */
3417 #define NEED_UPDATE 1
3420 #define horiz(i) ((i % 3) - 1)
3421 #define vert(i) ((i / 3) - 1)
3422 for (i = 0; i < 9; i++) {
3423 if ((i == 4) || (!ZAP_POS(levl[x + horiz(i)][y + vert(i)].typ)))
3426 if (inside_shop(x + horiz(i), y + vert(i))
3427 == ESHK(shkp)->shoproom)
3428 litter[i] |= INSHOP;
3430 if (Punished && !u.uswallow
3431 && ((uchain->ox == x && uchain->oy == y)
3432 || (uball->ox == x && uball->oy == y))) {
3434 * Either the ball or chain is in the repair location.
3436 * Take the easy way out and put ball&chain under hero.
3439 verbalize("Get your junk out of my wall!");
3440 unplacebc(); /* pick 'em up */
3441 placebc(); /* put 'em down */
3443 while ((otmp = level.objects[x][y]) != 0)
3444 /* Don't mess w/ boulders -- just merge into wall */
3445 if ((otmp->otyp == BOULDER) || (otmp->otyp == ROCK)) {
3446 obj_extract_self(otmp);
3447 obfree(otmp, (struct obj *) 0);
3449 while (!(litter[i = rn2(9)] & INSHOP))
3451 remove_object(otmp);
3452 place_object(otmp, x + horiz(i), y + vert(i));
3453 litter[i] |= NEED_UPDATE;
3457 return 1; /* repair occurred while off level */
3460 if (IS_DOOR(tmp_dam->typ)) {
3461 levl[x][y].doormask = D_CLOSED; /* arbitrary */
3464 /* don't set doormask - it is (hopefully) the same as it was
3465 if not, perhaps save it with the damage array... */
3467 if (IS_WALL(tmp_dam->typ) && cansee(x, y)) {
3468 /* Player sees actual repair process, so they KNOW it's a wall */
3469 levl[x][y].seenv = SVALL;
3472 /* Mark this wall as "repaired". There currently is no code
3473 to do anything about repaired walls, so don't do it. */
3475 for (i = 0; i < 9; i++)
3476 if (litter[i] & NEED_UPDATE)
3477 newsym(x + horiz(i), y + vert(i));
3487 * shk_move: return 1: moved 0: didn't -1: let m_move do it -2: died
3491 register struct monst *shkp;
3493 register xchar gx, gy, omx, omy;
3495 register schar appr;
3496 register struct eshk *eshkp = ESHK(shkp);
3498 boolean uondoor = FALSE, satdoor, avoid = FALSE, badinv;
3504 remove_damage(shkp, FALSE);
3506 if ((udist = distu(omx, omy)) < 3 && (shkp->data != &mons[PM_GRID_BUG]
3507 || (omx == u.ux || omy == u.uy))) {
3508 if (ANGRY(shkp) || (Conflict && !resist(shkp, RING_CLASS, 0, 0))) {
3510 Your("displaced image doesn't fool %s!", mon_nam(shkp));
3511 (void) mattacku(shkp);
3514 if (eshkp->following) {
3515 if (strncmp(eshkp->customer, plname, PL_NSIZ)) {
3517 verbalize("%s, %s! I was looking for %s.", Hello(shkp),
3518 plname, eshkp->customer);
3519 eshkp->following = 0;
3522 if (moves > followmsg + 4) {
3524 verbalize("%s, %s! Didn't you forget to pay?",
3525 Hello(shkp), plname);
3528 pline("%s doesn't like customers who don't pay.",
3541 satdoor = (gx == omx && gy == omy);
3542 if (eshkp->following || ((z = holetime()) >= 0 && z * z <= udist)) {
3543 /* [This distance check used to apply regardless of
3544 whether the shk was following, but that resulted in
3545 m_move() sometimes taking the shk out of the shop if
3546 the player had fenced him in with boulders or traps.
3547 Such voluntary abandonment left unpaid objects in
3548 invent, triggering billing impossibilities on the
3549 next level once the character fell through the hole.] */
3550 if (udist > 4 && eshkp->following && !eshkp->billct)
3551 return -1; /* leave it to m_move */
3554 } else if (ANGRY(shkp)) {
3555 /* Move towards the hero if the shopkeeper can see him. */
3556 if (shkp->mcansee && m_canseeu(shkp)) {
3562 #define GDIST(x, y) (dist2(x, y, gx, gy))
3563 if (Invis || u.usteed) {
3566 uondoor = (u.ux == eshkp->shd.x && u.uy == eshkp->shd.y);
3569 (carrying(PICK_AXE) || carrying(DWARVISH_MATTOCK)
3570 || (Fast && (sobj_at(PICK_AXE, u.ux, u.uy)
3571 || sobj_at(DWARVISH_MATTOCK, u.ux, u.uy))));
3572 if (satdoor && badinv)
3576 avoid = (*u.ushops && distu(gx, gy) > 8);
3580 if (((!eshkp->robbed && !eshkp->billct && !eshkp->debit) || avoid)
3581 && GDIST(omx, omy) < 3) {
3582 if (!badinv && !onlineu(omx, omy))
3590 z = move_special(shkp, inhishop(shkp), appr, uondoor, avoid, omx, omy, gx,
3593 after_shk_move(shkp);
3598 /* called after shopkeeper moves, in case themove causes re-entry into shop */
3600 after_shk_move(shkp)
3603 struct eshk *eshkp = ESHK(shkp);
3605 if (eshkp->bill_p == (struct bill_x *) -1000 && inhishop(shkp)) {
3606 /* reset bill_p, need to re-calc player's occupancy too */
3607 eshkp->bill_p = &eshkp->bill[0];
3608 check_special_room(FALSE);
3612 /* for use in levl_follower (mondata.c) */
3615 register struct monst *mtmp;
3617 return (boolean) (mtmp->isshk && ESHK(mtmp)->following);
3620 /* You are digging in the shop. */
3625 register struct monst *shkp = shop_keeper(*u.ushops);
3627 const char *grabs = "grabs";
3632 /* 0 == can't speak, 1 == makes animal noises, 2 == speaks */
3634 if (shkp->msleeping || !shkp->mcanmove || is_silent(shkp->data))
3635 ; /* lang stays 0 */
3636 else if (shkp->data->msound <= MS_ANIMAL)
3638 else if (shkp->data->msound >= MS_HUMANOID)
3641 if (!inhishop(shkp)) {
3642 if (Role_if(PM_KNIGHT)) {
3643 You_feel("like a common thief.");
3644 adjalign(-sgn(u.ualign.type));
3651 if (u.utraptype == TT_PIT)
3653 "Be careful, %s, or you might fall through the floor.",
3654 flags.female ? "madam" : "sir");
3656 verbalize("%s, do not damage the floor here!",
3657 flags.female ? "Madam" : "Sir");
3659 if (Role_if(PM_KNIGHT)) {
3660 You_feel("like a common thief.");
3661 adjalign(-sgn(u.ualign.type));
3663 } else if (!um_dist(shkp->mx, shkp->my, 5)
3664 && !shkp->msleeping && shkp->mcanmove
3665 && (ESHK(shkp)->billct || ESHK(shkp)->debit)) {
3666 register struct obj *obj, *obj2;
3668 if (nolimbs(shkp->data)) {
3669 grabs = "knocks off";
3671 /* This is what should happen, but for balance
3672 * reasons, it isn't currently.
3675 pline("%s curses %s inability to grab your backpack!",
3676 shkname(shkp), mhim(shkp));
3681 if (distu(shkp->mx, shkp->my) > 2) {
3683 /* for some reason the shopkeeper can't come next to you */
3684 if (distu(shkp->mx, shkp->my) > 2) {
3686 pline("%s curses you in anger and frustration!",
3693 pline("%s %s, and %s your backpack!", shkname(shkp),
3694 makeplural(locomotion(shkp->data, "leap")), grabs);
3696 pline("%s %s your backpack!", shkname(shkp), grabs);
3698 for (obj = invent; obj; obj = obj2) {
3700 if ((obj->owornmask & ~(W_SWAPWEP | W_QUIVER)) != 0
3701 || (obj == uswapwep && u.twoweap)
3702 || (obj->otyp == LEASH && obj->leashmon))
3704 if (obj == current_wand)
3708 subfrombill(obj, shkp);
3709 (void) add_to_minv(shkp, obj); /* may free obj */
3718 static const short k_mndx[4] = { PM_KEYSTONE_KOP, PM_KOP_SERGEANT,
3719 PM_KOP_LIEUTENANT, PM_KOP_KAPTAIN };
3720 int k_cnt[4], cnt, mndx, k;
3722 k_cnt[0] = cnt = abs(depth(&u.uz)) + rnd(5);
3723 k_cnt[1] = (cnt / 3) + 1; /* at least one sarge */
3724 k_cnt[2] = (cnt / 6); /* maybe a lieutenant */
3725 k_cnt[3] = (cnt / 9); /* and maybe a kaptain */
3727 for (k = 0; k < 4; k++) {
3728 if ((cnt = k_cnt[k]) == 0)
3731 if (mvitals[mndx].mvflags & G_GONE)
3735 if (enexto(mm, mm->x, mm->y, &mons[mndx]))
3736 (void) makemon(&mons[mndx], mm->x, mm->y, NO_MM_FLAGS);
3741 pay_for_damage(dmgstr, cant_mollify)
3743 boolean cant_mollify;
3745 register struct monst *shkp = (struct monst *) 0;
3746 char shops_affected[5];
3747 register boolean uinshp = (*u.ushops != '\0');
3749 register xchar x, y;
3750 boolean dugwall = (!strcmp(dmgstr, "dig into") /* wand */
3751 || !strcmp(dmgstr, "damage")); /* pick-axe */
3752 boolean animal, pursue;
3753 struct damage *tmp_dam, *appear_here = 0;
3754 /* any number >= (80*80)+(24*24) would do, actually */
3755 long cost_of_damage = 0L;
3756 unsigned int nearest_shk = 7000, nearest_damage = 7000;
3759 for (tmp_dam = level.damagelist;
3760 (tmp_dam && (tmp_dam->when == monstermoves));
3761 tmp_dam = tmp_dam->next) {
3766 cost_of_damage += tmp_dam->cost;
3767 Strcpy(shops_affected,
3768 in_rooms(tmp_dam->place.x, tmp_dam->place.y, SHOPBASE));
3769 for (shp = shops_affected; *shp; shp++) {
3770 struct monst *tmp_shk;
3771 unsigned int shk_distance;
3773 if (!(tmp_shk = shop_keeper(*shp)))
3775 if (tmp_shk == shkp) {
3776 unsigned int damage_distance =
3777 distu(tmp_dam->place.x, tmp_dam->place.y);
3779 if (damage_distance < nearest_damage) {
3780 nearest_damage = damage_distance;
3781 appear_here = tmp_dam;
3785 if (!inhishop(tmp_shk))
3787 shk_distance = distu(tmp_shk->mx, tmp_shk->my);
3788 if (shk_distance > nearest_shk)
3790 if ((shk_distance == nearest_shk) && picks) {
3796 nearest_shk = shk_distance;
3797 appear_here = tmp_dam;
3798 nearest_damage = distu(tmp_dam->place.x, tmp_dam->place.y);
3802 if (!cost_of_damage || !shkp)
3805 animal = (shkp->data->msound <= MS_ANIMAL);
3807 x = appear_here->place.x;
3808 y = appear_here->place.y;
3810 /* not the best introduction to the shk... */
3811 (void) strncpy(ESHK(shkp)->customer, plname, PL_NSIZ);
3813 /* if the shk is already on the war path, be sure it's all out */
3814 if (ANGRY(shkp) || ESHK(shkp)->following) {
3819 /* if the shk is not in their shop.. */
3820 if (!*in_rooms(shkp->mx, shkp->my, SHOPBASE)) {
3821 if (!cansee(shkp->mx, shkp->my))
3828 if (um_dist(shkp->mx, shkp->my, 1)
3829 && !um_dist(shkp->mx, shkp->my, 3)) {
3830 pline("%s leaps towards you!", shkname(shkp));
3833 pursue = um_dist(shkp->mx, shkp->my, 1);
3838 * Make shkp show up at the door. Effect: If there is a monster
3839 * in the doorway, have the hero hear the shopkeeper yell a bit,
3840 * pause, then have the shopkeeper appear at the door, having
3841 * yanked the hapless critter out of the way.
3844 if (!Deaf && !animal) {
3845 You_hear("an angry voice:");
3846 verbalize("Out of my way, scum!");
3848 #if defined(UNIX) || defined(VMS)
3849 #if defined(SYSV) || defined(ULTRIX) || defined(VMS)
3858 (void) mnearto(shkp, x, y, TRUE);
3861 if ((um_dist(x, y, 1) && !uinshp) || cant_mollify
3862 || (money_cnt(invent) + ESHK(shkp)->credit) < cost_of_damage
3865 if (muteshk(shkp)) {
3866 if (animal && shkp->mcanmove && !shkp->msleeping)
3868 } else if (pursue || uinshp || !um_dist(x, y, 1)) {
3869 verbalize("How dare you %s my %s?", dmgstr,
3870 dugwall ? "shop" : "door");
3872 pline("%s shouts:", shkname(shkp));
3873 verbalize("Who dared %s my %s?", dmgstr,
3874 dugwall ? "shop" : "door");
3881 Your("invisibility does not fool %s!", shkname(shkp));
3882 Sprintf(qbuf, "%sYou did %ld %s worth of damage!%s Pay?",
3883 !animal ? cad(TRUE) : "", cost_of_damage,
3884 currency(cost_of_damage), !animal ? "\"" : "");
3885 if (yn(qbuf) != 'n') {
3886 cost_of_damage = check_credit(cost_of_damage, shkp);
3887 money2mon(shkp, cost_of_damage);
3889 pline("Mollified, %s accepts your restitution.", shkname(shkp));
3890 /* move shk back to his home loc */
3891 home_shk(shkp, FALSE);
3895 verbalize("Oh, yes! You'll pay!");
3899 adjalign(-sgn(u.ualign.type));
3903 /* called in dokick.c when we kick an object that might be in a store */
3906 register xchar x, y;
3911 if (!level.flags.has_shop)
3913 shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
3914 if (!shkp || !inhishop(shkp))
3917 return (boolean) (inside_shop(x, y)
3918 && !(x == eshkp->shk.x && y == eshkp->shk.y));
3921 /* called by dotalk(sounds.c) when #chatting; returns obj if location
3922 contains shop goods and shopkeeper is willing & able to speak */
3925 register xchar x, y;
3927 register struct obj *otmp;
3928 register struct monst *shkp;
3930 if (!(shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) || !inhishop(shkp))
3931 return (struct obj *) 0;
3933 for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
3934 if (otmp->oclass != COIN_CLASS)
3936 /* note: otmp might have ->no_charge set, but that's ok */
3937 return (otmp && costly_spot(x, y)
3938 && NOTANGRY(shkp) && shkp->mcanmove && !shkp->msleeping)
3943 /* give price quotes for all objects linked to this one (ie, on this spot) */
3945 price_quote(first_obj)
3946 register struct obj *first_obj;
3948 register struct obj *otmp;
3949 char buf[BUFSZ], price[40];
3952 boolean contentsonly = FALSE;
3954 struct monst *shkp = shop_keeper(inside_shop(u.ux, u.uy));
3956 tmpwin = create_nhwindow(NHW_MENU);
3957 putstr(tmpwin, 0, "Fine goods for sale:");
3958 putstr(tmpwin, 0, "");
3959 for (otmp = first_obj; otmp; otmp = otmp->nexthere) {
3960 if (otmp->oclass == COIN_CLASS)
3962 cost = (otmp->no_charge || otmp == uball || otmp == uchain)
3964 : get_cost(otmp, (struct monst *) 0);
3965 contentsonly = !cost;
3966 if (Has_contents(otmp))
3967 cost += contained_cost(otmp, shkp, 0L, FALSE, FALSE);
3969 Strcpy(price, "no charge");
3970 contentsonly = FALSE;
3972 Sprintf(price, "%ld %s%s", cost, currency(cost),
3973 (otmp->quan) > 1L ? " each" : "");
3975 Sprintf(buf, "%s%s, %s", contentsonly ? the_contents_of : "",
3976 doname(otmp), price);
3977 putstr(tmpwin, 0, buf), cnt++;
3980 display_nhwindow(tmpwin, TRUE);
3981 } else if (cnt == 1) {
3983 /* "<doname(obj)>, no charge" */
3984 pline("%s!", upstart(buf)); /* buf still contains the string */
3986 /* print cost in slightly different format, so can't reuse buf;
3987 cost and contentsonly are already set up */
3988 Sprintf(buf, "%s%s", contentsonly ? the_contents_of : "",
3990 pline("%s, price %ld %s%s%s", upstart(buf), cost, currency(cost),
3991 (first_obj->quan > 1L) ? " each" : "",
3992 contentsonly ? "." : shk_embellish(first_obj, cost));
3995 destroy_nhwindow(tmpwin);
3998 STATIC_OVL const char *
3999 shk_embellish(itm, cost)
4000 register struct obj *itm;
4004 register int o, choice = rn2(5);
4006 choice = (cost < 100L ? 1 : cost < 500L ? 2 : 3);
4013 if (o == FOOD_CLASS)
4014 return ", gourmets' delight!";
4015 if (objects[itm->otyp].oc_name_known
4016 ? objects[itm->otyp].oc_magic
4017 : (o == AMULET_CLASS || o == RING_CLASS || o == WAND_CLASS
4018 || o == POTION_CLASS || o == SCROLL_CLASS
4019 || o == SPBOOK_CLASS))
4020 return ", painstakingly developed!";
4021 return ", superb craftsmanship!";
4023 return ", finest quality.";
4025 return ", an excellent choice.";
4027 return ", a real bargain.";
4031 } else if (itm->oartifact) {
4032 return ", one of a kind!";
4037 /* First 4 supplied by Ronen and Tamar, remainder by development team */
4038 const char *Izchak_speaks[] = {
4039 "%s says: 'These shopping malls give me a headache.'",
4040 "%s says: 'Slow down. Think clearly.'",
4041 "%s says: 'You need to take things one at a time.'",
4042 "%s says: 'I don't like poofy coffee... give me Columbian Supremo.'",
4043 "%s says that getting the devteam's agreement on anything is difficult.",
4044 "%s says that he has noticed those who serve their deity will prosper.",
4045 "%s says: 'Don't try to steal from me - I have friends in high places!'",
4046 "%s says: 'You may well need something from this shop in the future.'",
4047 "%s comments about the Valley of the Dead as being a gateway."
4057 /* The monster type is shopkeeper, but this monster is
4058 not actually a shk, which could happen if someone
4059 wishes for a shopkeeper statue and then animates it.
4060 (Note: shkname() would be "" in a case like this.) */
4061 pline("%s asks whether you've seen any untended shops recently.",
4063 /* [Perhaps we ought to check whether this conversation
4064 is taking place inside an untended shop, but a shopless
4065 shk can probably be expected to be rather disoriented.] */
4071 pline("%s mentions how much %s dislikes %s customers.",
4072 shkname(shkp), mhe(shkp), eshk->robbed ? "non-paying" : "rude");
4073 } else if (eshk->following) {
4074 if (strncmp(eshk->customer, plname, PL_NSIZ)) {
4075 verbalize("%s %s! I was looking for %s.",
4076 Hello(shkp), plname, eshk->customer);
4077 eshk->following = 0;
4079 verbalize("%s %s! Didn't you forget to pay?",
4080 Hello(shkp), plname);
4082 } else if (eshk->billct) {
4083 register long total = addupbill(shkp) + eshk->debit;
4085 pline("%s says that your bill comes to %ld %s.",
4086 shkname(shkp), total, currency(total));
4087 } else if (eshk->debit) {
4088 pline("%s reminds you that you owe %s %ld %s.",
4089 shkname(shkp), mhim(shkp), eshk->debit, currency(eshk->debit));
4090 } else if (eshk->credit) {
4091 pline("%s encourages you to use your %ld %s of credit.",
4092 shkname(shkp), eshk->credit, currency(eshk->credit));
4093 } else if (eshk->robbed) {
4094 pline("%s complains about a recent robbery.", shkname(shkp));
4095 } else if ((shkmoney = money_cnt(shkp->minvent)) < 50) {
4096 pline("%s complains that business is bad.", shkname(shkp));
4097 } else if (shkmoney > 4000) {
4098 pline("%s says that business is good.", shkname(shkp));
4099 } else if (is_izchak(shkp, FALSE)) {
4100 pline(Izchak_speaks[rn2(SIZE(Izchak_speaks))], shkname(shkp));
4102 pline("%s talks about the problem of shoplifters.", shkname(shkp));
4110 register int cnt = 0;
4111 register struct monst *mtmp, *mtmp2;
4113 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
4115 if (mtmp->data->mlet == S_KOP) {
4116 if (canspotmon(mtmp))
4122 pline_The("Kop%s (disappointed) vanish%s into thin air.",
4123 plur(cnt), (cnt == 1) ? "es" : "");
4127 cost_per_charge(shkp, otmp, altusage)
4130 boolean altusage; /* some items have an "alternate" use with different cost */
4134 if (!shkp || !inhishop(shkp))
4135 return 0L; /* insurance */
4136 tmp = get_cost(otmp, shkp);
4138 /* The idea is to make the exhaustive use of an unpaid item
4139 * more expensive than buying it outright.
4141 if (otmp->otyp == MAGIC_LAMP) { /* 1 */
4142 /* normal use (ie, as light source) of a magic lamp never
4143 degrades its value, but not charging anything would make
4144 identification too easy; charge an amount comparable to
4145 what is charged for an ordinary lamp (don't bother with
4146 angry shk surcharge) */
4148 tmp = (long) objects[OIL_LAMP].oc_cost;
4150 tmp += tmp / 3L; /* djinni is being released */
4151 } else if (otmp->otyp == MAGIC_MARKER) { /* 70 - 100 */
4152 /* No way to determine in advance how many charges will be
4153 * wasted. So, arbitrarily, one half of the price per use.
4156 } else if (otmp->otyp == BAG_OF_TRICKS /* 1 - 20 */
4157 || otmp->otyp == HORN_OF_PLENTY) {
4158 /* altusage: emptying of all the contents at once */
4161 } else if (otmp->otyp == CRYSTAL_BALL /* 1 - 5 */
4162 || otmp->otyp == OIL_LAMP /* 1 - 10 */
4163 || otmp->otyp == BRASS_LANTERN
4164 || (otmp->otyp >= MAGIC_FLUTE
4165 && otmp->otyp <= DRUM_OF_EARTHQUAKE) /* 5 - 9 */
4166 || otmp->oclass == WAND_CLASS) { /* 3 - 11 */
4169 } else if (otmp->oclass == SPBOOK_CLASS) {
4171 } else if (otmp->otyp == CAN_OF_GREASE || otmp->otyp == TINNING_KIT
4172 || otmp->otyp == EXPENSIVE_CAMERA) {
4174 } else if (otmp->otyp == POT_OIL) {
4180 /* Charge the player for partial use of an unpaid object.
4182 * Note that bill_dummy_object() should be used instead
4183 * when an object is completely used.
4186 check_unpaid_usage(otmp, altusage)
4191 const char *fmt, *arg1, *arg2;
4195 if (!otmp->unpaid || !*u.ushops
4196 || (otmp->spe <= 0 && objects[otmp->otyp].oc_charged))
4198 if (!(shkp = shop_keeper(*u.ushops)) || !inhishop(shkp))
4200 if ((tmp = cost_per_charge(shkp, otmp, altusage)) == 0L)
4204 if (otmp->oclass == SPBOOK_CLASS) {
4205 fmt = "%sYou owe%s %ld %s.";
4206 Sprintf(buf, "This is no free library, %s! ", cad(FALSE));
4207 arg1 = rn2(2) ? buf : "";
4208 arg2 = ESHK(shkp)->debit > 0L ? " an additional" : "";
4209 } else if (otmp->otyp == POT_OIL) {
4210 fmt = "%s%sThat will cost you %ld %s (Yendorian Fuel Tax).";
4211 } else if (altusage && (otmp->otyp == BAG_OF_TRICKS
4212 || otmp->otyp == HORN_OF_PLENTY)) {
4213 fmt = "%s%sEmptying that will cost you %ld %s.";
4217 arg1 = "Watch it! ";
4219 fmt = "%s%sUsage fee, %ld %s.";
4226 if (!muteshk(shkp)) {
4227 verbalize(fmt, arg1, arg2, tmp, currency(tmp));
4228 exercise(A_WIS, TRUE); /* you just got info */
4230 ESHK(shkp)->debit += tmp;
4233 /* for using charges of unpaid objects "used in the normal manner" */
4238 check_unpaid_usage(otmp, FALSE); /* normal item use */
4242 costly_gold(x, y, amount)
4243 register xchar x, y;
4244 register long amount;
4246 register long delta;
4247 register struct monst *shkp;
4248 register struct eshk *eshkp;
4250 if (!costly_spot(x, y))
4252 /* shkp now guaranteed to exist by costly_spot() */
4253 shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
4256 if (eshkp->credit >= amount) {
4257 if (eshkp->credit > amount)
4258 Your("credit is reduced by %ld %s.", amount, currency(amount));
4260 Your("credit is erased.");
4261 eshkp->credit -= amount;
4263 delta = amount - eshkp->credit;
4265 Your("credit is erased.");
4267 Your("debt increases by %ld %s.", delta, currency(delta));
4269 You("owe %s %ld %s.", shkname(shkp), delta, currency(delta));
4270 eshkp->debit += delta;
4271 eshkp->loan += delta;
4276 /* used in domove to block diagonal shop-exit */
4277 /* x,y should always be a door */
4280 register xchar x, y;
4282 register int roomno = *in_rooms(x, y, SHOPBASE);
4283 register struct monst *shkp;
4285 if (roomno < 0 || !IS_SHOP(roomno))
4287 if (!IS_DOOR(levl[x][y].typ))
4289 if (roomno != *u.ushops)
4292 if (!(shkp = shop_keeper((char) roomno)) || !inhishop(shkp))
4295 if (shkp->mx == ESHK(shkp)->shk.x && shkp->my == ESHK(shkp)->shk.y
4296 /* Actually, the shk should be made to block _any_
4297 * door, including a door the player digs, if the
4298 * shk is within a 'jumping' distance.
4300 && ESHK(shkp)->shd.x == x
4301 && ESHK(shkp)->shd.y == y
4302 && shkp->mcanmove && !shkp->msleeping
4303 && (ESHK(shkp)->debit || ESHK(shkp)->billct || ESHK(shkp)->robbed)) {
4304 pline("%s%s blocks your way!", shkname(shkp),
4305 Invis ? " senses your motion and" : "");
4311 /* used in domove to block diagonal shop-entry;
4312 u.ux, u.uy should always be a door */
4315 register xchar x, y;
4317 register xchar sx, sy;
4318 register int roomno;
4319 register struct monst *shkp;
4321 if (!(IS_DOOR(levl[u.ux][u.uy].typ)
4322 && levl[u.ux][u.uy].doormask == D_BROKEN))
4325 roomno = *in_rooms(x, y, SHOPBASE);
4326 if (roomno < 0 || !IS_SHOP(roomno))
4328 if (!(shkp = shop_keeper((char) roomno)) || !inhishop(shkp))
4331 if (ESHK(shkp)->shd.x != u.ux || ESHK(shkp)->shd.y != u.uy)
4334 sx = ESHK(shkp)->shk.x;
4335 sy = ESHK(shkp)->shk.y;
4337 if (shkp->mx == sx && shkp->my == sy && shkp->mcanmove && !shkp->msleeping
4338 && (x == sx - 1 || x == sx + 1 || y == sy - 1 || y == sy + 1)
4339 && (Invis || carrying(PICK_AXE) || carrying(DWARVISH_MATTOCK)
4341 pline("%s%s blocks your way!", shkname(shkp),
4342 Invis ? " senses your motion and" : "");
4348 /* "your " or "Foobar's " (note the trailing space) */
4354 if (!shk_owns(buf, obj) && !mon_owns(buf, obj))
4355 Strcpy(buf, the_your[carried(obj) ? 1 : 0]);
4356 return strcat(buf, " ");
4364 (void) shk_your(buf, obj);
4377 if (get_obj_location(obj, &x, &y, 0)
4378 && (obj->unpaid || (obj->where == OBJ_FLOOR && !obj->no_charge
4379 && costly_spot(x, y)))) {
4380 shkp = shop_keeper(inside_shop(x, y));
4381 return strcpy(buf, shkp ? s_suffix(shkname(shkp)) : the_your[0]);
4391 if (obj->where == OBJ_MINVENT)
4392 return strcpy(buf, s_suffix(y_monnam(obj->ocarry)));
4396 STATIC_OVL const char *
4398 boolean altusage; /* used as a verbalized exclamation: \"Cad! ...\" */
4400 const char *res = 0;
4402 switch (is_demon(youmonst.data) ? 3 : poly_gender()) {
4416 impossible("cad: unknown gender");
4421 char *cadbuf = mon_nam(&youmonst); /* snag an output buffer */
4423 /* alternate usage adds a leading double quote and trailing
4424 exclamation point plus sentence separating spaces */
4425 Sprintf(cadbuf, "\"%s! ", res);
4426 cadbuf[1] = highc(cadbuf[1]);
4434 sasc_bug(struct obj *op, unsigned x)