Home | History | Annotate | Line # | Download | only in hack
      1  1.13  dholland /*	$NetBSD: hack.do_name.c,v 1.13 2011/08/07 06:03:45 dholland Exp $	*/
      2   1.4  christos 
      3   1.2   mycroft /*
      4   1.6       jsm  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
      5   1.6       jsm  * Amsterdam
      6   1.6       jsm  * All rights reserved.
      7   1.6       jsm  *
      8   1.6       jsm  * Redistribution and use in source and binary forms, with or without
      9   1.6       jsm  * modification, are permitted provided that the following conditions are
     10   1.6       jsm  * met:
     11   1.6       jsm  *
     12   1.6       jsm  * - Redistributions of source code must retain the above copyright notice,
     13   1.6       jsm  * this list of conditions and the following disclaimer.
     14   1.6       jsm  *
     15   1.6       jsm  * - Redistributions in binary form must reproduce the above copyright
     16   1.6       jsm  * notice, this list of conditions and the following disclaimer in the
     17   1.6       jsm  * documentation and/or other materials provided with the distribution.
     18   1.6       jsm  *
     19   1.6       jsm  * - Neither the name of the Stichting Centrum voor Wiskunde en
     20   1.6       jsm  * Informatica, nor the names of its contributors may be used to endorse or
     21   1.6       jsm  * promote products derived from this software without specific prior
     22   1.6       jsm  * written permission.
     23   1.6       jsm  *
     24   1.6       jsm  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
     25   1.6       jsm  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     26   1.6       jsm  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     27   1.6       jsm  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
     28   1.6       jsm  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     29   1.6       jsm  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     30   1.6       jsm  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     31   1.6       jsm  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     32   1.6       jsm  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     33   1.6       jsm  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     34   1.6       jsm  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     35   1.6       jsm  */
     36   1.6       jsm 
     37   1.6       jsm /*
     38   1.6       jsm  * Copyright (c) 1982 Jay Fenlason <hack (at) gnu.org>
     39   1.6       jsm  * All rights reserved.
     40   1.6       jsm  *
     41   1.6       jsm  * Redistribution and use in source and binary forms, with or without
     42   1.6       jsm  * modification, are permitted provided that the following conditions
     43   1.6       jsm  * are met:
     44   1.6       jsm  * 1. Redistributions of source code must retain the above copyright
     45   1.6       jsm  *    notice, this list of conditions and the following disclaimer.
     46   1.6       jsm  * 2. Redistributions in binary form must reproduce the above copyright
     47   1.6       jsm  *    notice, this list of conditions and the following disclaimer in the
     48   1.6       jsm  *    documentation and/or other materials provided with the distribution.
     49   1.6       jsm  * 3. The name of the author may not be used to endorse or promote products
     50   1.6       jsm  *    derived from this software without specific prior written permission.
     51   1.6       jsm  *
     52   1.6       jsm  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
     53   1.6       jsm  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
     54   1.6       jsm  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
     55   1.6       jsm  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     56   1.6       jsm  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     57   1.6       jsm  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     58   1.6       jsm  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     59   1.6       jsm  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     60   1.6       jsm  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     61   1.6       jsm  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     62   1.2   mycroft  */
     63   1.2   mycroft 
     64   1.4  christos #include <sys/cdefs.h>
     65   1.2   mycroft #ifndef lint
     66  1.13  dholland __RCSID("$NetBSD: hack.do_name.c,v 1.13 2011/08/07 06:03:45 dholland Exp $");
     67   1.4  christos #endif				/* not lint */
     68   1.1       cgd 
     69   1.4  christos #include <stdlib.h>
     70   1.1       cgd #include "hack.h"
     71   1.4  christos #include "extern.h"
     72   1.1       cgd 
     73  1.11  dholland static void do_oname(struct obj *);
     74  1.11  dholland static char *xmonnam(struct monst *, int);
     75  1.11  dholland static char *lmonnam(struct monst *);
     76  1.11  dholland static char *visctrl(int);
     77  1.11  dholland 
     78   1.1       cgd coord
     79   1.8  dholland getpos(int force, const char *goal)
     80   1.4  christos {
     81   1.4  christos 	int             cx, cy, i, c;
     82   1.4  christos 	coord           cc;
     83   1.1       cgd 	pline("(For instructions type a ?)");
     84   1.1       cgd 	cx = u.ux;
     85   1.1       cgd 	cy = u.uy;
     86   1.4  christos 	curs(cx, cy + 2);
     87   1.4  christos 	while ((c = readchar()) != '.') {
     88   1.4  christos 		for (i = 0; i < 8; i++)
     89   1.4  christos 			if (sdir[i] == c) {
     90   1.4  christos 				if (1 <= cx + xdir[i] && cx + xdir[i] <= COLNO)
     91   1.4  christos 					cx += xdir[i];
     92   1.4  christos 				if (0 <= cy + ydir[i] && cy + ydir[i] <= ROWNO - 1)
     93   1.4  christos 					cy += ydir[i];
     94   1.4  christos 				goto nxtc;
     95   1.4  christos 			}
     96   1.4  christos 		if (c == '?') {
     97   1.1       cgd 			pline("Use [hjkl] to move the cursor to %s.", goal);
     98   1.1       cgd 			pline("Type a . when you are at the right place.");
     99   1.1       cgd 		} else {
    100   1.1       cgd 			pline("Unknown direction: '%s' (%s).",
    101   1.4  christos 			      visctrl(c),
    102   1.4  christos 			      force ? "use hjkl or ." : "aborted");
    103   1.4  christos 			if (force)
    104   1.4  christos 				goto nxtc;
    105   1.1       cgd 			cc.x = -1;
    106   1.1       cgd 			cc.y = 0;
    107   1.4  christos 			return (cc);
    108   1.1       cgd 		}
    109   1.4  christos nxtc:		;
    110   1.4  christos 		curs(cx, cy + 2);
    111   1.1       cgd 	}
    112   1.1       cgd 	cc.x = cx;
    113   1.1       cgd 	cc.y = cy;
    114   1.4  christos 	return (cc);
    115   1.1       cgd }
    116   1.1       cgd 
    117   1.4  christos int
    118   1.8  dholland do_mname(void)
    119   1.4  christos {
    120   1.4  christos 	char            buf[BUFSZ];
    121   1.4  christos 	coord           cc;
    122  1.13  dholland 	int             cx, cy;
    123  1.13  dholland 	size_t lth;
    124   1.7  dholland 	unsigned        i;
    125   1.4  christos 	struct monst   *mtmp, *mtmp2;
    126   1.1       cgd 	cc = getpos(0, "the monster you want to name");
    127   1.1       cgd 	cx = cc.x;
    128   1.1       cgd 	cy = cc.y;
    129   1.4  christos 	if (cx < 0)
    130   1.4  christos 		return (0);
    131   1.4  christos 	mtmp = m_at(cx, cy);
    132   1.4  christos 	if (!mtmp) {
    133   1.4  christos 		if (cx == u.ux && cy == u.uy)
    134   1.4  christos 			pline("This ugly monster is called %s and cannot be renamed.",
    135   1.4  christos 			      plname);
    136   1.4  christos 		else
    137   1.4  christos 			pline("There is no monster there.");
    138   1.4  christos 		return (1);
    139   1.4  christos 	}
    140   1.4  christos 	if (mtmp->mimic) {
    141   1.4  christos 		pline("I see no monster there.");
    142   1.4  christos 		return (1);
    143   1.4  christos 	}
    144   1.4  christos 	if (!cansee(cx, cy)) {
    145   1.4  christos 		pline("I cannot see a monster there.");
    146   1.4  christos 		return (1);
    147   1.1       cgd 	}
    148   1.1       cgd 	pline("What do you want to call %s? ", lmonnam(mtmp));
    149   1.1       cgd 	getlin(buf);
    150   1.1       cgd 	clrlin();
    151   1.4  christos 	if (!*buf || *buf == '\033')
    152   1.4  christos 		return (1);
    153   1.4  christos 	lth = strlen(buf) + 1;
    154   1.4  christos 	if (lth > 63) {
    155   1.1       cgd 		buf[62] = 0;
    156   1.1       cgd 		lth = 63;
    157   1.1       cgd 	}
    158   1.1       cgd 	mtmp2 = newmonst(mtmp->mxlth + lth);
    159   1.1       cgd 	*mtmp2 = *mtmp;
    160   1.4  christos 	for (i = 0; i < mtmp->mxlth; i++)
    161   1.1       cgd 		((char *) mtmp2->mextra)[i] = ((char *) mtmp->mextra)[i];
    162   1.1       cgd 	mtmp2->mnamelth = lth;
    163   1.1       cgd 	(void) strcpy(NAME(mtmp2), buf);
    164   1.4  christos 	replmon(mtmp, mtmp2);
    165   1.4  christos 	return (1);
    166   1.1       cgd }
    167   1.1       cgd 
    168   1.1       cgd /*
    169   1.1       cgd  * This routine changes the address of  obj . Be careful not to call it
    170   1.1       cgd  * when there might be pointers around in unknown places. For now: only
    171   1.1       cgd  * when  obj  is in the inventory.
    172   1.1       cgd  */
    173  1.11  dholland static void
    174   1.8  dholland do_oname(struct obj *obj)
    175   1.4  christos {
    176   1.4  christos 	struct obj     *otmp, *otmp2;
    177  1.13  dholland 	size_t lth;
    178   1.4  christos 	char            buf[BUFSZ];
    179   1.1       cgd 	pline("What do you want to name %s? ", doname(obj));
    180   1.1       cgd 	getlin(buf);
    181   1.1       cgd 	clrlin();
    182   1.4  christos 	if (!*buf || *buf == '\033')
    183   1.1       cgd 		return;
    184   1.4  christos 	lth = strlen(buf) + 1;
    185   1.4  christos 	if (lth > 63) {
    186   1.1       cgd 		buf[62] = 0;
    187   1.1       cgd 		lth = 63;
    188   1.1       cgd 	}
    189   1.1       cgd 	otmp2 = newobj(lth);
    190   1.1       cgd 	*otmp2 = *obj;
    191   1.1       cgd 	otmp2->onamelth = lth;
    192   1.1       cgd 	(void) strcpy(ONAME(otmp2), buf);
    193   1.1       cgd 
    194   1.1       cgd 	setworn((struct obj *) 0, obj->owornmask);
    195   1.1       cgd 	setworn(otmp2, otmp2->owornmask);
    196   1.1       cgd 
    197   1.4  christos 	/*
    198   1.4  christos 	 * do freeinv(obj); etc. by hand in order to preserve the position of
    199   1.4  christos 	 * this object in the inventory
    200   1.4  christos 	 */
    201   1.4  christos 	if (obj == invent)
    202   1.4  christos 		invent = otmp2;
    203   1.4  christos 	else
    204   1.4  christos 		for (otmp = invent;; otmp = otmp->nobj) {
    205   1.4  christos 			if (!otmp)
    206   1.4  christos 				panic("Do_oname: cannot find obj.");
    207   1.4  christos 			if (otmp->nobj == obj) {
    208   1.4  christos 				otmp->nobj = otmp2;
    209   1.4  christos 				break;
    210   1.4  christos 			}
    211   1.1       cgd 		}
    212   1.4  christos #if 0
    213   1.4  christos 	obfree(obj, otmp2);	/* now unnecessary: no pointers on bill */
    214   1.4  christos #endif
    215  1.12  dholland 	free(obj);	/* let us hope nobody else saved a pointer */
    216   1.1       cgd }
    217   1.1       cgd 
    218   1.4  christos int
    219   1.8  dholland ddocall(void)
    220   1.1       cgd {
    221   1.4  christos 	struct obj     *obj;
    222   1.1       cgd 
    223   1.1       cgd 	pline("Do you want to name an individual object? [ny] ");
    224   1.4  christos 	switch (readchar()) {
    225   1.1       cgd 	case '\033':
    226   1.1       cgd 		break;
    227   1.1       cgd 	case 'y':
    228   1.1       cgd 		obj = getobj("#", "name");
    229   1.4  christos 		if (obj)
    230   1.4  christos 			do_oname(obj);
    231   1.1       cgd 		break;
    232   1.1       cgd 	default:
    233   1.1       cgd 		obj = getobj("?!=/", "call");
    234   1.4  christos 		if (obj)
    235   1.4  christos 			docall(obj);
    236   1.1       cgd 	}
    237   1.4  christos 	return (0);
    238   1.1       cgd }
    239   1.1       cgd 
    240   1.4  christos void
    241   1.8  dholland docall(struct obj *obj)
    242   1.1       cgd {
    243   1.4  christos 	char            buf[BUFSZ];
    244   1.4  christos 	struct obj      otemp;
    245   1.4  christos 	char          **str1;
    246   1.4  christos 	char           *str;
    247   1.1       cgd 
    248   1.1       cgd 	otemp = *obj;
    249   1.1       cgd 	otemp.quan = 1;
    250   1.1       cgd 	otemp.onamelth = 0;
    251   1.1       cgd 	str = xname(&otemp);
    252   1.4  christos 	pline("Call %s %s: ", strchr(vowels, *str) ? "an" : "a", str);
    253   1.1       cgd 	getlin(buf);
    254   1.1       cgd 	clrlin();
    255   1.4  christos 	if (!*buf || *buf == '\033')
    256   1.1       cgd 		return;
    257   1.4  christos 	str = newstring(strlen(buf) + 1);
    258   1.4  christos 	(void) strcpy(str, buf);
    259   1.1       cgd 	str1 = &(objects[obj->otyp].oc_uname);
    260   1.4  christos 	if (*str1)
    261   1.4  christos 		free(*str1);
    262   1.1       cgd 	*str1 = str;
    263   1.1       cgd }
    264   1.1       cgd 
    265  1.11  dholland static const char *const ghostnames[] = {
    266  1.11  dholland 	/* these names should have length < PL_NSIZ */
    267   1.1       cgd 	"adri", "andries", "andreas", "bert", "david", "dirk", "emile",
    268   1.1       cgd 	"frans", "fred", "greg", "hether", "jay", "john", "jon", "kay",
    269   1.1       cgd 	"kenny", "maud", "michiel", "mike", "peter", "robert", "ron",
    270   1.1       cgd 	"tom", "wilmar"
    271   1.1       cgd };
    272   1.1       cgd 
    273  1.11  dholland static char *
    274   1.8  dholland xmonnam(struct monst *mtmp, int vb)
    275   1.4  christos {
    276   1.4  christos 	static char     buf[BUFSZ];	/* %% */
    277   1.4  christos 	if (mtmp->mnamelth && !vb) {
    278   1.9  dholland 		(void) strlcpy(buf, NAME(mtmp), sizeof(buf));
    279   1.4  christos 		return (buf);
    280   1.1       cgd 	}
    281   1.4  christos 	switch (mtmp->data->mlet) {
    282   1.1       cgd 	case ' ':
    283   1.4  christos 		{
    284   1.5       jsm 			const char           *gn = (char *) mtmp->mextra;
    285   1.4  christos 			if (!*gn) {	/* might also look in scorefile */
    286   1.4  christos 				gn = ghostnames[rn2(SIZE(ghostnames))];
    287   1.4  christos 				if (!rn2(2))
    288   1.4  christos 					(void)
    289  1.10  dholland 						strlcpy((char *) mtmp->mextra, !rn2(5) ? plname : gn, mtmp->mxlth);
    290   1.4  christos 			}
    291   1.9  dholland 			(void) snprintf(buf, sizeof(buf), "%s's ghost", gn);
    292   1.1       cgd 		}
    293   1.1       cgd 		break;
    294   1.1       cgd 	case '@':
    295   1.4  christos 		if (mtmp->isshk) {
    296   1.9  dholland 			(void) strlcpy(buf, shkname(mtmp), sizeof(buf));
    297   1.1       cgd 			break;
    298   1.1       cgd 		}
    299  1.13  dholland 		/* FALLTHROUGH */
    300   1.1       cgd 	default:
    301   1.9  dholland 		(void) snprintf(buf, sizeof(buf), "the %s%s",
    302   1.4  christos 			       mtmp->minvis ? "invisible " : "",
    303   1.4  christos 			       mtmp->data->mname);
    304   1.1       cgd 	}
    305   1.4  christos 	if (vb && mtmp->mnamelth) {
    306   1.9  dholland 		(void) strlcat(buf, " called ", sizeof(buf));
    307   1.9  dholland 		(void) strlcat(buf, NAME(mtmp), sizeof(buf));
    308   1.1       cgd 	}
    309   1.4  christos 	return (buf);
    310   1.1       cgd }
    311   1.1       cgd 
    312  1.11  dholland static char *
    313   1.8  dholland lmonnam(struct monst *mtmp)
    314   1.4  christos {
    315   1.4  christos 	return (xmonnam(mtmp, 1));
    316   1.1       cgd }
    317   1.1       cgd 
    318   1.4  christos char           *
    319   1.8  dholland monnam(struct monst *mtmp)
    320   1.4  christos {
    321   1.4  christos 	return (xmonnam(mtmp, 0));
    322   1.1       cgd }
    323   1.1       cgd 
    324   1.4  christos char           *
    325   1.8  dholland Monnam(struct monst *mtmp)
    326   1.4  christos {
    327   1.4  christos 	char           *bp = monnam(mtmp);
    328   1.4  christos 	if ('a' <= *bp && *bp <= 'z')
    329   1.4  christos 		*bp += ('A' - 'a');
    330   1.4  christos 	return (bp);
    331   1.1       cgd }
    332   1.1       cgd 
    333   1.4  christos char           *
    334   1.8  dholland amonnam(struct monst *mtmp, const char *adj)
    335   1.1       cgd {
    336   1.4  christos 	char           *bp = monnam(mtmp);
    337   1.4  christos 	static char     buf[BUFSZ];	/* %% */
    338   1.1       cgd 
    339   1.4  christos 	if (!strncmp(bp, "the ", 4))
    340   1.4  christos 		bp += 4;
    341   1.9  dholland 	(void) snprintf(buf, sizeof(buf), "the %s %s", adj, bp);
    342   1.4  christos 	return (buf);
    343   1.1       cgd }
    344   1.1       cgd 
    345   1.4  christos char           *
    346   1.8  dholland Amonnam(struct monst *mtmp, const char *adj)
    347   1.1       cgd {
    348   1.4  christos 	char           *bp = amonnam(mtmp, adj);
    349   1.1       cgd 
    350   1.1       cgd 	*bp = 'T';
    351   1.4  christos 	return (bp);
    352   1.1       cgd }
    353   1.1       cgd 
    354   1.4  christos char           *
    355   1.8  dholland Xmonnam(struct monst *mtmp)
    356   1.4  christos {
    357   1.4  christos 	char           *bp = Monnam(mtmp);
    358   1.4  christos 	if (!strncmp(bp, "The ", 4)) {
    359   1.1       cgd 		bp += 2;
    360   1.1       cgd 		*bp = 'A';
    361   1.1       cgd 	}
    362   1.4  christos 	return (bp);
    363   1.1       cgd }
    364   1.1       cgd 
    365  1.11  dholland static char *
    366   1.8  dholland visctrl(int c)
    367   1.1       cgd {
    368   1.4  christos 	static char     ccc[3];
    369   1.4  christos 	if (c < 040) {
    370   1.1       cgd 		ccc[0] = '^';
    371   1.1       cgd 		ccc[1] = c + 0100;
    372   1.1       cgd 		ccc[2] = 0;
    373   1.1       cgd 	} else {
    374   1.1       cgd 		ccc[0] = c;
    375   1.1       cgd 		ccc[1] = 0;
    376   1.1       cgd 	}
    377   1.4  christos 	return (ccc);
    378   1.1       cgd }
    379