hack.do_name.c revision 1.4 1 1.4 christos /* $NetBSD: hack.do_name.c,v 1.4 1997/10/19 16:57:46 christos Exp $ */
2 1.4 christos
3 1.2 mycroft /*
4 1.2 mycroft * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
5 1.2 mycroft */
6 1.2 mycroft
7 1.4 christos #include <sys/cdefs.h>
8 1.2 mycroft #ifndef lint
9 1.4 christos __RCSID("$NetBSD: hack.do_name.c,v 1.4 1997/10/19 16:57:46 christos Exp $");
10 1.4 christos #endif /* not lint */
11 1.1 cgd
12 1.4 christos #include <stdlib.h>
13 1.1 cgd #include "hack.h"
14 1.4 christos #include "extern.h"
15 1.1 cgd
16 1.1 cgd coord
17 1.4 christos getpos(force, goal)
18 1.4 christos int force;
19 1.4 christos char *goal;
20 1.4 christos {
21 1.4 christos int cx, cy, i, c;
22 1.4 christos coord cc;
23 1.1 cgd pline("(For instructions type a ?)");
24 1.1 cgd cx = u.ux;
25 1.1 cgd cy = u.uy;
26 1.4 christos curs(cx, cy + 2);
27 1.4 christos while ((c = readchar()) != '.') {
28 1.4 christos for (i = 0; i < 8; i++)
29 1.4 christos if (sdir[i] == c) {
30 1.4 christos if (1 <= cx + xdir[i] && cx + xdir[i] <= COLNO)
31 1.4 christos cx += xdir[i];
32 1.4 christos if (0 <= cy + ydir[i] && cy + ydir[i] <= ROWNO - 1)
33 1.4 christos cy += ydir[i];
34 1.4 christos goto nxtc;
35 1.4 christos }
36 1.4 christos if (c == '?') {
37 1.1 cgd pline("Use [hjkl] to move the cursor to %s.", goal);
38 1.1 cgd pline("Type a . when you are at the right place.");
39 1.1 cgd } else {
40 1.1 cgd pline("Unknown direction: '%s' (%s).",
41 1.4 christos visctrl(c),
42 1.4 christos force ? "use hjkl or ." : "aborted");
43 1.4 christos if (force)
44 1.4 christos goto nxtc;
45 1.1 cgd cc.x = -1;
46 1.1 cgd cc.y = 0;
47 1.4 christos return (cc);
48 1.1 cgd }
49 1.4 christos nxtc: ;
50 1.4 christos curs(cx, cy + 2);
51 1.1 cgd }
52 1.1 cgd cc.x = cx;
53 1.1 cgd cc.y = cy;
54 1.4 christos return (cc);
55 1.1 cgd }
56 1.1 cgd
57 1.4 christos int
58 1.4 christos do_mname()
59 1.4 christos {
60 1.4 christos char buf[BUFSZ];
61 1.4 christos coord cc;
62 1.4 christos int cx, cy, lth, i;
63 1.4 christos struct monst *mtmp, *mtmp2;
64 1.1 cgd cc = getpos(0, "the monster you want to name");
65 1.1 cgd cx = cc.x;
66 1.1 cgd cy = cc.y;
67 1.4 christos if (cx < 0)
68 1.4 christos return (0);
69 1.4 christos mtmp = m_at(cx, cy);
70 1.4 christos if (!mtmp) {
71 1.4 christos if (cx == u.ux && cy == u.uy)
72 1.4 christos pline("This ugly monster is called %s and cannot be renamed.",
73 1.4 christos plname);
74 1.4 christos else
75 1.4 christos pline("There is no monster there.");
76 1.4 christos return (1);
77 1.4 christos }
78 1.4 christos if (mtmp->mimic) {
79 1.4 christos pline("I see no monster there.");
80 1.4 christos return (1);
81 1.4 christos }
82 1.4 christos if (!cansee(cx, cy)) {
83 1.4 christos pline("I cannot see a monster there.");
84 1.4 christos return (1);
85 1.1 cgd }
86 1.1 cgd pline("What do you want to call %s? ", lmonnam(mtmp));
87 1.1 cgd getlin(buf);
88 1.1 cgd clrlin();
89 1.4 christos if (!*buf || *buf == '\033')
90 1.4 christos return (1);
91 1.4 christos lth = strlen(buf) + 1;
92 1.4 christos if (lth > 63) {
93 1.1 cgd buf[62] = 0;
94 1.1 cgd lth = 63;
95 1.1 cgd }
96 1.1 cgd mtmp2 = newmonst(mtmp->mxlth + lth);
97 1.1 cgd *mtmp2 = *mtmp;
98 1.4 christos for (i = 0; i < mtmp->mxlth; i++)
99 1.1 cgd ((char *) mtmp2->mextra)[i] = ((char *) mtmp->mextra)[i];
100 1.1 cgd mtmp2->mnamelth = lth;
101 1.1 cgd (void) strcpy(NAME(mtmp2), buf);
102 1.4 christos replmon(mtmp, mtmp2);
103 1.4 christos return (1);
104 1.1 cgd }
105 1.1 cgd
106 1.1 cgd /*
107 1.1 cgd * This routine changes the address of obj . Be careful not to call it
108 1.1 cgd * when there might be pointers around in unknown places. For now: only
109 1.1 cgd * when obj is in the inventory.
110 1.1 cgd */
111 1.4 christos void
112 1.4 christos do_oname(obj)
113 1.4 christos struct obj *obj;
114 1.4 christos {
115 1.4 christos struct obj *otmp, *otmp2;
116 1.4 christos int lth;
117 1.4 christos char buf[BUFSZ];
118 1.1 cgd pline("What do you want to name %s? ", doname(obj));
119 1.1 cgd getlin(buf);
120 1.1 cgd clrlin();
121 1.4 christos if (!*buf || *buf == '\033')
122 1.1 cgd return;
123 1.4 christos lth = strlen(buf) + 1;
124 1.4 christos if (lth > 63) {
125 1.1 cgd buf[62] = 0;
126 1.1 cgd lth = 63;
127 1.1 cgd }
128 1.1 cgd otmp2 = newobj(lth);
129 1.1 cgd *otmp2 = *obj;
130 1.1 cgd otmp2->onamelth = lth;
131 1.1 cgd (void) strcpy(ONAME(otmp2), buf);
132 1.1 cgd
133 1.1 cgd setworn((struct obj *) 0, obj->owornmask);
134 1.1 cgd setworn(otmp2, otmp2->owornmask);
135 1.1 cgd
136 1.4 christos /*
137 1.4 christos * do freeinv(obj); etc. by hand in order to preserve the position of
138 1.4 christos * this object in the inventory
139 1.4 christos */
140 1.4 christos if (obj == invent)
141 1.4 christos invent = otmp2;
142 1.4 christos else
143 1.4 christos for (otmp = invent;; otmp = otmp->nobj) {
144 1.4 christos if (!otmp)
145 1.4 christos panic("Do_oname: cannot find obj.");
146 1.4 christos if (otmp->nobj == obj) {
147 1.4 christos otmp->nobj = otmp2;
148 1.4 christos break;
149 1.4 christos }
150 1.1 cgd }
151 1.4 christos #if 0
152 1.4 christos obfree(obj, otmp2); /* now unnecessary: no pointers on bill */
153 1.4 christos #endif
154 1.1 cgd free((char *) obj); /* let us hope nobody else saved a pointer */
155 1.1 cgd }
156 1.1 cgd
157 1.4 christos int
158 1.1 cgd ddocall()
159 1.1 cgd {
160 1.4 christos struct obj *obj;
161 1.1 cgd
162 1.1 cgd pline("Do you want to name an individual object? [ny] ");
163 1.4 christos switch (readchar()) {
164 1.1 cgd case '\033':
165 1.1 cgd break;
166 1.1 cgd case 'y':
167 1.1 cgd obj = getobj("#", "name");
168 1.4 christos if (obj)
169 1.4 christos do_oname(obj);
170 1.1 cgd break;
171 1.1 cgd default:
172 1.1 cgd obj = getobj("?!=/", "call");
173 1.4 christos if (obj)
174 1.4 christos docall(obj);
175 1.1 cgd }
176 1.4 christos return (0);
177 1.1 cgd }
178 1.1 cgd
179 1.4 christos void
180 1.1 cgd docall(obj)
181 1.4 christos struct obj *obj;
182 1.1 cgd {
183 1.4 christos char buf[BUFSZ];
184 1.4 christos struct obj otemp;
185 1.4 christos char **str1;
186 1.4 christos char *str;
187 1.1 cgd
188 1.1 cgd otemp = *obj;
189 1.1 cgd otemp.quan = 1;
190 1.1 cgd otemp.onamelth = 0;
191 1.1 cgd str = xname(&otemp);
192 1.4 christos pline("Call %s %s: ", strchr(vowels, *str) ? "an" : "a", str);
193 1.1 cgd getlin(buf);
194 1.1 cgd clrlin();
195 1.4 christos if (!*buf || *buf == '\033')
196 1.1 cgd return;
197 1.4 christos str = newstring(strlen(buf) + 1);
198 1.4 christos (void) strcpy(str, buf);
199 1.1 cgd str1 = &(objects[obj->otyp].oc_uname);
200 1.4 christos if (*str1)
201 1.4 christos free(*str1);
202 1.1 cgd *str1 = str;
203 1.1 cgd }
204 1.1 cgd
205 1.4 christos char *ghostnames[] = {/* these names should have length < PL_NSIZ */
206 1.1 cgd "adri", "andries", "andreas", "bert", "david", "dirk", "emile",
207 1.1 cgd "frans", "fred", "greg", "hether", "jay", "john", "jon", "kay",
208 1.1 cgd "kenny", "maud", "michiel", "mike", "peter", "robert", "ron",
209 1.1 cgd "tom", "wilmar"
210 1.1 cgd };
211 1.1 cgd
212 1.4 christos char *
213 1.4 christos xmonnam(mtmp, vb)
214 1.4 christos struct monst *mtmp;
215 1.4 christos int vb;
216 1.4 christos {
217 1.4 christos static char buf[BUFSZ]; /* %% */
218 1.4 christos if (mtmp->mnamelth && !vb) {
219 1.1 cgd (void) strcpy(buf, NAME(mtmp));
220 1.4 christos return (buf);
221 1.1 cgd }
222 1.4 christos switch (mtmp->data->mlet) {
223 1.1 cgd case ' ':
224 1.4 christos {
225 1.4 christos char *gn = (char *) mtmp->mextra;
226 1.4 christos if (!*gn) { /* might also look in scorefile */
227 1.4 christos gn = ghostnames[rn2(SIZE(ghostnames))];
228 1.4 christos if (!rn2(2))
229 1.4 christos (void)
230 1.4 christos strcpy((char *) mtmp->mextra, !rn2(5) ? plname : gn);
231 1.4 christos }
232 1.4 christos (void) sprintf(buf, "%s's ghost", gn);
233 1.1 cgd }
234 1.1 cgd break;
235 1.1 cgd case '@':
236 1.4 christos if (mtmp->isshk) {
237 1.1 cgd (void) strcpy(buf, shkname(mtmp));
238 1.1 cgd break;
239 1.1 cgd }
240 1.1 cgd /* fall into next case */
241 1.1 cgd default:
242 1.1 cgd (void) sprintf(buf, "the %s%s",
243 1.4 christos mtmp->minvis ? "invisible " : "",
244 1.4 christos mtmp->data->mname);
245 1.1 cgd }
246 1.4 christos if (vb && mtmp->mnamelth) {
247 1.1 cgd (void) strcat(buf, " called ");
248 1.1 cgd (void) strcat(buf, NAME(mtmp));
249 1.1 cgd }
250 1.4 christos return (buf);
251 1.1 cgd }
252 1.1 cgd
253 1.4 christos char *
254 1.4 christos lmonnam(mtmp)
255 1.4 christos struct monst *mtmp;
256 1.4 christos {
257 1.4 christos return (xmonnam(mtmp, 1));
258 1.1 cgd }
259 1.1 cgd
260 1.4 christos char *
261 1.4 christos monnam(mtmp)
262 1.4 christos struct monst *mtmp;
263 1.4 christos {
264 1.4 christos return (xmonnam(mtmp, 0));
265 1.1 cgd }
266 1.1 cgd
267 1.4 christos char *
268 1.4 christos Monnam(mtmp)
269 1.4 christos struct monst *mtmp;
270 1.4 christos {
271 1.4 christos char *bp = monnam(mtmp);
272 1.4 christos if ('a' <= *bp && *bp <= 'z')
273 1.4 christos *bp += ('A' - 'a');
274 1.4 christos return (bp);
275 1.1 cgd }
276 1.1 cgd
277 1.4 christos char *
278 1.4 christos amonnam(mtmp, adj)
279 1.4 christos struct monst *mtmp;
280 1.4 christos char *adj;
281 1.1 cgd {
282 1.4 christos char *bp = monnam(mtmp);
283 1.4 christos static char buf[BUFSZ]; /* %% */
284 1.1 cgd
285 1.4 christos if (!strncmp(bp, "the ", 4))
286 1.4 christos bp += 4;
287 1.1 cgd (void) sprintf(buf, "the %s %s", adj, bp);
288 1.4 christos return (buf);
289 1.1 cgd }
290 1.1 cgd
291 1.4 christos char *
292 1.1 cgd Amonnam(mtmp, adj)
293 1.4 christos struct monst *mtmp;
294 1.4 christos char *adj;
295 1.1 cgd {
296 1.4 christos char *bp = amonnam(mtmp, adj);
297 1.1 cgd
298 1.1 cgd *bp = 'T';
299 1.4 christos return (bp);
300 1.1 cgd }
301 1.1 cgd
302 1.4 christos char *
303 1.4 christos Xmonnam(mtmp)
304 1.4 christos struct monst *mtmp;
305 1.4 christos {
306 1.4 christos char *bp = Monnam(mtmp);
307 1.4 christos if (!strncmp(bp, "The ", 4)) {
308 1.1 cgd bp += 2;
309 1.1 cgd *bp = 'A';
310 1.1 cgd }
311 1.4 christos return (bp);
312 1.1 cgd }
313 1.1 cgd
314 1.4 christos char *
315 1.1 cgd visctrl(c)
316 1.4 christos char c;
317 1.1 cgd {
318 1.4 christos static char ccc[3];
319 1.4 christos if (c < 040) {
320 1.1 cgd ccc[0] = '^';
321 1.1 cgd ccc[1] = c + 0100;
322 1.1 cgd ccc[2] = 0;
323 1.1 cgd } else {
324 1.1 cgd ccc[0] = c;
325 1.1 cgd ccc[1] = 0;
326 1.1 cgd }
327 1.4 christos return (ccc);
328 1.1 cgd }
329