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