xref: /netbsd-src/games/hack/hack.do_name.c (revision 76dfffe33547c37f8bdd446e3e4ab0f3c16cea4b)
1 /*
2  * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
3  */
4 
5 #ifndef lint
6 static char rcsid[] = "$NetBSD: hack.do_name.c,v 1.3 1995/03/23 08:29:56 cgd Exp $";
7 #endif /* not lint */
8 
9 #include "hack.h"
10 #include <stdio.h>
11 extern char plname[];
12 
13 coord
14 getpos(force,goal) int force; char *goal; {
15 register cx,cy,i,c;
16 extern char sdir[];		/* defined in hack.c */
17 extern schar xdir[], ydir[];	/* idem */
18 extern char *visctrl();		/* see below */
19 coord cc;
20 	pline("(For instructions type a ?)");
21 	cx = u.ux;
22 	cy = u.uy;
23 	curs(cx,cy+2);
24 	while((c = readchar()) != '.'){
25 		for(i=0; i<8; i++) if(sdir[i] == c){
26 			if(1 <= cx + xdir[i] && cx + xdir[i] <= COLNO)
27 				cx += xdir[i];
28 			if(0 <= cy + ydir[i] && cy + ydir[i] <= ROWNO-1)
29 				cy += ydir[i];
30 			goto nxtc;
31 		}
32 		if(c == '?'){
33 			pline("Use [hjkl] to move the cursor to %s.", goal);
34 			pline("Type a . when you are at the right place.");
35 		} else {
36 			pline("Unknown direction: '%s' (%s).",
37 				visctrl(c),
38 				force ? "use hjkl or ." : "aborted");
39 			if(force) goto nxtc;
40 			cc.x = -1;
41 			cc.y = 0;
42 			return(cc);
43 		}
44 	nxtc:	;
45 		curs(cx,cy+2);
46 	}
47 	cc.x = cx;
48 	cc.y = cy;
49 	return(cc);
50 }
51 
52 do_mname(){
53 char buf[BUFSZ];
54 coord cc;
55 register int cx,cy,lth,i;
56 register struct monst *mtmp, *mtmp2;
57 extern char *lmonnam();
58 	cc = getpos(0, "the monster you want to name");
59 	cx = cc.x;
60 	cy = cc.y;
61 	if(cx < 0) return(0);
62 	mtmp = m_at(cx,cy);
63 	if(!mtmp){
64 	    if(cx == u.ux && cy == u.uy)
65 		pline("This ugly monster is called %s and cannot be renamed.",
66 		    plname);
67 	    else
68 		pline("There is no monster there.");
69 	    return(1);
70 	}
71 	if(mtmp->mimic){
72 	    pline("I see no monster there.");
73 	    return(1);
74 	}
75 	if(!cansee(cx,cy)) {
76 	    pline("I cannot see a monster there.");
77 	    return(1);
78 	}
79 	pline("What do you want to call %s? ", lmonnam(mtmp));
80 	getlin(buf);
81 	clrlin();
82 	if(!*buf || *buf == '\033')
83 		return(1);
84 	lth = strlen(buf)+1;
85 	if(lth > 63){
86 		buf[62] = 0;
87 		lth = 63;
88 	}
89 	mtmp2 = newmonst(mtmp->mxlth + lth);
90 	*mtmp2 = *mtmp;
91 	for(i=0; i<mtmp->mxlth; i++)
92 		((char *) mtmp2->mextra)[i] = ((char *) mtmp->mextra)[i];
93 	mtmp2->mnamelth = lth;
94 	(void) strcpy(NAME(mtmp2), buf);
95 	replmon(mtmp,mtmp2);
96 	return(1);
97 }
98 
99 /*
100  * This routine changes the address of  obj . Be careful not to call it
101  * when there might be pointers around in unknown places. For now: only
102  * when  obj  is in the inventory.
103  */
104 do_oname(obj) register struct obj *obj; {
105 register struct obj *otmp, *otmp2;
106 register lth;
107 char buf[BUFSZ];
108 	pline("What do you want to name %s? ", doname(obj));
109 	getlin(buf);
110 	clrlin();
111 	if(!*buf || *buf == '\033')
112 		return;
113 	lth = strlen(buf)+1;
114 	if(lth > 63){
115 		buf[62] = 0;
116 		lth = 63;
117 	}
118 	otmp2 = newobj(lth);
119 	*otmp2 = *obj;
120 	otmp2->onamelth = lth;
121 	(void) strcpy(ONAME(otmp2), buf);
122 
123 	setworn((struct obj *) 0, obj->owornmask);
124 	setworn(otmp2, otmp2->owornmask);
125 
126 	/* do freeinv(obj); etc. by hand in order to preserve
127 	   the position of this object in the inventory */
128 	if(obj == invent) invent = otmp2;
129 	else for(otmp = invent; ; otmp = otmp->nobj){
130 		if(!otmp)
131 			panic("Do_oname: cannot find obj.");
132 		if(otmp->nobj == obj){
133 			otmp->nobj = otmp2;
134 			break;
135 		}
136 	}
137 	/* obfree(obj, otmp2);	/* now unnecessary: no pointers on bill */
138 	free((char *) obj);	/* let us hope nobody else saved a pointer */
139 }
140 
141 ddocall()
142 {
143 	register struct obj *obj;
144 
145 	pline("Do you want to name an individual object? [ny] ");
146 	switch(readchar()) {
147 	case '\033':
148 		break;
149 	case 'y':
150 		obj = getobj("#", "name");
151 		if(obj) do_oname(obj);
152 		break;
153 	default:
154 		obj = getobj("?!=/", "call");
155 		if(obj) docall(obj);
156 	}
157 	return(0);
158 }
159 
160 docall(obj)
161 register struct obj *obj;
162 {
163 	char buf[BUFSZ];
164 	struct obj otemp;
165 	register char **str1;
166 	extern char *xname();
167 	register char *str;
168 
169 	otemp = *obj;
170 	otemp.quan = 1;
171 	otemp.onamelth = 0;
172 	str = xname(&otemp);
173 	pline("Call %s %s: ", index(vowels,*str) ? "an" : "a", str);
174 	getlin(buf);
175 	clrlin();
176 	if(!*buf || *buf == '\033')
177 		return;
178 	str = newstring(strlen(buf)+1);
179 	(void) strcpy(str,buf);
180 	str1 = &(objects[obj->otyp].oc_uname);
181 	if(*str1) free(*str1);
182 	*str1 = str;
183 }
184 
185 char *ghostnames[] = {		/* these names should have length < PL_NSIZ */
186 	"adri", "andries", "andreas", "bert", "david", "dirk", "emile",
187 	"frans", "fred", "greg", "hether", "jay", "john", "jon", "kay",
188 	"kenny", "maud", "michiel", "mike", "peter", "robert", "ron",
189 	"tom", "wilmar"
190 };
191 
192 char *
193 xmonnam(mtmp, vb) register struct monst *mtmp; int vb; {
194 static char buf[BUFSZ];		/* %% */
195 extern char *shkname();
196 	if(mtmp->mnamelth && !vb) {
197 		(void) strcpy(buf, NAME(mtmp));
198 		return(buf);
199 	}
200 	switch(mtmp->data->mlet) {
201 	case ' ':
202 		{ register char *gn = (char *) mtmp->mextra;
203 		  if(!*gn) {		/* might also look in scorefile */
204 		    gn = ghostnames[rn2(SIZE(ghostnames))];
205 		    if(!rn2(2)) (void)
206 		      strcpy((char *) mtmp->mextra, !rn2(5) ? plname : gn);
207 		  }
208 		  (void) sprintf(buf, "%s's ghost", gn);
209 		}
210 		break;
211 	case '@':
212 		if(mtmp->isshk) {
213 			(void) strcpy(buf, shkname(mtmp));
214 			break;
215 		}
216 		/* fall into next case */
217 	default:
218 		(void) sprintf(buf, "the %s%s",
219 			mtmp->minvis ? "invisible " : "",
220 			mtmp->data->mname);
221 	}
222 	if(vb && mtmp->mnamelth) {
223 		(void) strcat(buf, " called ");
224 		(void) strcat(buf, NAME(mtmp));
225 	}
226 	return(buf);
227 }
228 
229 char *
230 lmonnam(mtmp) register struct monst *mtmp; {
231 	return(xmonnam(mtmp, 1));
232 }
233 
234 char *
235 monnam(mtmp) register struct monst *mtmp; {
236 	return(xmonnam(mtmp, 0));
237 }
238 
239 char *
240 Monnam(mtmp) register struct monst *mtmp; {
241 register char *bp = monnam(mtmp);
242 	if('a' <= *bp && *bp <= 'z') *bp += ('A' - 'a');
243 	return(bp);
244 }
245 
246 char *
247 amonnam(mtmp,adj)
248 register struct monst *mtmp;
249 register char *adj;
250 {
251 	register char *bp = monnam(mtmp);
252 	static char buf[BUFSZ];		/* %% */
253 
254 	if(!strncmp(bp, "the ", 4)) bp += 4;
255 	(void) sprintf(buf, "the %s %s", adj, bp);
256 	return(buf);
257 }
258 
259 char *
260 Amonnam(mtmp, adj)
261 register struct monst *mtmp;
262 register char *adj;
263 {
264 	register char *bp = amonnam(mtmp,adj);
265 
266 	*bp = 'T';
267 	return(bp);
268 }
269 
270 char *
271 Xmonnam(mtmp) register struct monst *mtmp; {
272 register char *bp = Monnam(mtmp);
273 	if(!strncmp(bp, "The ", 4)) {
274 		bp += 2;
275 		*bp = 'A';
276 	}
277 	return(bp);
278 }
279 
280 char *
281 visctrl(c)
282 char c;
283 {
284 static char ccc[3];
285 	if(c < 040) {
286 		ccc[0] = '^';
287 		ccc[1] = c + 0100;
288 		ccc[2] = 0;
289 	} else {
290 		ccc[0] = c;
291 		ccc[1] = 0;
292 	}
293 	return(ccc);
294 }
295