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