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