home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / sources / games / 318 < prev    next >
Encoding:
Internet Message Format  |  1993-01-28  |  57.3 KB

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