home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume10 / nethack3p9 / part09 < prev    next >
Internet Message Format  |  1990-07-12  |  60KB

  1. Path: uunet!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!wuarchive!mit-eddie!uw-beaver!zephyr.ens.tek.com!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v10i054:  nethack3p9 -  display oriented dungeons & dragons (Ver. 3.0i), Part09/56
  5. Message-ID: <5909@tekred.CNA.TEK.COM>
  6. Date: 12 Jul 90 00:29:38 GMT
  7. Sender: news@tekred.CNA.TEK.COM
  8. Lines: 2080
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
  12. Posting-number: Volume 10, Issue 54
  13. Archive-name: nethack3p9/Part09
  14. Supersedes: NetHack3: Volume 7, Issue 56-93
  15.  
  16.  
  17.  
  18. #! /bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 9 (of 56)."
  25. # Contents:  others/random.c src/shk.c
  26. # Wrapped by billr@saab on Wed Jul 11 17:11:02 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'others/random.c' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'others/random.c'\"
  30. else
  31. echo shar: Extracting \"'others/random.c'\" \(13466 characters\)
  32. sed "s/^X//" >'others/random.c' <<'END_OF_FILE'
  33. X/*
  34. X * Copyright (c) 1983 Regents of the University of California.
  35. X * All rights reserved.
  36. X *
  37. X * Redistribution and use in source and binary forms are permitted
  38. X * provided that the above copyright notice and this paragraph are
  39. X * duplicated in all such forms and that any documentation,
  40. X * advertising materials, and other materials related to such
  41. X * distribution and use acknowledge that the software was developed
  42. X * by the University of California, Berkeley.  The name of the
  43. X * University may not be used to endorse or promote products derived
  44. X * from this software without specific prior written permission.
  45. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  46. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  47. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  48. X */
  49. X
  50. X/* Several minor changes were made for the NetHack distribution to satisfy
  51. X * non-BSD compilers (by definition BSD compilers do not need to compile
  52. X * this file for NetHack).  These changes consisted of:
  53. X *    - changing the sccsid conditions to nested ifdefs from defined()s
  54. X *    to accommodate stupid preprocessors
  55. X *    - giving srandom() type void instead of allowing it to default to int
  56. X *    - making the first return in initstate() return a value consistent
  57. X *    with its type (instead of no value)
  58. X *    - ANSI function prototyping in extern.h - therefore include hack.h
  59. X *    instead of stdio.h and remove separate declaration of random() from
  60. X *    the beginning of function srandom
  61. X */
  62. X
  63. X#ifdef LIBC_SCCS
  64. X# ifndef lint
  65. Xstatic char sccsid[] = "@(#)random.c    5.5 (Berkeley) 7/6/88";
  66. X# endif
  67. X#endif /* LIBC_SCCS and not lint */
  68. X
  69. X#include "hack.h"
  70. X
  71. X/*
  72. X * random.c:
  73. X * An improved random number generation package.  In addition to the standard
  74. X * rand()/srand() like interface, this package also has a special state info
  75. X * interface.  The initstate() routine is called with a seed, an array of
  76. X * bytes, and a count of how many bytes are being passed in; this array is then
  77. X * initialized to contain information for random number generation with that
  78. X * much state information.  Good sizes for the amount of state information are
  79. X * 32, 64, 128, and 256 bytes.  The state can be switched by calling the
  80. X * setstate() routine with the same array as was initiallized with initstate().
  81. X * By default, the package runs with 128 bytes of state information and
  82. X * generates far better random numbers than a linear congruential generator.
  83. X * If the amount of state information is less than 32 bytes, a simple linear
  84. X * congruential R.N.G. is used.
  85. X * Internally, the state information is treated as an array of longs; the
  86. X * zeroeth element of the array is the type of R.N.G. being used (small
  87. X * integer); the remainder of the array is the state information for the
  88. X * R.N.G.  Thus, 32 bytes of state information will give 7 longs worth of
  89. X * state information, which will allow a degree seven polynomial.  (Note: the 
  90. X * zeroeth word of state information also has some other information stored
  91. X * in it -- see setstate() for details).
  92. X * The random number generation technique is a linear feedback shift register
  93. X * approach, employing trinomials (since there are fewer terms to sum up that
  94. X * way).  In this approach, the least significant bit of all the numbers in
  95. X * the state table will act as a linear feedback shift register, and will have
  96. X * period 2^deg - 1 (where deg is the degree of the polynomial being used,
  97. X * assuming that the polynomial is irreducible and primitive).  The higher
  98. X * order bits will have longer periods, since their values are also influenced
  99. X * by pseudo-random carries out of the lower bits.  The total period of the
  100. X * generator is approximately deg*(2**deg - 1); thus doubling the amount of
  101. X * state information has a vast influence on the period of the generator.
  102. X * Note: the deg*(2**deg - 1) is an approximation only good for large deg,
  103. X * when the period of the shift register is the dominant factor.  With deg
  104. X * equal to seven, the period is actually much longer than the 7*(2**7 - 1)
  105. X * predicted by this formula.
  106. X */
  107. X
  108. X
  109. X
  110. X/*
  111. X * For each of the currently supported random number generators, we have a
  112. X * break value on the amount of state information (you need at least this
  113. X * many bytes of state info to support this random number generator), a degree
  114. X * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
  115. X * the separation between the two lower order coefficients of the trinomial.
  116. X */
  117. X
  118. X#define        TYPE_0        0        /* linear congruential */
  119. X#define        BREAK_0        8
  120. X#define        DEG_0        0
  121. X#define        SEP_0        0
  122. X
  123. X#define        TYPE_1        1        /* x**7 + x**3 + 1 */
  124. X#define        BREAK_1        32
  125. X#define        DEG_1        7
  126. X#define        SEP_1        3
  127. X
  128. X#define        TYPE_2        2        /* x**15 + x + 1 */
  129. X#define        BREAK_2        64
  130. X#define        DEG_2        15
  131. X#define        SEP_2        1
  132. X
  133. X#define        TYPE_3        3        /* x**31 + x**3 + 1 */
  134. X#define        BREAK_3        128
  135. X#define        DEG_3        31
  136. X#define        SEP_3        3
  137. X
  138. X#define        TYPE_4        4        /* x**63 + x + 1 */
  139. X#define        BREAK_4        256
  140. X#define        DEG_4        63
  141. X#define        SEP_4        1
  142. X
  143. X
  144. X/*
  145. X * Array versions of the above information to make code run faster -- relies
  146. X * on fact that TYPE_i == i.
  147. X */
  148. X
  149. X#define        MAX_TYPES    5        /* max number of types above */
  150. X
  151. Xstatic  int        degrees[ MAX_TYPES ]    = { DEG_0, DEG_1, DEG_2,
  152. X                                DEG_3, DEG_4 };
  153. X
  154. Xstatic  int        seps[ MAX_TYPES ]    = { SEP_0, SEP_1, SEP_2,
  155. X                                SEP_3, SEP_4 };
  156. X
  157. X
  158. X
  159. X/*
  160. X * Initially, everything is set up as if from :
  161. X *        initstate( 1, &randtbl, 128 );
  162. X * Note that this initialization takes advantage of the fact that srandom()
  163. X * advances the front and rear pointers 10*rand_deg times, and hence the
  164. X * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
  165. X * element of the state information, which contains info about the current
  166. X * position of the rear pointer is just
  167. X *    MAX_TYPES*(rptr - state) + TYPE_3 == TYPE_3.
  168. X */
  169. X
  170. Xstatic  long        randtbl[ DEG_3 + 1 ]    = { TYPE_3,
  171. X                0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 
  172. X                0xde3b81e0, 0xdf0a6fb5, 0xf103bc02, 0x48f340fb, 
  173. X                0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, 
  174. X                0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 
  175. X                0xda672e2a, 0x1588ca88, 0xe369735d, 0x904f35f7, 
  176. X                0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, 
  177. X                0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 
  178. X                    0xf5ad9d0e, 0x8999220b, 0x27fb47b9 };
  179. X
  180. X/*
  181. X * fptr and rptr are two pointers into the state info, a front and a rear
  182. X * pointer.  These two pointers are always rand_sep places aparts, as they cycle
  183. X * cyclically through the state information.  (Yes, this does mean we could get
  184. X * away with just one pointer, but the code for random() is more efficient this
  185. X * way).  The pointers are left positioned as they would be from the call
  186. X *            initstate( 1, randtbl, 128 )
  187. X * (The position of the rear pointer, rptr, is really 0 (as explained above
  188. X * in the initialization of randtbl) because the state table pointer is set
  189. X * to point to randtbl[1] (as explained below).
  190. X */
  191. X
  192. Xstatic  long        *fptr            = &randtbl[ SEP_3 + 1 ];
  193. Xstatic  long        *rptr            = &randtbl[ 1 ];
  194. X
  195. X
  196. X
  197. X/*
  198. X * The following things are the pointer to the state information table,
  199. X * the type of the current generator, the degree of the current polynomial
  200. X * being used, and the separation between the two pointers.
  201. X * Note that for efficiency of random(), we remember the first location of
  202. X * the state information, not the zeroeth.  Hence it is valid to access
  203. X * state[-1], which is used to store the type of the R.N.G.
  204. X * Also, we remember the last location, since this is more efficient than
  205. X * indexing every time to find the address of the last element to see if
  206. X * the front and rear pointers have wrapped.
  207. X */
  208. X
  209. Xstatic  long        *state            = &randtbl[ 1 ];
  210. X
  211. Xstatic  int        rand_type        = TYPE_3;
  212. Xstatic  int        rand_deg        = DEG_3;
  213. Xstatic  int        rand_sep        = SEP_3;
  214. X
  215. Xstatic  long        *end_ptr        = &randtbl[ DEG_3 + 1 ];
  216. X
  217. X
  218. X
  219. X/*
  220. X * srandom:
  221. X * Initialize the random number generator based on the given seed.  If the
  222. X * type is the trivial no-state-information type, just remember the seed.
  223. X * Otherwise, initializes state[] based on the given "seed" via a linear
  224. X * congruential generator.  Then, the pointers are set to known locations
  225. X * that are exactly rand_sep places apart.  Lastly, it cycles the state
  226. X * information a given number of times to get rid of any initial dependencies
  227. X * introduced by the L.C.R.N.G.
  228. X * Note that the initialization of randtbl[] for default usage relies on
  229. X * values produced by this routine.
  230. X */
  231. X
  232. Xvoid
  233. Xsrandom( x )
  234. X
  235. X    unsigned        x;
  236. X{
  237. X        register  int        i, j;
  238. X
  239. X    if(  rand_type  ==  TYPE_0  )  {
  240. X        state[ 0 ] = x;
  241. X    }
  242. X    else  {
  243. X        j = 1;
  244. X        state[ 0 ] = x;
  245. X        for( i = 1; i < rand_deg; i++ )  {
  246. X        state[i] = 1103515245*state[i - 1] + 12345;
  247. X        }
  248. X        fptr = &state[ rand_sep ];
  249. X        rptr = &state[ 0 ];
  250. X        for( i = 0; i < 10*rand_deg; i++ )  random();
  251. X    }
  252. X}
  253. X
  254. X
  255. X
  256. X/*
  257. X * initstate:
  258. X * Initialize the state information in the given array of n bytes for
  259. X * future random number generation.  Based on the number of bytes we
  260. X * are given, and the break values for the different R.N.G.'s, we choose
  261. X * the best (largest) one we can and set things up for it.  srandom() is
  262. X * then called to initialize the state information.
  263. X * Note that on return from srandom(), we set state[-1] to be the type
  264. X * multiplexed with the current value of the rear pointer; this is so
  265. X * successive calls to initstate() won't lose this information and will
  266. X * be able to restart with setstate().
  267. X * Note: the first thing we do is save the current state, if any, just like
  268. X * setstate() so that it doesn't matter when initstate is called.
  269. X * Returns a pointer to the old state.
  270. X */
  271. X
  272. Xchar  *
  273. Xinitstate( seed, arg_state, n )
  274. X
  275. X    unsigned        seed;            /* seed for R. N. G. */
  276. X    char        *arg_state;        /* pointer to state array */
  277. X    int            n;            /* # bytes of state info */
  278. X{
  279. X    register  char        *ostate        = (char *)( &state[ -1 ] );
  280. X
  281. X    if(  rand_type  ==  TYPE_0  )  state[ -1 ] = rand_type;
  282. X    else  state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type;
  283. X    if(  n  <  BREAK_1  )  {
  284. X        if(  n  <  BREAK_0  )  {
  285. X        fprintf( stderr, "initstate: not enough state (%d bytes) with which to do jack; ignored.\n", n );
  286. X        return (char *)0;
  287. X        }
  288. X        rand_type = TYPE_0;
  289. X        rand_deg = DEG_0;
  290. X        rand_sep = SEP_0;
  291. X    }
  292. X    else  {
  293. X        if(  n  <  BREAK_2  )  {
  294. X        rand_type = TYPE_1;
  295. X        rand_deg = DEG_1;
  296. X        rand_sep = SEP_1;
  297. X        }
  298. X        else  {
  299. X        if(  n  <  BREAK_3  )  {
  300. X            rand_type = TYPE_2;
  301. X            rand_deg = DEG_2;
  302. X            rand_sep = SEP_2;
  303. X        }
  304. X        else  {
  305. X            if(  n  <  BREAK_4  )  {
  306. X            rand_type = TYPE_3;
  307. X            rand_deg = DEG_3;
  308. X            rand_sep = SEP_3;
  309. X            }
  310. X            else  {
  311. X            rand_type = TYPE_4;
  312. X            rand_deg = DEG_4;
  313. X            rand_sep = SEP_4;
  314. X            }
  315. X        }
  316. X        }
  317. X    }
  318. X    state = &(  ( (long *)arg_state )[1]  );    /* first location */
  319. X    end_ptr = &state[ rand_deg ];    /* must set end_ptr before srandom */
  320. X    srandom( seed );
  321. X    if(  rand_type  ==  TYPE_0  )  state[ -1 ] = rand_type;
  322. X    else  state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type;
  323. X    return( ostate );
  324. X}
  325. X
  326. X
  327. X
  328. X/*
  329. X * setstate:
  330. X * Restore the state from the given state array.
  331. X * Note: it is important that we also remember the locations of the pointers
  332. X * in the current state information, and restore the locations of the pointers
  333. X * from the old state information.  This is done by multiplexing the pointer
  334. X * location into the zeroeth word of the state information.
  335. X * Note that due to the order in which things are done, it is OK to call
  336. X * setstate() with the same state as the current state.
  337. X * Returns a pointer to the old state information.
  338. X */
  339. X
  340. Xchar  *
  341. Xsetstate( arg_state )
  342. X
  343. X    char        *arg_state;
  344. X{
  345. X    register  long        *new_state    = (long *)arg_state;
  346. X    register  int        type        = new_state[0]%MAX_TYPES;
  347. X    register  int        rear        = new_state[0]/MAX_TYPES;
  348. X    char            *ostate        = (char *)( &state[ -1 ] );
  349. X
  350. X    if(  rand_type  ==  TYPE_0  )  state[ -1 ] = rand_type;
  351. X    else  state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type;
  352. X    switch(  type  )  {
  353. X        case  TYPE_0:
  354. X        case  TYPE_1:
  355. X        case  TYPE_2:
  356. X        case  TYPE_3:
  357. X        case  TYPE_4:
  358. X        rand_type = type;
  359. X        rand_deg = degrees[ type ];
  360. X        rand_sep = seps[ type ];
  361. X        break;
  362. X
  363. X        default:
  364. X        fprintf( stderr, "setstate: state info has been munged; not changed.\n" );
  365. X    }
  366. X    state = &new_state[ 1 ];
  367. X    if(  rand_type  !=  TYPE_0  )  {
  368. X        rptr = &state[ rear ];
  369. X        fptr = &state[ (rear + rand_sep)%rand_deg ];
  370. X    }
  371. X    end_ptr = &state[ rand_deg ];        /* set end_ptr too */
  372. X    return( ostate );
  373. X}
  374. X
  375. X
  376. X
  377. X/*
  378. X * random:
  379. X * If we are using the trivial TYPE_0 R.N.G., just do the old linear
  380. X * congruential bit.  Otherwise, we do our fancy trinomial stuff, which is the
  381. X * same in all ther other cases due to all the global variables that have been
  382. X * set up.  The basic operation is to add the number at the rear pointer into
  383. X * the one at the front pointer.  Then both pointers are advanced to the next
  384. X * location cyclically in the table.  The value returned is the sum generated,
  385. X * reduced to 31 bits by throwing away the "least random" low bit.
  386. X * Note: the code takes advantage of the fact that both the front and
  387. X * rear pointers can't wrap on the same call by not testing the rear
  388. X * pointer if the front one has wrapped.
  389. X * Returns a 31-bit random number.
  390. X */
  391. X
  392. Xlong
  393. Xrandom()
  394. X{
  395. X    long        i;
  396. X    
  397. X    if(  rand_type  ==  TYPE_0  )  {
  398. X        i = state[0] = ( state[0]*1103515245 + 12345 )&0x7fffffff;
  399. X    }
  400. X    else  {
  401. X        *fptr += *rptr;
  402. X        i = (*fptr >> 1)&0x7fffffff;    /* chucking least random bit */
  403. X        if(  ++fptr  >=  end_ptr  )  {
  404. X        fptr = state;
  405. X        ++rptr;
  406. X        }
  407. X        else  {
  408. X        if(  ++rptr  >=  end_ptr  )  rptr = state;
  409. X        }
  410. X    }
  411. X    return( i );
  412. X}
  413. X
  414. END_OF_FILE
  415. if test 13466 -ne `wc -c <'others/random.c'`; then
  416.     echo shar: \"'others/random.c'\" unpacked with wrong size!
  417. fi
  418. # end of 'others/random.c'
  419. fi
  420. if test -f 'src/shk.c' -a "${1}" != "-c" ; then 
  421.   echo shar: Will not clobber existing file \"'src/shk.c'\"
  422. else
  423. echo shar: Extracting \"'src/shk.c'\" \(42124 characters\)
  424. sed "s/^X//" >'src/shk.c' <<'END_OF_FILE'
  425. X/*    SCCS Id: @(#)shk.c    3.0    89/11/27
  426. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  427. X/* NetHack may be freely redistributed.  See license for details. */
  428. X
  429. X#define MONATTK_H    /* comment line for pre-compiled headers */
  430. X/* block some unused #defines to avoid overloading some cpp's */
  431. X#include "hack.h"
  432. X
  433. X#include "eshk.h"
  434. X
  435. X
  436. X# ifdef KOPS
  437. XSTATIC_DCL int FDECL(makekops, (coord *));
  438. X# ifdef OVLB
  439. Xstatic void NDECL(kops_gone);
  440. X# endif /* OVLB */
  441. X#endif /* KOPS */
  442. X
  443. X#define    NOTANGRY(mon)    mon->mpeaceful
  444. X#define    ANGRY(mon)    !NOTANGRY(mon)
  445. X
  446. X/* Descriptor of current shopkeeper. Note that the bill need not be
  447. X   per-shopkeeper, since it is valid only when in a shop. */
  448. XSTATIC_VAR struct monst NEARDATA *shopkeeper;
  449. XSTATIC_VAR struct bill_x NEARDATA *bill;
  450. XSTATIC_VAR int NEARDATA shlevel; /* level of this shopkeeper */
  451. X/* struct obj *billobjs;    /* objects on bill with bp->useup */
  452. X                /* only accessed here and by save & restore */
  453. XSTATIC_VAR long int NEARDATA total;     /* filled by addupbill() */
  454. XSTATIC_VAR long int NEARDATA followmsg;    /* last time of follow message */
  455. X
  456. XSTATIC_DCL void NDECL(setpaid);
  457. XSTATIC_DCL void NDECL(addupbill);
  458. XSTATIC_DCL boolean FDECL(monstinroom, (struct permonst *,int));
  459. XSTATIC_DCL void FDECL(findshk, (int));
  460. X
  461. X#ifdef OVLB
  462. X
  463. Xstatic struct bill_x * FDECL(onbill, (struct obj *));
  464. Xstatic long FDECL(check_credit, (long,struct monst *));
  465. Xstatic void FDECL(pay, (long,struct monst *));
  466. Xstatic unsigned FDECL(get_cost, (struct obj *));
  467. Xstatic unsigned FDECL(cost_per_charge, (struct obj *));
  468. Xstatic int FDECL(dopayobj, (struct bill_x *)), FDECL(getprice, (struct obj *));
  469. Xstatic struct obj *FDECL(bp_to_obj, (struct bill_x *));
  470. X
  471. X/*
  472. X    invariants: obj->unpaid iff onbill(obj) [unless bp->useup]
  473. X        obj->quan <= bp->bquan
  474. X */
  475. X
  476. Xchar *
  477. Xshkname(mtmp)                /* called in do_name.c */
  478. Xregister struct monst *mtmp;
  479. X{
  480. X    return(ESHK(mtmp)->shknam);
  481. X}
  482. X
  483. Xvoid
  484. Xshkdead(mtmp)                /* called in mon.c */
  485. Xregister struct monst *mtmp;
  486. X{
  487. X    register struct eshk *eshk = ESHK(mtmp);
  488. X
  489. X    if(eshk->shoplevel == dlevel)
  490. X        rooms[eshk->shoproom].rtype = OROOM;
  491. X    if(mtmp == shopkeeper) {
  492. X        setpaid();
  493. X        shopkeeper = 0;
  494. X        bill = (struct bill_x *) -1000;    /* dump core when referenced */
  495. X    }
  496. X}
  497. X
  498. Xvoid
  499. Xreplshk(mtmp,mtmp2)
  500. Xregister struct monst *mtmp, *mtmp2;
  501. X{
  502. X    if(mtmp == shopkeeper) {
  503. X        shopkeeper = mtmp2;
  504. X        bill = &(ESHK(shopkeeper)->bill[0]);
  505. X    }
  506. X}
  507. X
  508. XSTATIC_OVL void
  509. Xsetpaid(){    /* caller has checked that shopkeeper exists */
  510. X        /* either we paid or left the shop or he just died */
  511. X    register struct obj *obj;
  512. X    register struct monst *mtmp;
  513. X    for(obj = invent; obj; obj = obj->nobj)
  514. X        obj->unpaid = 0;
  515. X    for(obj = fobj; obj; obj = obj->nobj)
  516. X        obj->unpaid = 0;
  517. X    for(obj = fcobj; obj; obj = obj->nobj)
  518. X        obj->unpaid = 0;
  519. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  520. X        for(obj = mtmp->minvent; obj; obj = obj->nobj)
  521. X            obj->unpaid = 0;
  522. X    for(mtmp = fallen_down; mtmp; mtmp = mtmp->nmon)
  523. X        for(obj = mtmp->minvent; obj; obj = obj->nobj)
  524. X            obj->unpaid = 0;
  525. X    while(obj = billobjs){
  526. X        billobjs = obj->nobj;
  527. X        free((genericptr_t) obj);
  528. X    }
  529. X    if(shopkeeper) {
  530. X        ESHK(shopkeeper)->billct = 0;
  531. X        ESHK(shopkeeper)->credit = 0L;
  532. X        ESHK(shopkeeper)->debit = 0L;
  533. X    }
  534. X}
  535. X
  536. XSTATIC_OVL void
  537. Xaddupbill(){    /* delivers result in total */
  538. X        /* caller has checked that shopkeeper exists */
  539. X    register int ct = ESHK(shopkeeper)->billct;
  540. X    register struct bill_x *bp = bill;
  541. X    total = 0;
  542. X    while(ct--){
  543. X        total += bp->price * bp->bquan;
  544. X        bp++;
  545. X    }
  546. X}
  547. X
  548. XSTATIC_OVL boolean
  549. Xmonstinroom(mdat,roomno)
  550. Xstruct permonst *mdat;
  551. Xint roomno;
  552. X{
  553. X    register struct monst *mtmp;
  554. X
  555. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  556. X        if(mtmp->data == mdat && inroom(mtmp->mx,mtmp->my) == roomno)
  557. X            return(TRUE);
  558. X    return(FALSE);
  559. X}
  560. X
  561. X#endif /* OVLB */
  562. X#ifdef OVL1
  563. X
  564. Xint
  565. Xinshop() {
  566. X    register int roomno = inroom(u.ux,u.uy);
  567. X
  568. X    /* Did we just leave a shop? */
  569. X    if(u.uinshop &&
  570. X        (u.uinshop != roomno + 1 || shlevel != dlevel || !shopkeeper)) {
  571. X
  572. X    /* This is part of the bugfix for shopkeepers not having their
  573. X     * bill paid.  As reported by ab@unido -dgk
  574. X     * I made this standard due to the KOPS code below. -mrs
  575. X     */
  576. X        if(shopkeeper) {
  577. X            if(ESHK(shopkeeper)->billct || ESHK(shopkeeper)->debit) {
  578. X            if(inroom(shopkeeper->mx, shopkeeper->my)
  579. X                == u.uinshop - 1)    /* ab@unido */
  580. X                You("escaped the shop without paying!");
  581. X            addupbill();
  582. X            total += ESHK(shopkeeper)->debit;
  583. X            You("stole %ld zorkmid%s worth of merchandise.",
  584. X                total, plur(total));
  585. X            ESHK(shopkeeper)->robbed += total;
  586. X            ESHK(shopkeeper)->credit = 0L;
  587. X            ESHK(shopkeeper)->debit = 0L;
  588. X            if (pl_character[0] != 'R') /* stealing is unlawful */
  589. X                adjalign(-sgn(u.ualigntyp));
  590. X            setpaid();
  591. X            if((rooms[ESHK(shopkeeper)->shoproom].rtype == SHOPBASE)
  592. X                == (rn2(3) == 0))
  593. X                ESHK(shopkeeper)->following = 1;
  594. X#ifdef KOPS
  595. X            {   /* Keystone Kops srt@ucla */
  596. X            coord mm;
  597. X
  598. X            if (flags.soundok)
  599. X                pline("An alarm sounds throughout the dungeon!");
  600. X            if(flags.verbose) {
  601. X                if((mons[PM_KEYSTONE_KOP].geno & G_GENOD) &&
  602. X                    (mons[PM_KOP_SERGEANT].geno & G_GENOD) &&
  603. X                    (mons[PM_KOP_LIEUTENANT].geno & G_GENOD) &&
  604. X                   (mons[PM_KOP_KAPTAIN].geno & G_GENOD)) {
  605. X                if (flags.soundok)
  606. X                    pline("But no one seems to respond to it.");
  607. X                } else
  608. X                pline("The Keystone Kops are after you!");
  609. X            }
  610. X            /* Create a swarm near the staircase */
  611. X            mm.x = xdnstair;
  612. X            mm.y = ydnstair;
  613. X            (void) makekops(&mm);
  614. X            /* Create a swarm near the shopkeeper */
  615. X            mm.x = shopkeeper->mx;
  616. X            mm.y = shopkeeper->my;
  617. X            (void) makekops(&mm);
  618. X            }
  619. X#endif
  620. X            }
  621. X            shopkeeper = 0;
  622. X            shlevel = 0;
  623. X        }
  624. X        u.uinshop = 0;
  625. X    }
  626. X
  627. X    /* Did we just enter a zoo of some kind? */
  628. X    /* This counts everything except shops and vaults
  629. X       -- vault.c insists that a vault remain a VAULT */
  630. X    if(roomno >= 0) {
  631. X        register int rt = rooms[roomno].rtype;
  632. X        register struct monst *mtmp;
  633. X
  634. X        switch (rt) {
  635. X        case ZOO:
  636. X            pline("Welcome to David's treasure zoo!");
  637. X            break;
  638. X        case SWAMP:
  639. X            pline("It looks rather muddy down here.");
  640. X            break;
  641. X#ifdef THRONES
  642. X        case COURT:
  643. X            You("enter an opulent throne room!");
  644. X            break;
  645. X#endif
  646. X        case MORGUE:
  647. X            if(midnight())
  648. X            pline("Run away!  Run away!");
  649. X            else
  650. X            You("have an uncanny feeling...");
  651. X            break;
  652. X        case BEEHIVE:
  653. X            You("enter a giant beehive!");
  654. X            break;
  655. X#ifdef ARMY
  656. X        case BARRACKS:
  657. X            if(monstinroom(&mons[PM_SOLDIER], roomno) ||
  658. X                monstinroom(&mons[PM_SERGEANT], roomno) ||
  659. X                monstinroom(&mons[PM_LIEUTENANT], roomno) ||
  660. X                monstinroom(&mons[PM_CAPTAIN], roomno))
  661. X                You("enter a military barracks!");
  662. X            else You("enter an abandoned barracks.");
  663. X            break;
  664. X#endif
  665. X#ifdef ORACLE
  666. X        case DELPHI:
  667. X            if(monstinroom(&mons[PM_ORACLE], roomno))
  668. X                pline("\"Hello, %s, welcome to Delphi!\"", plname);
  669. X            break;
  670. X#endif
  671. X        default:
  672. X            rt = 0;
  673. X        }
  674. X
  675. X        if(rt != 0) {
  676. X            rooms[roomno].rtype = OROOM;
  677. X            if(rt==COURT || rt==SWAMP || rt==MORGUE || rt==ZOO)
  678. X            for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  679. X                /* was if(rt != ZOO || !rn2(3)) -- why should ZOO
  680. X                   be different from COURT or MORGUE? */
  681. X                if(!Stealth && !rn2(3))
  682. X                mtmp->msleep = 0;
  683. X        }
  684. X    }
  685. X#if defined(ALTARS) && defined(THEOLOGY)
  686. X    if(roomno >= 0 && rooms[roomno].rtype == TEMPLE) {
  687. X        intemple();
  688. X    }
  689. X#endif
  690. X    /* Did we just enter a shop? */
  691. X    if(roomno >= 0 && rooms[roomno].rtype >= SHOPBASE) {
  692. X        register int rt = rooms[roomno].rtype;
  693. X
  694. X        if(shlevel != dlevel || !shopkeeper
  695. X                 || ESHK(shopkeeper)->shoproom != roomno)
  696. X        findshk(roomno);
  697. X        if(!shopkeeper) {
  698. X        rooms[roomno].rtype = OROOM;
  699. X        u.uinshop = 0;
  700. X        } else if(!u.uinshop){
  701. X        if(!ESHK(shopkeeper)->visitct ||
  702. X           strncmp(ESHK(shopkeeper)->customer, plname, PL_NSIZ)) {
  703. X            /* He seems to be new here */
  704. X            ESHK(shopkeeper)->visitct = 0;
  705. X            ESHK(shopkeeper)->following = 0;
  706. X            (void) strncpy(ESHK(shopkeeper)->customer,plname,PL_NSIZ);
  707. X            NOTANGRY(shopkeeper) = 1;
  708. X        }
  709. X        if(!ESHK(shopkeeper)->following && inhishop(shopkeeper)) {
  710. X            if(Invis) {
  711. X            pline("%s senses your presence.", shkname(shopkeeper));
  712. X            verbalize("Invisible customers are not welcome!");
  713. X            }
  714. X            else
  715. X            if(ANGRY(shopkeeper))
  716. X            pline("\"So, %s, you dare return to %s's %s?!\"",
  717. X                plname,
  718. X                shkname(shopkeeper),
  719. X                shtypes[rt - SHOPBASE].name);
  720. X            else
  721. X            if(ESHK(shopkeeper)->robbed)
  722. X            pline("\"Beware, %s!  I am upset about missing stock!\"",
  723. X                plname);
  724. X            else
  725. X            pline("\"Hello, %s!  Welcome%s to %s's %s!\"",
  726. X                plname,
  727. X                ESHK(shopkeeper)->visitct++ ? " again" : "",
  728. X                shkname(shopkeeper),
  729. X                shtypes[rt - SHOPBASE].name);
  730. X            if(carrying(PICK_AXE) != (struct obj *)0 && !Invis) {
  731. X            verbalize(NOTANGRY(shopkeeper) ?
  732. X               "Will you please leave your pick-axe outside?" :
  733. X               "Leave the pick-axe outside.");
  734. X            if(dochug(shopkeeper)) {
  735. X                u.uinshop = 0;    /* he died moving */
  736. X                return(0);
  737. X            }
  738. X            }
  739. X        }
  740. X        u.uinshop = (unsigned int)(roomno + 1);
  741. X        }
  742. X    }
  743. X    return (int)u.uinshop;
  744. X}
  745. X
  746. X#endif /* OVL1 */
  747. X#ifdef OVLB
  748. X
  749. Xint
  750. Xinhishop(mtmp)
  751. Xregister struct monst *mtmp;
  752. X{
  753. X    return((ESHK(mtmp)->shoproom == inroom(mtmp->mx, mtmp->my) &&
  754. X        ESHK(mtmp)->shoplevel == dlevel));
  755. X}
  756. X
  757. X#ifdef SOUNDS
  758. Xboolean
  759. Xtended_shop(sroom)
  760. Xstruct mkroom *sroom;
  761. X{
  762. X    register struct monst *mtmp;
  763. X
  764. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  765. X        if(mtmp->isshk && &rooms[ESHK(mtmp)->shoproom] == sroom
  766. X        && inhishop(mtmp)) return(TRUE);
  767. X    return(FALSE);
  768. X}
  769. X#endif
  770. X
  771. XSTATIC_OVL void
  772. Xfindshk(roomno)
  773. Xregister int roomno;
  774. X{
  775. X    register struct monst *mtmp;
  776. X
  777. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  778. X        if(mtmp->isshk && ESHK(mtmp)->shoproom == roomno
  779. X               && ESHK(mtmp)->shoplevel == dlevel) {
  780. X        shopkeeper = mtmp;
  781. X        bill = &(ESHK(shopkeeper)->bill[0]);
  782. X        shlevel = dlevel;
  783. X        if(ANGRY(shopkeeper) &&
  784. X           strncmp(ESHK(shopkeeper)->customer,plname,PL_NSIZ))
  785. X            NOTANGRY(shopkeeper) = 1;
  786. X        /* billobjs = 0; -- this is wrong if we save in a shop */
  787. X        /* (and it is harmless to have too many things in billobjs) */
  788. X        return;
  789. X    }
  790. X    shopkeeper = 0;
  791. X    shlevel = 0;
  792. X    bill = (struct bill_x *) -1000;    /* dump core when referenced */
  793. X}
  794. X
  795. Xstatic struct bill_x *
  796. Xonbill(obj)
  797. Xregister struct obj *obj;
  798. X{
  799. X    register struct bill_x *bp;
  800. X    if(!shopkeeper) return (struct bill_x *)0;
  801. X    for(bp = bill; bp < &bill[ESHK(shopkeeper)->billct]; bp++)
  802. X        if(bp->bo_id == obj->o_id) {
  803. X            if(!obj->unpaid) pline("onbill: paid obj on bill?");
  804. X            return(bp);
  805. X        }
  806. X    if(obj->unpaid) pline("onbill: unpaid obj not on bill?");
  807. X    return (struct bill_x *)0;
  808. X}
  809. X
  810. X/* called with two args on merge */
  811. Xvoid
  812. Xobfree(obj, merge)
  813. Xregister struct obj *obj, *merge;
  814. X{
  815. X    register struct bill_x *bp = onbill(obj);
  816. X    register struct bill_x *bpm;
  817. X    if(bp) {
  818. X        if(!merge){
  819. X            bp->useup = 1;
  820. X            obj->unpaid = 0;    /* only for doinvbill */
  821. X            obj->nobj = billobjs;
  822. X            billobjs = obj;
  823. X            return;
  824. X        }
  825. X        bpm = onbill(merge);
  826. X        if(!bpm){
  827. X            /* this used to be a rename */
  828. X            impossible("obfree: not on bill??");
  829. X            return;
  830. X        } else {
  831. X            /* this was a merger */
  832. X            bpm->bquan += bp->bquan;
  833. X            ESHK(shopkeeper)->billct--;
  834. X            *bp = bill[ESHK(shopkeeper)->billct];
  835. X        }
  836. X    }
  837. X    free((genericptr_t) obj);
  838. X}
  839. X
  840. Xstatic long
  841. Xcheck_credit(tmp, shkp)
  842. Xlong tmp;
  843. Xregister struct monst *shkp;
  844. X{
  845. X    long credit = ESHK(shkp)->credit;
  846. X
  847. X    if(credit == 0L) return(tmp);
  848. X    if(credit >= tmp) {
  849. X        pline("The price is deducted from your credit.");
  850. X        ESHK(shkp)->credit -=tmp;
  851. X        tmp = 0L;
  852. X    } else {
  853. X        pline("The price is partially covered by your credit.");
  854. X        ESHK(shkp)->credit = 0L;
  855. X        tmp -= credit;
  856. X    }
  857. X    return(tmp);
  858. X}
  859. X
  860. Xstatic void
  861. Xpay(tmp,shkp)
  862. Xlong tmp;
  863. Xregister struct monst *shkp;
  864. X{
  865. X    long robbed = ESHK(shkp)->robbed;
  866. X    long balance = ((tmp <= 0L) ? tmp : check_credit(tmp, shkp));
  867. X
  868. X    u.ugold -= balance;
  869. X    shkp->mgold += balance;
  870. X    flags.botl = 1;
  871. X    if(robbed) {
  872. X        robbed -= tmp;
  873. X        if(robbed < 0) robbed = 0L;
  874. X        ESHK(shkp)->robbed = robbed;
  875. X    }
  876. X}
  877. X
  878. X/* return shkp to home position */
  879. Xvoid
  880. Xhome_shk(shkp)
  881. Xregister struct monst *shkp;
  882. X{
  883. X    register xchar x = ESHK(shkp)->shk.x, y = ESHK(shkp)->shk.y;
  884. X    if(MON_AT(x, y))
  885. X        mnearto(m_at(x,y), x, y, FALSE);
  886. X    remove_monster(shkp->mx, shkp->my);
  887. X    place_monster(shkp, x, y);
  888. X    unpmon(shkp);
  889. X}
  890. X
  891. Xvoid
  892. Xmake_happy_shk(shkp)
  893. Xstruct monst *shkp;
  894. X{
  895. X    register boolean wasmad = ANGRY(shkp);
  896. X
  897. X    NOTANGRY(shkp) = 1;
  898. X    ESHK(shkp)->following = 0;
  899. X    ESHK(shkp)->robbed = 0L;
  900. X    if (pl_character[0] != 'R')
  901. X        adjalign(sgn(u.ualigntyp));
  902. X    if(!inhishop(shkp)) {
  903. X        pline("Satisfied, %s suddenly disappears!", mon_nam(shkp));
  904. X        if(ESHK(shkp)->shoplevel == dlevel)
  905. X            home_shk(shkp);
  906. X        else
  907. X            fall_down(shkp, ESHK(shkp)->shoplevel);
  908. X    } else if(wasmad)
  909. X        pline("%s calms down.", Monnam(shkp));
  910. X#ifdef KOPS
  911. X    kops_gone();
  912. X#endif
  913. X}
  914. X
  915. Xstatic const char no_money[] = "Moreover, you have no money.";
  916. X
  917. Xint
  918. Xdopay()
  919. X{
  920. X    long ltmp;
  921. X    register struct bill_x *bp;
  922. X    register struct monst *shkp;
  923. X    int pass, tmp;
  924. X
  925. X    multi = 0;
  926. X    (void) inshop();
  927. X    for(shkp = fmon; shkp; shkp = shkp->nmon)
  928. X        if(shkp->isshk && dist(shkp->mx,shkp->my) < 3)
  929. X            break;
  930. X    if(!shkp && u.uinshop && inhishop(shopkeeper))
  931. X        shkp = shopkeeper;
  932. X
  933. X    if(!shkp) {
  934. X        pline("There is nobody here to receive your payment.");
  935. X        return(0);
  936. X    }
  937. X    ltmp = ESHK(shkp)->robbed;
  938. X    if(shkp != shopkeeper && NOTANGRY(shkp)) {
  939. X        if(!ltmp)
  940. X            You("do not owe %s anything.", mon_nam(shkp));
  941. X        else if(!u.ugold)
  942. X            You("have no money.");
  943. X        else {
  944. X            long ugold = u.ugold;
  945. X
  946. X            if(ugold > ltmp) {
  947. X            You("give %s the %ld gold piece%s %s asked for.",
  948. X                mon_nam(shkp), ltmp, plur(ltmp),
  949. X                ESHK(shkp)->ismale ? "he" : "she");
  950. X            pay(ltmp, shkp);
  951. X            } else {
  952. X            You("give %s all your gold.", mon_nam(shkp));
  953. X            pay(u.ugold, shkp);
  954. X            }
  955. X            if(ugold < ltmp/2L)
  956. X            pline("Unfortunately, %s doesn't look satisfied.",
  957. X                ESHK(shkp)->ismale ? "he" : "she");
  958. X            else
  959. X            make_happy_shk(shkp);
  960. X        }
  961. X        return(1);
  962. X    }
  963. X
  964. X    /* ltmp is still ESHK(shkp)->robbed here */
  965. X    if(!ESHK(shkp)->billct && !ESHK(shkp)->debit) {
  966. X        if(!ltmp && NOTANGRY(shkp)) {
  967. X            You("do not owe %s anything.", mon_nam(shkp));
  968. X            if(!u.ugold) pline(no_money);
  969. X        } else if(ltmp) {
  970. X            pline("%s is after blood, not money!", mon_nam(shkp));
  971. X            if(u.ugold < ltmp/2L) {
  972. X            if(!u.ugold) pline(no_money);
  973. X            else pline("Besides, you don't have enough to interest %s.",
  974. X                ESHK(shkp)->ismale ? "him" : "her");
  975. X            return(1);
  976. X            }
  977. X            pline("But since %s shop has been robbed recently,",
  978. X            ESHK(shkp)->ismale ? "his" : "her");
  979. X            pline("you %scompensate %s for %s losses.",
  980. X            (u.ugold < ltmp) ? "partially " : "",
  981. X            mon_nam(shkp),
  982. X            ESHK(shkp)->ismale ? "his" : "her");
  983. X            pay(u.ugold < ltmp ? u.ugold : ltmp, shkp);
  984. X            make_happy_shk(shkp);
  985. X        } else {
  986. X            /* shopkeeper is angry, but has not been robbed --
  987. X             * door broken, attacked, etc. */
  988. X            pline("%s is after your hide, not your money!",
  989. X                    mon_nam(shkp));
  990. X            if(u.ugold < 1000L) {
  991. X            if(!u.ugold) pline(no_money);
  992. X            else
  993. X        pline("Besides, you don't have enough to interest %s.",
  994. X                ESHK(shkp)->ismale ? "him" : "her");
  995. X            return(1);
  996. X            }
  997. X            You("try to appease %s by giving %s 1000 gold pieces.",
  998. X                a_monnam(shkp, "angry"),
  999. X                ESHK(shkp)->ismale ? "him" : "her");
  1000. X            pay(1000L,shkp);
  1001. X            if(strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)
  1002. X                    || rn2(3))
  1003. X            make_happy_shk(shkp);
  1004. X            else
  1005. X            pline("But %s is as angry as ever.", Monnam(shkp));
  1006. X        }
  1007. X        return(1);
  1008. X    }
  1009. X    if(shkp != shopkeeper) {
  1010. X        impossible("dopay: not to shopkeeper?");
  1011. X        if(shopkeeper) setpaid();
  1012. X        return(0);
  1013. X    }
  1014. X    /* pay debt, if any, first */
  1015. X    if(ESHK(shopkeeper)->debit) {
  1016. X            You("owe %s %ld zorkmid%s for the use of merchandise.",
  1017. X            shkname(shopkeeper), ESHK(shopkeeper)->debit,
  1018. X                plur(ESHK(shopkeeper)->debit));
  1019. X            if(u.ugold + ESHK(shopkeeper)->credit < 
  1020. X                    ESHK(shopkeeper)->debit) {
  1021. X            pline("But you don't have enough gold%s.",
  1022. X            ESHK(shopkeeper)->credit ? " or credit" : "");
  1023. X            return(1);
  1024. X            } else {
  1025. X            long dtmp = ESHK(shopkeeper)->debit;
  1026. X
  1027. X            if(ESHK(shopkeeper)->credit >= dtmp) {
  1028. X            ESHK(shopkeeper)->credit -= dtmp;
  1029. X            ESHK(shopkeeper)->debit = 0L;
  1030. X                    Your("debt is covered by your credit.");
  1031. X            } else if(!ESHK(shopkeeper)->credit) {
  1032. X            u.ugold -= dtmp;
  1033. X            shopkeeper->mgold += dtmp;
  1034. X            ESHK(shopkeeper)->debit = 0L;
  1035. X            You("pay that debt.");
  1036. X            flags.botl = 1;
  1037. X            } else {
  1038. X            dtmp -= ESHK(shopkeeper)->credit;
  1039. X            ESHK(shopkeeper)->credit = 0L;
  1040. X            u.ugold -= dtmp;
  1041. X            shopkeeper->mgold += dtmp;
  1042. X            ESHK(shopkeeper)->debit = 0L;
  1043. X            pline("That debt is partially offset by your credit.");
  1044. X            You("pay the remainder.");
  1045. X            flags.botl = 1;
  1046. X            }
  1047. X        }
  1048. X    }
  1049. X    for(pass = 0; pass <= 1; pass++) {
  1050. X        tmp = 0;
  1051. X        while(tmp < ESHK(shopkeeper)->billct) {
  1052. X            bp = &bill[tmp];
  1053. X            if(!pass && !bp->useup) {
  1054. X            tmp++;
  1055. X            continue;
  1056. X            }
  1057. X            if(!dopayobj(bp)) return(1);
  1058. X#ifdef MSDOS
  1059. X            *bp = bill[--ESHK(shopkeeper)->billct];
  1060. X#else
  1061. X            bill[tmp] = bill[--ESHK(shopkeeper)->billct];
  1062. X#endif /* MSDOS /**/
  1063. X        }
  1064. X    }
  1065. X    if(!ANGRY(shopkeeper))
  1066. X        pline("\"Thank you for shopping in %s's %s!\"",
  1067. X        shkname(shopkeeper),
  1068. X        shtypes[rooms[ESHK(shopkeeper)->shoproom].rtype - SHOPBASE].name);
  1069. X    return(1);
  1070. X}
  1071. X
  1072. X/* return 1 if paid successfully */
  1073. X/*        0 if not enough money */
  1074. X/*       -1 if object could not be found (but was paid) */
  1075. Xstatic int
  1076. Xdopayobj(bp)
  1077. Xregister struct bill_x *bp;
  1078. X{
  1079. X    register struct obj *obj;
  1080. X    long ltmp;
  1081. X
  1082. X    /* find the object on one of the lists */
  1083. X    obj = bp_to_obj(bp);
  1084. X
  1085. X    if(!obj) {
  1086. X        impossible("Shopkeeper administration out of order.");
  1087. X        setpaid();    /* be nice to the player */
  1088. X        return(0);
  1089. X    }
  1090. X
  1091. X    if(!obj->unpaid && !bp->useup){
  1092. X        impossible("Paid object on bill??");
  1093. X        return(1);
  1094. X    }
  1095. X    obj->unpaid = 0;
  1096. X    ltmp = bp->price * bp->bquan;
  1097. X    if(ANGRY(shopkeeper)) ltmp += ltmp/3L;
  1098. X    if(u.ugold + ESHK(shopkeeper)->credit < ltmp){
  1099. X        You("don't have gold%s enough to pay for %s.",
  1100. X            (ESHK(shopkeeper)->credit > 0L) ? " or credit" : "",
  1101. X            doname(obj));
  1102. X        obj->unpaid = 1;
  1103. X        return(0);
  1104. X    }
  1105. X    pay(ltmp, shopkeeper);
  1106. X    You("bought %s for %ld gold piece%s.",
  1107. X        doname(obj), ltmp, plur(ltmp));
  1108. X    if(bp->useup) {
  1109. X        register struct obj *otmp = billobjs;
  1110. X        if(obj == billobjs)
  1111. X            billobjs = obj->nobj;
  1112. X        else {
  1113. X            while(otmp && otmp->nobj != obj) otmp = otmp->nobj;
  1114. X            if(otmp) otmp->nobj = obj->nobj;
  1115. X            else pline("Error in shopkeeper administration.");
  1116. X        }
  1117. X        free((genericptr_t) obj);
  1118. X    }
  1119. X    return(1);
  1120. X}
  1121. X
  1122. X/* routine called after dying (or quitting) with nonempty bill or upset shk */
  1123. Xboolean
  1124. Xpaybill(){
  1125. X    register struct monst *mtmp, *mtmp2;
  1126. X    register long loss = 0L;
  1127. X    register struct obj *otmp;
  1128. X    register xchar ox, oy;
  1129. X    register boolean take = FALSE;
  1130. X    register boolean taken = FALSE;
  1131. X
  1132. X    for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  1133. X        mtmp2 = mtmp->nmon;
  1134. X        if(mtmp->isshk) {
  1135. X        /* for bones: we don't want a shopless shk around */
  1136. X        if(ESHK(mtmp)->shoplevel != dlevel) mongone(mtmp);
  1137. X        else shopkeeper = mtmp;
  1138. X        }
  1139. X    }
  1140. X
  1141. X    if(!shopkeeper) goto clear;
  1142. X
  1143. X    /* get one case out of the way: you die in the shop, the */
  1144. X    /* shopkeeper is peaceful, nothing stolen, nothing owed. */
  1145. X    if(in_shop(u.ux,u.uy) && !IS_DOOR(levl[u.ux][u.uy].typ) &&
  1146. X        !ESHK(shopkeeper)->billct && !ESHK(shopkeeper)->robbed &&
  1147. X        !ESHK(shopkeeper)->debit && inhishop(shopkeeper) && 
  1148. X         NOTANGRY(shopkeeper) && !ESHK(shopkeeper)->following) {
  1149. X        pline("%s gratefully inherits all your possessions.",
  1150. X                Monnam(shopkeeper));
  1151. X        goto clear;
  1152. X    }
  1153. X
  1154. X    if(ESHK(shopkeeper)->billct || ESHK(shopkeeper)->debit ||
  1155. X            ESHK(shopkeeper)->robbed) {
  1156. X        addupbill();
  1157. X        total += ESHK(shopkeeper)->debit;
  1158. X        loss = ((total >= ESHK(shopkeeper)->robbed) ? total :
  1159. X                ESHK(shopkeeper)->robbed);
  1160. X        take = TRUE;
  1161. X    }
  1162. X
  1163. X    if(ESHK(shopkeeper)->following || ANGRY(shopkeeper) || take) {
  1164. X        if((loss > u.ugold) || !loss) {
  1165. X            pline("%s %sand takes all your possessions.",
  1166. X                Monnam(shopkeeper), 
  1167. X                (shopkeeper->msleep || shopkeeper->mfrozen) ?
  1168. X                "wakes up " : "comes ");
  1169. X            taken = TRUE;
  1170. X            shopkeeper->mgold += u.ugold;
  1171. X            u.ugold = 0L;
  1172. X            /* in case bones: make it be for real... */
  1173. X            if(!in_shop(u.ux, u.uy) || IS_DOOR(levl[u.ux][u.uy].typ)) {
  1174. X                /* shk.x,shk.y is the position immediately in
  1175. X                 * front of the door -- move in one more space
  1176. X                 */
  1177. X                ox = ESHK(shopkeeper)->shk.x;
  1178. X                oy = ESHK(shopkeeper)->shk.y;
  1179. X                ox += sgn(ox - ESHK(shopkeeper)->shd.x);
  1180. X                oy += sgn(oy - ESHK(shopkeeper)->shd.y);
  1181. X            } else {
  1182. X                ox = u.ux;
  1183. X                oy = u.uy;
  1184. X            }
  1185. X
  1186. X            if (invent) {
  1187. X                for(otmp = invent; otmp; otmp = otmp->nobj)
  1188. X                place_object(otmp, ox, oy);
  1189. X
  1190. X                /* add to main object list at end so invent is
  1191. X                   still good */
  1192. X                if (fobj) {
  1193. X                otmp = fobj;
  1194. X                while(otmp->nobj)
  1195. X                    otmp = otmp->nobj;
  1196. X                otmp->nobj = invent;
  1197. X                } else
  1198. X                fobj = invent;
  1199. X            }
  1200. X        } else {
  1201. X            u.ugold -= loss;
  1202. X            shopkeeper->mgold += loss;
  1203. X            pline("%s %sand takes %ld zorkmid%s %sowed %s.",
  1204. X                  Monnam(shopkeeper),
  1205. X                  (shopkeeper->msleep || shopkeeper->mfrozen) ?
  1206. X                    "wakes up " : "comes ",
  1207. X                  loss,
  1208. X                  plur(loss),
  1209. X                  strncmp(ESHK(shopkeeper)->customer, plname, PL_NSIZ) ? "" : "you ",
  1210. X                  ESHK(shopkeeper)->ismale ? "him" : "her");
  1211. X        }
  1212. X
  1213. X        /* in case we create bones */
  1214. X        if(!inhishop(shopkeeper))
  1215. X            home_shk(shopkeeper);
  1216. X    }
  1217. Xclear:
  1218. X    setpaid();
  1219. X    return(taken);
  1220. X}
  1221. X
  1222. X/* find obj on one of the lists */
  1223. Xstatic struct obj *
  1224. Xbp_to_obj(bp)
  1225. Xregister struct bill_x *bp;
  1226. X{
  1227. X    register struct obj *obj;
  1228. X    register struct monst *mtmp;
  1229. X    register unsigned int id = bp->bo_id;
  1230. X
  1231. X    if(bp->useup)
  1232. X        obj = o_on(id, billobjs);
  1233. X    else if(!(obj = o_on(id, invent)) &&
  1234. X        !(obj = o_on(id, fobj)) &&
  1235. X        !(obj = o_on(id, fcobj))) {
  1236. X            for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  1237. X            if(obj = o_on(id, mtmp->minvent))
  1238. X                break;
  1239. X            for(mtmp = fallen_down; mtmp; mtmp = mtmp->nmon)
  1240. X            if(obj = o_on(id, mtmp->minvent))
  1241. X                break;
  1242. X        }
  1243. X    return(obj);
  1244. X}
  1245. X
  1246. Xstatic unsigned
  1247. Xget_cost(obj)
  1248. Xregister struct obj *obj;
  1249. X{
  1250. X    register unsigned tmp;
  1251. X
  1252. X    tmp = getprice(obj);
  1253. X    if (!tmp) tmp = 5;
  1254. X    if (ANGRY(shopkeeper) || 
  1255. X        (pl_character[0] == 'T' && u.ulevel < (MAXULEV/2))
  1256. X#ifdef SHIRT
  1257. X        || (uarmu && !uarm) /* wearing just a Hawaiian shirt */
  1258. X#endif
  1259. X       )
  1260. X        tmp += tmp/3;
  1261. X    if (ACURR(A_CHA) > 18)        tmp /= 2;
  1262. X    else if (ACURR(A_CHA) > 17)    tmp = (tmp * 2)/3;
  1263. X    else if (ACURR(A_CHA) > 15)    tmp = (tmp * 3)/4;
  1264. X    else if (ACURR(A_CHA) < 6)    tmp *= 2;
  1265. X    else if (ACURR(A_CHA) < 8)    tmp = (tmp * 3)/2;
  1266. X    else if (ACURR(A_CHA) < 11)    tmp = (tmp * 4)/3;
  1267. X    if (!tmp) return 1;
  1268. X    return(tmp);
  1269. X}
  1270. X
  1271. X
  1272. X/* called in hack.c when we pickup an object */
  1273. Xvoid
  1274. Xaddtobill(obj, ininv)
  1275. Xregister struct obj *obj;
  1276. Xregister boolean ininv;
  1277. X{
  1278. X    register struct bill_x *bp;
  1279. X    char    buf[40];
  1280. X    if(!shopkeeper || !inhishop(shopkeeper)) return;
  1281. X
  1282. X    if(!costly_spot(obj->ox,obj->oy) ||    /* either pickup or kick */
  1283. X        onbill(obj) /* perhaps we threw it away earlier */
  1284. X          ) return;
  1285. X    if(ESHK(shopkeeper)->billct == BILLSZ) {
  1286. X        You("got that for free!");
  1287. X        return;
  1288. X    }
  1289. X    /* To recognize objects the shopkeeper is not interested in. -dgk
  1290. X     */
  1291. X    if (obj->no_charge) {
  1292. X        obj->no_charge = 0;
  1293. X        return;
  1294. X    }
  1295. X    bp = &bill[ESHK(shopkeeper)->billct];
  1296. X    bp->bo_id = obj->o_id;
  1297. X    bp->bquan = obj->quan;
  1298. X    bp->useup = 0;
  1299. X    bp->price = get_cost(obj);
  1300. X    if(!shopkeeper->msleep && !shopkeeper->mfrozen) {
  1301. X        Strcpy(buf, "\"For you, ");
  1302. X        if (ANGRY(shopkeeper)) Strcat(buf, "scum ");
  1303. X        else {
  1304. X            switch(rnd(4)
  1305. X#ifdef HARD
  1306. X           + u.udemigod
  1307. X#endif
  1308. X                ) {
  1309. X        case 1:    Strcat(buf, "good");
  1310. X            break;
  1311. X        case 2:    Strcat(buf, "honored");
  1312. X            break;
  1313. X        case 3:    Strcat(buf, "most gracious");
  1314. X            break;
  1315. X        case 4:    Strcat(buf, "esteemed");
  1316. X            break;
  1317. X        case 5: if (u.ualigntyp == U_CHAOTIC) Strcat(buf, "un");
  1318. X            Strcat(buf, "holy");
  1319. X            break;
  1320. X            }
  1321. X#ifdef POLYSELF
  1322. X            if(!is_human(uasmon)) Strcat(buf, " creature");
  1323. X            else
  1324. X#endif
  1325. X            Strcat(buf, (flags.female) ? " lady" : " sir");
  1326. X        }
  1327. X        obj->dknown = 1; /* after all, the shk is telling you what it is */
  1328. X        if(ininv) {
  1329. X        obj->quan = 1; /* fool xname() into giving singular */
  1330. X        pline("%s; only %d %s %s.\"", buf, bp->price,
  1331. X            (bp->bquan > 1) ? "per" : "for this", xname(obj));
  1332. X        obj->quan = bp->bquan;
  1333. X        } else pline("The %s will cost you %d zorkmid%s%s.",
  1334. X            xname(obj), bp->price, plur((long)bp->price),
  1335. X            (bp->bquan > 1) ? " each" : "");
  1336. X    } else pline("The list price of %s is %d zorkmid%s%s.",
  1337. X            xname(obj), bp->price, plur((long)bp->price),
  1338. X            (bp->bquan > 1) ? " each" : "");
  1339. X    ESHK(shopkeeper)->billct++;
  1340. X    obj->unpaid = 1;
  1341. X}
  1342. X
  1343. Xvoid
  1344. Xsplitbill(obj, otmp)
  1345. Xregister struct obj *obj, *otmp;
  1346. X{
  1347. X    /* otmp has been split off from obj */
  1348. X    register struct bill_x *bp;
  1349. X    register int tmp;
  1350. X    bp = onbill(obj);
  1351. X    if(!bp) {
  1352. X        impossible("splitbill: not on bill?");
  1353. X        return;
  1354. X    }
  1355. X    if(bp->bquan < otmp->quan) {
  1356. X        impossible("Negative quantity on bill??");
  1357. X    }
  1358. X    if(bp->bquan == otmp->quan) {
  1359. X        impossible("Zero quantity on bill??");
  1360. X    }
  1361. X    bp->bquan -= otmp->quan;
  1362. X
  1363. X    if(ESHK(shopkeeper)->billct == BILLSZ) otmp->unpaid = 0;
  1364. X    else {
  1365. X        tmp = bp->price;
  1366. X        bp = &bill[ESHK(shopkeeper)->billct];
  1367. X        bp->bo_id = otmp->o_id;
  1368. X        bp->bquan = otmp->quan;
  1369. X        bp->useup = 0;
  1370. X        bp->price = tmp;
  1371. X        ESHK(shopkeeper)->billct++;
  1372. X    }
  1373. X}
  1374. X
  1375. Xvoid
  1376. Xsubfrombill(obj)
  1377. Xregister struct obj *obj;
  1378. X{
  1379. X    register struct bill_x *bp;
  1380. X
  1381. X    if(!shopkeeper) return;
  1382. X
  1383. X    if((bp = onbill(obj)) != 0) {
  1384. X        register struct obj *otmp;
  1385. X
  1386. X        obj->unpaid = 0;
  1387. X        if(bp->bquan > obj->quan){
  1388. X            otmp = newobj(0);
  1389. X            *otmp = *obj;
  1390. X            bp->bo_id = otmp->o_id = flags.ident++;
  1391. X            otmp->quan = (bp->bquan -= obj->quan);
  1392. X            otmp->owt = 0;    /* superfluous */
  1393. X            otmp->onamelth = 0;
  1394. X            bp->useup = 1;
  1395. X            otmp->nobj = billobjs;
  1396. X            billobjs = otmp;
  1397. X            return;
  1398. X        }
  1399. X        ESHK(shopkeeper)->billct--;
  1400. X        *bp = bill[ESHK(shopkeeper)->billct];
  1401. X        return;
  1402. X    } else if (obj->unpaid) {
  1403. X        impossible("subfrombill: unpaid object not on bill");
  1404. X        obj->unpaid = 0;
  1405. X    }
  1406. X}
  1407. X
  1408. Xvoid
  1409. Xsellobj(obj)
  1410. Xregister struct obj *obj;
  1411. X{
  1412. X    long ltmp;
  1413. X
  1414. X    if(!costly_spot(u.ux,u.uy))
  1415. X        return;
  1416. X    if(obj->unpaid) {
  1417. X        subfrombill(obj);
  1418. X        return;
  1419. X    }
  1420. X    /* you dropped something of your own - probably want to sell it */
  1421. X    if(shopkeeper->msleep || !shopkeeper->mcanmove || !inhishop(shopkeeper))
  1422. X        return;
  1423. X    ltmp = (long) getprice(obj) * (long) obj->quan;
  1424. X    if (ANGRY(shopkeeper) || (pl_character[0] == 'T' && u.ulevel < (MAXULEV/2))
  1425. X#ifdef SHIRT
  1426. X        || (uarmu && !uarm) /* wearing just a Hawaiian shirt */
  1427. X#endif
  1428. X       ) {
  1429. X        ltmp /= 3L;
  1430. X        NOTANGRY(shopkeeper) = 1;
  1431. X    } else    ltmp /= 2L;
  1432. X    if(ESHK(shopkeeper)->billct == BILLSZ
  1433. X       || !saleable(rooms[ESHK(shopkeeper)->shoproom].rtype-SHOPBASE, obj)
  1434. X       || obj->olet == BALL_SYM || ltmp == 0L
  1435. X       || (obj->olet == FOOD_SYM && obj->oeaten)) {
  1436. X        pline("%s seems not interested.", Monnam(shopkeeper));
  1437. X        obj->no_charge = 1;
  1438. X        return;
  1439. X    }
  1440. X    if(ESHK(shopkeeper)->robbed) {
  1441. X        if((ESHK(shopkeeper)->robbed -= ltmp) < 0L)
  1442. X            ESHK(shopkeeper)->robbed = 0L;
  1443. Xverbalize("Thank you for your contribution to restock this recently plundered shop.");
  1444. X        return;
  1445. X    }
  1446. X    if(ltmp > shopkeeper->mgold)
  1447. X        ltmp = shopkeeper->mgold;
  1448. X    pay(-ltmp, shopkeeper);
  1449. X    if(!ltmp) {
  1450. X        pline("%s gladly accepts %s but cannot pay you at present.",
  1451. X            Monnam(shopkeeper), doname(obj));
  1452. X            obj->no_charge = 1;
  1453. X    } else
  1454. X    You("sold %s for %ld gold piece%s.", doname(obj), ltmp,
  1455. X        plur(ltmp));
  1456. X}
  1457. X
  1458. Xint
  1459. Xdoinvbill(mode)
  1460. Xint mode;        /* 0: deliver count 1: paged */
  1461. X{
  1462. X    register struct bill_x *bp;
  1463. X    register struct obj *obj;
  1464. X#ifdef __GNULINT__
  1465. X    long totused, thisused = 0L;
  1466. X/* possibly a bug in the GCC; clearly thisused is always set before use */
  1467. X#else
  1468. X    long totused, thisused;
  1469. X#endif
  1470. X    char buf[BUFSZ];
  1471. X
  1472. X    if(mode == 0) {
  1473. X        register int cnt = 0;
  1474. X
  1475. X        if(shopkeeper)
  1476. X        for(bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++)
  1477. X            if(bp->useup ||
  1478. X              ((obj = bp_to_obj(bp)) && obj->quan < bp->bquan))
  1479. X            cnt++;
  1480. X        return(cnt);
  1481. X    }
  1482. X
  1483. X    if(!shopkeeper) {
  1484. X        impossible("doinvbill: no shopkeeper?");
  1485. X        return(0);
  1486. X    }
  1487. X
  1488. X    set_pager(0);
  1489. X    if(page_line("Unpaid articles already used up:") || page_line(""))
  1490. X        goto quit;
  1491. X
  1492. X    totused = 0L;
  1493. X    for(bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++) {
  1494. X        obj = bp_to_obj(bp);
  1495. X        if(!obj) {
  1496. X        impossible("Bad shopkeeper administration.");
  1497. X        goto quit;
  1498. X        }
  1499. X        if(bp->useup || bp->bquan > obj->quan) {
  1500. X        register int cnt;
  1501. X        register unsigned oquan, uquan;
  1502. X
  1503. X        oquan = obj->quan;
  1504. X        uquan = (bp->useup ? bp->bquan : bp->bquan - oquan);
  1505. X        thisused = bp->price * uquan;
  1506. X        totused += thisused;
  1507. X        obj->quan = uquan;        /* cheat doname */
  1508. X        Sprintf(buf, "x -  %s", doname(obj));
  1509. X        obj->quan = oquan;        /* restore value */
  1510. X        for(cnt = 0; buf[cnt]; cnt++);
  1511. X        while(cnt < 50)
  1512. X            buf[cnt++] = ' ';
  1513. X        Sprintf(&buf[cnt], " %5ld zorkmid%s", thisused, plur(thisused));
  1514. X        if(page_line(buf))
  1515. X            goto quit;
  1516. X        }
  1517. X    }
  1518. X    Sprintf(buf, "Total:%50ld zorkmid%s", totused, plur(totused));
  1519. X    if(page_line("") || page_line(buf))
  1520. X        goto quit;
  1521. X    set_pager(1);
  1522. X    return(0);
  1523. Xquit:
  1524. X    set_pager(2);
  1525. X    return(0);
  1526. X}
  1527. X
  1528. X#define HUNGRY    2
  1529. Xstatic int
  1530. Xgetprice(obj)
  1531. Xregister struct obj *obj;
  1532. X{
  1533. X    register int tmp = objects[obj->otyp].oc_cost;
  1534. X
  1535. X    switch(obj->olet) {
  1536. X    case AMULET_SYM:
  1537. X        if(obj->otyp == AMULET_OF_YENDOR) {
  1538. X            /* don't let the player get rich selling fakes */
  1539. X            tmp = (obj->spe < 0 ? 0 : 3500);
  1540. X        }
  1541. X        break;
  1542. X    case FOOD_SYM:
  1543. X        /* simpler hunger check, (2-4)*cost */
  1544. X        if (u.uhs >= HUNGRY) tmp *= u.uhs;
  1545. X        if (obj->oeaten) tmp = eaten_stat(tmp, obj); /* partly eaten */
  1546. X        break;
  1547. X    case WAND_SYM:
  1548. X        if (obj->spe == -1) tmp = 0;
  1549. X        break;
  1550. X    case POTION_SYM:
  1551. X        if (obj->otyp == POT_WATER && !obj->blessed && !obj->cursed)
  1552. X            tmp = 0;
  1553. X        break;
  1554. X    case ARMOR_SYM:
  1555. X    case WEAPON_SYM:
  1556. X        if (obj->spe > 0) tmp += 10 * obj->spe;
  1557. X        break;
  1558. X    case CHAIN_SYM:
  1559. X        pline("Strange... carrying a chain?");
  1560. X        break;
  1561. X    }
  1562. X    return(tmp);
  1563. X}
  1564. X
  1565. Xint
  1566. Xshkcatch(obj)
  1567. Xregister struct obj *obj;
  1568. X{
  1569. X    register struct monst *shkp = shopkeeper;
  1570. X
  1571. X    if(obj->otyp != PICK_AXE) return(0);
  1572. X    if(u.uinshop && shkp && shkp->mcanmove && !shkp->msleep &&
  1573. X        inroom(u.ux+u.dx, u.uy+u.dy) + 1 == u.uinshop &&
  1574. X        shkp->mx == ESHK(shkp)->shk.x && shkp->my == ESHK(shkp)->shk.y &&
  1575. X        u.ux == ESHK(shkp)->shd.x && u.uy == ESHK(shkp)->shd.y) {
  1576. X        pline("%s nimbly catches the %s.", Monnam(shkp), xname(obj));
  1577. X        obj->nobj = shkp->minvent;
  1578. X        shkp->minvent = obj;
  1579. X        subfrombill(obj);
  1580. X        return(1);
  1581. X    }
  1582. X    return(0);
  1583. X}
  1584. X
  1585. X/*
  1586. X * shk_move: return 1: he moved  0: he didn't  -1: let m_move do it  -2: died
  1587. X */
  1588. Xint
  1589. Xshk_move(shkp)
  1590. Xregister struct monst *shkp;
  1591. X{
  1592. X    register xchar gx,gy,omx,omy;
  1593. X    register int udist;
  1594. X    register schar appr;
  1595. X    int z;
  1596. X    schar shkroom;
  1597. X    boolean uondoor = FALSE, satdoor, avoid = FALSE, badinv;
  1598. X
  1599. X    omx = shkp->mx;
  1600. X    omy = shkp->my;
  1601. X
  1602. X    if((udist = dist(omx,omy)) < 3 &&
  1603. X       (shkp->data != &mons[PM_GRID_BUG] || (omx==u.ux || omy==u.uy))) {
  1604. X        if(ANGRY(shkp)) {
  1605. X            if(Displaced)
  1606. X              Your("displaced image doesn't fool %s!",
  1607. X                Monnam(shkp));
  1608. X            (void) mattacku(shkp);
  1609. X            return(0);
  1610. X        }
  1611. X        if(ESHK(shkp)->following) {
  1612. X            if(strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)) {
  1613. X                pline("\"Hello, %s!  I was looking for %s.\"",
  1614. X                    plname, ESHK(shkp)->customer);
  1615. X                    ESHK(shkp)->following = 0;
  1616. X                return(0);
  1617. X            }
  1618. X            if(moves > followmsg+4) {
  1619. X                pline("\"Hello, %s!  Didn't you forget to pay?\"",
  1620. X                    plname);
  1621. X                followmsg = moves;
  1622. X#ifdef HARD
  1623. X                if (!rn2(4)) {
  1624. X        pline ("%s doesn't like customers who don't pay.", Monnam(shkp));
  1625. X                NOTANGRY(shkp) = 0;
  1626. X                }
  1627. X#endif
  1628. X            }
  1629. X            if(udist < 2)
  1630. X                return(0);
  1631. X        }
  1632. X    }
  1633. X
  1634. X    shkroom = inroom(omx,omy);
  1635. X    appr = 1;
  1636. X    gx = ESHK(shkp)->shk.x;
  1637. X    gy = ESHK(shkp)->shk.y;
  1638. X    satdoor = (gx == omx && gy == omy);
  1639. X    if(ESHK(shkp)->following || ((z = holetime()) >= 0 && z*z <= udist)){
  1640. X        gx = u.ux;
  1641. X        gy = u.uy;
  1642. X        if(shkroom < 0 || shkroom != inroom(u.ux,u.uy))
  1643. X            if(udist > 4)
  1644. X            return(-1);    /* leave it to m_move */
  1645. X    } else if(ANGRY(shkp)) {
  1646. X        long saveBlind = Blinded;
  1647. X        struct obj *saveUblindf = ublindf;
  1648. X        Blinded = 0;
  1649. X        ublindf = (struct obj *)0;
  1650. X        if(shkp->mcansee && !Invis && cansee(omx,omy)) {
  1651. X            gx = u.ux;
  1652. X            gy = u.uy;
  1653. X        }
  1654. X        Blinded = saveBlind;
  1655. X        ublindf = saveUblindf;
  1656. X        avoid = FALSE;
  1657. X    } else {
  1658. X#define    GDIST(x,y)    (dist2(x,y,gx,gy))
  1659. X        if(Invis)
  1660. X            avoid = FALSE;
  1661. X        else {
  1662. X            uondoor = (u.ux == ESHK(shkp)->shd.x &&
  1663. X                u.uy == ESHK(shkp)->shd.y);
  1664. X            if(uondoor) {
  1665. X            if((ESHK(shkp)->billct || ESHK(shkp)->debit) 
  1666. X                    && inhishop(shkp))
  1667. X                pline(NOTANGRY(shkp) ?
  1668. X                "\"Hello, %s!  Will you please pay before leaving?\"" :
  1669. X                "\"Hey, %s!  Don't leave without paying!\"",
  1670. X                plname);
  1671. X            badinv = (!!carrying(PICK_AXE));
  1672. X            if(satdoor && badinv)
  1673. X                return(0);
  1674. X            avoid = !badinv;
  1675. X            } else {
  1676. X            avoid = (u.uinshop && dist(gx,gy) > 8);
  1677. X            badinv = FALSE;
  1678. X            }
  1679. X
  1680. X            if(((!ESHK(shkp)->robbed && !ESHK(shkp)->billct &&
  1681. X                !ESHK(shkp)->debit) || avoid)
  1682. X            && GDIST(omx,omy) < 3) {
  1683. X            if(!badinv && !online(omx,omy))
  1684. X                return(0);
  1685. X            if(satdoor)
  1686. X                appr = gx = gy = 0;
  1687. X            }
  1688. X        }
  1689. X    }
  1690. X    
  1691. X    return(move_special(shkp,shkroom,appr,uondoor,avoid,omx,omy,gx,gy));
  1692. X}
  1693. X
  1694. X#endif /* OVLB */
  1695. X#ifdef OVL0
  1696. X
  1697. Xint
  1698. Xonline(x,y)        /*    New version to speed things up.
  1699. X             *    Compiler dependant, may not always work.
  1700. X             */
  1701. Xregister xchar x, y;
  1702. X{
  1703. X    return((x-=u.ux) == 0 || (y-=u.uy) == 0 || x == y || (x+=y) == 0);
  1704. X}
  1705. X
  1706. X/*            Original version, just in case...
  1707. X *online(x,y) {
  1708. X *    return(x==u.ux || y==u.uy || (x-u.ux)*(x-u.ux) == (y-u.uy)*(y-u.uy));
  1709. X *}
  1710. X */
  1711. X
  1712. X#endif /* OVL0 */
  1713. X#ifdef OVLB
  1714. X
  1715. X/* for use in levl_follower (mondata.c) */
  1716. Xboolean
  1717. Xis_fshk(mtmp)
  1718. Xregister struct monst *mtmp;
  1719. X{
  1720. X    return(mtmp->isshk && ESHK(mtmp)->following);
  1721. X}
  1722. X
  1723. X/* He is digging in the shop. */
  1724. Xvoid
  1725. Xshopdig(fall)
  1726. Xregister int fall;
  1727. X{
  1728. X    if(!shopkeeper) return;
  1729. X    if(!inhishop(shopkeeper)) {
  1730. X    if (pl_character[0] == 'K') adjalign(-sgn(u.ualigntyp));
  1731. X    return;
  1732. X    }
  1733. X
  1734. X    if(!fall) {
  1735. X    if(u.utraptype == TT_PIT)
  1736. X        pline("\"Be careful, %s, or you might fall through the floor.\"",
  1737. X        flags.female ? "madam" : "sir");
  1738. X    else
  1739. X        pline("\"%s, do not damage the floor here!\"",
  1740. X            flags.female ? "Madam" : "Sir");
  1741. X    if (pl_character[0] == 'K') adjalign(-sgn(u.ualigntyp));
  1742. X    } else 
  1743. X    if(!um_dist(shopkeeper->mx, shopkeeper->my, 5) &&
  1744. X          !shopkeeper->msleep && shopkeeper->mcanmove &&
  1745. X          (ESHK(shopkeeper)->billct || ESHK(shopkeeper)->debit)) {
  1746. X        register struct obj *obj, *obj2;
  1747. X
  1748. X        if(dist(shopkeeper->mx, shopkeeper->my) > 2) {
  1749. X        mnexto(shopkeeper);
  1750. X        /* for some reason he can't come next to you */
  1751. X        if(dist(shopkeeper->mx, shopkeeper->my) > 2) {
  1752. X            pline("%s curses you in anger and frustration!",
  1753. X                    shkname(shopkeeper));
  1754. X            NOTANGRY(shopkeeper) = 0;
  1755. X            return;
  1756. X        } else pline("%s leaps, and grabs your backpack!",
  1757. X                    shkname(shopkeeper));
  1758. X        } else pline("%s grabs your backpack!", shkname(shopkeeper));
  1759. X
  1760. X        for(obj = invent; obj; obj = obj2) {
  1761. X        obj2 = obj->nobj;
  1762. X        if(obj->owornmask) continue;
  1763. X#ifdef WALKIES
  1764. X        if(obj->otyp == LEASH && obj->leashmon) continue;
  1765. X#endif
  1766. X        freeinv(obj);
  1767. X        obj->nobj = shopkeeper->minvent;
  1768. X        shopkeeper->minvent = obj;
  1769. X        subfrombill(obj);
  1770. X        }
  1771. X    }
  1772. X}
  1773. X
  1774. X#ifdef KOPS
  1775. XSTATIC_OVL int
  1776. Xmakekops(mm)        /* returns the number of (all types of) Kops  made */
  1777. Xcoord *mm;
  1778. X{
  1779. X    register int cnt = dlevel + rnd(5);
  1780. X    register int scnt = (cnt / 3) + 1;    /* at least one sarge */
  1781. X    register int lcnt = (cnt / 6);        /* maybe a lieutenant */
  1782. X    register int kcnt = (cnt / 9);        /* and maybe a kaptain */
  1783. X
  1784. X    while(cnt--) {
  1785. X        if (enexto(mm, mm->x, mm->y, &mons[PM_KEYSTONE_KOP]))
  1786. X            (void) makemon(&mons[PM_KEYSTONE_KOP], mm->x, mm->y);
  1787. X    }
  1788. X    while(scnt--) {
  1789. X        if (enexto(mm, mm->x, mm->y, &mons[PM_KOP_SERGEANT]))
  1790. X            (void) makemon(&mons[PM_KOP_SERGEANT], mm->x, mm->y);
  1791. X    }
  1792. X    while(lcnt--) {
  1793. X        if (enexto(mm, mm->x, mm->y, &mons[PM_KOP_LIEUTENANT]))
  1794. X            (void) makemon(&mons[PM_KOP_LIEUTENANT], mm->x, mm->y);
  1795. X    }
  1796. X    while(kcnt--) {
  1797. X        if (enexto(mm, mm->x, mm->y, &mons[PM_KOP_KAPTAIN]))
  1798. X            (void) makemon(&mons[PM_KOP_KAPTAIN], mm->x, mm->y);
  1799. X    }
  1800. X    return(cnt + scnt + lcnt + kcnt);
  1801. X}
  1802. X#endif
  1803. X
  1804. X#endif /* OVLB */
  1805. X#ifdef OVL1
  1806. X
  1807. Xboolean
  1808. Xin_shop(x,y)
  1809. Xregister int x, y;
  1810. X{
  1811. X    register int roomno = inroom(x, y);
  1812. X
  1813. X    if (roomno < 0) return(FALSE);
  1814. X    return (IS_SHOP(rooms[roomno]));
  1815. X}
  1816. X
  1817. X#endif /* OVL1 */
  1818. X#ifdef OVLB
  1819. X
  1820. Xvoid
  1821. Xpay_for_door(x,y,dmgstr)
  1822. Xint x, y;
  1823. Xconst char *dmgstr;
  1824. X{
  1825. X    struct monst *mtmp;
  1826. X    int roomno = inroom(x, y);
  1827. X    long damage;
  1828. X    boolean uinshp = in_shop(u.ux, u.uy);
  1829. X
  1830. X    /* make sure this function is not used in the wrong place */
  1831. X    if(!(IS_DOOR(levl[x][y].typ) && in_shop(x, y))) return;
  1832. X
  1833. X    findshk(roomno);
  1834. X
  1835. X    if(!shopkeeper) return;
  1836. X
  1837. X    /* not the best introduction to the shk... */
  1838. X    (void) strncpy(ESHK(shopkeeper)->customer,plname,PL_NSIZ);
  1839. X
  1840. X    /* if he is already on the war path, be sure it's all out */
  1841. X    if(ANGRY(shopkeeper) || ESHK(shopkeeper)->following) {
  1842. X        NOTANGRY(shopkeeper) = 0;
  1843. X        ESHK(shopkeeper)->following = 1;
  1844. X        return;
  1845. X    }
  1846. X
  1847. X    /* if he's not in his shop.. */
  1848. X    if(!in_shop(shopkeeper->mx ,shopkeeper->my)) {
  1849. X        if(!cansee(shopkeeper->mx, shopkeeper->my)) return;
  1850. X        goto gethim;
  1851. X    }
  1852. X
  1853. X    if(uinshp) {
  1854. X        if(um_dist(shopkeeper->mx, shopkeeper->my, 1) &&
  1855. X               !um_dist(shopkeeper->mx, shopkeeper->my, 3)) { 
  1856. X            pline("%s leaps towards you!", shkname(shopkeeper));
  1857. X            mnexto(shopkeeper);
  1858. X        }
  1859. X        if(um_dist(shopkeeper->mx, shopkeeper->my, 1)) goto gethim;
  1860. X    } else {
  1861. X        /* if a !shopkeeper shows up at the door, move him */
  1862. X        if((mtmp = m_at(x, y)) && mtmp != shopkeeper) {
  1863. X        if(flags.soundok) {
  1864. X            You("hear an angry voice:");
  1865. X            verbalize("Out of my way, scum!");
  1866. X            (void) fflush(stdout);
  1867. X#if defined(SYSV) || defined(ULTRIX) || defined(VMS)
  1868. X            (void)
  1869. X#endif
  1870. X#if defined(UNIX) || defined(VMS)
  1871. X            sleep(1);
  1872. X#endif
  1873. X        }
  1874. X        mnearto(mtmp, x, y, FALSE);
  1875. X        }
  1876. X
  1877. X        /* make shk show up at the door */
  1878. X        remove_monster(shopkeeper->mx, shopkeeper->my);
  1879. X        place_monster(shopkeeper, x, y);
  1880. X        pmon(shopkeeper);
  1881. X    }
  1882. X
  1883. X    if(!strcmp(dmgstr, "destroy")) damage = 400L;
  1884. X    else damage = (long)(ACURR(A_STR) > 18) ? 400 : 20 * ACURR(A_STR);
  1885. X
  1886. X    if((um_dist(x, y, 1) && !uinshp) || 
  1887. X            (u.ugold + ESHK(shopkeeper)->credit) < damage 
  1888. X                || !rn2(50)) {
  1889. X        if(um_dist(x, y, 1) && !uinshp) {
  1890. X            pline("%s shouts:", shkname(shopkeeper));
  1891. X            pline("\"Who dared %s my door?\"", dmgstr);
  1892. X        } 
  1893. X        else
  1894. Xgethim:
  1895. X            pline("\"How dare you %s my door?\"", dmgstr);
  1896. X
  1897. X        NOTANGRY(shopkeeper) = 0;
  1898. X        ESHK(shopkeeper)->following = 1;
  1899. X        return;
  1900. X    }
  1901. X
  1902. X    if(Invis) Your("invisibility does not fool %s!", shkname(shopkeeper));
  1903. X    pline("\"Cad!  You did %ld zorkmids worth of damage!\"  Pay? ", damage);
  1904. X    if(yn() != 'n') {
  1905. X        damage = check_credit(damage, shopkeeper);
  1906. X        u.ugold -= damage;
  1907. X        shopkeeper->mgold += damage;
  1908. X        flags.botl = 1;
  1909. X        pline("Mollified, %s accepts your restitution.",
  1910. X            shkname(shopkeeper));
  1911. X        /* move shk back to his home loc */
  1912. X        home_shk(shopkeeper);
  1913. X        NOTANGRY(shopkeeper) = 1;
  1914. X    } else {
  1915. X        verbalize("Oh, yes!  You'll pay!");
  1916. X        ESHK(shopkeeper)->following = 1;
  1917. X        NOTANGRY(shopkeeper) = 0;
  1918. X        adjalign(-sgn(u.ualigntyp));
  1919. X    }
  1920. X}
  1921. X
  1922. X/* called in dokick.c when we kick an object in a store */
  1923. Xboolean
  1924. Xcostly_spot(x, y)
  1925. Xregister int x, y;
  1926. X{
  1927. X    register struct monst *shkp = shopkeeper;
  1928. X    
  1929. X    if(!shkp) return(FALSE);
  1930. X
  1931. X    return(in_shop(x, y) && levl[x][y].typ != DOOR &&
  1932. X        !(x == ESHK(shkp)->shk.x && y == ESHK(shkp)->shk.y));
  1933. X}
  1934. X
  1935. X#ifdef KOPS
  1936. Xstatic void
  1937. Xkops_gone()
  1938. X{
  1939. X    register int cnt = 0;
  1940. X    register struct monst *mtmp, *mtmp2;
  1941. X
  1942. X    /* turn off automatic resurrection of kops */
  1943. X    allow_kops = FALSE;
  1944. X
  1945. X    for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  1946. X        mtmp2 = mtmp->nmon;
  1947. X        if(mtmp->data->mlet == S_KOP) {
  1948. X            mongone(mtmp);
  1949. X            cnt++;
  1950. X        }
  1951. X    }
  1952. X    if(cnt) pline("The Kops (disappointed) disappear into thin air.");
  1953. X    allow_kops = TRUE;
  1954. X}
  1955. X#endif
  1956. X
  1957. Xstatic unsigned
  1958. Xcost_per_charge(otmp)
  1959. Xregister struct obj *otmp;
  1960. X{
  1961. X    register unsigned tmp = get_cost(otmp);
  1962. X
  1963. X    /* The idea is to make the exhaustive use of */
  1964. X    /* an unpaid item more expensive than buying */
  1965. X    /* outright.                     */
  1966. X    if(otmp->otyp == MAGIC_LAMP) {             /* 1 */
  1967. X        tmp += (tmp/3);
  1968. X    } else if(otmp->otyp == MAGIC_MARKER) {       /* 70 - 100 */
  1969. X        /* no way to determine in advance   */
  1970. X        /* how many charges will be wasted. */
  1971. X        /* so, arbitrarily, one half of the */
  1972. X        /* price per use.            */
  1973. X        tmp = (tmp/2);
  1974. X    } else if(otmp->otyp == BAG_OF_TRICKS) {      /* 1 - 20 */
  1975. X        tmp = (tmp/5);
  1976. X    } else if(otmp->otyp == CRYSTAL_BALL ||       /* 1 - 5 */
  1977. X          otmp->otyp == LAMP ||                     /* 1-10 */
  1978. X#ifdef MUSIC
  1979. X         (otmp->otyp >= MAGIC_FLUTE &&
  1980. X          otmp->otyp <= DRUM_OF_EARTHQUAKE) ||      /* 5 - 9 */
  1981. X#endif
  1982. X            otmp->olet == WAND_SYM) {         /* 3 - 11 */
  1983. X        if(otmp->spe > 1) tmp = (tmp/4);
  1984. X    }
  1985. X    else return(0);
  1986. X    return(tmp);
  1987. X}
  1988. X
  1989. X/* for using charges of unpaid objects */
  1990. Xvoid
  1991. Xcheck_unpaid(otmp)
  1992. Xregister struct obj *otmp;
  1993. X{
  1994. X    if(!in_shop(u.ux, u.uy)) return;
  1995. X    
  1996. X    if(otmp->spe <= 0) return;
  1997. X
  1998. X    if(otmp->unpaid) {
  1999. X        ESHK(shopkeeper)->debit += cost_per_charge(otmp);
  2000. X    }
  2001. X}
  2002. X
  2003. Xboolean
  2004. Xblock_door(x,y)      /* used in domove to block diagonal shop-exit */
  2005. Xregister int x, y;
  2006. X{
  2007. X    register int roomno = inroom(x, y);
  2008. X
  2009. X    if(!in_shop(u.ux, u.uy)) return(FALSE);
  2010. X
  2011. X    if(!IS_DOOR(levl[x][y].typ)) return(FALSE);
  2012. X
  2013. X    if(roomno != inroom(u.ux,u.uy)) return(FALSE);
  2014. X
  2015. X    findshk(roomno);
  2016. X
  2017. X    if(inhishop(shopkeeper)
  2018. X        && shopkeeper->mx == ESHK(shopkeeper)->shk.x
  2019. X        && shopkeeper->my == ESHK(shopkeeper)->shk.y
  2020. X        /* Actually, the shk should be made to block _any_ */
  2021. X        /* door, including a door the player digs, if the  */
  2022. X        /* shk is within a 'jumping' distance.           */
  2023. X        && ESHK(shopkeeper)->shd.x == x && ESHK(shopkeeper)->shd.y == y
  2024. X        && shopkeeper->mcanmove && !shopkeeper->msleep
  2025. X        && (ESHK(shopkeeper)->debit || ESHK(shopkeeper)->billct ||
  2026. X        ESHK(shopkeeper)->robbed)) {
  2027. X        pline("%s%s blocks your way!", shkname(shopkeeper),
  2028. X                Invis ? " senses your motion and" : "");
  2029. X        return(TRUE);
  2030. X    }
  2031. X    return(FALSE);
  2032. X}
  2033. X
  2034. Xboolean
  2035. Xblock_entry(x,y)      /* used in domove to block diagonal shop-entry */
  2036. Xregister int x, y;
  2037. X{
  2038. X    register int sx, sy, roomno = inroom(x, y);
  2039. X
  2040. X    if(roomno != inroom(u.ux,u.uy)) return(FALSE);
  2041. X
  2042. X    if(!(in_shop(u.ux, u.uy) && IS_DOOR(levl[u.ux][u.uy].typ) &&
  2043. X        levl[u.ux][u.uy].doormask == D_BROKEN)) return(FALSE);
  2044. X
  2045. X    findshk(roomno);
  2046. X    if(!inhishop(shopkeeper)) return(FALSE);
  2047. X
  2048. X    if(ESHK(shopkeeper)->shd.x != u.ux || ESHK(shopkeeper)->shd.y != u.uy)
  2049. X        return(FALSE);
  2050. X
  2051. X    sx = ESHK(shopkeeper)->shk.x;
  2052. X    sy = ESHK(shopkeeper)->shk.y;
  2053. X
  2054. X    if(shopkeeper->mx == sx && shopkeeper->my == sy
  2055. X            && shopkeeper->mcanmove && !shopkeeper->msleep
  2056. X            && in_shop(x, y)
  2057. X            && (x == sx-1 || x == sx+1 || y == sy-1 || y == sy+1)  
  2058. X            && (Invis || carrying(PICK_AXE))
  2059. X          ) {
  2060. X        pline("%s%s blocks your way!", shkname(shopkeeper),
  2061. X                Invis ? " senses your motion and" : "");
  2062. X        return(TRUE);
  2063. X    }
  2064. X    return(FALSE);
  2065. X}
  2066. X
  2067. X#endif /* OVLB */
  2068. END_OF_FILE
  2069. if test 42124 -ne `wc -c <'src/shk.c'`; then
  2070.     echo shar: \"'src/shk.c'\" unpacked with wrong size!
  2071. fi
  2072. # end of 'src/shk.c'
  2073. fi
  2074. echo shar: End of archive 9 \(of 56\).
  2075. cp /dev/null ark9isdone
  2076. MISSING=""
  2077. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 ; do
  2078.     if test ! -f ark${I}isdone ; then
  2079.     MISSING="${MISSING} ${I}"
  2080.     fi
  2081. done
  2082. if test "${MISSING}" = "" ; then
  2083.     echo You have unpacked all 56 archives.
  2084.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2085. else
  2086.     echo You still need to unpack the following archives:
  2087.     echo "        " ${MISSING}
  2088. fi
  2089. ##  End of shell archive.
  2090. exit 0
  2091.