home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / games / volume16 / nethack31 / part10 < prev    next >
Internet Message Format  |  1993-02-01  |  59KB

  1. Path: uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v16i010:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part10/108
  5. Message-ID: <4293@master.CNA.TEK.COM>
  6. Date: 28 Jan 93 19:12:05 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2496
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1566
  11.  
  12. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  13. Posting-number: Volume 16, Issue 10
  14. Archive-name: nethack31/Part10
  15. Supersedes: nethack3p9: Volume 10, Issue 46-102
  16. Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
  17.  
  18.  
  19.  
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then unpack
  22. # it by saving it into a file and typing "sh file".  To overwrite existing
  23. # files, type "sh file -c".  You can also feed this as standard input via
  24. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  25. # will see the following message at the end:
  26. #        "End of archive 10 (of 108)."
  27. # Contents:  src/objnam.c sys/amiga/char.c
  28. # Wrapped by billr@saab on Wed Jan 27 16:08:48 1993
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'src/objnam.c' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'src/objnam.c'\"
  32. else
  33. echo shar: Extracting \"'src/objnam.c'\" \(47782 characters\)
  34. sed "s/^X//" >'src/objnam.c' <<'END_OF_FILE'
  35. X/*    SCCS Id: @(#)objnam.c    3.1    92/12/13    */
  36. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  37. X/* NetHack may be freely redistributed.  See license for details. */
  38. X
  39. X#include    "hack.h"
  40. X
  41. X/* "an uncursed partly eaten guardian naga hatchling corpse" */
  42. X#define    PREFIX    50
  43. X#define SCHAR_LIM 127
  44. X
  45. XSTATIC_DCL char *FDECL(strprepend,(char *,const char *));
  46. X
  47. Xstruct Jitem {
  48. X    int item;
  49. X    const char *name;
  50. X};
  51. X
  52. X#ifndef OVLB
  53. X
  54. XSTATIC_DCL struct Jitem Japanese_items[];
  55. X
  56. X#else /* OVLB */
  57. X
  58. XSTATIC_OVL struct Jitem Japanese_items[] = {
  59. X    { SHORT_SWORD, "wakizashi" },
  60. X    { BROADSWORD, "ninja-to" },
  61. X    { GLAIVE, "naginata" },
  62. X    { LOCK_PICK, "osaku" },
  63. X    {0, "" }
  64. X};
  65. X
  66. X#endif /* OVLB */
  67. X
  68. XSTATIC_DCL const char *FDECL(Japanese_item_name,(int i));
  69. X
  70. X#ifdef OVL1
  71. X
  72. XSTATIC_OVL char *
  73. Xstrprepend(s,pref)
  74. Xregister char *s;
  75. Xregister const char *pref; {
  76. Xregister int i = strlen(pref);
  77. X    if(i > PREFIX) {
  78. X        pline("WARNING: prefix too short.");
  79. X        return(s);
  80. X    }
  81. X    s -= i;
  82. X    (void) strncpy(s, pref, i);    /* do not copy trailing 0 */
  83. X    return(s);
  84. X}
  85. X
  86. X#endif /* OVL1 */
  87. X#ifdef OVLB
  88. X
  89. Xchar *
  90. Xtypename(otyp)
  91. Xregister int otyp;
  92. X{
  93. X#ifdef LINT    /* static char buf[BUFSZ]; */
  94. Xchar buf[BUFSZ];
  95. X#else
  96. Xstatic char NEARDATA buf[BUFSZ];
  97. X#endif
  98. Xregister struct objclass *ocl = &objects[otyp];
  99. Xregister const char *actualn = OBJ_NAME(*ocl);
  100. Xregister const char *dn = OBJ_DESCR(*ocl);
  101. Xregister const char *un = ocl->oc_uname;
  102. Xregister int nn = ocl->oc_name_known;
  103. X
  104. X    if (pl_character[0] == 'S' && Japanese_item_name(otyp))
  105. X        actualn = Japanese_item_name(otyp);
  106. X    switch(ocl->oc_class) {
  107. X    case GOLD_CLASS:
  108. X        Strcpy(buf, "coin");
  109. X        break;
  110. X    case POTION_CLASS:
  111. X        Strcpy(buf, "potion");
  112. X        break;
  113. X    case SCROLL_CLASS:
  114. X        Strcpy(buf, "scroll");
  115. X        break;
  116. X    case WAND_CLASS:
  117. X        Strcpy(buf, "wand");
  118. X        break;
  119. X    case SPBOOK_CLASS:
  120. X        Strcpy(buf, "spellbook");
  121. X        break;
  122. X    case RING_CLASS:
  123. X        Strcpy(buf, "ring");
  124. X        break;
  125. X    case AMULET_CLASS:
  126. X        if(nn)
  127. X            Strcpy(buf,actualn);
  128. X        else
  129. X            Strcpy(buf,"amulet");
  130. X        if(un)
  131. X            Sprintf(eos(buf)," called %s",un);
  132. X        if(dn)
  133. X            Sprintf(eos(buf)," (%s)",dn);
  134. X        return(buf);
  135. X    default:
  136. X        if(nn) {
  137. X            Strcpy(buf, actualn);
  138. X            if(otyp >= TURQUOISE && otyp <= JADE)
  139. X                Strcat(buf, " stone");
  140. X            if(un)
  141. X                Sprintf(eos(buf), " called %s", un);
  142. X            if(dn)
  143. X                Sprintf(eos(buf), " (%s)", dn);
  144. X        } else {
  145. X            Strcpy(buf, dn ? dn : actualn);
  146. X            if(ocl->oc_class == GEM_CLASS) {
  147. X                if (otyp == LOADSTONE || otyp == LUCKSTONE)
  148. X                    Strcat(buf, " stone");
  149. X                else
  150. X                    Strcat(buf, " gem");
  151. X            }
  152. X            if(un)
  153. X                Sprintf(eos(buf), " called %s", un);
  154. X        }
  155. X        return(buf);
  156. X    }
  157. X    /* here for ring/scroll/potion/wand */
  158. X    if(nn)
  159. X        Sprintf(eos(buf), " of %s", actualn);
  160. X    if(un)
  161. X        Sprintf(eos(buf), " called %s", un);
  162. X    if(dn)
  163. X        Sprintf(eos(buf), " (%s)", dn);
  164. X    return(buf);
  165. X}
  166. X
  167. Xboolean
  168. Xobj_is_pname(obj)
  169. Xregister struct obj *obj;
  170. X{
  171. X    return (obj->dknown && obj->known && obj->onamelth && obj->oartifact &&
  172. X        !objects[obj->otyp].oc_unique);
  173. X}
  174. X
  175. X/* Give the name of an object seen at a distance.  Unlike xname/doname,
  176. X * we don't want to set dknown if it's not set already.  The kludge used is
  177. X * to temporarily set Blind so that xname() skips the dknown setting.  This
  178. X * assumes that we don't want to do this too often; if this function becomes
  179. X * frequently used, it'd probably be better to pass a parameter to xname()
  180. X * or doname() instead.
  181. X */
  182. Xchar *
  183. Xdistant_name(obj, func)
  184. Xregister struct obj *obj;
  185. Xchar *FDECL((*func), (OBJ_P));
  186. X{
  187. X    char *str;
  188. X
  189. X    long save_Blinded = Blinded;
  190. X    Blinded = 1;
  191. X    str = (*func)(obj);
  192. X    Blinded = save_Blinded;
  193. X    return str;
  194. X}
  195. X
  196. X#endif /* OVLB */
  197. X#ifdef OVL1
  198. X
  199. Xchar *
  200. Xxname(obj)
  201. Xregister struct obj *obj;
  202. X{
  203. X#ifdef LINT    /* lint may handle static decl poorly -- static char bufr[]; */
  204. Xchar bufr[BUFSZ];
  205. X#else
  206. Xstatic char bufr[BUFSZ];
  207. X#endif
  208. Xregister char *buf = &(bufr[PREFIX]);    /* leave room for "17 -3 " */
  209. Xregister int typ = obj->otyp;
  210. Xregister int nn = objects[typ].oc_name_known;
  211. Xregister const char *actualn = OBJ_NAME(objects[typ]);
  212. Xregister const char *dn = OBJ_DESCR(objects[typ]);
  213. Xregister const char *un = objects[typ].oc_uname;
  214. X
  215. X    if (pl_character[0] == 'S' && Japanese_item_name(typ))
  216. X        actualn = Japanese_item_name(typ);
  217. X
  218. X    buf[0] = '\0';
  219. X    if (!Blind) obj->dknown=1;
  220. X    if (obj_is_pname(obj))
  221. X        goto nameit;
  222. X    switch (obj->oclass) {
  223. X        case AMULET_CLASS:
  224. X        if (!obj->dknown)
  225. X            Strcpy(buf, "amulet");
  226. X        else if (typ == FAKE_AMULET_OF_YENDOR)
  227. X            /* each must be identified individually */
  228. X            Strcpy(buf, obj->known ? actualn : dn);
  229. X        else if (nn) /* should be true for the Amulet of Yendor */
  230. X            Strcpy(buf, actualn);
  231. X        else if (un)
  232. X            Sprintf(buf,"amulet called %s", un);
  233. X        else
  234. X            Sprintf(buf,"%s amulet", dn);
  235. X        break;
  236. X        case WEAPON_CLASS:
  237. X        if (typ <= SHURIKEN && obj->opoisoned)
  238. X            Strcpy(buf, "poisoned ");
  239. X        case VENOM_CLASS:
  240. X        case TOOL_CLASS:
  241. X        if(un) {
  242. X            /* un must come first here.  If it does not, they could
  243. X             * tell objects apart by seeing which ones refuse to
  244. X             * accept names.
  245. X             */
  246. X            Sprintf(buf, "%s called %s",
  247. X                nn ? actualn : dn, un);
  248. X        } else if(nn)
  249. X            Strcat(buf, actualn);
  250. X        else
  251. X            Strcat(buf, dn);
  252. X        /* If we use an() here we'd have to remember never to use */
  253. X        /* it whenever calling doname() or xname(). */
  254. X        if (typ == FIGURINE)
  255. X            Sprintf(eos(buf), " of a%s %s",
  256. X            index(vowels,*(mons[obj->corpsenm].mname)) ? "n" : "",
  257. X            mons[obj->corpsenm].mname);
  258. X        break;
  259. X        case ARMOR_CLASS:
  260. X        /* depends on order of the dragon scales objects */
  261. X        if (typ >= GRAY_DRAGON_SCALES && typ <= YELLOW_DRAGON_SCALES) {
  262. X            Sprintf(buf, "set of %s", OBJ_NAME(objects[typ]));
  263. X            break;
  264. X        }
  265. X        if(is_boots(obj) || is_gloves(obj)) Strcpy(buf,"pair of ");
  266. X
  267. X        if(nn)    Strcat(buf, actualn);
  268. X        else if(un) {
  269. X            if(is_boots(obj))
  270. X                Strcat(buf,"boots");
  271. X            else if(is_gloves(obj))
  272. X                Strcat(buf,"gloves");
  273. X            else if(is_cloak(obj))
  274. X                Strcpy(buf,"cloak");
  275. X            else if(is_helmet(obj))
  276. X                Strcpy(buf,"helmet");
  277. X            else if(is_shield(obj))
  278. X                Strcpy(buf,"shield");
  279. X            else
  280. X                Strcpy(buf,"armor");
  281. X            Strcat(buf, " called ");
  282. X            Strcat(buf, un);
  283. X        } else    Strcat(buf, dn);
  284. X        break;
  285. X        case FOOD_CLASS:
  286. X#ifdef TUTTI_FRUTTI
  287. X        if (typ == SLIME_MOLD) {
  288. X            register struct fruit *f;
  289. X
  290. X            for(f=ffruit; f; f = f->nextf) {
  291. X                if(f->fid == obj->spe) {
  292. X                    Strcpy(buf, f->fname);
  293. X                    break;
  294. X                }
  295. X            }
  296. X            if (!f) impossible("Bad fruit #%d?", obj->spe);
  297. X            break;
  298. X        }
  299. X#endif
  300. X        Strcpy(buf, actualn);
  301. X        if (typ == TIN && obj->known) {
  302. X            if(obj->spe > 0)
  303. X            Strcat(buf, " of spinach");
  304. X            else if (obj->corpsenm < 0)
  305. X                Strcpy(buf, "empty tin");
  306. X            else if (is_meaty(&mons[obj->corpsenm]))
  307. X            Sprintf(eos(buf), " of %s meat", mons[obj->corpsenm].mname);
  308. X            else
  309. X            Sprintf(eos(buf), " of %s", mons[obj->corpsenm].mname);
  310. X        }
  311. X        break;
  312. X        case GOLD_CLASS:
  313. X        case CHAIN_CLASS:
  314. X        Strcpy(buf, actualn);
  315. X        break;
  316. X        case ROCK_CLASS:
  317. X        if (typ == STATUE)
  318. X            Sprintf(buf, "%s of %s%s", actualn,
  319. X            type_is_pname(&mons[obj->corpsenm]) ? "" :
  320. X                (index(vowels,*(mons[obj->corpsenm].mname)) ?
  321. X                                "an " : "a "),
  322. X            mons[obj->corpsenm].mname);
  323. X        else Strcpy(buf, actualn);
  324. X        break;
  325. X        case BALL_CLASS:
  326. X        Sprintf(buf, "%sheavy iron ball",
  327. X            (obj->owt > objects[typ].oc_weight) ? "very " : "");
  328. X        break;
  329. X        case POTION_CLASS:
  330. X        if(nn || un || !obj->dknown) {
  331. X            Strcpy(buf, "potion");
  332. X            if(!obj->dknown) break;
  333. X            if(nn) {
  334. X                Strcat(buf, " of ");
  335. X                if (typ == POT_WATER &&
  336. X                objects[POT_WATER].oc_name_known &&
  337. X                (obj->bknown || pl_character[0] == 'P') &&
  338. X                (obj->blessed || obj->cursed)) {
  339. X                Strcat(buf, obj->blessed ? "holy " : "unholy ");
  340. X                }
  341. X                Strcat(buf, actualn);
  342. X            } else {
  343. X                Strcat(buf, " called ");
  344. X                Strcat(buf, un);
  345. X            }
  346. X        } else {
  347. X            Strcpy(buf, dn);
  348. X            Strcat(buf, " potion");
  349. X        }
  350. X        break;
  351. X    case SCROLL_CLASS:
  352. X        Strcpy(buf, "scroll");
  353. X        if(!obj->dknown) break;
  354. X        if(nn) {
  355. X            Strcat(buf, " of ");
  356. X            Strcat(buf, actualn);
  357. X        } else if(un) {
  358. X            Strcat(buf, " called ");
  359. X            Strcat(buf, un);
  360. X        } else if (objects[typ].oc_magic) {
  361. X            Strcat(buf, " labeled ");
  362. X            Strcat(buf, dn);
  363. X        } else {
  364. X            Strcpy(buf, dn);
  365. X            Strcat(buf, " scroll");
  366. X        }
  367. X        break;
  368. X    case WAND_CLASS:
  369. X        if(!obj->dknown)
  370. X            Strcpy(buf, "wand");
  371. X        else if(nn)
  372. X            Sprintf(buf, "wand of %s", actualn);
  373. X        else if(un)
  374. X            Sprintf(buf, "wand called %s", un);
  375. X        else
  376. X            Sprintf(buf, "%s wand", dn);
  377. X        break;
  378. X    case SPBOOK_CLASS:
  379. X        if (!obj->dknown) {
  380. X            Strcpy(buf, "spellbook");
  381. X        } else if (nn) {
  382. X            if (typ != SPE_BOOK_OF_THE_DEAD)
  383. X                Strcpy(buf, "spellbook of ");
  384. X            Strcat(buf, actualn);
  385. X        } else if (un) {
  386. X            Sprintf(buf, "spellbook called %s", un);
  387. X        } else
  388. X            Sprintf(buf, "%s spellbook", dn);
  389. X        break;
  390. X    case RING_CLASS:
  391. X        if(!obj->dknown)
  392. X            Strcpy(buf, "ring");
  393. X        else if(nn)
  394. X            Sprintf(buf, "ring of %s", actualn);
  395. X        else if(un)
  396. X            Sprintf(buf, "ring called %s", un);
  397. X        else
  398. X            Sprintf(buf, "%s ring", dn);
  399. X        break;
  400. X    case GEM_CLASS:
  401. X        if(!obj->dknown) {
  402. X            if (typ == ROCK || typ == LOADSTONE || typ == LUCKSTONE)
  403. X                Strcpy(buf, "stone");
  404. X            else
  405. X                Strcpy(buf, "gem");
  406. X            break;
  407. X        }
  408. X        if(!nn) {
  409. X            const char *rock =
  410. X              (typ==LOADSTONE || typ==LUCKSTONE) ? "stone" : "gem";
  411. X            if(un)    Sprintf(buf,"%s called %s", rock, un);
  412. X            else    Sprintf(buf, "%s %s", dn, rock);
  413. X            break;
  414. X        }
  415. X        Strcpy(buf, actualn);
  416. X        if(typ >= TURQUOISE && typ <= JADE)
  417. X            Strcat(buf, " stone");
  418. X        break;
  419. X    default:
  420. X        Sprintf(buf,"glorkum %d %d %d", obj->oclass, typ, obj->spe);
  421. X    }
  422. X    if(obj->quan != 1L) Strcpy(buf, makeplural(buf));
  423. X
  424. X    if(obj->onamelth &&
  425. X       (!obj->oartifact || !objects[obj->otyp].oc_unique)) {
  426. X        Strcat(buf, " named ");
  427. X        nameit:
  428. X        Strcat(buf, ONAME(obj));
  429. X    }
  430. X    return(buf);
  431. X}
  432. X
  433. X#endif /* OVL1 */
  434. X#ifdef OVL0
  435. X
  436. Xchar *
  437. Xdoname(obj)
  438. Xregister struct obj *obj;
  439. X{
  440. X    boolean ispoisoned = FALSE;
  441. X    char prefix[PREFIX];
  442. X    char tmpbuf[PREFIX+1];
  443. X    /* when we have to add something at the start of prefix instead of the
  444. X     * end (Strcat is used on the end)
  445. X     */
  446. X    register char *bp = xname(obj);
  447. X    /* When using xname, we want "poisoned arrow", and when using
  448. X     * doname, we want "poisoned +0 arrow".  This kludge is about the only
  449. X     * way to do it, at least until someone overhauls xname() and doname(),
  450. X     * combining both into one function taking a parameter.
  451. X     */
  452. X    if (!strncmp(bp, "poisoned ", 9)) {
  453. X        bp += 9;
  454. X        ispoisoned = TRUE;
  455. X    }
  456. X
  457. X    if(obj->quan != 1L)
  458. X        Sprintf(prefix, "%ld ", obj->quan);
  459. X    else if(obj_is_pname(obj)) {
  460. X        if (!strncmpi(bp, "the ", 4))
  461. X            bp += 4;
  462. X        Strcpy(prefix, "the ");
  463. X    } else
  464. X        Strcpy(prefix, "a ");
  465. X    if((obj->bknown || pl_character[0] == 'P') &&
  466. X        (obj->otyp != POT_WATER || !objects[POT_WATER].oc_name_known
  467. X        || (!obj->cursed && !obj->blessed))) {
  468. X        /* allow 'blessed clear potion' if we don't know it's holy water;
  469. X         * always allow "uncursed potion of water"
  470. X         */
  471. X        if(obj->cursed)
  472. X        Strcat(prefix, "cursed ");
  473. X        else if(obj->blessed)
  474. X        Strcat(prefix, "blessed ");
  475. X        else if (((obj->oclass != ARMOR_CLASS
  476. X            && obj->oclass != WAND_CLASS
  477. X            && obj->oclass != WEAPON_CLASS
  478. X            && ((obj->oclass != TOOL_CLASS &&
  479. X                 obj->oclass != RING_CLASS) ||
  480. X                 !objects[obj->otyp].oc_charged))
  481. X                || !obj->known)
  482. X        /* For items with charges or +/-, knowing the +/- means that
  483. X         * the item has been totally identified, and therefore there
  484. X         * is no doubt as to the object being uncursed if it's
  485. X         * not described as "blessed" or "cursed".
  486. X         *
  487. X         * If the +/- isn't known, "uncursed" must be printed to
  488. X         * avoid ambiguity between an item whose curse status is
  489. X         * unknown, and an item known to be uncursed.
  490. X         */
  491. X#ifdef MAIL
  492. X            && obj->otyp != SCR_MAIL
  493. X#endif
  494. X            && obj->otyp != FAKE_AMULET_OF_YENDOR
  495. X            && obj->otyp != AMULET_OF_YENDOR
  496. X            && pl_character[0] != 'P')
  497. X        Strcat(prefix, "uncursed ");
  498. X    }
  499. X    if(obj->greased) Strcat(prefix, "greased ");
  500. X    switch(obj->oclass) {
  501. X    case AMULET_CLASS:
  502. X        if(obj->otyp == FAKE_AMULET_OF_YENDOR ||
  503. X           obj->otyp == AMULET_OF_YENDOR)
  504. X            if(strncmp(bp, "cheap ", 6)) {
  505. X            Strcpy(tmpbuf, "the ");
  506. X            Strcat(tmpbuf, prefix+2); /* skip the "a " */
  507. X            Strcpy(prefix, tmpbuf);
  508. X            }
  509. X        if(obj->owornmask & W_AMUL)
  510. X            Strcat(bp, " (being worn)");
  511. X        break;
  512. X    case WEAPON_CLASS:
  513. X        if(ispoisoned)
  514. X            Strcat(prefix, "poisoned ");
  515. Xplus:
  516. X        if (obj->oeroded) {
  517. X            switch (obj->oeroded) {
  518. X                case 2:    Strcat(prefix, "very "); break;
  519. X                case 3:    Strcat(prefix, "thoroughly "); break;
  520. X            }            
  521. X            Strcat(prefix,
  522. X                   is_rustprone(obj) ? "rusty " :
  523. X                   is_corrodeable(obj) ? "corroded " :
  524. X                   is_flammable(obj) ? "burnt " : "");
  525. X        } else if (obj->rknown && obj->oerodeproof)
  526. X            Strcat(prefix,
  527. X                   is_rustprone(obj) ? "rustproof " :
  528. X                   is_corrodeable(obj) ? "corrodeproof " :    /* "stainless"? */
  529. X                   is_flammable(obj) ? "fireproof " : "");
  530. X        if(obj->known) {
  531. X            Strcat(prefix, sitoa(obj->spe));
  532. X            Strcat(prefix, " ");
  533. X        }
  534. X        break;
  535. X    case ARMOR_CLASS:
  536. X        if(obj->owornmask & W_ARMOR)
  537. X            Strcat(bp,
  538. X#ifdef POLYSELF
  539. X                (obj == uskin) ? " (embedded in your skin)" :
  540. X#endif
  541. X                " (being worn)");
  542. X        goto plus;
  543. X    case TOOL_CLASS:        /* temp. hack by GAN 11/18/86 */
  544. X        if(obj->owornmask & W_TOOL) { /* blindfold */
  545. X            Strcat(bp, " (being worn)");
  546. X            break;
  547. X        }
  548. X#ifdef WALKIES
  549. X        if(obj->otyp == LEASH && obj->leashmon != 0) {
  550. X            Strcat(bp, " (in use)");
  551. X            break;
  552. X        }
  553. X#endif
  554. X        if(obj->otyp == PICK_AXE || obj->otyp == UNICORN_HORN)
  555. X            goto plus;
  556. X        if (Is_candle(obj) &&
  557. X            obj->age < 20L * (long)objects[obj->otyp].oc_cost)
  558. X            Sprintf(eos(prefix), "partly used ");
  559. X        if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
  560. X            obj->otyp == BRASS_LANTERN ||
  561. X            Is_candle(obj) || obj->otyp == CANDELABRUM_OF_INVOCATION) {
  562. X            if(obj->lamplit)
  563. X                Sprintf(eos(bp), " (lit)");
  564. X            break;
  565. X        }
  566. X        if(!objects[obj->otyp].oc_charged) break;
  567. X        /* if special tool, fall through to show charges */
  568. X    case WAND_CLASS:
  569. X        if(obj->known)
  570. X            Sprintf(eos(bp), " (%d)", obj->spe);
  571. X        break;
  572. X    case RING_CLASS:
  573. X        if(obj->owornmask & W_RINGR) Strcat(bp, " (on right ");
  574. X        if(obj->owornmask & W_RINGL) Strcat(bp, " (on left ");
  575. X        if(obj->owornmask & W_RING) {
  576. X            Strcat(bp, body_part(HAND));
  577. X            Strcat(bp, ")");
  578. X        }
  579. X        if(obj->known && objects[obj->otyp].oc_charged) {
  580. X            Strcat(prefix, sitoa(obj->spe));
  581. X            Strcat(prefix, " ");
  582. X        }
  583. X        break;
  584. X    case FOOD_CLASS:
  585. X        if (obj->oeaten)
  586. X            Strcat(prefix, "partly eaten ");
  587. X        if (obj->otyp == CORPSE) {
  588. X            if (type_is_pname(&mons[obj->corpsenm])) {
  589. X            Sprintf(prefix, "%s ",
  590. X                s_suffix(mons[obj->corpsenm].mname));
  591. X            if (obj->oeaten) Strcat(prefix, "partly eaten ");
  592. X            } else {
  593. X            Strcat(prefix, mons[obj->corpsenm].mname);
  594. X            Strcat(prefix, " ");
  595. X            }
  596. X        } else if (obj->otyp == EGG && obj->known) {
  597. X            if (obj->corpsenm >= 0) {
  598. X            Strcat(prefix, mons[obj->corpsenm].mname);
  599. X            Strcat(prefix, " ");
  600. X#ifdef POLYSELF
  601. X            if (obj->spe)
  602. X                Strcat(bp, " (laid by you)");
  603. X#endif
  604. X            }
  605. X        }
  606. X        break;
  607. X    case BALL_CLASS:
  608. X        if(obj->owornmask & W_BALL)
  609. X            Strcat(bp, " (chained to you)");
  610. X            break;
  611. X    }
  612. X
  613. X    if((obj->owornmask & W_WEP) && !mrg_to_wielded) {
  614. X        if (obj->quan != 1L)
  615. X            Strcat(bp, " (wielded)");
  616. X        else {
  617. X            Strcat(bp, " (weapon in ");
  618. X            Strcat(bp, body_part(HAND));
  619. X            Strcat(bp, ")");
  620. X        }
  621. X    }
  622. X    if(obj->unpaid)
  623. X        Strcat(bp, " (unpaid)");
  624. X    if (!strncmp(prefix, "a ", 2) &&
  625. X            index(vowels, *(prefix+2) ? *(prefix+2) : *bp)
  626. X            && (*(prefix+2) || (strncmp(bp, "uranium", 7)
  627. X                && strncmp(bp, "unicorn", 7)))) {
  628. X        Strcpy(tmpbuf, prefix);
  629. X        Strcpy(prefix, "an ");
  630. X        Strcpy(prefix+3, tmpbuf+2);
  631. X    }
  632. X    bp = strprepend(bp, prefix);
  633. X    return(bp);
  634. X}
  635. X
  636. X#endif /* OVL0 */
  637. X#ifdef OVLB
  638. X
  639. X/*
  640. X * Used if only one of a collection of objects is named (e.g. in eat.c).
  641. X */
  642. X
  643. Xchar *
  644. Xsingular(otmp, func)
  645. Xregister struct obj *otmp;
  646. Xchar *FDECL((*func), (OBJ_P));
  647. X{
  648. X    long savequan;
  649. X    char *nam;
  650. X
  651. X    /* Note: using xname for corpses will not give the monster type */
  652. X    if (otmp->otyp == CORPSE && func == xname) {
  653. X        static char NEARDATA buf[31];
  654. X
  655. X        Sprintf(buf, "%s corpse", mons[otmp->corpsenm].mname);
  656. X        return buf;
  657. X    }
  658. X    savequan = otmp->quan;
  659. X    otmp->quan = 1L;
  660. X    nam = (*func)(otmp);
  661. X    otmp->quan = savequan;
  662. X    return nam;
  663. X}
  664. X
  665. Xchar *
  666. Xan(str)
  667. Xregister const char *str;
  668. X{
  669. X    static char NEARDATA buf[BUFSZ];
  670. X
  671. X    buf[0] = '\0';
  672. X
  673. X    if (strncmpi(str, "the ", 4) &&
  674. X        strcmp(str, "molten lava") &&
  675. X        strcmp(str, "ice"))
  676. X            if (index(vowels, *str) &&
  677. X            strncmp(str, "useful", 6) &&
  678. X            strncmp(str, "unicorn", 7) &&
  679. X            strncmp(str, "uranium", 7))
  680. X                Strcpy(buf, "an ");
  681. X            else
  682. X            Strcpy(buf, "a ");
  683. X
  684. X    Strcat(buf, str);
  685. X    return buf;
  686. X}
  687. X
  688. Xchar *
  689. XAn(str)
  690. Xconst char *str;
  691. X{
  692. X    register char *tmp = an(str);
  693. X    *tmp = highc(*tmp);
  694. X    return tmp;
  695. X}
  696. X
  697. X/*
  698. X * Prepend "the" if necessary; assumes str is a subject derived from xname.
  699. X * Use type_is_pname() for monster names, not the().  the() is idempotent.
  700. X */
  701. Xchar *
  702. Xthe(str)
  703. Xconst char *str;
  704. X{
  705. X    static char NEARDATA buf[BUFSZ];
  706. X
  707. X    if (!strncmpi(str, "the ", 4)) {
  708. X        buf[0] = lowc(*str);
  709. X        Strcpy(&buf[1], str+1);
  710. X        return buf;
  711. X    } else if (*str < 'A' || *str > 'Z') {
  712. X        /* not a proper name, needs an article */
  713. X        Strcpy(buf, "the ");
  714. X    } else {
  715. X        /* Probably a proper name, might not need an article */
  716. X        register char *tmp;
  717. X
  718. X        buf[0] = 0;
  719. X
  720. X        /* some objects have capitalized adjectives in their names */
  721. X        if(((tmp = rindex(str, ' ')) || (tmp = rindex(str, '-'))) &&
  722. X           (tmp[1] < 'A' || tmp[1] > 'Z'))
  723. X        Strcpy(buf, "the ");
  724. X        else if (tmp && (tmp = index(str, ' ')) != NULL) {
  725. X        /* it needs an article if the name contains "of" */
  726. X        while(tmp && strncmp(++tmp, "of ", 3))
  727. X            tmp = index(tmp, ' ');
  728. X        if (tmp) /* found an "of" */
  729. X            Strcpy(buf, "the ");
  730. X        }
  731. X    }
  732. X    Strcat(buf, str);
  733. X
  734. X    return buf;
  735. X}
  736. X
  737. Xchar *
  738. XThe(str)
  739. Xconst char *str;
  740. X{
  741. X    register char *tmp = the(str);
  742. X    *tmp = highc(*tmp);
  743. X    return tmp;
  744. X}
  745. X
  746. Xchar *
  747. Xaobjnam(otmp,verb)
  748. Xregister struct obj *otmp;
  749. Xregister const char *verb;
  750. X{
  751. X    register char *bp = xname(otmp);
  752. X    char prefix[PREFIX];
  753. X
  754. X    if(otmp->quan != 1L) {
  755. X        Sprintf(prefix, "%ld ", otmp->quan);
  756. X        bp = strprepend(bp, prefix);
  757. X    }
  758. X
  759. X    if(verb) {
  760. X        /* verb is given in plural (without trailing s) */
  761. X        Strcat(bp, " ");
  762. X        if(otmp->quan != 1L)
  763. X            Strcat(bp, verb);
  764. X        else if(!strcmp(verb, "are"))
  765. X            Strcat(bp, "is");
  766. X        else {
  767. X            Strcat(bp, verb);
  768. X            Strcat(bp, "s");
  769. X        }
  770. X    }
  771. X    return(bp);
  772. X}
  773. X
  774. Xchar *
  775. XDoname2(obj)
  776. Xregister struct obj *obj;
  777. X{
  778. X    register char *s = doname(obj);
  779. X
  780. X    if('a' <= *s && *s <= 'z') *s -= ('a' - 'A');
  781. X    return(s);
  782. X}
  783. X
  784. Xstatic const char *wrp[] = {
  785. X    "wand", "ring", "potion", "scroll", "gem", "amulet",
  786. X    "spellbook", "spell book",
  787. X    /* for non-specific wishes */
  788. X    "weapon", "armor", "tool", "food", "comestible",
  789. X};
  790. Xstatic const char wrpsym[] = {
  791. X    WAND_CLASS, RING_CLASS, POTION_CLASS, SCROLL_CLASS, GEM_CLASS, 
  792. X        AMULET_CLASS, SPBOOK_CLASS, SPBOOK_CLASS,
  793. X    WEAPON_CLASS, ARMOR_CLASS, TOOL_CLASS, FOOD_CLASS, FOOD_CLASS
  794. X};
  795. X
  796. X#endif /* OVLB */
  797. X#ifdef OVL0
  798. X
  799. X/* Plural routine; chiefly used for user-defined fruits.  We have to try to
  800. X * account for everything reasonable the player has; something unreasonable
  801. X * can still break the code.  However, it's still a lot more accurate than
  802. X * "just add an s at the end", which Rogue uses...
  803. X *
  804. X * Also used for plural monster names ("Wiped out all homunculi.")
  805. X * and body parts.
  806. X *
  807. X * Also misused by muse.c to convert 1st person present verbs to 2nd person.
  808. X */
  809. Xchar *
  810. Xmakeplural(oldstr)
  811. Xconst char *oldstr;
  812. X{
  813. X    /* Note: cannot use strcmpi here -- it'd give MATZot, CAVEMeN,... */
  814. X    register char *spot;
  815. X    static char NEARDATA str[BUFSZ];
  816. X    const char *excess;
  817. X    int len;
  818. X
  819. X    while (*oldstr==' ') oldstr++;
  820. X    if (!oldstr || !*oldstr) {
  821. X        impossible("plural of null?");
  822. X        Strcpy(str, "s");
  823. X        return str;
  824. X    }
  825. X    Strcpy(str, oldstr);
  826. X
  827. X    /* Search for common compounds, ex. lump of royal jelly */
  828. X    for(excess=(char *)0, spot=str; *spot; spot++) {
  829. X        if (!strncmp(spot, " of ", 4)
  830. X                || !strncmp(spot, " labeled ", 9)
  831. X                || !strncmp(spot, " called ", 8)
  832. X                || !strncmp(spot, " named ", 7)
  833. X                || !strcmp(spot, " above") /* lurkers above */
  834. X                || !strncmp(spot, " versus ", 8)
  835. X#ifdef TUTTI_FRUTTI
  836. X                || !strncmp(spot, " from ", 6)
  837. X                || !strncmp(spot, " in ", 4)
  838. X                || !strncmp(spot, " on ", 4)
  839. X                || !strncmp(spot, " a la ", 6)
  840. X                || !strncmp(spot, " with", 5)    /* " with "? */
  841. X                || !strncmp(spot, " de ", 4)
  842. X                || !strncmp(spot, " d'", 3)
  843. X                || !strncmp(spot, " du ", 4)
  844. X#endif
  845. X                ) {
  846. X            excess = oldstr + (int) (spot - str);
  847. X            *spot = 0;
  848. X            break;
  849. X        }
  850. X    }
  851. X    spot--;
  852. X    while (*spot==' ') spot--; /* Strip blanks from end */
  853. X    *(spot+1) = 0;
  854. X    /* Now spot is the last character of the string */
  855. X
  856. X    len = strlen(str);
  857. X#ifdef TUTTI_FRUTTI
  858. X    /* Single letters */
  859. X    if (len==1 || !letter(*spot)) {
  860. X        Strcpy(spot+1, "'s");
  861. X        goto bottom;
  862. X    }
  863. X#endif
  864. X
  865. X    /* man/men ("Wiped out all cavemen.") */
  866. X    if (len >= 3 && !strcmp(spot-2, "man") &&
  867. X            (len<6 || strcmp(spot-5, "shaman")) &&
  868. X            (len<5 || strcmp(spot-4, "human"))) {
  869. X        *(spot-1) = 'e';
  870. X        goto bottom;
  871. X    }
  872. X
  873. X    /* tooth/teeth */
  874. X    if (len >= 5 && !strcmp(spot-4, "tooth")) {
  875. X        Strcpy(spot-3, "eeth");
  876. X        goto bottom;
  877. X    }
  878. X
  879. X    /* knife/knives, etc... */
  880. X    if (!strcmp(spot-1, "fe"))
  881. X        *(spot-1) = 'v';
  882. X    else if (*spot == 'f')
  883. X        if (index("lr", *(spot-1)) || index(vowels, *(spot-1)))
  884. X            *spot = 'v';
  885. X        else if (len >= 5 && !strncmp(spot-4, "staf", 4))
  886. X            Strcpy(spot-1, "ve");
  887. X
  888. X    /* foot/feet (body part) */
  889. X    if (len >= 4 && !strcmp(spot-3, "foot")) {
  890. X        Strcpy(spot-2, "eet");
  891. X        goto bottom;
  892. X    }
  893. X
  894. X    /* ium/ia (mycelia, baluchitheria) */
  895. X    if (len >= 3 && !strcmp(spot-2, "ium")) {
  896. X        *(spot--) = (char)0;
  897. X        *spot = 'a';
  898. X        goto bottom;
  899. X    }
  900. X
  901. X    /* algae, larvae, hyphae (another fungus part) */
  902. X#ifdef TUTTI_FRUTTI
  903. X    if ((len >= 4 && !strcmp(spot-3, "alga")) ||
  904. X        (len >= 5 &&
  905. X         (!strcmp(spot-4, "hypha") || !strcmp(spot-4, "larva"))))
  906. X#else
  907. X    if (len >= 5 && (!strcmp(spot-4, "hypha")))
  908. X#endif
  909. X    {
  910. X        Strcpy(spot, "ae");
  911. X        goto bottom;
  912. X    }
  913. X
  914. X    /* fungus/fungi, homunculus/homunculi, but wumpuses */
  915. X    if (!strcmp(spot-1, "us") && (len < 6 || strcmp(spot-5, "wumpus"))) {
  916. X        *(spot--) = (char)0;
  917. X        *spot = 'i';
  918. X        goto bottom;
  919. X    }
  920. X
  921. X    /* vortex/vortices */
  922. X    if (len >= 6 && !strcmp(spot-3, "rtex")) {
  923. X        Strcpy(spot-1, "ices");
  924. X        goto bottom;
  925. X    }
  926. X
  927. X    /* djinni/djinn (note: also efreeti/efreet) */
  928. X    if (len >= 6 && !strcmp(spot-5, "djinni")) {
  929. X        *spot = (char)0;
  930. X        goto bottom;
  931. X    }
  932. X
  933. X    /* mumak/mumakil */
  934. X    if (len >= 5 && !strcmp(spot-4, "mumak")) {
  935. X        Strcpy(spot, "il");
  936. X        goto bottom;
  937. X    }
  938. X
  939. X    /* same singular and plural */
  940. X    /* note: also swine, trout, grouse */
  941. X    if ((len >= 7 && !strcmp(spot-6, "samurai")) ||
  942. X#ifdef TUTTI_FRUTTI
  943. X        (len >= 5 &&
  944. X         (!strcmp(spot-4, "manes") || !strcmp(spot-4, "sheep"))) ||
  945. X        (len >= 4 &&
  946. X         (!strcmp(spot-3, "fish") || !strcmp(spot-3, "tuna") ||
  947. X          !strcmp(spot-3, "deer")))
  948. X#else
  949. X        (len >= 5 && !strcmp(spot-4, "manes"))
  950. X#endif
  951. X        ) goto bottom;
  952. X
  953. X    /* sis/ses (nemesis) */
  954. X    if (len >= 3 && !strcmp(spot-2, "sis")) {
  955. X        *(spot-1) = 'e';
  956. X        goto bottom;
  957. X    }
  958. X
  959. X#ifdef TUTTI_FRUTTI
  960. X    /* mouse/mice,louse/lice (not a monster, but possible in food names) */
  961. X    if (len >= 5 && !strcmp(spot-3, "ouse") && index("MmLl", *(spot-4))) {
  962. X        Strcpy(spot-3, "ice");
  963. X        goto bottom;
  964. X    }
  965. X
  966. X    /* matzoh/matzot, possible food name */
  967. X    if (len >= 6 && (!strcmp(spot-5, "matzoh")
  968. X                    || !strcmp(spot-5, "matzah"))) {
  969. X        Strcpy(spot-1, "ot");
  970. X        goto bottom;
  971. X    }
  972. X    if (len >= 5 && (!strcmp(spot-4, "matzo")
  973. X                    || !strcmp(spot-5, "matza"))) {
  974. X        Strcpy(spot, "ot");
  975. X        goto bottom;
  976. X    }
  977. X
  978. X    /* child/children (for wise guys who give their food funny names) */
  979. X    if (len >= 5 && !strcmp(spot-4, "child")) {
  980. X        Strcpy(spot, "dren");
  981. X        goto bottom;
  982. X    }
  983. X
  984. X    /* note: -eau/-eaux (gateau, bordeau...) */
  985. X    /* note: ox/oxen, VAX/VAXen, goose/geese */
  986. X#endif
  987. X
  988. X    /* Ends in z, x, s, ch, sh; add an "es" */
  989. X    if (index("zxsv", *spot)
  990. X            || (len >= 2 && *spot=='h' && index("cs", *(spot-1)))
  991. X#ifdef TUTTI_FRUTTI
  992. X    /* Kludge to get "tomatoes" and "potatoes" right */
  993. X            || (len >= 4 && !strcmp(spot-2, "ato"))
  994. X#endif
  995. X                                    ) {
  996. X        Strcpy(spot+1, "es");
  997. X        goto bottom;
  998. X    }
  999. X
  1000. X    /* Ends in y preceded by consonant (note: also "qu") change to "ies" */
  1001. X    if (*spot == 'y' &&
  1002. X        (!index(vowels, *(spot-1)))) {
  1003. X        Strcpy(spot, "ies");
  1004. X        goto bottom;
  1005. X    }
  1006. X
  1007. X    /* Japanese words: plurals are the same as singlar */
  1008. X    if (len == 2 && !strcmp(str, "ya"))
  1009. X        goto bottom;
  1010. X
  1011. X    /* Default: append an 's' */
  1012. X    Strcpy(spot+1, "s");
  1013. X
  1014. Xbottom:    if (excess) Strcpy(eos(str), excess);
  1015. X    return str;
  1016. X}
  1017. X
  1018. X#endif /* OVL0 */
  1019. X
  1020. Xstruct o_range {
  1021. X    const char *name, osym;
  1022. X    int  f_o_range, l_o_range;
  1023. X};
  1024. X
  1025. X#ifndef OVLB
  1026. X
  1027. XSTATIC_DCL const struct o_range o_ranges[];
  1028. X
  1029. X#else /* OVLB */
  1030. X
  1031. X/* wishable subranges of objects */
  1032. XSTATIC_OVL const struct o_range NEARDATA o_ranges[] = {
  1033. X    { "bag",    TOOL_CLASS,   SACK,          BAG_OF_TRICKS },
  1034. X    { "candle",    TOOL_CLASS,   TALLOW_CANDLE,  WAX_CANDLE },
  1035. X    { "horn",    TOOL_CLASS,   TOOLED_HORN,    HORN_OF_PLENTY },
  1036. X    { "gloves",    ARMOR_CLASS,  LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY },
  1037. X    { "gauntlets",    ARMOR_CLASS,  LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY },
  1038. X    { "boots",    ARMOR_CLASS,  LOW_BOOTS,      LEVITATION_BOOTS },
  1039. X    { "shoes",    ARMOR_CLASS,  LOW_BOOTS,      IRON_SHOES },
  1040. X    { "cloak",    ARMOR_CLASS,  MUMMY_WRAPPING, CLOAK_OF_DISPLACEMENT },
  1041. X    { "shield",    ARMOR_CLASS,  SMALL_SHIELD,   SHIELD_OF_REFLECTION },
  1042. X    { "helm",    ARMOR_CLASS,  ELVEN_LEATHER_HELM, HELM_OF_TELEPATHY },
  1043. X    { "dragon scales",
  1044. X            ARMOR_CLASS,  GRAY_DRAGON_SCALES, YELLOW_DRAGON_SCALES },
  1045. X    { "dragon scale mail",
  1046. X            ARMOR_CLASS,  GRAY_DRAGON_SCALE_MAIL, YELLOW_DRAGON_SCALE_MAIL },
  1047. X    { "sword",    WEAPON_CLASS, SHORT_SWORD,    KATANA },
  1048. X#ifdef WIZARD
  1049. X    { "venom",    VENOM_CLASS,  BLINDING_VENOM, ACID_VENOM },
  1050. X#endif
  1051. X};
  1052. X
  1053. X#define BSTRCMP(base,ptr,string) ((ptr) < base || strcmp((ptr),string))
  1054. X#define BSTRCMPI(base,ptr,string) ((ptr) < base || strcmpi((ptr),string))
  1055. X#define BSTRNCMP(base,ptr,string,num) ((ptr)<base || strncmp((ptr),string,num))
  1056. X
  1057. X/*
  1058. X * Singularize a string the user typed in; this helps reduce the complexity
  1059. X * of readobjnam, and is also used in pager.c to singularize the string
  1060. X * for which help is sought.
  1061. X */
  1062. X
  1063. Xchar *
  1064. Xmakesingular(oldstr)
  1065. Xconst char *oldstr;
  1066. X{
  1067. X    register char *p, *bp;
  1068. X    static char NEARDATA str[BUFSZ];
  1069. X
  1070. X    if (!oldstr || !*oldstr) {
  1071. X        impossible("singular of null?");
  1072. X        str[0] = 0; return str;
  1073. X    }
  1074. X    Strcpy(str, oldstr);
  1075. X    bp = str;
  1076. X
  1077. X    while (*bp == ' ') bp++;
  1078. X    /* find "cloves of garlic", "worthless pieces of blue glass" */
  1079. X    if ((p = strstri(bp, "s of ")) != 0) {
  1080. X        /* but don't singularize "gauntlets" */
  1081. X        if (BSTRNCMP(bp, p-8, "gauntlet", 8))
  1082. X        while ((*p = *(p+1)) != 0) p++;
  1083. X        return bp;
  1084. X    }
  1085. X
  1086. X    /* remove -s or -es (boxes) or -ies (rubies) */
  1087. X    p = eos(bp);
  1088. X    if (p >= bp+1 && p[-1] == 's') {
  1089. X        if (p >= bp+2 && p[-2] == 'e') {
  1090. X            if (p >= bp+3 && p[-3] == 'i') {
  1091. X                if(!BSTRCMP(bp, p-7, "cookies") ||
  1092. X                   !BSTRCMP(bp, p-4, "pies"))
  1093. X                    goto mins;
  1094. X                Strcpy(p-3, "y");
  1095. X                return bp;
  1096. X            }
  1097. X
  1098. X            /* note: cloves / knives from clove / knife */
  1099. X            if(!BSTRCMP(bp, p-6, "knives")) {
  1100. X                Strcpy(p-3, "fe");
  1101. X                return bp;
  1102. X            }
  1103. X
  1104. X            if(!BSTRCMP(bp, p-6, "staves")) {
  1105. X                Strcpy(p-3, "ff");
  1106. X                return bp;
  1107. X            }
  1108. X
  1109. X            /* note: nurses, axes but boxes */
  1110. X            if(!BSTRCMP(bp, p-5, "boxes")) {
  1111. X                p[-2] = 0;
  1112. X                return bp;
  1113. X            }
  1114. X            if (!BSTRCMP(bp, p-6, "gloves") ||
  1115. X                !BSTRCMP(bp, p-5, "shoes") ||
  1116. X                !BSTRCMP(bp, p-6, "scales"))
  1117. X                return bp;
  1118. X        } else if (!BSTRCMP(bp, p-5, "boots") ||
  1119. X               !BSTRCMP(bp, p-6, "tricks") ||
  1120. X               !BSTRCMP(bp, p-9, "paralysis") ||
  1121. X               !BSTRCMP(bp, p-5, "glass") ||
  1122. X               !BSTRCMP(bp, p-4, "ness") ||
  1123. X               !BSTRCMP(bp, p-14, "shape changers") ||
  1124. X               !BSTRCMP(bp, p-15, "detect monsters") ||
  1125. X               !BSTRCMPI(bp, p-11, "Aesculapius"))    /* staff */
  1126. X                return bp;
  1127. X    mins:
  1128. X        p[-1] = 0;
  1129. X    } else {
  1130. X        if(!BSTRCMP(bp, p-5, "teeth")) {
  1131. X            Strcpy(p-5, "tooth");
  1132. X            return bp;
  1133. X        }
  1134. X        /* here we cannot find the plural suffix */
  1135. X    }
  1136. X    return bp;
  1137. X}
  1138. X
  1139. X/* alternate spellings: extra space, space instead of hyphen, etc */
  1140. Xstruct alt_spellings {
  1141. X    const char *sp;
  1142. X    int ob;
  1143. X} spellings[] = {
  1144. X    { "two handed sword", TWO_HANDED_SWORD },
  1145. X    { "battle axe", BATTLE_AXE },
  1146. X    { "lockpick", LOCK_PICK },
  1147. X    { "pick axe", PICK_AXE },
  1148. X    { "luck stone", LUCKSTONE },
  1149. X    { "load stone", LOADSTONE },
  1150. X    { "broad sword", BROADSWORD },
  1151. X    { "elven broad sword", ELVEN_BROADSWORD },
  1152. X    { "longsword", LONG_SWORD },
  1153. X    { "shortsword", SHORT_SWORD },
  1154. X    { "elven shortsword", ELVEN_SHORT_SWORD },
  1155. X    { "dwarvish shortsword", DWARVISH_SHORT_SWORD },
  1156. X    { "orcish shortsword", ORCISH_SHORT_SWORD },
  1157. X    { "warhammer", WAR_HAMMER },
  1158. X    { "grey dragon scale mail", GRAY_DRAGON_SCALE_MAIL },
  1159. X    { "grey dragon scales", GRAY_DRAGON_SCALES },
  1160. X    { "iron ball", HEAVY_IRON_BALL },
  1161. X    { "stone", ROCK },
  1162. X    { (const char *)0, 0 },
  1163. X};
  1164. X
  1165. X/* Return something wished for.  If not an object, return &zeroobj; if an error
  1166. X * (no matching object), return (struct obj *)0.  Giving readobjnam() a null
  1167. X * pointer skips the error return and creates a random object instead.
  1168. X */
  1169. Xstruct obj *
  1170. Xreadobjnam(bp)
  1171. Xregister char *bp;
  1172. X{
  1173. X    register char *p;
  1174. X    register int i;
  1175. X    register struct obj *otmp;
  1176. X    int cnt, spe, spesgn, typ, very;
  1177. X    int blessed, uncursed, iscursed, ispoisoned;
  1178. X    int eroded, erodeproof;
  1179. X    int halfeaten, mntmp, contents;
  1180. X    int islit, unlabeled;
  1181. X#ifdef TUTTI_FRUTTI
  1182. X    struct fruit *f;
  1183. X    int ftype = current_fruit;
  1184. X    char fruitbuf[BUFSZ];
  1185. X    /* We want to check for fruits last so that, for example, someone
  1186. X     * who names their fruit "katana" and wishes for a katana gets a real
  1187. X     * one.  But, we have to keep around the old buf since in the meantime
  1188. X     * we have deleted "empty", "+6", etc...
  1189. X     */
  1190. X#endif
  1191. X    char let;
  1192. X    char *un, *dn, *actualn;
  1193. X    const char *name=0;
  1194. X
  1195. X    cnt = spe = spesgn = typ = very = blessed = uncursed =
  1196. X        iscursed = ispoisoned = eroded = erodeproof = halfeaten =
  1197. X        islit = unlabeled = 0;
  1198. X    mntmp = -1;
  1199. X#define UNDEFINED 0
  1200. X#define EMPTY 1
  1201. X#define SPINACH 2
  1202. X    contents = UNDEFINED;
  1203. X    let = 0;
  1204. X    actualn = dn = un = 0;
  1205. X
  1206. X    /* first, remove extra whitespace they may have typed */
  1207. X    if (bp) {
  1208. X        char c, *p2;
  1209. X        boolean was_space = TRUE;
  1210. X
  1211. X        for (p = p2 = bp; (c = *p) != '\0'; p++) {
  1212. X             /* if (c == '\t') c = ' '; */
  1213. X            if (c != ' ' || !was_space)  *p2++ = c;
  1214. X            was_space = (c == ' ');
  1215. X        }
  1216. X        if (was_space && p2 > bp)  p2--;
  1217. X        *p2 = '\0';
  1218. X    }
  1219. X
  1220. X    for(;;) {
  1221. X        register int l;
  1222. X
  1223. X        if (!bp || !*bp) goto any;
  1224. X        if (!strncmpi(bp, "an ", l=3) ||
  1225. X            !strncmpi(bp, "a ", l=2)) {
  1226. X            cnt = 1;
  1227. X        } else if (!strncmpi(bp, "the ", l=4)) {
  1228. X            ;    /* just increment `bp' by `l' below */
  1229. X        } else if (!cnt && digit(*bp)) {
  1230. X            cnt = atoi(bp);
  1231. X            while(digit(*bp)) bp++;
  1232. X            while(*bp == ' ') bp++;
  1233. X            l = 0;
  1234. X        } else if (!strncmpi(bp, "blessed ", l=8) ||
  1235. X               !strncmpi(bp, "holy ", l=5)) {
  1236. X            blessed = 1;
  1237. X        } else if (!strncmpi(bp, "cursed ", l=7) ||
  1238. X               !strncmpi(bp, "unholy ", l=7)) {
  1239. X            iscursed = 1;
  1240. X        } else if (!strncmpi(bp, "uncursed ", l=9)) {
  1241. X            uncursed = 1;
  1242. X        } else if (!strncmp(bp, "rustproof ", l=10) ||
  1243. X               !strncmp(bp, "erodeproof ", l=11) ||
  1244. X               !strncmp(bp, "corrodeproof ", l=13) ||
  1245. X               !strncmp(bp, "fireproof ", l=10)) {
  1246. X            erodeproof = 1;
  1247. X        } else if (!strncmpi(bp,"lit ", l=4) ||
  1248. X               !strncmpi(bp,"burning ", l=8)) {
  1249. X            islit = 1;
  1250. X        } else if (!strncmpi(bp,"unlit ", l=6) ||
  1251. X               !strncmpi(bp,"extinguished ", l=13)) {
  1252. X            islit = 0;
  1253. X        /* "unlabeled" and "blank" are synonymous */
  1254. X        } else if (!strncmpi(bp,"unlabeled ", l=10) ||
  1255. X               !strncmpi(bp,"unlabelled ", l=11) ||
  1256. X               !strncmpi(bp,"blank ", l=6)) {
  1257. X            unlabeled = 1;
  1258. X        } else if (!strncmpi(bp, "very ", l=5)) {
  1259. X            very = 1;
  1260. X        } else if (!strncmpi(bp, "thoroughly ", l=11)) {
  1261. X            very = 2;
  1262. X        } else if (!strncmp(bp, "rusty ", l=6) ||
  1263. X               !strncmp(bp, "rusted ", l=7) ||
  1264. X               !strncmp(bp, "eroded ", l=7) ||
  1265. X               !strncmp(bp, "corroded ", l=9) ||
  1266. X               !strncmp(bp, "burnt ", l=6) ||
  1267. X               !strncmp(bp, "burned ", l=7) ||
  1268. X               !strncmp(bp, "rotted ", l=7)) {
  1269. X            eroded = 1 + very; very = 0;
  1270. X        } else if (!strncmpi(bp, "partly eaten ", l=13)) {
  1271. X            halfeaten = 1;
  1272. X        } else break;
  1273. X        bp += l;
  1274. X    }
  1275. X    if(!cnt) cnt = 1;        /* %% what with "gems" etc. ? */
  1276. X#ifdef TUTTI_FRUTTI
  1277. X    Strcpy(fruitbuf, bp);
  1278. X#endif
  1279. X    if(!strncmpi(bp, "empty ", 6)) {
  1280. X        contents = EMPTY;
  1281. X        bp += 6;
  1282. X    } else if(!strncmpi(bp, "poisoned ",9)) {
  1283. X        ispoisoned=1;
  1284. X        bp += 9;
  1285. X#ifdef WIZARD
  1286. X    } else if(wizard && !strncmpi(bp, "trapped ",8)) {
  1287. X        ispoisoned=1;
  1288. X        bp += 8;
  1289. X#endif
  1290. X    }
  1291. X    if (strlen(bp) > 1) {
  1292. X        if (*bp == '+' || *bp == '-') {
  1293. X        spesgn = (*bp++ == '+') ? 1 : -1;
  1294. X        spe = atoi(bp);
  1295. X        while(digit(*bp)) bp++;
  1296. X        while(*bp == ' ') bp++;
  1297. X        } else if ((p = rindex(bp, '(')) != 0) {
  1298. X        if (p > bp && p[-1] == ' ') p[-1] = 0;
  1299. X        else *p = 0;
  1300. X        p++;
  1301. X        if (!strcmpi(p, "lit)"))
  1302. X            islit = 1;
  1303. X        else {
  1304. X            spe = atoi(p);
  1305. X            while(digit(*p)) p++;
  1306. X            if (*p != ')') spe = 0;
  1307. X            else {
  1308. X            spesgn = 1;
  1309. X            p++;
  1310. X            if (*p) Strcat(bp, p);
  1311. X            }
  1312. X        }
  1313. X        }
  1314. X    }
  1315. X/*
  1316. X   otmp->spe is type schar; so we don't want spe to be any bigger or smaller.
  1317. X   also, spe should always be positive  -- some cheaters may try to confuse
  1318. X   atoi()
  1319. X*/
  1320. X    if (spe < 0) {
  1321. X        spesgn = -1;    /* cheaters get what they deserve */
  1322. X        spe = abs(spe);
  1323. X    }
  1324. X    if (spe > SCHAR_LIM)
  1325. X        spe = SCHAR_LIM;
  1326. X
  1327. X    /* now we have the actual name, as delivered by xname, say
  1328. X        green potions called whisky
  1329. X        scrolls labeled "QWERTY"
  1330. X        egg
  1331. X        fortune cookies
  1332. X        very heavy iron ball named hoei
  1333. X        wand of wishing
  1334. X        elven cloak
  1335. X    */
  1336. X    if ((p = strstri(bp, " named ")) != 0) {
  1337. X        *p = 0;
  1338. X        name = p+7;
  1339. X    }
  1340. X    if ((p = strstri(bp, " called ")) != 0) {
  1341. X        *p = 0;
  1342. X        un = p+8;
  1343. X        /* "helmet called telepathy" is not "helmet" (a specific type)
  1344. X         * "shield called reflection" is not "shield" (a general type)
  1345. X         */
  1346. X        for(i = 0; i < SIZE(o_ranges); i++)
  1347. X            if(!strcmpi(bp, o_ranges[i].name)) {
  1348. X            let = o_ranges[i].osym;
  1349. X            goto srch;
  1350. X            }
  1351. X    }
  1352. X    if ((p = strstri(bp, " labeled ")) != 0) {
  1353. X        *p = 0;
  1354. X        dn = p+9;
  1355. X    } else if ((p = strstri(bp, " labelled ")) != 0) {
  1356. X        *p = 0;
  1357. X        dn = p+10;
  1358. X    }
  1359. X    if ((p = strstri(bp, " of spinach")) != 0) {
  1360. X        *p = 0;
  1361. X        contents = SPINACH;
  1362. X    }
  1363. X
  1364. X    /* Skip over "pair of ", then jump to the singular since we don't
  1365. X       need to convert "gloves" or "boots". */
  1366. X    if(cnt == 1 && !strncmpi(bp, "pair of ",8)) {
  1367. X        bp += 8;
  1368. X        cnt = 2;
  1369. X        goto sing;
  1370. X        /* cnt is ignored for armor and other non-stackable objects;
  1371. X           DTRT for stackable objects */
  1372. X    } else if(cnt > 1 && !strncmpi(bp, "pairs of ",9)) {
  1373. X        bp += 9;
  1374. X        cnt *= 2;
  1375. X    } else if (!strncmpi(bp, "set of ",7)) {
  1376. X        bp += 7;
  1377. X    } else if (!strncmpi(bp, "sets of ",8)) {
  1378. X        bp += 8;
  1379. X    }
  1380. X
  1381. X    /*
  1382. X     * Find corpse type using "of" (figurine of an orc, tin of orc meat)
  1383. X     * Don't check if it's a wand or spellbook.
  1384. X     * (avoid "wand/finger of death" confusion).
  1385. X     */
  1386. X    if (!strstri(bp, "wand ")
  1387. X     && !strstri(bp, "spellbook ")
  1388. X     && !strstri(bp, "finger ")) {
  1389. X        if ((p = strstri(bp, " of ")) != 0
  1390. X        && (mntmp = name_to_mon(p+4)) >= 0)
  1391. X        *p = 0;
  1392. X    }
  1393. X    /* Find corpse type w/o "of" (red dragon scale mail, yeti corpse) */
  1394. X    if (strncmp(bp, "samurai sword", 13)) /* not the "samurai" monster! */
  1395. X    if (strncmp(bp, "wizard lock", 11)) /* not the "wizard" monster! */
  1396. X    if (strncmp(bp, "ninja-to", 8)) /* not the "ninja" rank */
  1397. X    if (mntmp < 0 && strlen(bp) > 2 && (mntmp = name_to_mon(bp)) >= 0) {
  1398. X        int mntmptoo, mntmplen;    /* double check for rank title */
  1399. X        char *obp = bp;
  1400. X        mntmptoo = title_to_mon(bp, (int *)0, &mntmplen);
  1401. X        bp += mntmp != mntmptoo ? strlen(mons[mntmp].mname) : mntmplen;
  1402. X        if (*bp == ' ') bp++;
  1403. X        else if (!strncmpi(bp, "s ", 2)) bp += 2;
  1404. X        else if (!strncmpi(bp, "es ", 3)) bp += 3;
  1405. X        else if (!*bp && !actualn && !dn && !un && !let) {
  1406. X            /* no referent; they don't really mean a monster type */
  1407. X            bp = obp;
  1408. X            mntmp = -1;
  1409. X        }
  1410. X    }
  1411. X
  1412. X    /* first change to singular if necessary */
  1413. X    if (*bp) {
  1414. X        char *sng = makesingular(bp);
  1415. X        if (strcmp(bp, sng)) {
  1416. X            if (cnt == 1) cnt = 2;
  1417. X            Strcpy(bp, sng);
  1418. X        }
  1419. X    }
  1420. X
  1421. Xsing:
  1422. X    /* Alternate spellings (two-handed sword vs. two handed sword) */
  1423. X    {struct alt_spellings *as = spellings;
  1424. X        while(as->sp) {
  1425. X            if (!strcmpi(bp, as->sp)) {
  1426. X                typ = as->ob;
  1427. X                goto typfnd;
  1428. X            }
  1429. X            as++;
  1430. X        }
  1431. X    }
  1432. X
  1433. X    /* dragon scales - assumes order of dragons */
  1434. X    if(!strcmpi(bp, "scales") &&
  1435. X            mntmp >= PM_GRAY_DRAGON && mntmp <= PM_YELLOW_DRAGON) {
  1436. X        typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON;
  1437. X        mntmp = -1;    /* no monster */
  1438. X        goto typfnd;
  1439. X    }
  1440. X
  1441. X    if(!strcmpi(bp, "ring mail") ||    /* Note: ring mail is not a ring ! */
  1442. X       !strcmpi(bp, "leather armor") || /* Prevent falling to 'armor'. */
  1443. X       !strcmpi(bp, "studded leather armor")) {
  1444. X        let = ARMOR_CLASS;
  1445. X        actualn = bp;
  1446. X        goto srch;
  1447. X    }
  1448. X    if(!strcmpi(bp, "food ration")){
  1449. X        let = FOOD_CLASS;
  1450. X        actualn = bp;
  1451. X        goto srch;
  1452. X    }
  1453. X    p = eos(bp);
  1454. X    if(!BSTRCMPI(bp, p-10, "holy water")) {
  1455. X        typ = POT_WATER;
  1456. X        if ((p-bp) >= 12 && *(p-12) == 'u')
  1457. X            iscursed = 1; /* unholy water */
  1458. X        else blessed = 1;
  1459. X        goto typfnd;
  1460. X    }
  1461. X    if(unlabeled && !BSTRCMPI(bp, p-6, "scroll")) {
  1462. X        typ = SCR_BLANK_PAPER;
  1463. X        goto typfnd;
  1464. X    }
  1465. X    if(unlabeled && !BSTRCMPI(bp, p-9, "spellbook")) {
  1466. X        typ = SPE_BLANK_PAPER;
  1467. X        goto typfnd;
  1468. X    }
  1469. X#ifdef TOURIST
  1470. X    if (!BSTRCMPI(bp, p-5, "shirt")) {
  1471. X        typ = HAWAIIAN_SHIRT;
  1472. X        goto typfnd;
  1473. X    }
  1474. X#endif
  1475. X    /*
  1476. X     * NOTE: Gold pieces are handled as objects nowadays, and therefore
  1477. X     * this section should probably be reconsidered as well as the entire
  1478. X     * gold/money concept.  Maybe we want to add other monetary units as
  1479. X     * well in the future. (TH)
  1480. X     */
  1481. X    if(!BSTRCMPI(bp, p-10, "gold piece") || !BSTRCMPI(bp, p-7, "zorkmid") ||
  1482. X       !strcmpi(bp, "gold") || !strcmpi(bp, "money") || 
  1483. X       !strcmpi(bp, "coin") || *bp == GOLD_SYM) {
  1484. X            if (cnt > 5000
  1485. X#ifdef WIZARD
  1486. X                    && !wizard
  1487. X#endif
  1488. X                        ) cnt=5000;
  1489. X        if (cnt < 1) cnt=1;
  1490. X        pline("%d gold piece%s.", cnt, plur(cnt));
  1491. X        u.ugold += cnt;
  1492. X        flags.botl=1;
  1493. X        return (&zeroobj);
  1494. X    }
  1495. X    if (strlen(bp) == 1 &&
  1496. X       (i = def_char_to_objclass(*bp)) < MAXOCLASSES && i > ILLOBJ_CLASS) {
  1497. X        let = i;
  1498. X        goto any;
  1499. X    }
  1500. X    if(strncmpi(bp, "enchant ", 8) &&
  1501. X       strncmpi(bp, "destroy ", 8) &&
  1502. X       strncmpi(bp, "food detection", 14))
  1503. X    /* allow wishes for "enchant weapon" and "food detection" */
  1504. X    for(i = 0; i < sizeof(wrpsym); i++) {
  1505. X        register int j = strlen(wrp[i]);
  1506. X        if(!strncmpi(bp, wrp[i], j)){
  1507. X            let = wrpsym[i];
  1508. X            if(let != AMULET_CLASS) {
  1509. X                bp += j;
  1510. X                if(!strncmpi(bp, " of ", 4)) actualn = bp+4;
  1511. X                /* else if(*bp) ?? */
  1512. X            } else
  1513. X                actualn = bp;
  1514. X            goto srch;
  1515. X        }
  1516. X        if(!BSTRCMPI(bp, p-j, wrp[i])){
  1517. X            let = wrpsym[i];
  1518. X            p -= j;
  1519. X            *p = 0;
  1520. X            if(p > bp && p[-1] == ' ') p[-1] = 0;
  1521. X            actualn = dn = bp;
  1522. X            goto srch;
  1523. X        }
  1524. X    }
  1525. X    if (!BSTRCMPI(bp, p-6, " stone")) {
  1526. X        p[-6] = 0;
  1527. X        let = GEM_CLASS;
  1528. X        dn = actualn = bp;
  1529. X        goto srch;
  1530. X    } else if (!BSTRCMPI(bp, p-6, " glass") || !strcmpi(bp, "glass")) {
  1531. X        register char *g = bp;
  1532. X        if (strstri(g, "broken")) return (struct obj *)0;
  1533. X        if (!strncmpi(g, "worthless ", 10)) g += 10;
  1534. X        if (!strncmpi(g, "piece of ", 9)) g += 9;
  1535. X        if (!strncmpi(g, "colored ", 8)) g += 8;
  1536. X        if (!strcmpi(g, "glass")) {    /* choose random color */
  1537. X            /* white, blue, red, yellowish brown, green, violet */
  1538. X            typ = LAST_GEM + rnd(6);
  1539. X            if (objects[typ].oc_class == GEM_CLASS) goto typfnd;
  1540. X            else typ = 0;    /* somebody changed objects[]? punt */
  1541. X        } else if (g > bp) {    /* try to construct canonical form */
  1542. X            char tbuf[BUFSZ];
  1543. X            Strcpy(tbuf, "worthless piece of ");
  1544. X            Strcat(tbuf, g);  /* assume it starts with the color */
  1545. X            Strcpy(bp, tbuf);
  1546. X        }
  1547. X    }
  1548. X#ifdef WIZARD
  1549. X    /* Let wizards wish for traps --KAA */
  1550. X    if (wizard) {
  1551. X        int trap;
  1552. X        char *tname;
  1553. X
  1554. X        for (trap = NO_TRAP+1; trap < TRAPNUM; trap++) {
  1555. X            tname = index(traps[trap], ' ');
  1556. X            if (tname) {
  1557. X                if (!strncmpi(tname+1, bp, strlen(tname+1))) {
  1558. X                /* avoid stupid mistakes */
  1559. X                if(trap == TRAPDOOR && !Can_fall_thru(&u.uz))
  1560. X                    trap = ROCKTRAP;
  1561. X
  1562. X                (void) maketrap(u.ux, u.uy, trap);
  1563. X                pline("A%s.", traps[trap]);
  1564. X                return(&zeroobj);
  1565. X                }
  1566. X            }
  1567. X        }
  1568. X        /* or some other dungeon features -dlc */
  1569. X        p = eos(bp);
  1570. X        if(!BSTRCMP(bp, p-8, "fountain")) {
  1571. X            levl[u.ux][u.uy].typ = FOUNTAIN;
  1572. X            if(!strncmpi(bp, "magic ", 6))
  1573. X                levl[u.ux][u.uy].blessedftn = 1;
  1574. X            pline("A %sfountain.",
  1575. X                  levl[u.ux][u.uy].blessedftn ? "magic " : "");
  1576. X            newsym(u.ux, u.uy);
  1577. X            return(&zeroobj);
  1578. X        }
  1579. X        if(!BSTRCMP(bp, p-5, "altar")) {
  1580. X            aligntyp al;
  1581. X
  1582. X            levl[u.ux][u.uy].typ = ALTAR;
  1583. X            if(!strncmpi(bp, "chaotic ", 8))
  1584. X            al = A_CHAOTIC;
  1585. X            else if(!strncmpi(bp, "neutral ", 8))
  1586. X            al = A_NEUTRAL;
  1587. X            else if(!strncmpi(bp, "lawful ", 7))
  1588. X            al = A_LAWFUL;
  1589. X            else if(!strncmpi(bp, "unaligned ", 10))
  1590. X            al = A_NONE;
  1591. X            else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
  1592. X            al = (!rn2(6)) ? A_NONE : rn2((int)A_LAWFUL+2) - 1;
  1593. X            levl[u.ux][u.uy].altarmask = Align2amask( al );
  1594. X            pline("%s altar.", An(align_str(al)));
  1595. X            newsym(u.ux, u.uy);
  1596. X            return(&zeroobj);
  1597. X        }
  1598. X    }
  1599. X#endif
  1600. X    for (i = 0; i < SIZE(o_ranges); i++)
  1601. X        if(!strcmpi(bp, o_ranges[i].name)) {
  1602. X        typ = rnd_class(o_ranges[i].f_o_range, o_ranges[i].l_o_range);
  1603. X        goto typfnd;
  1604. X        }
  1605. X
  1606. X    actualn = bp;
  1607. X    if (!dn) dn = actualn; /* ex. "skull cap" */
  1608. Xsrch:
  1609. X    /* check real names of gems first */
  1610. X    if(!let && actualn) {
  1611. X        for(i = bases[letindex(GEM_CLASS)]; i <= LAST_GEM; i++) {
  1612. X        register const char *zn;
  1613. X
  1614. X        if((zn = OBJ_NAME(objects[i])) && !strcmpi(actualn, zn)) {
  1615. X            typ = i;
  1616. X            goto typfnd;
  1617. X        }
  1618. X        }
  1619. X    }
  1620. X    i = 1;
  1621. X    if(let) i = bases[letindex(let)];
  1622. X    while(i <= NROFOBJECTS && (!let || objects[i].oc_class == let)){
  1623. X        register const char *zn;
  1624. X
  1625. X        if(actualn && (zn = OBJ_NAME(objects[i])) && !strcmpi(actualn, zn)) {
  1626. X            typ = i;
  1627. X            goto typfnd;
  1628. X        }
  1629. X        if(dn && (zn = OBJ_DESCR(objects[i])) && !strcmpi(dn, zn)) {
  1630. X            /* don't match extra descriptions (w/o real name) */
  1631. X            if (!OBJ_NAME(objects[i])) return (struct obj *)0;
  1632. X            typ = i;
  1633. X            goto typfnd;
  1634. X        }
  1635. X        if(un && (zn = objects[i].oc_uname) && !strcmpi(un, zn)) {
  1636. X            typ = i;
  1637. X            goto typfnd;
  1638. X        }
  1639. X        i++;
  1640. X    }
  1641. X    if (actualn) {
  1642. X        struct Jitem *j = Japanese_items;
  1643. X        while(j->item) {
  1644. X            if (actualn && !strcmpi(actualn, j->name)) {
  1645. X                typ = j->item;
  1646. X                goto typfnd;
  1647. X            }
  1648. X            j++;
  1649. X        }
  1650. X    }
  1651. X#ifdef TUTTI_FRUTTI
  1652. X    /* Note: not strncmpi.  2 fruits, one capital, one not, is possible. */
  1653. X    for(f=ffruit; f; f = f->nextf) {
  1654. X        char *f1 = f->fname, *f2 = makeplural(f->fname);
  1655. X
  1656. X        if(!strncmp(fruitbuf, f1, strlen(f1)) ||
  1657. X                    !strncmp(fruitbuf, f2, strlen(f2))) {
  1658. X            typ = SLIME_MOLD;
  1659. X            ftype = f->fid;
  1660. X            goto typfnd;
  1661. X        }
  1662. X    }
  1663. X#endif
  1664. X    if (!strcmpi(bp, "spinach")) {
  1665. X        contents = SPINACH;
  1666. X        typ = TIN;
  1667. X        goto typfnd;
  1668. X    }
  1669. X
  1670. X    if(!let && actualn) {
  1671. X        short objtyp;
  1672. X
  1673. X        /* Perhaps it's an artifact specified by name, not type */
  1674. X        name = artifact_name(actualn, &objtyp);
  1675. X        if(name) {
  1676. X        typ = objtyp;
  1677. X        goto typfnd;
  1678. X        }
  1679. X    }
  1680. X    if(!let) return((struct obj *)0);
  1681. Xany:
  1682. X    if(!let) let = wrpsym[rn2((int)sizeof(wrpsym))];
  1683. Xtypfnd:
  1684. X    if (typ) let = objects[typ].oc_class;
  1685. X
  1686. X    /* check for some objects that are not allowed */
  1687. X    if (typ && objects[typ].oc_unique
  1688. X#ifdef WIZARD
  1689. X        && !wizard 
  1690. X        /* should check flags.made_amulet, but it's not set anywhere */
  1691. X#endif
  1692. X       )
  1693. X        switch (typ) {
  1694. X        case AMULET_OF_YENDOR:
  1695. X            typ = FAKE_AMULET_OF_YENDOR;
  1696. X            break;
  1697. X        case CANDELABRUM_OF_INVOCATION:
  1698. X            typ = rnd_class(TALLOW_CANDLE, WAX_CANDLE);
  1699. X            break;
  1700. X        case BELL_OF_OPENING:
  1701. X            typ = BELL;
  1702. X            break;
  1703. X        case SPE_BOOK_OF_THE_DEAD:
  1704. X            typ = SPE_BLANK_PAPER;
  1705. X            break;
  1706. X        }
  1707. X
  1708. X    /* venom isn't really an object and can't be wished for; but allow
  1709. X     * wizards to wish for it since it's faster than polymorphing and
  1710. X     * spitting.
  1711. X     */
  1712. X    if(let == VENOM_CLASS)
  1713. X#ifdef WIZARD
  1714. X        if (!wizard)
  1715. X#endif
  1716. X            return((struct obj *)0);
  1717. X
  1718. X    if(typ) {
  1719. X        otmp = mksobj(typ, TRUE, FALSE);
  1720. X    } else {
  1721. X        otmp = mkobj(let, FALSE);
  1722. X        if (otmp) typ = otmp->otyp;
  1723. X    }
  1724. X
  1725. X    if(typ == OIL_LAMP || typ == MAGIC_LAMP || typ == BRASS_LANTERN)
  1726. X        otmp->lamplit = islit;
  1727. X
  1728. X    if(cnt > 0 && objects[typ].oc_merge && let != SPBOOK_CLASS && 
  1729. X        (cnt < rnd(6) ||
  1730. X#ifdef WIZARD
  1731. X        wizard ||
  1732. X#endif
  1733. X         (cnt <= 20 &&
  1734. X          ((let == WEAPON_CLASS && typ <= SHURIKEN) || (typ == ROCK)))))
  1735. X            otmp->quan = (long) cnt;
  1736. X
  1737. X#ifdef WIZARD
  1738. X    if (let == VENOM_CLASS) otmp->spe = 1;
  1739. X#endif
  1740. X
  1741. X    if (spesgn == 0) spe = otmp->spe;
  1742. X#ifdef WIZARD
  1743. X    else if (wizard) /* no alteration to spe */ ;
  1744. X#endif
  1745. X    else if (let == ARMOR_CLASS || let == WEAPON_CLASS || typ == PICK_AXE ||
  1746. X            typ == UNICORN_HORN ||
  1747. X            (let==RING_CLASS && objects[typ].oc_charged)) {
  1748. X        if(spe > rnd(5) && spe > otmp->spe) spe = 0;
  1749. X        if(spe > 2 && Luck < 0) spesgn = -1;
  1750. X    } else {
  1751. X        if (let == WAND_CLASS) {
  1752. X            if (spe > 1 && spesgn == -1) spe = 1;
  1753. X        } else {
  1754. X            if (spe > 0 && spesgn == -1) spe = 0;
  1755. X        }
  1756. X        if (spe > otmp->spe) spe = otmp->spe;
  1757. X    }
  1758. X
  1759. X    if (spesgn == -1) spe = -spe;
  1760. X
  1761. X    /* set otmp->spe.  This may, or may not, use spe... */
  1762. X    switch (typ) {
  1763. X        case TIN: if (contents==EMPTY) {
  1764. X                otmp->corpsenm = -1;
  1765. X                otmp->spe = 0;
  1766. X            } else if (contents==SPINACH) {
  1767. X                otmp->corpsenm = -1;
  1768. X                otmp->spe = 1;
  1769. X            }
  1770. X            break;
  1771. X#ifdef TUTTI_FRUTTI
  1772. X        case SLIME_MOLD: otmp->spe = ftype;
  1773. X            /* Fall through */
  1774. X#endif
  1775. X        case SKELETON_KEY: case CHEST: case LARGE_BOX:
  1776. X        case HEAVY_IRON_BALL: case IRON_CHAIN: case STATUE:
  1777. X            /* otmp->cobj already done in mksobj() */
  1778. X                break;
  1779. X#ifdef MAIL
  1780. X        case SCR_MAIL: otmp->spe = 1; break;
  1781. X#endif
  1782. X        case WAN_WISHING:
  1783. X#ifdef WIZARD
  1784. X            if (!wizard) {
  1785. X#endif
  1786. X                otmp->spe = (rn2(10) ? -1 : 0);
  1787. X                break;
  1788. X#ifdef WIZARD
  1789. X            }
  1790. X            /* fall through (twice), if wizard */
  1791. X#endif
  1792. X        case MAGIC_LAMP:
  1793. X#ifdef WIZARD
  1794. X            if (!wizard) {
  1795. X#endif
  1796. X                otmp->spe = 0;
  1797. X                break;
  1798. X#ifdef WIZARD
  1799. X            }
  1800. X            /* fall through, if wizard */
  1801. X#endif
  1802. X        default: otmp->spe = spe;
  1803. X    }
  1804. X
  1805. X    /* set otmp->corpsenm or dragon scale [mail] */
  1806. X    if (mntmp > -1) switch(typ) {
  1807. X        case TIN:
  1808. X            otmp->spe = 0; /* No spinach */
  1809. X        case CORPSE:
  1810. X            if (!(mons[mntmp].geno & (G_UNIQ | G_NOCORPSE)))
  1811. X                otmp->corpsenm = mntmp;
  1812. X            break;
  1813. X        case FIGURINE:
  1814. X            if (!(mons[mntmp].geno & G_UNIQ)
  1815. X                && !is_human(&mons[mntmp]))
  1816. X                otmp->corpsenm = mntmp;
  1817. X            break;
  1818. X        case EGG: if (lays_eggs(&mons[mntmp]) || mntmp==PM_KILLER_BEE)
  1819. X                otmp->corpsenm = mntmp;
  1820. X            break;
  1821. X        case STATUE: otmp->corpsenm = mntmp;
  1822. X            break;
  1823. X        case SCALE_MAIL:
  1824. X            /* Dragon mail - depends on the order of objects */
  1825. X            /*         & dragons.             */
  1826. X                if (mntmp >= PM_GRAY_DRAGON &&
  1827. X                        mntmp <= PM_YELLOW_DRAGON)
  1828. X                otmp->otyp = GRAY_DRAGON_SCALE_MAIL +
  1829. X                            mntmp - PM_GRAY_DRAGON;
  1830. X            break;
  1831. X    }
  1832. X
  1833. X    /* set blessed/cursed -- setting the fields directly is safe
  1834. X     * since weight() is called below and addinv() will take care
  1835. X     * of luck */
  1836. X    if (iscursed) {
  1837. X        curse(otmp);
  1838. X    } else if (uncursed) {
  1839. X        otmp->blessed = 0;
  1840. X        otmp->cursed = (Luck < 0
  1841. X#ifdef WIZARD
  1842. X                     && !wizard
  1843. X#endif
  1844. X                            );
  1845. X    } else if (blessed) {
  1846. X        otmp->blessed = (Luck >= 0
  1847. X#ifdef WIZARD
  1848. X                     || wizard
  1849. X#endif
  1850. X                            );
  1851. X        otmp->cursed = (Luck < 0
  1852. X#ifdef WIZARD
  1853. X                     && !wizard
  1854. X#endif
  1855. X                            );
  1856. X    } else if (spesgn < 0) {
  1857. X        curse(otmp);
  1858. X    }
  1859. X
  1860. X    /* set eroded */
  1861. X    if (eroded)
  1862. X        otmp->oeroded = eroded;
  1863. X
  1864. X    /* set erodeproof */
  1865. X    else if (erodeproof)
  1866. X        otmp->oerodeproof = (Luck >= 0
  1867. X#ifdef WIZARD
  1868. X                     || wizard
  1869. X#endif
  1870. X                    );
  1871. X
  1872. X    /* prevent wishing abuse */
  1873. X    if (
  1874. X#ifdef WIZARD
  1875. X        !wizard &&
  1876. X#endif
  1877. X            otmp->otyp == WAN_WISHING)
  1878. X        otmp->recharged = 1;
  1879. X
  1880. X    /* set poisoned */
  1881. X    if (ispoisoned) {
  1882. X        if (let == WEAPON_CLASS && typ <= SHURIKEN)
  1883. X        otmp->opoisoned = (Luck >= 0);
  1884. X        else if (Is_box(otmp))
  1885. X        otmp->otrapped = 1;
  1886. X        else if (let == FOOD_CLASS)
  1887. X        /* try to taint by making it as old as possible */
  1888. X            otmp->age = 1L;
  1889. X    }
  1890. X
  1891. X    if (name) {
  1892. X        otmp = oname(otmp, name, 0);
  1893. X        if (otmp->oartifact) otmp->quan = 1L;
  1894. X    }
  1895. X    otmp->owt = weight(otmp);
  1896. X    if (very && otmp->otyp == HEAVY_IRON_BALL) otmp->owt += 160;
  1897. X    if (halfeaten && otmp->oclass == FOOD_CLASS) {
  1898. X        if (otmp->otyp == CORPSE)
  1899. X            otmp->oeaten = mons[otmp->corpsenm].cnutrit;
  1900. X        else otmp->oeaten = objects[otmp->otyp].oc_nutrition;
  1901. X        otmp->owt /= 2;
  1902. X        otmp->oeaten /= 2;
  1903. X        if (!otmp->owt) otmp->owt = 1;
  1904. X        if (!otmp->oeaten) otmp->oeaten = 1;
  1905. X    }
  1906. X    return(otmp);
  1907. X}
  1908. X
  1909. Xint
  1910. Xrnd_class(first,last)
  1911. Xint first,last;
  1912. X{
  1913. X    int i, x, sum=0;
  1914. X    for(i=first; i<=last; i++)
  1915. X        sum += objects[i].oc_prob;
  1916. X    if (!sum) /* all zero */
  1917. X        return first + rn2(last-first+1);
  1918. X    x = rnd(sum);
  1919. X    for(i=first; i<=last; i++)
  1920. X        if (objects[i].oc_prob && (x -= objects[i].oc_prob) <= 0)
  1921. X            return i;
  1922. X    return 0;
  1923. X}
  1924. X
  1925. XSTATIC_OVL const char *
  1926. XJapanese_item_name(i)
  1927. Xint i;
  1928. X{
  1929. X    struct Jitem *j = Japanese_items;
  1930. X
  1931. X    while(j->item) {
  1932. X        if (i == j->item)
  1933. X            return j->name;
  1934. X        j++;
  1935. X    }
  1936. X    return (const char *)0;
  1937. X}
  1938. X#endif /* OVLB */
  1939. X
  1940. X/*objnam.c*/
  1941. END_OF_FILE
  1942. if test 47782 -ne `wc -c <'src/objnam.c'`; then
  1943.     echo shar: \"'src/objnam.c'\" unpacked with wrong size!
  1944. fi
  1945. # end of 'src/objnam.c'
  1946. fi
  1947. if test -f 'sys/amiga/char.c' -a "${1}" != "-c" ; then 
  1948.   echo shar: Will not clobber existing file \"'sys/amiga/char.c'\"
  1949. else
  1950. echo shar: Extracting \"'sys/amiga/char.c'\" \(5759 characters\)
  1951. sed "s/^X//" >'sys/amiga/char.c' <<'END_OF_FILE'
  1952. XSHORT Type_BorderVectors1[] = {
  1953. X    0,0,
  1954. X    123,0,
  1955. X    123,11,
  1956. X    0,11,
  1957. X    0,0
  1958. X};
  1959. Xstruct Border Type_Border1 = {
  1960. X    -1,-1,
  1961. X    3,0,JAM1,
  1962. X    5,
  1963. X    Type_BorderVectors1,
  1964. X    NULL
  1965. X};
  1966. X
  1967. Xstruct IntuiText Type_IText1 = {
  1968. X    3,0,JAM2,
  1969. X    38,1,
  1970. X    NULL,
  1971. X    (UBYTE *)"Wizard",
  1972. X    NULL
  1973. X};
  1974. X
  1975. Xstruct Gadget Type_Gadget13 = {
  1976. X    NULL,
  1977. X    137,79,
  1978. X    122,10,
  1979. X    NULL,
  1980. X    RELVERIFY,
  1981. X    BOOLGADGET,
  1982. X    (APTR)&Type_Border1,
  1983. X    NULL,
  1984. X    &Type_IText1,
  1985. X    NULL,
  1986. X    NULL,
  1987. X    'W',
  1988. X    NULL
  1989. X};
  1990. X
  1991. XSHORT Type_BorderVectors2[] = {
  1992. X    0,0,
  1993. X    123,0,
  1994. X    123,11,
  1995. X    0,11,
  1996. X    0,0
  1997. X};
  1998. Xstruct Border Type_Border2 = {
  1999. X    -1,-1,
  2000. X    3,0,JAM1,
  2001. X    5,
  2002. X    Type_BorderVectors2,
  2003. X    NULL
  2004. X};
  2005. X
  2006. Xstruct IntuiText Type_IText2 = {
  2007. X    3,0,JAM2,
  2008. X    29,1,
  2009. X    NULL,
  2010. X    (UBYTE *)"Valkyrie",
  2011. X    NULL
  2012. X};
  2013. X
  2014. Xstruct Gadget Type_Gadget12 = {
  2015. X    &Type_Gadget13,
  2016. X    9,79,
  2017. X    122,10,
  2018. X    NULL,
  2019. X    RELVERIFY,
  2020. X    BOOLGADGET,
  2021. X    (APTR)&Type_Border2,
  2022. X    NULL,
  2023. X    &Type_IText2,
  2024. X    NULL,
  2025. X    NULL,
  2026. X    'V',
  2027. X    NULL
  2028. X};
  2029. X
  2030. XSHORT Type_BorderVectors3[] = {
  2031. X    0,0,
  2032. X    251,0,
  2033. X    251,11,
  2034. X    0,11,
  2035. X    0,0
  2036. X};
  2037. Xstruct Border Type_Border3 = {
  2038. X    -1,-1,
  2039. X    1,0,JAM1,
  2040. X    5,
  2041. X    Type_BorderVectors3,
  2042. X    NULL
  2043. X};
  2044. X
  2045. Xstruct IntuiText Type_IText3 = {
  2046. X    1,0,JAM2,
  2047. X    14,1,
  2048. X    NULL,
  2049. X    (UBYTE *)"Pick a Random Character Type",
  2050. X    NULL
  2051. X};
  2052. X
  2053. Xstruct Gadget Type_Gadget11 = {
  2054. X    &Type_Gadget12,
  2055. X    9,94,
  2056. X    250,10,
  2057. X    NULL,
  2058. X    RELVERIFY,
  2059. X    BOOLGADGET,
  2060. X    (APTR)&Type_Border3,
  2061. X    NULL,
  2062. X    &Type_IText3,
  2063. X    NULL,
  2064. X    NULL,
  2065. X    1,
  2066. X    NULL
  2067. X};
  2068. X
  2069. XSHORT Type_BorderVectors4[] = {
  2070. X    0,0,
  2071. X    123,0,
  2072. X    123,11,
  2073. X    0,11,
  2074. X    0,0
  2075. X};
  2076. Xstruct Border Type_Border4 = {
  2077. X    -1,-1,
  2078. X    3,0,JAM1,
  2079. X    5,
  2080. X    Type_BorderVectors4,
  2081. X    NULL
  2082. X};
  2083. X
  2084. Xstruct IntuiText Type_IText4 = {
  2085. X    3,0,JAM2,
  2086. X    33,1,
  2087. X    NULL,
  2088. X    (UBYTE *)"Samurai",
  2089. X    NULL
  2090. X};
  2091. X
  2092. Xstruct Gadget Type_Gadget10 = {
  2093. X    &Type_Gadget11,
  2094. X    9,66,
  2095. X    122,10,
  2096. X    NULL,
  2097. X    RELVERIFY,
  2098. X    BOOLGADGET,
  2099. X    (APTR)&Type_Border4,
  2100. X    NULL,
  2101. X    &Type_IText4,
  2102. X    NULL,
  2103. X    NULL,
  2104. X    'S',
  2105. X    NULL
  2106. X};
  2107. X
  2108. XSHORT Type_BorderVectors5[] = {
  2109. X    0,0,
  2110. X    123,0,
  2111. X    123,11,
  2112. X    0,11,
  2113. X    0,0
  2114. X};
  2115. Xstruct Border Type_Border5 = {
  2116. X    -1,-1,
  2117. X    3,0,JAM1,
  2118. X    5,
  2119. X    Type_BorderVectors5,
  2120. X    NULL
  2121. X};
  2122. X
  2123. Xstruct IntuiText Type_IText5 = {
  2124. X    3,0,JAM2,
  2125. X    34,1,
  2126. X    NULL,
  2127. X    (UBYTE *)"Tourist",
  2128. X    NULL
  2129. X};
  2130. X
  2131. Xstruct Gadget Type_Gadget9 = {
  2132. X    &Type_Gadget10,
  2133. X    137,66,
  2134. X    122,10,
  2135. X    NULL,
  2136. X    RELVERIFY,
  2137. X    BOOLGADGET,
  2138. X    (APTR)&Type_Border5,
  2139. X    NULL,
  2140. X    &Type_IText5,
  2141. X    NULL,
  2142. X    NULL,
  2143. X    'T',
  2144. X    NULL
  2145. X};
  2146. X
  2147. XSHORT Type_BorderVectors6[] = {
  2148. X    0,0,
  2149. X    123,0,
  2150. X    123,11,
  2151. X    0,11,
  2152. X    0,0
  2153. X};
  2154. Xstruct Border Type_Border6 = {
  2155. X    -1,-1,
  2156. X    3,0,JAM1,
  2157. X    5,
  2158. X    Type_BorderVectors6,
  2159. X    NULL
  2160. X};
  2161. X
  2162. Xstruct IntuiText Type_IText6 = {
  2163. X    3,0,JAM2,
  2164. X    40,1,
  2165. X    NULL,
  2166. X    (UBYTE *)"Rogue",
  2167. X    NULL
  2168. X};
  2169. X
  2170. Xstruct Gadget Type_Gadget8 = {
  2171. X    &Type_Gadget9,
  2172. X    137,53,
  2173. X    122,10,
  2174. X    NULL,
  2175. X    RELVERIFY,
  2176. X    BOOLGADGET,
  2177. X    (APTR)&Type_Border6,
  2178. X    NULL,
  2179. X    &Type_IText6,
  2180. X    NULL,
  2181. X    NULL,
  2182. X    'R',
  2183. X    NULL
  2184. X};
  2185. X
  2186. XSHORT Type_BorderVectors7[] = {
  2187. X    0,0,
  2188. X    123,0,
  2189. X    123,11,
  2190. X    0,11,
  2191. X    0,0
  2192. X};
  2193. Xstruct Border Type_Border7 = {
  2194. X    -1,-1,
  2195. X    3,0,JAM1,
  2196. X    5,
  2197. X    Type_BorderVectors7,
  2198. X    NULL
  2199. X};
  2200. X
  2201. Xstruct IntuiText Type_IText7 = {
  2202. X    3,0,JAM2,
  2203. X    36,1,
  2204. X    NULL,
  2205. X    (UBYTE *)"Priest",
  2206. X    NULL
  2207. X};
  2208. X
  2209. Xstruct Gadget Type_Gadget7 = {
  2210. X    &Type_Gadget8,
  2211. X    9,53,
  2212. X    122,10,
  2213. X    NULL,
  2214. X    RELVERIFY,
  2215. X    BOOLGADGET,
  2216. X    (APTR)&Type_Border7,
  2217. X    NULL,
  2218. X    &Type_IText7,
  2219. X    NULL,
  2220. X    NULL,
  2221. X    'P',
  2222. X    NULL
  2223. X};
  2224. X
  2225. XSHORT Type_BorderVectors8[] = {
  2226. X    0,0,
  2227. X    123,0,
  2228. X    123,11,
  2229. X    0,11,
  2230. X    0,0
  2231. X};
  2232. Xstruct Border Type_Border8 = {
  2233. X    -1,-1,
  2234. X    3,0,JAM1,
  2235. X    5,
  2236. X    Type_BorderVectors8,
  2237. X    NULL
  2238. X};
  2239. X
  2240. Xstruct IntuiText Type_IText8 = {
  2241. X    3,0,JAM2,
  2242. X    35,1,
  2243. X    NULL,
  2244. X    (UBYTE *)"Healer",
  2245. X    NULL
  2246. X};
  2247. X
  2248. Xstruct Gadget Type_Gadget6 = {
  2249. X    &Type_Gadget7,
  2250. X    9,40,
  2251. X    122,10,
  2252. X    NULL,
  2253. X    RELVERIFY,
  2254. X    BOOLGADGET,
  2255. X    (APTR)&Type_Border8,
  2256. X    NULL,
  2257. X    &Type_IText8,
  2258. X    NULL,
  2259. X    NULL,
  2260. X    'H',
  2261. X    NULL
  2262. X};
  2263. X
  2264. XSHORT Type_BorderVectors9[] = {
  2265. X    0,0,
  2266. X    123,0,
  2267. X    123,11,
  2268. X    0,11,
  2269. X    0,0
  2270. X};
  2271. Xstruct Border Type_Border9 = {
  2272. X    -1,-1,
  2273. X    3,0,JAM1,
  2274. X    5,
  2275. X    Type_BorderVectors9,
  2276. X    NULL
  2277. X};
  2278. X
  2279. Xstruct IntuiText Type_IText9 = {
  2280. X    3,0,JAM2,
  2281. X    33,1,
  2282. X    NULL,
  2283. X    (UBYTE *)"Caveman",
  2284. X    NULL
  2285. X};
  2286. X
  2287. Xstruct Gadget Type_Gadget5 = {
  2288. X    &Type_Gadget6,
  2289. X    9,27,
  2290. X    122,10,
  2291. X    NULL,
  2292. X    RELVERIFY,
  2293. X    BOOLGADGET,
  2294. X    (APTR)&Type_Border9,
  2295. X    NULL,
  2296. X    &Type_IText9,
  2297. X    NULL,
  2298. X    NULL,
  2299. X    'C',
  2300. X    NULL
  2301. X};
  2302. X
  2303. XSHORT Type_BorderVectors10[] = {
  2304. X    0,0,
  2305. X    123,0,
  2306. X    123,11,
  2307. X    0,11,
  2308. X    0,0
  2309. X};
  2310. Xstruct Border Type_Border10 = {
  2311. X    -1,-1,
  2312. X    3,0,JAM1,
  2313. X    5,
  2314. X    Type_BorderVectors10,
  2315. X    NULL
  2316. X};
  2317. X
  2318. Xstruct IntuiText Type_IText10 = {
  2319. X    3,0,JAM2,
  2320. X    16,1,
  2321. X    NULL,
  2322. X    (UBYTE *)"Archeologist",
  2323. X    NULL
  2324. X};
  2325. X
  2326. Xstruct Gadget Type_Gadget4 = {
  2327. X    &Type_Gadget5,
  2328. X    9,14,
  2329. X    122,10,
  2330. X    NULL,
  2331. X    RELVERIFY,
  2332. X    BOOLGADGET,
  2333. X    (APTR)&Type_Border10,
  2334. X    NULL,
  2335. X    &Type_IText10,
  2336. X    NULL,
  2337. X    NULL,
  2338. X    'A',
  2339. X    NULL
  2340. X};
  2341. X
  2342. XSHORT Type_BorderVectors11[] = {
  2343. X    0,0,
  2344. X    123,0,
  2345. X    123,11,
  2346. X    0,11,
  2347. X    0,0
  2348. X};
  2349. Xstruct Border Type_Border11 = {
  2350. X    -1,-1,
  2351. X    3,0,JAM1,
  2352. X    5,
  2353. X    Type_BorderVectors11,
  2354. X    NULL
  2355. X};
  2356. X
  2357. Xstruct IntuiText Type_IText11 = {
  2358. X    3,0,JAM2,
  2359. X    36,1,
  2360. X    NULL,
  2361. X    (UBYTE *)"Knight",
  2362. X    NULL
  2363. X};
  2364. X
  2365. Xstruct Gadget Type_Gadget3 = {
  2366. X    &Type_Gadget4,
  2367. X    137,40,
  2368. X    122,10,
  2369. X    NULL,
  2370. X    RELVERIFY,
  2371. X    BOOLGADGET,
  2372. X    (APTR)&Type_Border11,
  2373. X    NULL,
  2374. X    &Type_IText11,
  2375. X    NULL,
  2376. X    NULL,
  2377. X    'K',
  2378. X    NULL
  2379. X};
  2380. X
  2381. XSHORT Type_BorderVectors12[] = {
  2382. X    0,0,
  2383. X    123,0,
  2384. X    123,11,
  2385. X    0,11,
  2386. X    0,0
  2387. X};
  2388. Xstruct Border Type_Border12 = {
  2389. X    -1,-1,
  2390. X    3,0,JAM1,
  2391. X    5,
  2392. X    Type_BorderVectors12,
  2393. X    NULL
  2394. X};
  2395. X
  2396. Xstruct IntuiText Type_IText12 = {
  2397. X    3,0,JAM2,
  2398. X    48,1,
  2399. X    NULL,
  2400. X    (UBYTE *)"Elf",
  2401. X    NULL
  2402. X};
  2403. X
  2404. Xstruct Gadget Type_Gadget2 = {
  2405. X    &Type_Gadget3,
  2406. X    137,27,
  2407. X    122,10,
  2408. X    NULL,
  2409. X    RELVERIFY,
  2410. X    BOOLGADGET,
  2411. X    (APTR)&Type_Border12,
  2412. X    NULL,
  2413. X    &Type_IText12,
  2414. X    NULL,
  2415. X    NULL,
  2416. X    'E',
  2417. X    NULL
  2418. X};
  2419. X
  2420. XSHORT Type_BorderVectors13[] = {
  2421. X    0,0,
  2422. X    123,0,
  2423. X    123,11,
  2424. X    0,11,
  2425. X    0,0
  2426. X};
  2427. Xstruct Border Type_Border13 = {
  2428. X    -1,-1,
  2429. X    3,0,JAM1,
  2430. X    5,
  2431. X    Type_BorderVectors13,
  2432. X    NULL
  2433. X};
  2434. X
  2435. Xstruct IntuiText Type_IText13 = {
  2436. X    3,0,JAM2,
  2437. X    27,1,
  2438. X    NULL,
  2439. X    (UBYTE *)"Barbarian",
  2440. X    NULL
  2441. X};
  2442. X
  2443. Xstruct Gadget Type_Gadget1 = {
  2444. X    &Type_Gadget2,
  2445. X    137,14,
  2446. X    122,10,
  2447. X    NULL,
  2448. X    RELVERIFY,
  2449. X    BOOLGADGET,
  2450. X    (APTR)&Type_Border13,
  2451. X    NULL,
  2452. X    &Type_IText13,
  2453. X    NULL,
  2454. X    NULL,
  2455. X    'B',
  2456. X    NULL
  2457. X};
  2458. X
  2459. X#define Type_GadgetList1 Type_Gadget1
  2460. X
  2461. Xstruct NewWindow Type_NewWindowStructure1 = {
  2462. X    155,24,
  2463. X    267,108,
  2464. X    0,1,
  2465. X    GADGETUP+CLOSEWINDOW+VANILLAKEY,
  2466. X    WINDOWCLOSE+ACTIVATE+NOCAREREFRESH,
  2467. X    &Type_Gadget1,
  2468. X    NULL,
  2469. X    (UBYTE *)"Pick a Character",
  2470. X    NULL,
  2471. X    NULL,
  2472. X    5,5,
  2473. X    -1,-1,
  2474. X    CUSTOMSCREEN
  2475. X};
  2476. X
  2477. X
  2478. X/* end of PowerWindows source generation */
  2479. END_OF_FILE
  2480. if test 5759 -ne `wc -c <'sys/amiga/char.c'`; then
  2481.     echo shar: \"'sys/amiga/char.c'\" unpacked with wrong size!
  2482. fi
  2483. # end of 'sys/amiga/char.c'
  2484. fi
  2485. echo shar: End of archive 10 \(of 108\).
  2486. cp /dev/null ark10isdone
  2487. MISSING=""
  2488. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  2489. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  2490. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  2491. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  2492. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  2493. 101 102 103 104 105 106 107 108 ; do
  2494.     if test ! -f ark${I}isdone ; then
  2495.     MISSING="${MISSING} ${I}"
  2496.     fi
  2497. done
  2498. if test "${MISSING}" = "" ; then
  2499.     echo You have unpacked all 108 archives.
  2500.     echo "Now execute 'rebuild.sh'"
  2501.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  2502. else
  2503.     echo You still need to unpack the following archives:
  2504.     echo "        " ${MISSING}
  2505. fi
  2506. ##  End of shell archive.
  2507. exit 0
  2508.