hack.do_name.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. /* $NetBSD: hack.do_name.c,v 1.6 2003/04/02 18:36:36 jsm Exp $ */
  2. /*
  3. * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
  4. * Amsterdam
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are
  9. * met:
  10. *
  11. * - Redistributions of source code must retain the above copyright notice,
  12. * this list of conditions and the following disclaimer.
  13. *
  14. * - Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. *
  18. * - Neither the name of the Stichting Centrum voor Wiskunde en
  19. * Informatica, nor the names of its contributors may be used to endorse or
  20. * promote products derived from this software without specific prior
  21. * written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  24. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  25. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  26. * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  27. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  28. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  29. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  30. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  31. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  32. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  33. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. /*
  36. * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
  37. * All rights reserved.
  38. *
  39. * Redistribution and use in source and binary forms, with or without
  40. * modification, are permitted provided that the following conditions
  41. * are met:
  42. * 1. Redistributions of source code must retain the above copyright
  43. * notice, this list of conditions and the following disclaimer.
  44. * 2. Redistributions in binary form must reproduce the above copyright
  45. * notice, this list of conditions and the following disclaimer in the
  46. * documentation and/or other materials provided with the distribution.
  47. * 3. The name of the author may not be used to endorse or promote products
  48. * derived from this software without specific prior written permission.
  49. *
  50. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  51. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  52. * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  53. * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  54. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  55. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  56. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  57. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  58. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  59. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60. */
  61. #include <sys/cdefs.h>
  62. #ifndef lint
  63. __RCSID("$NetBSD: hack.do_name.c,v 1.6 2003/04/02 18:36:36 jsm Exp $");
  64. #endif /* not lint */
  65. #include <stdlib.h>
  66. #include "hack.h"
  67. #include "extern.h"
  68. coord
  69. getpos(force, goal)
  70. int force;
  71. const char *goal;
  72. {
  73. int cx, cy, i, c;
  74. coord cc;
  75. pline("(For instructions type a ?)");
  76. cx = u.ux;
  77. cy = u.uy;
  78. curs(cx, cy + 2);
  79. while ((c = readchar()) != '.') {
  80. for (i = 0; i < 8; i++)
  81. if (sdir[i] == c) {
  82. if (1 <= cx + xdir[i] && cx + xdir[i] <= COLNO)
  83. cx += xdir[i];
  84. if (0 <= cy + ydir[i] && cy + ydir[i] <= ROWNO - 1)
  85. cy += ydir[i];
  86. goto nxtc;
  87. }
  88. if (c == '?') {
  89. pline("Use [hjkl] to move the cursor to %s.", goal);
  90. pline("Type a . when you are at the right place.");
  91. } else {
  92. pline("Unknown direction: '%s' (%s).",
  93. visctrl(c),
  94. force ? "use hjkl or ." : "aborted");
  95. if (force)
  96. goto nxtc;
  97. cc.x = -1;
  98. cc.y = 0;
  99. return (cc);
  100. }
  101. nxtc: ;
  102. curs(cx, cy + 2);
  103. }
  104. cc.x = cx;
  105. cc.y = cy;
  106. return (cc);
  107. }
  108. int
  109. do_mname()
  110. {
  111. char buf[BUFSZ];
  112. coord cc;
  113. int cx, cy, lth, i;
  114. struct monst *mtmp, *mtmp2;
  115. cc = getpos(0, "the monster you want to name");
  116. cx = cc.x;
  117. cy = cc.y;
  118. if (cx < 0)
  119. return (0);
  120. mtmp = m_at(cx, cy);
  121. if (!mtmp) {
  122. if (cx == u.ux && cy == u.uy)
  123. pline("This ugly monster is called %s and cannot be renamed.",
  124. plname);
  125. else
  126. pline("There is no monster there.");
  127. return (1);
  128. }
  129. if (mtmp->mimic) {
  130. pline("I see no monster there.");
  131. return (1);
  132. }
  133. if (!cansee(cx, cy)) {
  134. pline("I cannot see a monster there.");
  135. return (1);
  136. }
  137. pline("What do you want to call %s? ", lmonnam(mtmp));
  138. getlin(buf);
  139. clrlin();
  140. if (!*buf || *buf == '\033')
  141. return (1);
  142. lth = strlen(buf) + 1;
  143. if (lth > 63) {
  144. buf[62] = 0;
  145. lth = 63;
  146. }
  147. mtmp2 = newmonst(mtmp->mxlth + lth);
  148. *mtmp2 = *mtmp;
  149. for (i = 0; (unsigned)i < mtmp->mxlth; i++)
  150. ((char *) mtmp2->mextra)[i] = ((char *) mtmp->mextra)[i];
  151. mtmp2->mnamelth = lth;
  152. (void) strcpy(NAME(mtmp2), buf);
  153. replmon(mtmp, mtmp2);
  154. return (1);
  155. }
  156. /*
  157. * This routine changes the address of obj . Be careful not to call it
  158. * when there might be pointers around in unknown places. For now: only
  159. * when obj is in the inventory.
  160. */
  161. void
  162. do_oname(obj)
  163. struct obj *obj;
  164. {
  165. struct obj *otmp, *otmp2;
  166. int lth;
  167. char buf[BUFSZ];
  168. pline("What do you want to name %s? ", doname(obj));
  169. getlin(buf);
  170. clrlin();
  171. if (!*buf || *buf == '\033')
  172. return;
  173. lth = strlen(buf) + 1;
  174. if (lth > 63) {
  175. buf[62] = 0;
  176. lth = 63;
  177. }
  178. otmp2 = newobj(lth);
  179. *otmp2 = *obj;
  180. otmp2->onamelth = lth;
  181. (void) strcpy(ONAME(otmp2), buf);
  182. setworn((struct obj *) 0, obj->owornmask);
  183. setworn(otmp2, otmp2->owornmask);
  184. /*
  185. * do freeinv(obj); etc. by hand in order to preserve the position of
  186. * this object in the inventory
  187. */
  188. if (obj == invent)
  189. invent = otmp2;
  190. else
  191. for (otmp = invent;; otmp = otmp->nobj) {
  192. if (!otmp)
  193. panic("Do_oname: cannot find obj.");
  194. if (otmp->nobj == obj) {
  195. otmp->nobj = otmp2;
  196. break;
  197. }
  198. }
  199. #if 0
  200. obfree(obj, otmp2); /* now unnecessary: no pointers on bill */
  201. #endif
  202. free((char *) obj); /* let us hope nobody else saved a pointer */
  203. }
  204. int
  205. ddocall()
  206. {
  207. struct obj *obj;
  208. pline("Do you want to name an individual object? [ny] ");
  209. switch (readchar()) {
  210. case '\033':
  211. break;
  212. case 'y':
  213. obj = getobj("#", "name");
  214. if (obj)
  215. do_oname(obj);
  216. break;
  217. default:
  218. obj = getobj("?!=/", "call");
  219. if (obj)
  220. docall(obj);
  221. }
  222. return (0);
  223. }
  224. void
  225. docall(obj)
  226. struct obj *obj;
  227. {
  228. char buf[BUFSZ];
  229. struct obj otemp;
  230. char **str1;
  231. char *str;
  232. otemp = *obj;
  233. otemp.quan = 1;
  234. otemp.onamelth = 0;
  235. str = xname(&otemp);
  236. pline("Call %s %s: ", strchr(vowels, *str) ? "an" : "a", str);
  237. getlin(buf);
  238. clrlin();
  239. if (!*buf || *buf == '\033')
  240. return;
  241. str = newstring(strlen(buf) + 1);
  242. (void) strcpy(str, buf);
  243. str1 = &(objects[obj->otyp].oc_uname);
  244. if (*str1)
  245. free(*str1);
  246. *str1 = str;
  247. }
  248. const char *const ghostnames[] = {/* these names should have length < PL_NSIZ */
  249. "adri", "andries", "andreas", "bert", "david", "dirk", "emile",
  250. "frans", "fred", "greg", "hether", "jay", "john", "jon", "kay",
  251. "kenny", "maud", "michiel", "mike", "peter", "robert", "ron",
  252. "tom", "wilmar"
  253. };
  254. char *
  255. xmonnam(mtmp, vb)
  256. struct monst *mtmp;
  257. int vb;
  258. {
  259. static char buf[BUFSZ]; /* %% */
  260. if (mtmp->mnamelth && !vb) {
  261. (void) strcpy(buf, NAME(mtmp));
  262. return (buf);
  263. }
  264. switch (mtmp->data->mlet) {
  265. case ' ':
  266. {
  267. const char *gn = (char *) mtmp->mextra;
  268. if (!*gn) { /* might also look in scorefile */
  269. gn = ghostnames[rn2(SIZE(ghostnames))];
  270. if (!rn2(2))
  271. (void)
  272. strcpy((char *) mtmp->mextra, !rn2(5) ? plname : gn);
  273. }
  274. (void) sprintf(buf, "%s's ghost", gn);
  275. }
  276. break;
  277. case '@':
  278. if (mtmp->isshk) {
  279. (void) strcpy(buf, shkname(mtmp));
  280. break;
  281. }
  282. /* fall into next case */
  283. default:
  284. (void) sprintf(buf, "the %s%s",
  285. mtmp->minvis ? "invisible " : "",
  286. mtmp->data->mname);
  287. }
  288. if (vb && mtmp->mnamelth) {
  289. (void) strcat(buf, " called ");
  290. (void) strcat(buf, NAME(mtmp));
  291. }
  292. return (buf);
  293. }
  294. char *
  295. lmonnam(mtmp)
  296. struct monst *mtmp;
  297. {
  298. return (xmonnam(mtmp, 1));
  299. }
  300. char *
  301. monnam(mtmp)
  302. struct monst *mtmp;
  303. {
  304. return (xmonnam(mtmp, 0));
  305. }
  306. char *
  307. Monnam(mtmp)
  308. struct monst *mtmp;
  309. {
  310. char *bp = monnam(mtmp);
  311. if ('a' <= *bp && *bp <= 'z')
  312. *bp += ('A' - 'a');
  313. return (bp);
  314. }
  315. char *
  316. amonnam(mtmp, adj)
  317. struct monst *mtmp;
  318. const char *adj;
  319. {
  320. char *bp = monnam(mtmp);
  321. static char buf[BUFSZ]; /* %% */
  322. if (!strncmp(bp, "the ", 4))
  323. bp += 4;
  324. (void) sprintf(buf, "the %s %s", adj, bp);
  325. return (buf);
  326. }
  327. char *
  328. Amonnam(mtmp, adj)
  329. struct monst *mtmp;
  330. const char *adj;
  331. {
  332. char *bp = amonnam(mtmp, adj);
  333. *bp = 'T';
  334. return (bp);
  335. }
  336. char *
  337. Xmonnam(mtmp)
  338. struct monst *mtmp;
  339. {
  340. char *bp = Monnam(mtmp);
  341. if (!strncmp(bp, "The ", 4)) {
  342. bp += 2;
  343. *bp = 'A';
  344. }
  345. return (bp);
  346. }
  347. char *
  348. visctrl(c)
  349. char c;
  350. {
  351. static char ccc[3];
  352. if (c < 040) {
  353. ccc[0] = '^';
  354. ccc[1] = c + 0100;
  355. ccc[2] = 0;
  356. } else {
  357. ccc[0] = c;
  358. ccc[1] = 0;
  359. }
  360. return (ccc);
  361. }