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