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