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