| 5075 | } |
| 5076 | |
| 5077 | staticfn int |
| 5078 | wiz_force_cham_form(struct monst *mon) |
| 5079 | { |
| 5080 | char pprompt[BUFSZ], parttwo[QBUFSZ], buf[BUFSZ], prevbuf[BUFSZ]; |
| 5081 | int monclass, len, tryct, mndx = NON_PM; |
| 5082 | |
| 5083 | /* construct prompt in pieces */ |
| 5084 | Sprintf(pprompt, "Change %s", noit_mon_nam(mon)); |
| 5085 | Sprintf(parttwo, " @ %s into what?", |
| 5086 | coord_desc((int) mon->mx, (int) mon->my, buf, |
| 5087 | (iflags.getpos_coords != GPCOORDS_NONE) |
| 5088 | ? iflags.getpos_coords : GPCOORDS_MAP)); |
| 5089 | /* combine the two parts, not exceeding QBUFSZ-1 in overall length; |
| 5090 | if combined length is too long it has to be due to monster's |
| 5091 | name so we'll chop enough of that off to fit the second part */ |
| 5092 | if ((len = (int) strlen(pprompt) + (int) strlen(parttwo)) >= QBUFSZ) |
| 5093 | /* strlen(parttwo) is less than QBUFSZ/2 so strlen(pprompt) is |
| 5094 | more than QBUFSZ/2 and excess amount being truncated can't |
| 5095 | exceed pprompt's length and back up to before &pprompt[0]) */ |
| 5096 | *(eos(pprompt) - (len - (QBUFSZ - 1))) = '\0'; |
| 5097 | Strcat(pprompt, parttwo); |
| 5098 | |
| 5099 | buf[0] = prevbuf[0] = '\0'; /* clear buffer for EDIT_GETLIN */ |
| 5100 | #define TRYLIMIT 5 |
| 5101 | tryct = TRYLIMIT; |
| 5102 | do { |
| 5103 | if (tryct == TRYLIMIT - 1) { /* first retry */ |
| 5104 | /* change "into what?" to "into what kind of monster?" */ |
| 5105 | if (strlen(pprompt) + sizeof " kind of monster" - 1 < QBUFSZ) |
| 5106 | Strcpy(eos(pprompt) - 1, " kind of monster?"); |
| 5107 | } |
| 5108 | #undef TRYLIMIT |
| 5109 | monclass = 0; |
| 5110 | getlin(pprompt, buf); |
| 5111 | mungspaces(buf); |
| 5112 | /* for ESC, take form selected above (might be NON_PM) */ |
| 5113 | if (*buf == '\033') |
| 5114 | break; |
| 5115 | /* for "*", use NON_PM to pick an arbitrary shape below */ |
| 5116 | if (!strcmp(buf, "*") || !strcmpi(buf, "random")) { |
| 5117 | mndx = NON_PM; |
| 5118 | break; |
| 5119 | } |
| 5120 | mndx = name_to_mon(buf, (int *) 0); |
| 5121 | if (mndx == NON_PM) { |
| 5122 | /* didn't get a type, so check whether it's a class |
| 5123 | (single letter or text match with def_monsyms[]) */ |
| 5124 | monclass = name_to_monclass(buf, &mndx); |
| 5125 | if (monclass && mndx == NON_PM) |
| 5126 | mndx = mkclass_poly(monclass); |
| 5127 | } |
| 5128 | if (ismnum(mndx)) { |
| 5129 | /* got a specific type of monster; use it if we can */ |
| 5130 | if (validvamp(mon, &mndx, monclass)) |
| 5131 | break; |
| 5132 | /* can't; revert to random in case we exhaust tryct */ |
| 5133 | mndx = NON_PM; |
| 5134 | } |
no test coverage detected