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