]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.do_name.c
e29e4d20c25918947e370555e4584ab48a182da8
[bsdgames-darwin.git] / hack / hack.do_name.c
1 /* $NetBSD: hack.do_name.c,v 1.8 2009/06/07 18:30:39 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 <sys/cdefs.h>
65 #ifndef lint
66 __RCSID("$NetBSD: hack.do_name.c,v 1.8 2009/06/07 18:30:39 dholland Exp $");
67 #endif /* not lint */
68
69 #include <stdlib.h>
70 #include "hack.h"
71 #include "extern.h"
72
73 coord
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
113 do_mname(void)
114 {
115 char buf[BUFSZ];
116 coord cc;
117 int cx, cy, lth;
118 unsigned i;
119 struct monst *mtmp, *mtmp2;
120 cc = getpos(0, "the monster you want to name");
121 cx = cc.x;
122 cy = cc.y;
123 if (cx < 0)
124 return (0);
125 mtmp = m_at(cx, cy);
126 if (!mtmp) {
127 if (cx == u.ux && cy == u.uy)
128 pline("This ugly monster is called %s and cannot be renamed.",
129 plname);
130 else
131 pline("There is no monster there.");
132 return (1);
133 }
134 if (mtmp->mimic) {
135 pline("I see no monster there.");
136 return (1);
137 }
138 if (!cansee(cx, cy)) {
139 pline("I cannot see a monster there.");
140 return (1);
141 }
142 pline("What do you want to call %s? ", lmonnam(mtmp));
143 getlin(buf);
144 clrlin();
145 if (!*buf || *buf == '\033')
146 return (1);
147 lth = strlen(buf) + 1;
148 if (lth > 63) {
149 buf[62] = 0;
150 lth = 63;
151 }
152 mtmp2 = newmonst(mtmp->mxlth + lth);
153 *mtmp2 = *mtmp;
154 for (i = 0; i < mtmp->mxlth; i++)
155 ((char *) mtmp2->mextra)[i] = ((char *) mtmp->mextra)[i];
156 mtmp2->mnamelth = lth;
157 (void) strcpy(NAME(mtmp2), buf);
158 replmon(mtmp, mtmp2);
159 return (1);
160 }
161
162 /*
163 * This routine changes the address of obj . Be careful not to call it
164 * when there might be pointers around in unknown places. For now: only
165 * when obj is in the inventory.
166 */
167 void
168 do_oname(struct obj *obj)
169 {
170 struct obj *otmp, *otmp2;
171 int lth;
172 char buf[BUFSZ];
173 pline("What do you want to name %s? ", doname(obj));
174 getlin(buf);
175 clrlin();
176 if (!*buf || *buf == '\033')
177 return;
178 lth = strlen(buf) + 1;
179 if (lth > 63) {
180 buf[62] = 0;
181 lth = 63;
182 }
183 otmp2 = newobj(lth);
184 *otmp2 = *obj;
185 otmp2->onamelth = lth;
186 (void) strcpy(ONAME(otmp2), buf);
187
188 setworn((struct obj *) 0, obj->owornmask);
189 setworn(otmp2, otmp2->owornmask);
190
191 /*
192 * do freeinv(obj); etc. by hand in order to preserve the position of
193 * this object in the inventory
194 */
195 if (obj == invent)
196 invent = otmp2;
197 else
198 for (otmp = invent;; otmp = otmp->nobj) {
199 if (!otmp)
200 panic("Do_oname: cannot find obj.");
201 if (otmp->nobj == obj) {
202 otmp->nobj = otmp2;
203 break;
204 }
205 }
206 #if 0
207 obfree(obj, otmp2); /* now unnecessary: no pointers on bill */
208 #endif
209 free((char *) obj); /* let us hope nobody else saved a pointer */
210 }
211
212 int
213 ddocall(void)
214 {
215 struct obj *obj;
216
217 pline("Do you want to name an individual object? [ny] ");
218 switch (readchar()) {
219 case '\033':
220 break;
221 case 'y':
222 obj = getobj("#", "name");
223 if (obj)
224 do_oname(obj);
225 break;
226 default:
227 obj = getobj("?!=/", "call");
228 if (obj)
229 docall(obj);
230 }
231 return (0);
232 }
233
234 void
235 docall(struct obj *obj)
236 {
237 char buf[BUFSZ];
238 struct obj otemp;
239 char **str1;
240 char *str;
241
242 otemp = *obj;
243 otemp.quan = 1;
244 otemp.onamelth = 0;
245 str = xname(&otemp);
246 pline("Call %s %s: ", strchr(vowels, *str) ? "an" : "a", str);
247 getlin(buf);
248 clrlin();
249 if (!*buf || *buf == '\033')
250 return;
251 str = newstring(strlen(buf) + 1);
252 (void) strcpy(str, buf);
253 str1 = &(objects[obj->otyp].oc_uname);
254 if (*str1)
255 free(*str1);
256 *str1 = str;
257 }
258
259 const char *const ghostnames[] = {/* these names should have length < PL_NSIZ */
260 "adri", "andries", "andreas", "bert", "david", "dirk", "emile",
261 "frans", "fred", "greg", "hether", "jay", "john", "jon", "kay",
262 "kenny", "maud", "michiel", "mike", "peter", "robert", "ron",
263 "tom", "wilmar"
264 };
265
266 char *
267 xmonnam(struct monst *mtmp, int vb)
268 {
269 static char buf[BUFSZ]; /* %% */
270 if (mtmp->mnamelth && !vb) {
271 (void) strcpy(buf, NAME(mtmp));
272 return (buf);
273 }
274 switch (mtmp->data->mlet) {
275 case ' ':
276 {
277 const char *gn = (char *) mtmp->mextra;
278 if (!*gn) { /* might also look in scorefile */
279 gn = ghostnames[rn2(SIZE(ghostnames))];
280 if (!rn2(2))
281 (void)
282 strcpy((char *) mtmp->mextra, !rn2(5) ? plname : gn);
283 }
284 (void) sprintf(buf, "%s's ghost", gn);
285 }
286 break;
287 case '@':
288 if (mtmp->isshk) {
289 (void) strcpy(buf, shkname(mtmp));
290 break;
291 }
292 /* fall into next case */
293 default:
294 (void) sprintf(buf, "the %s%s",
295 mtmp->minvis ? "invisible " : "",
296 mtmp->data->mname);
297 }
298 if (vb && mtmp->mnamelth) {
299 (void) strcat(buf, " called ");
300 (void) strcat(buf, NAME(mtmp));
301 }
302 return (buf);
303 }
304
305 char *
306 lmonnam(struct monst *mtmp)
307 {
308 return (xmonnam(mtmp, 1));
309 }
310
311 char *
312 monnam(struct monst *mtmp)
313 {
314 return (xmonnam(mtmp, 0));
315 }
316
317 char *
318 Monnam(struct monst *mtmp)
319 {
320 char *bp = monnam(mtmp);
321 if ('a' <= *bp && *bp <= 'z')
322 *bp += ('A' - 'a');
323 return (bp);
324 }
325
326 char *
327 amonnam(struct monst *mtmp, const char *adj)
328 {
329 char *bp = monnam(mtmp);
330 static char buf[BUFSZ]; /* %% */
331
332 if (!strncmp(bp, "the ", 4))
333 bp += 4;
334 (void) sprintf(buf, "the %s %s", adj, bp);
335 return (buf);
336 }
337
338 char *
339 Amonnam(struct monst *mtmp, const char *adj)
340 {
341 char *bp = amonnam(mtmp, adj);
342
343 *bp = 'T';
344 return (bp);
345 }
346
347 char *
348 Xmonnam(struct monst *mtmp)
349 {
350 char *bp = Monnam(mtmp);
351 if (!strncmp(bp, "The ", 4)) {
352 bp += 2;
353 *bp = 'A';
354 }
355 return (bp);
356 }
357
358 char *
359 visctrl(int c)
360 {
361 static char ccc[3];
362 if (c < 040) {
363 ccc[0] = '^';
364 ccc[1] = c + 0100;
365 ccc[2] = 0;
366 } else {
367 ccc[0] = c;
368 ccc[1] = 0;
369 }
370 return (ccc);
371 }