Home | History | Annotate | Line # | Download | only in hack
hack.do_name.c revision 1.7
      1 /*	$NetBSD: hack.do_name.c,v 1.7 2008/01/28 06:55:41 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 (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.7 2008/01/28 06:55:41 dholland 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;
    120 	unsigned        i;
    121 	struct monst   *mtmp, *mtmp2;
    122 	cc = getpos(0, "the monster you want to name");
    123 	cx = cc.x;
    124 	cy = cc.y;
    125 	if (cx < 0)
    126 		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) strcpy(NAME(mtmp2), buf);
    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 void
    170 do_oname(obj)
    171 	struct obj     *obj;
    172 {
    173 	struct obj     *otmp, *otmp2;
    174 	int lth;
    175 	char            buf[BUFSZ];
    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) strcpy(ONAME(otmp2), buf);
    190 
    191 	setworn((struct obj *) 0, obj->owornmask);
    192 	setworn(otmp2, otmp2->owornmask);
    193 
    194 	/*
    195 	 * do freeinv(obj); etc. by hand in order to preserve the position of
    196 	 * this object in the inventory
    197 	 */
    198 	if (obj == invent)
    199 		invent = otmp2;
    200 	else
    201 		for (otmp = invent;; otmp = otmp->nobj) {
    202 			if (!otmp)
    203 				panic("Do_oname: cannot find obj.");
    204 			if (otmp->nobj == obj) {
    205 				otmp->nobj = otmp2;
    206 				break;
    207 			}
    208 		}
    209 #if 0
    210 	obfree(obj, otmp2);	/* now unnecessary: no pointers on bill */
    211 #endif
    212 	free((char *) obj);	/* let us hope nobody else saved a pointer */
    213 }
    214 
    215 int
    216 ddocall()
    217 {
    218 	struct obj     *obj;
    219 
    220 	pline("Do you want to name an individual object? [ny] ");
    221 	switch (readchar()) {
    222 	case '\033':
    223 		break;
    224 	case 'y':
    225 		obj = getobj("#", "name");
    226 		if (obj)
    227 			do_oname(obj);
    228 		break;
    229 	default:
    230 		obj = getobj("?!=/", "call");
    231 		if (obj)
    232 			docall(obj);
    233 	}
    234 	return (0);
    235 }
    236 
    237 void
    238 docall(obj)
    239 	struct obj     *obj;
    240 {
    241 	char            buf[BUFSZ];
    242 	struct obj      otemp;
    243 	char          **str1;
    244 	char           *str;
    245 
    246 	otemp = *obj;
    247 	otemp.quan = 1;
    248 	otemp.onamelth = 0;
    249 	str = xname(&otemp);
    250 	pline("Call %s %s: ", strchr(vowels, *str) ? "an" : "a", str);
    251 	getlin(buf);
    252 	clrlin();
    253 	if (!*buf || *buf == '\033')
    254 		return;
    255 	str = newstring(strlen(buf) + 1);
    256 	(void) strcpy(str, buf);
    257 	str1 = &(objects[obj->otyp].oc_uname);
    258 	if (*str1)
    259 		free(*str1);
    260 	*str1 = str;
    261 }
    262 
    263 const char *const ghostnames[] = {/* these names should have length < PL_NSIZ */
    264 	"adri", "andries", "andreas", "bert", "david", "dirk", "emile",
    265 	"frans", "fred", "greg", "hether", "jay", "john", "jon", "kay",
    266 	"kenny", "maud", "michiel", "mike", "peter", "robert", "ron",
    267 	"tom", "wilmar"
    268 };
    269 
    270 char           *
    271 xmonnam(mtmp, vb)
    272 	struct monst   *mtmp;
    273 	int             vb;
    274 {
    275 	static char     buf[BUFSZ];	/* %% */
    276 	if (mtmp->mnamelth && !vb) {
    277 		(void) strcpy(buf, NAME(mtmp));
    278 		return (buf);
    279 	}
    280 	switch (mtmp->data->mlet) {
    281 	case ' ':
    282 		{
    283 			const char           *gn = (char *) mtmp->mextra;
    284 			if (!*gn) {	/* might also look in scorefile */
    285 				gn = ghostnames[rn2(SIZE(ghostnames))];
    286 				if (!rn2(2))
    287 					(void)
    288 						strcpy((char *) mtmp->mextra, !rn2(5) ? plname : gn);
    289 			}
    290 			(void) sprintf(buf, "%s's ghost", gn);
    291 		}
    292 		break;
    293 	case '@':
    294 		if (mtmp->isshk) {
    295 			(void) strcpy(buf, shkname(mtmp));
    296 			break;
    297 		}
    298 		/* fall into next case */
    299 	default:
    300 		(void) sprintf(buf, "the %s%s",
    301 			       mtmp->minvis ? "invisible " : "",
    302 			       mtmp->data->mname);
    303 	}
    304 	if (vb && mtmp->mnamelth) {
    305 		(void) strcat(buf, " called ");
    306 		(void) strcat(buf, NAME(mtmp));
    307 	}
    308 	return (buf);
    309 }
    310 
    311 char           *
    312 lmonnam(mtmp)
    313 	struct monst   *mtmp;
    314 {
    315 	return (xmonnam(mtmp, 1));
    316 }
    317 
    318 char           *
    319 monnam(mtmp)
    320 	struct monst   *mtmp;
    321 {
    322 	return (xmonnam(mtmp, 0));
    323 }
    324 
    325 char           *
    326 Monnam(mtmp)
    327 	struct monst   *mtmp;
    328 {
    329 	char           *bp = monnam(mtmp);
    330 	if ('a' <= *bp && *bp <= 'z')
    331 		*bp += ('A' - 'a');
    332 	return (bp);
    333 }
    334 
    335 char           *
    336 amonnam(mtmp, adj)
    337 	struct monst   *mtmp;
    338 	const char           *adj;
    339 {
    340 	char           *bp = monnam(mtmp);
    341 	static char     buf[BUFSZ];	/* %% */
    342 
    343 	if (!strncmp(bp, "the ", 4))
    344 		bp += 4;
    345 	(void) sprintf(buf, "the %s %s", adj, bp);
    346 	return (buf);
    347 }
    348 
    349 char           *
    350 Amonnam(mtmp, adj)
    351 	struct monst   *mtmp;
    352 	const char           *adj;
    353 {
    354 	char           *bp = amonnam(mtmp, adj);
    355 
    356 	*bp = 'T';
    357 	return (bp);
    358 }
    359 
    360 char           *
    361 Xmonnam(mtmp)
    362 	struct monst   *mtmp;
    363 {
    364 	char           *bp = Monnam(mtmp);
    365 	if (!strncmp(bp, "The ", 4)) {
    366 		bp += 2;
    367 		*bp = 'A';
    368 	}
    369 	return (bp);
    370 }
    371 
    372 char           *
    373 visctrl(c)
    374 	char            c;
    375 {
    376 	static char     ccc[3];
    377 	if (c < 040) {
    378 		ccc[0] = '^';
    379 		ccc[1] = c + 0100;
    380 		ccc[2] = 0;
    381 	} else {
    382 		ccc[0] = c;
    383 		ccc[1] = 0;
    384 	}
    385 	return (ccc);
    386 }
    387