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