141260Sbostic /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
241260Sbostic /* hack.shk.c - version 1.0.3 */
341260Sbostic
441260Sbostic #include "hack.h"
541260Sbostic #ifdef QUEST
641260Sbostic int shlevel = 0;
741260Sbostic struct monst *shopkeeper = 0;
841260Sbostic struct obj *billobjs = 0;
obfree(obj,merge)941260Sbostic obfree(obj,merge) register struct obj *obj, *merge; {
1041260Sbostic free((char *) obj);
1141260Sbostic }
inshop()1241260Sbostic inshop(){ return(0); }
shopdig()1341260Sbostic shopdig(){}
addtobill()1441260Sbostic addtobill(){}
subfrombill()1541260Sbostic subfrombill(){}
splitbill()1641260Sbostic splitbill(){}
dopay()1741260Sbostic dopay(){ return(0); }
paybill()1841260Sbostic paybill(){}
doinvbill()1941260Sbostic doinvbill(){ return(0); }
shkdead()2041260Sbostic shkdead(){}
shkcatch()2141260Sbostic shkcatch(){ return(0); }
shk_move()2241260Sbostic shk_move(){ return(0); }
2341260Sbostic replshk(mtmp,mtmp2) struct monst *mtmp, *mtmp2; {}
shkname()2441260Sbostic char *shkname(){ return(""); }
2541260Sbostic
2641260Sbostic #else QUEST
2741260Sbostic #include "hack.mfndpos.h"
2841260Sbostic #include "def.mkroom.h"
2941260Sbostic #include "def.eshk.h"
3041260Sbostic
3141260Sbostic #define ESHK(mon) ((struct eshk *)(&(mon->mextra[0])))
3241260Sbostic #define NOTANGRY(mon) mon->mpeaceful
3341260Sbostic #define ANGRY(mon) !NOTANGRY(mon)
3441260Sbostic
3541260Sbostic extern char plname[], *xname();
3641260Sbostic extern struct obj *o_on(), *bp_to_obj();
3741260Sbostic
3841260Sbostic /* Descriptor of current shopkeeper. Note that the bill need not be
3941260Sbostic per-shopkeeper, since it is valid only when in a shop. */
4041260Sbostic static struct monst *shopkeeper = 0;
4141260Sbostic static struct bill_x *bill;
4241260Sbostic static int shlevel = 0; /* level of this shopkeeper */
4341260Sbostic struct obj *billobjs; /* objects on bill with bp->useup */
4441260Sbostic /* only accessed here and by save & restore */
4541260Sbostic static long int total; /* filled by addupbill() */
4641260Sbostic static long int followmsg; /* last time of follow message */
4741260Sbostic
4841260Sbostic /*
4941260Sbostic invariants: obj->unpaid iff onbill(obj) [unless bp->useup]
5041260Sbostic obj->quan <= bp->bquan
5141260Sbostic */
5241260Sbostic
5341260Sbostic
5441260Sbostic char shtypes[] = { /* 8 shoptypes: 7 specialized, 1 mixed */
5541260Sbostic RING_SYM, WAND_SYM, WEAPON_SYM, FOOD_SYM, SCROLL_SYM,
5641260Sbostic POTION_SYM, ARMOR_SYM, 0
5741260Sbostic };
5841260Sbostic
5941260Sbostic static char *shopnam[] = {
6041260Sbostic "engagement ring", "walking cane", "antique weapon",
6141260Sbostic "delicatessen", "second hand book", "liquor",
6241260Sbostic "used armor", "assorted antiques"
6341260Sbostic };
6441260Sbostic
6541260Sbostic char *
shkname(mtmp)6641260Sbostic shkname(mtmp) /* called in do_name.c */
6741260Sbostic register struct monst *mtmp;
6841260Sbostic {
6941260Sbostic return(ESHK(mtmp)->shknam);
7041260Sbostic }
7141260Sbostic
72*47700Sbostic static void setpaid();
73*47700Sbostic
shkdead(mtmp)7441260Sbostic shkdead(mtmp) /* called in mon.c */
7541260Sbostic register struct monst *mtmp;
7641260Sbostic {
7741260Sbostic register struct eshk *eshk = ESHK(mtmp);
7841260Sbostic
7941260Sbostic if(eshk->shoplevel == dlevel)
8041260Sbostic rooms[eshk->shoproom].rtype = 0;
8141260Sbostic if(mtmp == shopkeeper) {
8241260Sbostic setpaid();
8341260Sbostic shopkeeper = 0;
8441260Sbostic bill = (struct bill_x *) -1000; /* dump core when referenced */
8541260Sbostic }
8641260Sbostic }
8741260Sbostic
replshk(mtmp,mtmp2)8841260Sbostic replshk(mtmp,mtmp2)
8941260Sbostic register struct monst *mtmp, *mtmp2;
9041260Sbostic {
9141260Sbostic if(mtmp == shopkeeper) {
9241260Sbostic shopkeeper = mtmp2;
9341260Sbostic bill = &(ESHK(shopkeeper)->bill[0]);
9441260Sbostic }
9541260Sbostic }
9641260Sbostic
97*47700Sbostic static void
setpaid()9841260Sbostic setpaid(){ /* caller has checked that shopkeeper exists */
9941260Sbostic /* either we paid or left the shop or he just died */
10041260Sbostic register struct obj *obj;
10141260Sbostic register struct monst *mtmp;
10241260Sbostic for(obj = invent; obj; obj = obj->nobj)
10341260Sbostic obj->unpaid = 0;
10441260Sbostic for(obj = fobj; obj; obj = obj->nobj)
10541260Sbostic obj->unpaid = 0;
10641260Sbostic for(obj = fcobj; obj; obj = obj->nobj)
10741260Sbostic obj->unpaid = 0;
10841260Sbostic for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
10941260Sbostic for(obj = mtmp->minvent; obj; obj = obj->nobj)
11041260Sbostic obj->unpaid = 0;
11141260Sbostic for(mtmp = fallen_down; mtmp; mtmp = mtmp->nmon)
11241260Sbostic for(obj = mtmp->minvent; obj; obj = obj->nobj)
11341260Sbostic obj->unpaid = 0;
11441260Sbostic while(obj = billobjs){
11541260Sbostic billobjs = obj->nobj;
11641260Sbostic free((char *) obj);
11741260Sbostic }
11841260Sbostic ESHK(shopkeeper)->billct = 0;
11941260Sbostic }
12041260Sbostic
12141260Sbostic static
addupbill()12241260Sbostic addupbill(){ /* delivers result in total */
12341260Sbostic /* caller has checked that shopkeeper exists */
12441260Sbostic register ct = ESHK(shopkeeper)->billct;
12541260Sbostic register struct bill_x *bp = bill;
12641260Sbostic total = 0;
12741260Sbostic while(ct--){
12841260Sbostic total += bp->price * bp->bquan;
12941260Sbostic bp++;
13041260Sbostic }
13141260Sbostic }
13241260Sbostic
inshop()13341260Sbostic inshop(){
13441260Sbostic register roomno = inroom(u.ux,u.uy);
13541260Sbostic
136*47700Sbostic static void findshk();
137*47700Sbostic
13841260Sbostic /* Did we just leave a shop? */
13941260Sbostic if(u.uinshop &&
14041260Sbostic (u.uinshop != roomno + 1 || shlevel != dlevel || !shopkeeper)) {
14141260Sbostic if(shopkeeper) {
14241260Sbostic if(ESHK(shopkeeper)->billct) {
14341260Sbostic if(inroom(shopkeeper->mx, shopkeeper->my)
14441260Sbostic == u.uinshop - 1) /* ab@unido */
14541260Sbostic pline("Somehow you escaped the shop without paying!");
14641260Sbostic addupbill();
14741260Sbostic pline("You stole for a total worth of %ld zorkmids.",
14841260Sbostic total);
14941260Sbostic ESHK(shopkeeper)->robbed += total;
15041260Sbostic setpaid();
15141260Sbostic if((rooms[ESHK(shopkeeper)->shoproom].rtype == GENERAL)
15241260Sbostic == (rn2(3) == 0))
15341260Sbostic ESHK(shopkeeper)->following = 1;
15441260Sbostic }
15541260Sbostic shopkeeper = 0;
15641260Sbostic shlevel = 0;
15741260Sbostic }
15841260Sbostic u.uinshop = 0;
15941260Sbostic }
16041260Sbostic
16141260Sbostic /* Did we just enter a zoo of some kind? */
16241260Sbostic if(roomno >= 0) {
16341260Sbostic register int rt = rooms[roomno].rtype;
16441260Sbostic register struct monst *mtmp;
16541260Sbostic if(rt == ZOO) {
16641260Sbostic pline("Welcome to David's treasure zoo!");
16741260Sbostic } else
16841260Sbostic if(rt == SWAMP) {
16941260Sbostic pline("It looks rather muddy down here.");
17041260Sbostic } else
17141260Sbostic if(rt == MORGUE) {
17241260Sbostic if(midnight())
17341260Sbostic pline("Go away! Go away!");
17441260Sbostic else
17541260Sbostic pline("You get an uncanny feeling ...");
17641260Sbostic } else
17741260Sbostic rt = 0;
17841260Sbostic if(rt != 0) {
17941260Sbostic rooms[roomno].rtype = 0;
18041260Sbostic for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
18141260Sbostic if(rt != ZOO || !rn2(3))
18241260Sbostic mtmp->msleep = 0;
18341260Sbostic }
18441260Sbostic }
18541260Sbostic
18641260Sbostic /* Did we just enter a shop? */
18741260Sbostic if(roomno >= 0 && rooms[roomno].rtype >= 8) {
18841260Sbostic if(shlevel != dlevel || !shopkeeper
18941260Sbostic || ESHK(shopkeeper)->shoproom != roomno)
19041260Sbostic findshk(roomno);
19141260Sbostic if(!shopkeeper) {
19241260Sbostic rooms[roomno].rtype = 0;
19341260Sbostic u.uinshop = 0;
19441260Sbostic } else if(!u.uinshop){
19541260Sbostic if(!ESHK(shopkeeper)->visitct ||
19641260Sbostic strncmp(ESHK(shopkeeper)->customer, plname, PL_NSIZ)){
19741260Sbostic
19841260Sbostic /* He seems to be new here */
19941260Sbostic ESHK(shopkeeper)->visitct = 0;
20041260Sbostic ESHK(shopkeeper)->following = 0;
20141260Sbostic (void) strncpy(ESHK(shopkeeper)->customer,plname,PL_NSIZ);
20241260Sbostic NOTANGRY(shopkeeper) = 1;
20341260Sbostic }
20441260Sbostic if(!ESHK(shopkeeper)->following) {
20541260Sbostic boolean box, pick;
20641260Sbostic
20741260Sbostic pline("Hello %s! Welcome%s to %s's %s shop!",
20841260Sbostic plname,
20941260Sbostic ESHK(shopkeeper)->visitct++ ? " again" : "",
21041260Sbostic shkname(shopkeeper),
21141260Sbostic shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8] );
21241260Sbostic box = carrying(ICE_BOX);
21341260Sbostic pick = carrying(PICK_AXE);
21441260Sbostic if(box || pick) {
21541260Sbostic if(dochug(shopkeeper)) {
21641260Sbostic u.uinshop = 0; /* he died moving */
21741260Sbostic return(0);
21841260Sbostic }
21941260Sbostic pline("Will you please leave your %s outside?",
22041260Sbostic (box && pick) ? "box and pick-axe" :
22141260Sbostic box ? "box" : "pick-axe");
22241260Sbostic }
22341260Sbostic }
22441260Sbostic u.uinshop = roomno + 1;
22541260Sbostic }
22641260Sbostic }
22741260Sbostic return(u.uinshop);
22841260Sbostic }
22941260Sbostic
230*47700Sbostic static void
findshk(roomno)23141260Sbostic findshk(roomno)
23241260Sbostic register roomno;
23341260Sbostic {
23441260Sbostic register struct monst *mtmp;
23541260Sbostic for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
23641260Sbostic if(mtmp->isshk && ESHK(mtmp)->shoproom == roomno
23741260Sbostic && ESHK(mtmp)->shoplevel == dlevel) {
23841260Sbostic shopkeeper = mtmp;
23941260Sbostic bill = &(ESHK(shopkeeper)->bill[0]);
24041260Sbostic shlevel = dlevel;
24141260Sbostic if(ANGRY(shopkeeper) &&
24241260Sbostic strncmp(ESHK(shopkeeper)->customer,plname,PL_NSIZ))
24341260Sbostic NOTANGRY(shopkeeper) = 1;
24441260Sbostic /* billobjs = 0; -- this is wrong if we save in a shop */
24541260Sbostic /* (and it is harmless to have too many things in billobjs) */
24641260Sbostic return;
24741260Sbostic }
24841260Sbostic shopkeeper = 0;
24941260Sbostic shlevel = 0;
25041260Sbostic bill = (struct bill_x *) -1000; /* dump core when referenced */
25141260Sbostic }
25241260Sbostic
25341260Sbostic static struct bill_x *
onbill(obj)25441260Sbostic onbill(obj) register struct obj *obj; {
25541260Sbostic register struct bill_x *bp;
25641260Sbostic if(!shopkeeper) return(0);
25741260Sbostic for(bp = bill; bp < &bill[ESHK(shopkeeper)->billct]; bp++)
25841260Sbostic if(bp->bo_id == obj->o_id) {
25941260Sbostic if(!obj->unpaid) pline("onbill: paid obj on bill?");
26041260Sbostic return(bp);
26141260Sbostic }
26241260Sbostic if(obj->unpaid) pline("onbill: unpaid obj not on bill?");
26341260Sbostic return(0);
26441260Sbostic }
26541260Sbostic
26641260Sbostic /* called with two args on merge */
obfree(obj,merge)26741260Sbostic obfree(obj,merge) register struct obj *obj, *merge; {
26841260Sbostic register struct bill_x *bp = onbill(obj);
26941260Sbostic register struct bill_x *bpm;
27041260Sbostic if(bp) {
27141260Sbostic if(!merge){
27241260Sbostic bp->useup = 1;
27341260Sbostic obj->unpaid = 0; /* only for doinvbill */
27441260Sbostic obj->nobj = billobjs;
27541260Sbostic billobjs = obj;
27641260Sbostic return;
27741260Sbostic }
27841260Sbostic bpm = onbill(merge);
27941260Sbostic if(!bpm){
28041260Sbostic /* this used to be a rename */
28141260Sbostic impossible("obfree: not on bill??");
28241260Sbostic return;
28341260Sbostic } else {
28441260Sbostic /* this was a merger */
28541260Sbostic bpm->bquan += bp->bquan;
28641260Sbostic ESHK(shopkeeper)->billct--;
28741260Sbostic *bp = bill[ESHK(shopkeeper)->billct];
28841260Sbostic }
28941260Sbostic }
29041260Sbostic free((char *) obj);
29141260Sbostic }
29241260Sbostic
29341260Sbostic static
pay(tmp,shkp)29441260Sbostic pay(tmp,shkp)
29541260Sbostic long tmp;
29641260Sbostic register struct monst *shkp;
29741260Sbostic {
29841260Sbostic long robbed = ESHK(shkp)->robbed;
29941260Sbostic
30041260Sbostic u.ugold -= tmp;
30141260Sbostic shkp->mgold += tmp;
30241260Sbostic flags.botl = 1;
30341260Sbostic if(robbed) {
30441260Sbostic robbed -= tmp;
30541260Sbostic if(robbed < 0) robbed = 0;
30641260Sbostic ESHK(shkp)->robbed = robbed;
30741260Sbostic }
30841260Sbostic }
30941260Sbostic
dopay()31041260Sbostic dopay(){
31141260Sbostic long ltmp;
31241260Sbostic register struct bill_x *bp;
31341260Sbostic register struct monst *shkp;
31441260Sbostic int pass, tmp;
31541260Sbostic
316*47700Sbostic static int dopayobj();
317*47700Sbostic
31841260Sbostic multi = 0;
31941260Sbostic (void) inshop();
32041260Sbostic for(shkp = fmon; shkp; shkp = shkp->nmon)
32141260Sbostic if(shkp->isshk && dist(shkp->mx,shkp->my) < 3)
32241260Sbostic break;
32341260Sbostic if(!shkp && u.uinshop &&
32441260Sbostic inroom(shopkeeper->mx,shopkeeper->my) == ESHK(shopkeeper)->shoproom)
32541260Sbostic shkp = shopkeeper;
32641260Sbostic
32741260Sbostic if(!shkp) {
32841260Sbostic pline("There is nobody here to receive your payment.");
32941260Sbostic return(0);
33041260Sbostic }
33141260Sbostic ltmp = ESHK(shkp)->robbed;
33241260Sbostic if(shkp != shopkeeper && NOTANGRY(shkp)) {
33341260Sbostic if(!ltmp) {
33441260Sbostic pline("You do not owe %s anything.", monnam(shkp));
33541260Sbostic } else
33641260Sbostic if(!u.ugold) {
33741260Sbostic pline("You have no money.");
33841260Sbostic } else {
33941260Sbostic long ugold = u.ugold;
34041260Sbostic
34141260Sbostic if(u.ugold > ltmp) {
34241260Sbostic pline("You give %s the %ld gold pieces he asked for.",
34341260Sbostic monnam(shkp), ltmp);
34441260Sbostic pay(ltmp, shkp);
34541260Sbostic } else {
34641260Sbostic pline("You give %s all your gold.", monnam(shkp));
34741260Sbostic pay(u.ugold, shkp);
34841260Sbostic }
34941260Sbostic if(ugold < ltmp/2) {
35041260Sbostic pline("Unfortunately, he doesn't look satisfied.");
35141260Sbostic } else {
35241260Sbostic ESHK(shkp)->robbed = 0;
35341260Sbostic ESHK(shkp)->following = 0;
35441260Sbostic if(ESHK(shkp)->shoplevel != dlevel) {
35541260Sbostic /* For convenience's sake, let him disappear */
35641260Sbostic shkp->minvent = 0; /* %% */
35741260Sbostic shkp->mgold = 0;
35841260Sbostic mondead(shkp);
35941260Sbostic }
36041260Sbostic }
36141260Sbostic }
36241260Sbostic return(1);
36341260Sbostic }
36441260Sbostic
36541260Sbostic if(!ESHK(shkp)->billct){
36641260Sbostic pline("You do not owe %s anything.", monnam(shkp));
36741260Sbostic if(!u.ugold){
36841260Sbostic pline("Moreover, you have no money.");
36941260Sbostic return(1);
37041260Sbostic }
37141260Sbostic if(ESHK(shkp)->robbed){
37241260Sbostic #define min(a,b) ((a<b)?a:b)
37341260Sbostic pline("But since his shop has been robbed recently,");
37441260Sbostic pline("you %srepay %s's expenses.",
37541260Sbostic (u.ugold < ESHK(shkp)->robbed) ? "partially " : "",
37641260Sbostic monnam(shkp));
37741260Sbostic pay(min(u.ugold, ESHK(shkp)->robbed), shkp);
37841260Sbostic ESHK(shkp)->robbed = 0;
37941260Sbostic return(1);
38041260Sbostic }
38141260Sbostic if(ANGRY(shkp)){
38241260Sbostic pline("But in order to appease %s,",
38341260Sbostic amonnam(shkp, "angry"));
38441260Sbostic if(u.ugold >= 1000){
38541260Sbostic ltmp = 1000;
38641260Sbostic pline(" you give him 1000 gold pieces.");
38741260Sbostic } else {
38841260Sbostic ltmp = u.ugold;
38941260Sbostic pline(" you give him all your money.");
39041260Sbostic }
39141260Sbostic pay(ltmp, shkp);
39241260Sbostic if(strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)
39341260Sbostic || rn2(3)){
39441260Sbostic pline("%s calms down.", Monnam(shkp));
39541260Sbostic NOTANGRY(shkp) = 1;
39641260Sbostic } else pline("%s is as angry as ever.",
39741260Sbostic Monnam(shkp));
39841260Sbostic }
39941260Sbostic return(1);
40041260Sbostic }
40141260Sbostic if(shkp != shopkeeper) {
40241260Sbostic impossible("dopay: not to shopkeeper?");
40341260Sbostic if(shopkeeper) setpaid();
40441260Sbostic return(0);
40541260Sbostic }
40641260Sbostic for(pass = 0; pass <= 1; pass++) {
40741260Sbostic tmp = 0;
40841260Sbostic while(tmp < ESHK(shopkeeper)->billct) {
40941260Sbostic bp = &bill[tmp];
41041260Sbostic if(!pass && !bp->useup) {
41141260Sbostic tmp++;
41241260Sbostic continue;
41341260Sbostic }
41441260Sbostic if(!dopayobj(bp)) return(1);
41541260Sbostic bill[tmp] = bill[--ESHK(shopkeeper)->billct];
41641260Sbostic }
41741260Sbostic }
41841260Sbostic pline("Thank you for shopping in %s's %s store!",
41941260Sbostic shkname(shopkeeper),
42041260Sbostic shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]);
42141260Sbostic NOTANGRY(shopkeeper) = 1;
42241260Sbostic return(1);
42341260Sbostic }
42441260Sbostic
42541260Sbostic /* return 1 if paid successfully */
42641260Sbostic /* 0 if not enough money */
42741260Sbostic /* -1 if object could not be found (but was paid) */
42841260Sbostic static
dopayobj(bp)42941260Sbostic dopayobj(bp) register struct bill_x *bp; {
43041260Sbostic register struct obj *obj;
43141260Sbostic long ltmp;
43241260Sbostic
43341260Sbostic /* find the object on one of the lists */
43441260Sbostic obj = bp_to_obj(bp);
43541260Sbostic
43641260Sbostic if(!obj) {
43741260Sbostic impossible("Shopkeeper administration out of order.");
43841260Sbostic setpaid(); /* be nice to the player */
43941260Sbostic return(0);
44041260Sbostic }
44141260Sbostic
44241260Sbostic if(!obj->unpaid && !bp->useup){
44341260Sbostic impossible("Paid object on bill??");
44441260Sbostic return(1);
44541260Sbostic }
44641260Sbostic obj->unpaid = 0;
44741260Sbostic ltmp = bp->price * bp->bquan;
44841260Sbostic if(ANGRY(shopkeeper)) ltmp += ltmp/3;
44941260Sbostic if(u.ugold < ltmp){
45041260Sbostic pline("You don't have gold enough to pay %s.",
45141260Sbostic doname(obj));
45241260Sbostic obj->unpaid = 1;
45341260Sbostic return(0);
45441260Sbostic }
45541260Sbostic pay(ltmp, shopkeeper);
45641260Sbostic pline("You bought %s for %ld gold piece%s.",
45741260Sbostic doname(obj), ltmp, plur(ltmp));
45841260Sbostic if(bp->useup) {
45941260Sbostic register struct obj *otmp = billobjs;
46041260Sbostic if(obj == billobjs)
46141260Sbostic billobjs = obj->nobj;
46241260Sbostic else {
46341260Sbostic while(otmp && otmp->nobj != obj) otmp = otmp->nobj;
46441260Sbostic if(otmp) otmp->nobj = obj->nobj;
46541260Sbostic else pline("Error in shopkeeper administration.");
46641260Sbostic }
46741260Sbostic free((char *) obj);
46841260Sbostic }
46941260Sbostic return(1);
47041260Sbostic }
47141260Sbostic
47241260Sbostic /* routine called after dying (or quitting) with nonempty bill */
paybill()47341260Sbostic paybill(){
47441260Sbostic if(shlevel == dlevel && shopkeeper && ESHK(shopkeeper)->billct){
47541260Sbostic addupbill();
47641260Sbostic if(total > u.ugold){
47741260Sbostic shopkeeper->mgold += u.ugold;
47841260Sbostic u.ugold = 0;
47941260Sbostic pline("%s comes and takes all your possessions.",
48041260Sbostic Monnam(shopkeeper));
48141260Sbostic } else {
48241260Sbostic u.ugold -= total;
48341260Sbostic shopkeeper->mgold += total;
48441260Sbostic pline("%s comes and takes the %ld zorkmids you owed him.",
48541260Sbostic Monnam(shopkeeper), total);
48641260Sbostic }
48741260Sbostic setpaid(); /* in case we create bones */
48841260Sbostic }
48941260Sbostic }
49041260Sbostic
49141260Sbostic /* find obj on one of the lists */
49241260Sbostic struct obj *
bp_to_obj(bp)49341260Sbostic bp_to_obj(bp)
49441260Sbostic register struct bill_x *bp;
49541260Sbostic {
49641260Sbostic register struct obj *obj;
49741260Sbostic register struct monst *mtmp;
49841260Sbostic register unsigned id = bp->bo_id;
49941260Sbostic
50041260Sbostic if(bp->useup)
50141260Sbostic obj = o_on(id, billobjs);
50241260Sbostic else if(!(obj = o_on(id, invent)) &&
50341260Sbostic !(obj = o_on(id, fobj)) &&
50441260Sbostic !(obj = o_on(id, fcobj))) {
50541260Sbostic for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
50641260Sbostic if(obj = o_on(id, mtmp->minvent))
50741260Sbostic break;
50841260Sbostic for(mtmp = fallen_down; mtmp; mtmp = mtmp->nmon)
50941260Sbostic if(obj = o_on(id, mtmp->minvent))
51041260Sbostic break;
51141260Sbostic }
51241260Sbostic return(obj);
51341260Sbostic }
51441260Sbostic
515*47700Sbostic static int getprice();
516*47700Sbostic
51741260Sbostic /* called in hack.c when we pickup an object */
addtobill(obj)51841260Sbostic addtobill(obj) register struct obj *obj; {
51941260Sbostic register struct bill_x *bp;
52041260Sbostic if(!inshop() ||
52141260Sbostic (u.ux == ESHK(shopkeeper)->shk.x && u.uy == ESHK(shopkeeper)->shk.y) ||
52241260Sbostic (u.ux == ESHK(shopkeeper)->shd.x && u.uy == ESHK(shopkeeper)->shd.y) ||
52341260Sbostic onbill(obj) /* perhaps we threw it away earlier */
52441260Sbostic ) return;
52541260Sbostic if(ESHK(shopkeeper)->billct == BILLSZ){
52641260Sbostic pline("You got that for free!");
52741260Sbostic return;
52841260Sbostic }
52941260Sbostic bp = &bill[ESHK(shopkeeper)->billct];
53041260Sbostic bp->bo_id = obj->o_id;
53141260Sbostic bp->bquan = obj->quan;
53241260Sbostic bp->useup = 0;
53341260Sbostic bp->price = getprice(obj);
53441260Sbostic ESHK(shopkeeper)->billct++;
53541260Sbostic obj->unpaid = 1;
53641260Sbostic }
53741260Sbostic
splitbill(obj,otmp)53841260Sbostic splitbill(obj,otmp) register struct obj *obj, *otmp; {
53941260Sbostic /* otmp has been split off from obj */
54041260Sbostic register struct bill_x *bp;
54141260Sbostic register int tmp;
54241260Sbostic bp = onbill(obj);
54341260Sbostic if(!bp) {
54441260Sbostic impossible("splitbill: not on bill?");
54541260Sbostic return;
54641260Sbostic }
54741260Sbostic if(bp->bquan < otmp->quan) {
54841260Sbostic impossible("Negative quantity on bill??");
54941260Sbostic }
55041260Sbostic if(bp->bquan == otmp->quan) {
55141260Sbostic impossible("Zero quantity on bill??");
55241260Sbostic }
55341260Sbostic bp->bquan -= otmp->quan;
55441260Sbostic
55541260Sbostic /* addtobill(otmp); */
55641260Sbostic if(ESHK(shopkeeper)->billct == BILLSZ) otmp->unpaid = 0;
55741260Sbostic else {
55841260Sbostic tmp = bp->price;
55941260Sbostic bp = &bill[ESHK(shopkeeper)->billct];
56041260Sbostic bp->bo_id = otmp->o_id;
56141260Sbostic bp->bquan = otmp->quan;
56241260Sbostic bp->useup = 0;
56341260Sbostic bp->price = tmp;
56441260Sbostic ESHK(shopkeeper)->billct++;
56541260Sbostic }
56641260Sbostic }
56741260Sbostic
subfrombill(obj)56841260Sbostic subfrombill(obj) register struct obj *obj; {
56941260Sbostic long ltmp;
57041260Sbostic register int tmp;
57141260Sbostic register struct obj *otmp;
57241260Sbostic register struct bill_x *bp;
57341260Sbostic if(!inshop() || (u.ux == ESHK(shopkeeper)->shk.x && u.uy == ESHK(shopkeeper)->shk.y) ||
57441260Sbostic (u.ux == ESHK(shopkeeper)->shd.x && u.uy == ESHK(shopkeeper)->shd.y))
57541260Sbostic return;
57641260Sbostic if((bp = onbill(obj)) != 0){
57741260Sbostic obj->unpaid = 0;
57841260Sbostic if(bp->bquan > obj->quan){
57941260Sbostic otmp = newobj(0);
58041260Sbostic *otmp = *obj;
58141260Sbostic bp->bo_id = otmp->o_id = flags.ident++;
58241260Sbostic otmp->quan = (bp->bquan -= obj->quan);
58341260Sbostic otmp->owt = 0; /* superfluous */
58441260Sbostic otmp->onamelth = 0;
58541260Sbostic bp->useup = 1;
58641260Sbostic otmp->nobj = billobjs;
58741260Sbostic billobjs = otmp;
58841260Sbostic return;
58941260Sbostic }
59041260Sbostic ESHK(shopkeeper)->billct--;
59141260Sbostic *bp = bill[ESHK(shopkeeper)->billct];
59241260Sbostic return;
59341260Sbostic }
59441260Sbostic if(obj->unpaid){
59541260Sbostic pline("%s didn't notice.", Monnam(shopkeeper));
59641260Sbostic obj->unpaid = 0;
59741260Sbostic return; /* %% */
59841260Sbostic }
59941260Sbostic /* he dropped something of his own - probably wants to sell it */
60041260Sbostic if(shopkeeper->msleep || shopkeeper->mfroz ||
60141260Sbostic inroom(shopkeeper->mx,shopkeeper->my) != ESHK(shopkeeper)->shoproom)
60241260Sbostic return;
60341260Sbostic if(ESHK(shopkeeper)->billct == BILLSZ ||
60441260Sbostic ((tmp = shtypes[rooms[ESHK(shopkeeper)->shoproom].rtype-8]) && tmp != obj->olet)
60541260Sbostic || index("_0", obj->olet)) {
60641260Sbostic pline("%s seems not interested.", Monnam(shopkeeper));
60741260Sbostic return;
60841260Sbostic }
60941260Sbostic ltmp = getprice(obj) * obj->quan;
61041260Sbostic if(ANGRY(shopkeeper)) {
61141260Sbostic ltmp /= 3;
61241260Sbostic NOTANGRY(shopkeeper) = 1;
61341260Sbostic } else ltmp /= 2;
61441260Sbostic if(ESHK(shopkeeper)->robbed){
61541260Sbostic if((ESHK(shopkeeper)->robbed -= ltmp) < 0)
61641260Sbostic ESHK(shopkeeper)->robbed = 0;
61741260Sbostic pline("Thank you for your contribution to restock this recently plundered shop.");
61841260Sbostic return;
61941260Sbostic }
62041260Sbostic if(ltmp > shopkeeper->mgold)
62141260Sbostic ltmp = shopkeeper->mgold;
62241260Sbostic pay(-ltmp, shopkeeper);
62341260Sbostic if(!ltmp)
62441260Sbostic pline("%s gladly accepts %s but cannot pay you at present.",
62541260Sbostic Monnam(shopkeeper), doname(obj));
62641260Sbostic else
62741260Sbostic pline("You sold %s and got %ld gold piece%s.", doname(obj), ltmp,
62841260Sbostic plur(ltmp));
62941260Sbostic }
63041260Sbostic
doinvbill(mode)63141260Sbostic doinvbill(mode)
63241260Sbostic int mode; /* 0: deliver count 1: paged */
63341260Sbostic {
63441260Sbostic register struct bill_x *bp;
63541260Sbostic register struct obj *obj;
63641260Sbostic long totused, thisused;
63741260Sbostic char buf[BUFSZ];
63841260Sbostic
63941260Sbostic if(mode == 0) {
64041260Sbostic register int cnt = 0;
64141260Sbostic
64241260Sbostic if(shopkeeper)
64341260Sbostic for(bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++)
64441260Sbostic if(bp->useup ||
64541260Sbostic ((obj = bp_to_obj(bp)) && obj->quan < bp->bquan))
64641260Sbostic cnt++;
64741260Sbostic return(cnt);
64841260Sbostic }
64941260Sbostic
65041260Sbostic if(!shopkeeper) {
65141260Sbostic impossible("doinvbill: no shopkeeper?");
65241260Sbostic return(0);
65341260Sbostic }
65441260Sbostic
65541260Sbostic set_pager(0);
65641260Sbostic if(page_line("Unpaid articles already used up:") || page_line(""))
65741260Sbostic goto quit;
65841260Sbostic
65941260Sbostic totused = 0;
66041260Sbostic for(bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++) {
66141260Sbostic obj = bp_to_obj(bp);
66241260Sbostic if(!obj) {
66341260Sbostic impossible("Bad shopkeeper administration.");
66441260Sbostic goto quit;
66541260Sbostic }
66641260Sbostic if(bp->useup || bp->bquan > obj->quan) {
66741260Sbostic register int cnt, oquan, uquan;
66841260Sbostic
66941260Sbostic oquan = obj->quan;
67041260Sbostic uquan = (bp->useup ? bp->bquan : bp->bquan - oquan);
67141260Sbostic thisused = bp->price * uquan;
67241260Sbostic totused += thisused;
67341260Sbostic obj->quan = uquan; /* cheat doname */
67441260Sbostic (void) sprintf(buf, "x - %s", doname(obj));
67541260Sbostic obj->quan = oquan; /* restore value */
67641260Sbostic for(cnt = 0; buf[cnt]; cnt++);
67741260Sbostic while(cnt < 50)
67841260Sbostic buf[cnt++] = ' ';
67941260Sbostic (void) sprintf(&buf[cnt], " %5ld zorkmids", thisused);
68041260Sbostic if(page_line(buf))
68141260Sbostic goto quit;
68241260Sbostic }
68341260Sbostic }
68441260Sbostic (void) sprintf(buf, "Total:%50ld zorkmids", totused);
68541260Sbostic if(page_line("") || page_line(buf))
68641260Sbostic goto quit;
68741260Sbostic set_pager(1);
68841260Sbostic return(0);
68941260Sbostic quit:
69041260Sbostic set_pager(2);
69141260Sbostic return(0);
69241260Sbostic }
69341260Sbostic
69441260Sbostic static
getprice(obj)69541260Sbostic getprice(obj) register struct obj *obj; {
69641260Sbostic register int tmp, ac;
697*47700Sbostic static int realhunger();
698*47700Sbostic
69941260Sbostic switch(obj->olet){
70041260Sbostic case AMULET_SYM:
70141260Sbostic tmp = 10*rnd(500);
70241260Sbostic break;
70341260Sbostic case TOOL_SYM:
70441260Sbostic tmp = 10*rnd((obj->otyp == EXPENSIVE_CAMERA) ? 150 : 30);
70541260Sbostic break;
70641260Sbostic case RING_SYM:
70741260Sbostic tmp = 10*rnd(100);
70841260Sbostic break;
70941260Sbostic case WAND_SYM:
71041260Sbostic tmp = 10*rnd(100);
71141260Sbostic break;
71241260Sbostic case SCROLL_SYM:
71341260Sbostic tmp = 10*rnd(50);
71441260Sbostic #ifdef MAIL
71541260Sbostic if(obj->otyp == SCR_MAIL)
71641260Sbostic tmp = rnd(5);
71741260Sbostic #endif MAIL
71841260Sbostic break;
71941260Sbostic case POTION_SYM:
72041260Sbostic tmp = 10*rnd(50);
72141260Sbostic break;
72241260Sbostic case FOOD_SYM:
72341260Sbostic tmp = 10*rnd(5 + (2000/realhunger()));
72441260Sbostic break;
72541260Sbostic case GEM_SYM:
72641260Sbostic tmp = 10*rnd(20);
72741260Sbostic break;
72841260Sbostic case ARMOR_SYM:
72941260Sbostic ac = ARM_BONUS(obj);
73041260Sbostic if(ac <= -10) /* probably impossible */
73141260Sbostic ac = -9;
73241260Sbostic tmp = 100 + ac*ac*rnd(10+ac);
73341260Sbostic break;
73441260Sbostic case WEAPON_SYM:
73541260Sbostic if(obj->otyp < BOOMERANG)
73641260Sbostic tmp = 5*rnd(10);
73741260Sbostic else if(obj->otyp == LONG_SWORD ||
73841260Sbostic obj->otyp == TWO_HANDED_SWORD)
73941260Sbostic tmp = 10*rnd(150);
74041260Sbostic else tmp = 10*rnd(75);
74141260Sbostic break;
74241260Sbostic case CHAIN_SYM:
74341260Sbostic pline("Strange ..., carrying a chain?");
74441260Sbostic case BALL_SYM:
74541260Sbostic tmp = 10;
74641260Sbostic break;
74741260Sbostic default:
74841260Sbostic tmp = 10000;
74941260Sbostic }
75041260Sbostic return(tmp);
75141260Sbostic }
75241260Sbostic
75341260Sbostic static
realhunger()75441260Sbostic realhunger(){ /* not completely foolproof */
75541260Sbostic register tmp = u.uhunger;
75641260Sbostic register struct obj *otmp = invent;
75741260Sbostic while(otmp){
75841260Sbostic if(otmp->olet == FOOD_SYM && !otmp->unpaid)
75941260Sbostic tmp += objects[otmp->otyp].nutrition;
76041260Sbostic otmp = otmp->nobj;
76141260Sbostic }
76241260Sbostic return((tmp <= 0) ? 1 : tmp);
76341260Sbostic }
76441260Sbostic
shkcatch(obj)76541260Sbostic shkcatch(obj)
76641260Sbostic register struct obj *obj;
76741260Sbostic {
76841260Sbostic register struct monst *shkp = shopkeeper;
76941260Sbostic
77041260Sbostic if(u.uinshop && shkp && !shkp->mfroz && !shkp->msleep &&
77141260Sbostic u.dx && u.dy &&
77241260Sbostic inroom(u.ux+u.dx, u.uy+u.dy) + 1 == u.uinshop &&
77341260Sbostic shkp->mx == ESHK(shkp)->shk.x && shkp->my == ESHK(shkp)->shk.y &&
77441260Sbostic u.ux == ESHK(shkp)->shd.x && u.uy == ESHK(shkp)->shd.y) {
77541260Sbostic pline("%s nimbly catches the %s.", Monnam(shkp), xname(obj));
77641260Sbostic obj->nobj = shkp->minvent;
77741260Sbostic shkp->minvent = obj;
77841260Sbostic return(1);
77941260Sbostic }
78041260Sbostic return(0);
78141260Sbostic }
78241260Sbostic
78341260Sbostic /*
78441260Sbostic * shk_move: return 1: he moved 0: he didnt -1: let m_move do it
78541260Sbostic */
shk_move(shkp)78641260Sbostic shk_move(shkp)
78741260Sbostic register struct monst *shkp;
78841260Sbostic {
78941260Sbostic register struct monst *mtmp;
79041260Sbostic register struct permonst *mdat = shkp->data;
79141260Sbostic register xchar gx,gy,omx,omy,nx,ny,nix,niy;
79241260Sbostic register schar appr,i;
79341260Sbostic register int udist;
79441260Sbostic int z;
79541260Sbostic schar shkroom,chi,chcnt,cnt;
79641260Sbostic boolean uondoor, satdoor, avoid, badinv;
79741260Sbostic coord poss[9];
79841260Sbostic int info[9];
79941260Sbostic struct obj *ib = 0;
80041260Sbostic
80141260Sbostic omx = shkp->mx;
80241260Sbostic omy = shkp->my;
80341260Sbostic
80441260Sbostic if((udist = dist(omx,omy)) < 3) {
80541260Sbostic if(ANGRY(shkp)) {
80641260Sbostic (void) hitu(shkp, d(mdat->damn, mdat->damd)+1);
80741260Sbostic return(0);
80841260Sbostic }
80941260Sbostic if(ESHK(shkp)->following) {
81041260Sbostic if(strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)){
81141260Sbostic pline("Hello %s! I was looking for %s.",
81241260Sbostic plname, ESHK(shkp)->customer);
81341260Sbostic ESHK(shkp)->following = 0;
81441260Sbostic return(0);
81541260Sbostic }
81641260Sbostic if(!ESHK(shkp)->robbed) { /* impossible? */
81741260Sbostic ESHK(shkp)->following = 0;
81841260Sbostic return(0);
81941260Sbostic }
82041260Sbostic if(moves > followmsg+4) {
82141260Sbostic pline("Hello %s! Didn't you forget to pay?",
82241260Sbostic plname);
82341260Sbostic followmsg = moves;
82441260Sbostic }
82541260Sbostic if(udist < 2)
82641260Sbostic return(0);
82741260Sbostic }
82841260Sbostic }
82941260Sbostic
83041260Sbostic shkroom = inroom(omx,omy);
83141260Sbostic appr = 1;
83241260Sbostic gx = ESHK(shkp)->shk.x;
83341260Sbostic gy = ESHK(shkp)->shk.y;
83441260Sbostic satdoor = (gx == omx && gy == omy);
83541260Sbostic if(ESHK(shkp)->following || ((z = holetime()) >= 0 && z*z <= udist)){
83641260Sbostic gx = u.ux;
83741260Sbostic gy = u.uy;
83841260Sbostic if(shkroom < 0 || shkroom != inroom(u.ux,u.uy))
83941260Sbostic if(udist > 4)
84041260Sbostic return(-1); /* leave it to m_move */
84141260Sbostic } else if(ANGRY(shkp)) {
84241260Sbostic long saveBlind = Blind;
84341260Sbostic Blind = 0;
84441260Sbostic if(shkp->mcansee && !Invis && cansee(omx,omy)) {
84541260Sbostic gx = u.ux;
84641260Sbostic gy = u.uy;
84741260Sbostic }
84841260Sbostic Blind = saveBlind;
84941260Sbostic avoid = FALSE;
85041260Sbostic } else {
85141260Sbostic #define GDIST(x,y) ((x-gx)*(x-gx)+(y-gy)*(y-gy))
85241260Sbostic if(Invis)
85341260Sbostic avoid = FALSE;
85441260Sbostic else {
85541260Sbostic uondoor = (u.ux == ESHK(shkp)->shd.x &&
85641260Sbostic u.uy == ESHK(shkp)->shd.y);
85741260Sbostic if(uondoor) {
85841260Sbostic if(ESHK(shkp)->billct)
85941260Sbostic pline("Hello %s! Will you please pay before leaving?",
86041260Sbostic plname);
86141260Sbostic badinv = (carrying(PICK_AXE) || carrying(ICE_BOX));
86241260Sbostic if(satdoor && badinv)
86341260Sbostic return(0);
86441260Sbostic avoid = !badinv;
86541260Sbostic } else {
86641260Sbostic avoid = (u.uinshop && dist(gx,gy) > 8);
86741260Sbostic badinv = FALSE;
86841260Sbostic }
86941260Sbostic
87041260Sbostic if(((!ESHK(shkp)->robbed && !ESHK(shkp)->billct) || avoid)
87141260Sbostic && GDIST(omx,omy) < 3){
87241260Sbostic if(!badinv && !online(omx,omy))
87341260Sbostic return(0);
87441260Sbostic if(satdoor)
87541260Sbostic appr = gx = gy = 0;
87641260Sbostic }
87741260Sbostic }
87841260Sbostic }
87941260Sbostic if(omx == gx && omy == gy)
88041260Sbostic return(0);
88141260Sbostic if(shkp->mconf) {
88241260Sbostic avoid = FALSE;
88341260Sbostic appr = 0;
88441260Sbostic }
88541260Sbostic nix = omx;
88641260Sbostic niy = omy;
88741260Sbostic cnt = mfndpos(shkp,poss,info,ALLOW_SSM);
88841260Sbostic if(avoid && uondoor) { /* perhaps we cannot avoid him */
88941260Sbostic for(i=0; i<cnt; i++)
89041260Sbostic if(!(info[i] & NOTONL)) goto notonl_ok;
89141260Sbostic avoid = FALSE;
89241260Sbostic notonl_ok:
89341260Sbostic ;
89441260Sbostic }
89541260Sbostic chi = -1;
89641260Sbostic chcnt = 0;
89741260Sbostic for(i=0; i<cnt; i++){
89841260Sbostic nx = poss[i].x;
89941260Sbostic ny = poss[i].y;
90041260Sbostic if(levl[nx][ny].typ == ROOM
90141260Sbostic || shkroom != ESHK(shkp)->shoproom
90241260Sbostic || ESHK(shkp)->following) {
90341260Sbostic #ifdef STUPID
90441260Sbostic /* cater for stupid compilers */
90541260Sbostic register int zz;
90641260Sbostic #endif STUPID
90741260Sbostic if(uondoor && (ib = sobj_at(ICE_BOX, nx, ny))) {
90841260Sbostic nix = nx; niy = ny; chi = i; break;
90941260Sbostic }
91041260Sbostic if(avoid && (info[i] & NOTONL))
91141260Sbostic continue;
91241260Sbostic if((!appr && !rn2(++chcnt)) ||
91341260Sbostic #ifdef STUPID
91441260Sbostic (appr && (zz = GDIST(nix,niy)) && zz > GDIST(nx,ny))
91541260Sbostic #else
91641260Sbostic (appr && GDIST(nx,ny) < GDIST(nix,niy))
91741260Sbostic #endif STUPID
91841260Sbostic ) {
91941260Sbostic nix = nx;
92041260Sbostic niy = ny;
92141260Sbostic chi = i;
92241260Sbostic }
92341260Sbostic }
92441260Sbostic }
92541260Sbostic if(nix != omx || niy != omy){
92641260Sbostic if(info[chi] & ALLOW_M){
92741260Sbostic mtmp = m_at(nix,niy);
92841260Sbostic if(hitmm(shkp,mtmp) == 1 && rn2(3) &&
92941260Sbostic hitmm(mtmp,shkp) == 2) return(2);
93041260Sbostic return(0);
93141260Sbostic } else if(info[chi] & ALLOW_U){
93241260Sbostic (void) hitu(shkp, d(mdat->damn, mdat->damd)+1);
93341260Sbostic return(0);
93441260Sbostic }
93541260Sbostic shkp->mx = nix;
93641260Sbostic shkp->my = niy;
93741260Sbostic pmon(shkp);
93841260Sbostic if(ib) {
93941260Sbostic freeobj(ib);
94041260Sbostic mpickobj(shkp, ib);
94141260Sbostic }
94241260Sbostic return(1);
94341260Sbostic }
94441260Sbostic return(0);
94541260Sbostic }
94641260Sbostic
94741260Sbostic /* He is digging in the shop. */
shopdig(fall)94841260Sbostic shopdig(fall)
94941260Sbostic register int fall;
95041260Sbostic {
95141260Sbostic if(!fall) {
95241260Sbostic if(u.utraptype == TT_PIT)
95341260Sbostic pline("\"Be careful, sir, or you might fall through the floor.\"");
95441260Sbostic else
95541260Sbostic pline("\"Please, do not damage the floor here.\"");
95641260Sbostic } else if(dist(shopkeeper->mx, shopkeeper->my) < 3) {
95741260Sbostic register struct obj *obj, *obj2;
95841260Sbostic
95941260Sbostic pline("%s grabs your backpack!", shkname(shopkeeper));
96041260Sbostic for(obj = invent; obj; obj = obj2) {
96141260Sbostic obj2 = obj->nobj;
96241260Sbostic if(obj->owornmask) continue;
96341260Sbostic freeinv(obj);
96441260Sbostic obj->nobj = shopkeeper->minvent;
96541260Sbostic shopkeeper->minvent = obj;
96641260Sbostic if(obj->unpaid)
96741260Sbostic subfrombill(obj);
96841260Sbostic }
96941260Sbostic }
97041260Sbostic }
97141260Sbostic #endif QUEST
97241260Sbostic
online(x,y)97341260Sbostic online(x,y) {
97441260Sbostic return(x==u.ux || y==u.uy ||
97541260Sbostic (x-u.ux)*(x-u.ux) == (y-u.uy)*(y-u.uy));
97641260Sbostic }
97741260Sbostic
97841260Sbostic /* Does this monster follow me downstairs? */
follower(mtmp)97941260Sbostic follower(mtmp)
98041260Sbostic register struct monst *mtmp;
98141260Sbostic {
98241260Sbostic return( mtmp->mtame || index("1TVWZi&, ", mtmp->data->mlet)
98341260Sbostic #ifndef QUEST
98441260Sbostic || (mtmp->isshk && ESHK(mtmp)->following)
98541260Sbostic #endif QUEST
98641260Sbostic );
98741260Sbostic }
988