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