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