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