xref: /netbsd-src/games/hack/hack.do_name.c (revision d5b021c7edb8313eee3804ec3819b28abef1d1a0)
1*d5b021c7Sdholland /*	$NetBSD: hack.do_name.c,v 1.13 2011/08/07 06:03:45 dholland Exp $	*/
23ea4a95cSchristos 
302ded532Smycroft /*
41c7f94e5Sjsm  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
51c7f94e5Sjsm  * Amsterdam
61c7f94e5Sjsm  * All rights reserved.
71c7f94e5Sjsm  *
81c7f94e5Sjsm  * Redistribution and use in source and binary forms, with or without
91c7f94e5Sjsm  * modification, are permitted provided that the following conditions are
101c7f94e5Sjsm  * met:
111c7f94e5Sjsm  *
121c7f94e5Sjsm  * - Redistributions of source code must retain the above copyright notice,
131c7f94e5Sjsm  * this list of conditions and the following disclaimer.
141c7f94e5Sjsm  *
151c7f94e5Sjsm  * - Redistributions in binary form must reproduce the above copyright
161c7f94e5Sjsm  * notice, this list of conditions and the following disclaimer in the
171c7f94e5Sjsm  * documentation and/or other materials provided with the distribution.
181c7f94e5Sjsm  *
191c7f94e5Sjsm  * - Neither the name of the Stichting Centrum voor Wiskunde en
201c7f94e5Sjsm  * Informatica, nor the names of its contributors may be used to endorse or
211c7f94e5Sjsm  * promote products derived from this software without specific prior
221c7f94e5Sjsm  * written permission.
231c7f94e5Sjsm  *
241c7f94e5Sjsm  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
251c7f94e5Sjsm  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
261c7f94e5Sjsm  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
271c7f94e5Sjsm  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
281c7f94e5Sjsm  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
291c7f94e5Sjsm  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
301c7f94e5Sjsm  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
311c7f94e5Sjsm  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
321c7f94e5Sjsm  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
331c7f94e5Sjsm  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
341c7f94e5Sjsm  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
351c7f94e5Sjsm  */
361c7f94e5Sjsm 
371c7f94e5Sjsm /*
381c7f94e5Sjsm  * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
391c7f94e5Sjsm  * All rights reserved.
401c7f94e5Sjsm  *
411c7f94e5Sjsm  * Redistribution and use in source and binary forms, with or without
421c7f94e5Sjsm  * modification, are permitted provided that the following conditions
431c7f94e5Sjsm  * are met:
441c7f94e5Sjsm  * 1. Redistributions of source code must retain the above copyright
451c7f94e5Sjsm  *    notice, this list of conditions and the following disclaimer.
461c7f94e5Sjsm  * 2. Redistributions in binary form must reproduce the above copyright
471c7f94e5Sjsm  *    notice, this list of conditions and the following disclaimer in the
481c7f94e5Sjsm  *    documentation and/or other materials provided with the distribution.
491c7f94e5Sjsm  * 3. The name of the author may not be used to endorse or promote products
501c7f94e5Sjsm  *    derived from this software without specific prior written permission.
511c7f94e5Sjsm  *
521c7f94e5Sjsm  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
531c7f94e5Sjsm  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
541c7f94e5Sjsm  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
551c7f94e5Sjsm  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
561c7f94e5Sjsm  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
571c7f94e5Sjsm  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
581c7f94e5Sjsm  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
591c7f94e5Sjsm  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
601c7f94e5Sjsm  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
611c7f94e5Sjsm  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6202ded532Smycroft  */
6302ded532Smycroft 
643ea4a95cSchristos #include <sys/cdefs.h>
6502ded532Smycroft #ifndef lint
66*d5b021c7Sdholland __RCSID("$NetBSD: hack.do_name.c,v 1.13 2011/08/07 06:03:45 dholland Exp $");
6702ded532Smycroft #endif				/* not lint */
6861f28255Scgd 
693ea4a95cSchristos #include <stdlib.h>
7061f28255Scgd #include "hack.h"
713ea4a95cSchristos #include "extern.h"
7261f28255Scgd 
739b92b189Sdholland static void do_oname(struct obj *);
749b92b189Sdholland static char *xmonnam(struct monst *, int);
759b92b189Sdholland static char *lmonnam(struct monst *);
769b92b189Sdholland static char *visctrl(int);
779b92b189Sdholland 
7861f28255Scgd coord
getpos(int force,const char * goal)791fa8a9a6Sdholland getpos(int force, const char *goal)
803ea4a95cSchristos {
813ea4a95cSchristos 	int             cx, cy, i, c;
8261f28255Scgd 	coord           cc;
8361f28255Scgd 	pline("(For instructions type a ?)");
8461f28255Scgd 	cx = u.ux;
8561f28255Scgd 	cy = u.uy;
8661f28255Scgd 	curs(cx, cy + 2);
8761f28255Scgd 	while ((c = readchar()) != '.') {
883ea4a95cSchristos 		for (i = 0; i < 8; i++)
893ea4a95cSchristos 			if (sdir[i] == c) {
9061f28255Scgd 				if (1 <= cx + xdir[i] && cx + xdir[i] <= COLNO)
9161f28255Scgd 					cx += xdir[i];
9261f28255Scgd 				if (0 <= cy + ydir[i] && cy + ydir[i] <= ROWNO - 1)
9361f28255Scgd 					cy += ydir[i];
9461f28255Scgd 				goto nxtc;
9561f28255Scgd 			}
9661f28255Scgd 		if (c == '?') {
9761f28255Scgd 			pline("Use [hjkl] to move the cursor to %s.", goal);
9861f28255Scgd 			pline("Type a . when you are at the right place.");
9961f28255Scgd 		} else {
10061f28255Scgd 			pline("Unknown direction: '%s' (%s).",
10161f28255Scgd 			      visctrl(c),
10261f28255Scgd 			      force ? "use hjkl or ." : "aborted");
1033ea4a95cSchristos 			if (force)
1043ea4a95cSchristos 				goto nxtc;
10561f28255Scgd 			cc.x = -1;
10661f28255Scgd 			cc.y = 0;
10761f28255Scgd 			return (cc);
10861f28255Scgd 		}
10961f28255Scgd nxtc:		;
11061f28255Scgd 		curs(cx, cy + 2);
11161f28255Scgd 	}
11261f28255Scgd 	cc.x = cx;
11361f28255Scgd 	cc.y = cy;
11461f28255Scgd 	return (cc);
11561f28255Scgd }
11661f28255Scgd 
1173ea4a95cSchristos int
do_mname(void)1181fa8a9a6Sdholland do_mname(void)
1193ea4a95cSchristos {
12061f28255Scgd 	char            buf[BUFSZ];
12161f28255Scgd 	coord           cc;
122*d5b021c7Sdholland 	int             cx, cy;
123*d5b021c7Sdholland 	size_t lth;
1243c439f43Sdholland 	unsigned        i;
1253ea4a95cSchristos 	struct monst   *mtmp, *mtmp2;
12661f28255Scgd 	cc = getpos(0, "the monster you want to name");
12761f28255Scgd 	cx = cc.x;
12861f28255Scgd 	cy = cc.y;
1293ea4a95cSchristos 	if (cx < 0)
1303ea4a95cSchristos 		return (0);
13161f28255Scgd 	mtmp = m_at(cx, cy);
13261f28255Scgd 	if (!mtmp) {
13361f28255Scgd 		if (cx == u.ux && cy == u.uy)
13461f28255Scgd 			pline("This ugly monster is called %s and cannot be renamed.",
13561f28255Scgd 			      plname);
13661f28255Scgd 		else
13761f28255Scgd 			pline("There is no monster there.");
13861f28255Scgd 		return (1);
13961f28255Scgd 	}
14061f28255Scgd 	if (mtmp->mimic) {
14161f28255Scgd 		pline("I see no monster there.");
14261f28255Scgd 		return (1);
14361f28255Scgd 	}
14461f28255Scgd 	if (!cansee(cx, cy)) {
14561f28255Scgd 		pline("I cannot see a monster there.");
14661f28255Scgd 		return (1);
14761f28255Scgd 	}
14861f28255Scgd 	pline("What do you want to call %s? ", lmonnam(mtmp));
14961f28255Scgd 	getlin(buf);
15061f28255Scgd 	clrlin();
15161f28255Scgd 	if (!*buf || *buf == '\033')
15261f28255Scgd 		return (1);
15361f28255Scgd 	lth = strlen(buf) + 1;
15461f28255Scgd 	if (lth > 63) {
15561f28255Scgd 		buf[62] = 0;
15661f28255Scgd 		lth = 63;
15761f28255Scgd 	}
15861f28255Scgd 	mtmp2 = newmonst(mtmp->mxlth + lth);
15961f28255Scgd 	*mtmp2 = *mtmp;
16061f28255Scgd 	for (i = 0; i < mtmp->mxlth; i++)
16161f28255Scgd 		((char *) mtmp2->mextra)[i] = ((char *) mtmp->mextra)[i];
16261f28255Scgd 	mtmp2->mnamelth = lth;
16361f28255Scgd 	(void) strcpy(NAME(mtmp2), buf);
16461f28255Scgd 	replmon(mtmp, mtmp2);
16561f28255Scgd 	return (1);
16661f28255Scgd }
16761f28255Scgd 
16861f28255Scgd /*
16961f28255Scgd  * This routine changes the address of  obj . Be careful not to call it
17061f28255Scgd  * when there might be pointers around in unknown places. For now: only
17161f28255Scgd  * when  obj  is in the inventory.
17261f28255Scgd  */
1739b92b189Sdholland static void
do_oname(struct obj * obj)1741fa8a9a6Sdholland do_oname(struct obj *obj)
1753ea4a95cSchristos {
1763ea4a95cSchristos 	struct obj     *otmp, *otmp2;
177*d5b021c7Sdholland 	size_t lth;
17861f28255Scgd 	char            buf[BUFSZ];
17961f28255Scgd 	pline("What do you want to name %s? ", doname(obj));
18061f28255Scgd 	getlin(buf);
18161f28255Scgd 	clrlin();
18261f28255Scgd 	if (!*buf || *buf == '\033')
18361f28255Scgd 		return;
18461f28255Scgd 	lth = strlen(buf) + 1;
18561f28255Scgd 	if (lth > 63) {
18661f28255Scgd 		buf[62] = 0;
18761f28255Scgd 		lth = 63;
18861f28255Scgd 	}
18961f28255Scgd 	otmp2 = newobj(lth);
19061f28255Scgd 	*otmp2 = *obj;
19161f28255Scgd 	otmp2->onamelth = lth;
19261f28255Scgd 	(void) strcpy(ONAME(otmp2), buf);
19361f28255Scgd 
19461f28255Scgd 	setworn((struct obj *) 0, obj->owornmask);
19561f28255Scgd 	setworn(otmp2, otmp2->owornmask);
19661f28255Scgd 
1973ea4a95cSchristos 	/*
1983ea4a95cSchristos 	 * do freeinv(obj); etc. by hand in order to preserve the position of
1993ea4a95cSchristos 	 * this object in the inventory
2003ea4a95cSchristos 	 */
2013ea4a95cSchristos 	if (obj == invent)
2023ea4a95cSchristos 		invent = otmp2;
2033ea4a95cSchristos 	else
2043ea4a95cSchristos 		for (otmp = invent;; otmp = otmp->nobj) {
20561f28255Scgd 			if (!otmp)
20661f28255Scgd 				panic("Do_oname: cannot find obj.");
20761f28255Scgd 			if (otmp->nobj == obj) {
20861f28255Scgd 				otmp->nobj = otmp2;
20961f28255Scgd 				break;
21061f28255Scgd 			}
21161f28255Scgd 		}
2123ea4a95cSchristos #if 0
2133ea4a95cSchristos 	obfree(obj, otmp2);	/* now unnecessary: no pointers on bill */
2143ea4a95cSchristos #endif
2158e73b3adSdholland 	free(obj);	/* let us hope nobody else saved a pointer */
21661f28255Scgd }
21761f28255Scgd 
2183ea4a95cSchristos int
ddocall(void)2191fa8a9a6Sdholland ddocall(void)
22061f28255Scgd {
2213ea4a95cSchristos 	struct obj     *obj;
22261f28255Scgd 
22361f28255Scgd 	pline("Do you want to name an individual object? [ny] ");
22461f28255Scgd 	switch (readchar()) {
22561f28255Scgd 	case '\033':
22661f28255Scgd 		break;
22761f28255Scgd 	case 'y':
22861f28255Scgd 		obj = getobj("#", "name");
2293ea4a95cSchristos 		if (obj)
2303ea4a95cSchristos 			do_oname(obj);
23161f28255Scgd 		break;
23261f28255Scgd 	default:
23361f28255Scgd 		obj = getobj("?!=/", "call");
2343ea4a95cSchristos 		if (obj)
2353ea4a95cSchristos 			docall(obj);
23661f28255Scgd 	}
23761f28255Scgd 	return (0);
23861f28255Scgd }
23961f28255Scgd 
2403ea4a95cSchristos void
docall(struct obj * obj)2411fa8a9a6Sdholland docall(struct obj *obj)
24261f28255Scgd {
24361f28255Scgd 	char            buf[BUFSZ];
24461f28255Scgd 	struct obj      otemp;
2453ea4a95cSchristos 	char          **str1;
2463ea4a95cSchristos 	char           *str;
24761f28255Scgd 
24861f28255Scgd 	otemp = *obj;
24961f28255Scgd 	otemp.quan = 1;
25061f28255Scgd 	otemp.onamelth = 0;
25161f28255Scgd 	str = xname(&otemp);
2523ea4a95cSchristos 	pline("Call %s %s: ", strchr(vowels, *str) ? "an" : "a", str);
25361f28255Scgd 	getlin(buf);
25461f28255Scgd 	clrlin();
25561f28255Scgd 	if (!*buf || *buf == '\033')
25661f28255Scgd 		return;
25761f28255Scgd 	str = newstring(strlen(buf) + 1);
25861f28255Scgd 	(void) strcpy(str, buf);
25961f28255Scgd 	str1 = &(objects[obj->otyp].oc_uname);
2603ea4a95cSchristos 	if (*str1)
2613ea4a95cSchristos 		free(*str1);
26261f28255Scgd 	*str1 = str;
26361f28255Scgd }
26461f28255Scgd 
2659b92b189Sdholland static const char *const ghostnames[] = {
2669b92b189Sdholland 	/* these names should have length < PL_NSIZ */
26761f28255Scgd 	"adri", "andries", "andreas", "bert", "david", "dirk", "emile",
26861f28255Scgd 	"frans", "fred", "greg", "hether", "jay", "john", "jon", "kay",
26961f28255Scgd 	"kenny", "maud", "michiel", "mike", "peter", "robert", "ron",
27061f28255Scgd 	"tom", "wilmar"
27161f28255Scgd };
27261f28255Scgd 
2739b92b189Sdholland static char *
xmonnam(struct monst * mtmp,int vb)2741fa8a9a6Sdholland xmonnam(struct monst *mtmp, int vb)
2753ea4a95cSchristos {
27661f28255Scgd 	static char     buf[BUFSZ];	/* %% */
27761f28255Scgd 	if (mtmp->mnamelth && !vb) {
278907fca1bSdholland 		(void) strlcpy(buf, NAME(mtmp), sizeof(buf));
27961f28255Scgd 		return (buf);
28061f28255Scgd 	}
28161f28255Scgd 	switch (mtmp->data->mlet) {
28261f28255Scgd 	case ' ':
2833ea4a95cSchristos 		{
284ab8b6343Sjsm 			const char           *gn = (char *) mtmp->mextra;
28561f28255Scgd 			if (!*gn) {	/* might also look in scorefile */
28661f28255Scgd 				gn = ghostnames[rn2(SIZE(ghostnames))];
2873ea4a95cSchristos 				if (!rn2(2))
2883ea4a95cSchristos 					(void)
289165c915bSdholland 						strlcpy((char *) mtmp->mextra, !rn2(5) ? plname : gn, mtmp->mxlth);
29061f28255Scgd 			}
291907fca1bSdholland 			(void) snprintf(buf, sizeof(buf), "%s's ghost", gn);
29261f28255Scgd 		}
29361f28255Scgd 		break;
29461f28255Scgd 	case '@':
29561f28255Scgd 		if (mtmp->isshk) {
296907fca1bSdholland 			(void) strlcpy(buf, shkname(mtmp), sizeof(buf));
29761f28255Scgd 			break;
29861f28255Scgd 		}
299*d5b021c7Sdholland 		/* FALLTHROUGH */
30061f28255Scgd 	default:
301907fca1bSdholland 		(void) snprintf(buf, sizeof(buf), "the %s%s",
30261f28255Scgd 			       mtmp->minvis ? "invisible " : "",
30361f28255Scgd 			       mtmp->data->mname);
30461f28255Scgd 	}
30561f28255Scgd 	if (vb && mtmp->mnamelth) {
306907fca1bSdholland 		(void) strlcat(buf, " called ", sizeof(buf));
307907fca1bSdholland 		(void) strlcat(buf, NAME(mtmp), sizeof(buf));
30861f28255Scgd 	}
30961f28255Scgd 	return (buf);
31061f28255Scgd }
31161f28255Scgd 
3129b92b189Sdholland static char *
lmonnam(struct monst * mtmp)3131fa8a9a6Sdholland lmonnam(struct monst *mtmp)
3143ea4a95cSchristos {
31561f28255Scgd 	return (xmonnam(mtmp, 1));
31661f28255Scgd }
31761f28255Scgd 
31861f28255Scgd char           *
monnam(struct monst * mtmp)3191fa8a9a6Sdholland monnam(struct monst *mtmp)
3203ea4a95cSchristos {
32161f28255Scgd 	return (xmonnam(mtmp, 0));
32261f28255Scgd }
32361f28255Scgd 
32461f28255Scgd char           *
Monnam(struct monst * mtmp)3251fa8a9a6Sdholland Monnam(struct monst *mtmp)
3263ea4a95cSchristos {
3273ea4a95cSchristos 	char           *bp = monnam(mtmp);
3283ea4a95cSchristos 	if ('a' <= *bp && *bp <= 'z')
3293ea4a95cSchristos 		*bp += ('A' - 'a');
33061f28255Scgd 	return (bp);
33161f28255Scgd }
33261f28255Scgd 
33361f28255Scgd char           *
amonnam(struct monst * mtmp,const char * adj)3341fa8a9a6Sdholland amonnam(struct monst *mtmp, const char *adj)
33561f28255Scgd {
3363ea4a95cSchristos 	char           *bp = monnam(mtmp);
33761f28255Scgd 	static char     buf[BUFSZ];	/* %% */
33861f28255Scgd 
3393ea4a95cSchristos 	if (!strncmp(bp, "the ", 4))
3403ea4a95cSchristos 		bp += 4;
341907fca1bSdholland 	(void) snprintf(buf, sizeof(buf), "the %s %s", adj, bp);
34261f28255Scgd 	return (buf);
34361f28255Scgd }
34461f28255Scgd 
34561f28255Scgd char           *
Amonnam(struct monst * mtmp,const char * adj)3461fa8a9a6Sdholland Amonnam(struct monst *mtmp, const char *adj)
34761f28255Scgd {
3483ea4a95cSchristos 	char           *bp = amonnam(mtmp, adj);
34961f28255Scgd 
35061f28255Scgd 	*bp = 'T';
35161f28255Scgd 	return (bp);
35261f28255Scgd }
35361f28255Scgd 
35461f28255Scgd char           *
Xmonnam(struct monst * mtmp)3551fa8a9a6Sdholland Xmonnam(struct monst *mtmp)
3563ea4a95cSchristos {
3573ea4a95cSchristos 	char           *bp = Monnam(mtmp);
35861f28255Scgd 	if (!strncmp(bp, "The ", 4)) {
35961f28255Scgd 		bp += 2;
36061f28255Scgd 		*bp = 'A';
36161f28255Scgd 	}
36261f28255Scgd 	return (bp);
36361f28255Scgd }
36461f28255Scgd 
3659b92b189Sdholland static char *
visctrl(int c)3661fa8a9a6Sdholland visctrl(int c)
36761f28255Scgd {
36861f28255Scgd 	static char     ccc[3];
36961f28255Scgd 	if (c < 040) {
37061f28255Scgd 		ccc[0] = '^';
37161f28255Scgd 		ccc[1] = c + 0100;
37261f28255Scgd 		ccc[2] = 0;
37361f28255Scgd 	} else {
37461f28255Scgd 		ccc[0] = c;
37561f28255Scgd 		ccc[1] = 0;
37661f28255Scgd 	}
37761f28255Scgd 	return (ccc);
37861f28255Scgd }
379