Split out wizmode monpolycontrol part

This commit is contained in:
Pasi Kallinen
2023-12-08 08:32:07 +02:00
parent 4140a0023c
commit d2ae6fd5d2

157
src/mon.c
View File

@@ -30,6 +30,7 @@ static int pick_animal(void);
static int pickvampshape(struct monst *);
static boolean isspecmon(struct monst *);
static boolean validspecmon(struct monst *, int);
static int wiz_force_cham_form(struct monst *);
static struct permonst *accept_newcham_form(struct monst *, int);
static void kill_eggs(struct obj *);
static void pacify_guard(struct monst *);
@@ -4623,6 +4624,85 @@ validvamp(struct monst* mon, int* mndx_p, int monclass)
return (boolean) (*mndx_p != NON_PM);
}
static int
wiz_force_cham_form(struct monst *mon)
{
char pprompt[BUFSZ], parttwo[QBUFSZ], buf[BUFSZ], prevbuf[BUFSZ];
int monclass, len, tryct, mndx = NON_PM;
/* construct prompt in pieces */
Sprintf(pprompt, "Change %s", noit_mon_nam(mon));
Sprintf(parttwo, " @ %s into what?",
coord_desc((int) mon->mx, (int) mon->my, buf,
(iflags.getpos_coords != GPCOORDS_NONE)
? iflags.getpos_coords : GPCOORDS_MAP));
/* combine the two parts, not exceeding QBUFSZ-1 in overall length;
if combined length is too long it has to be due to monster's
name so we'll chop enough of that off to fit the second part */
if ((len = (int) strlen(pprompt) + (int) strlen(parttwo)) >= QBUFSZ)
/* strlen(parttwo) is less than QBUFSZ/2 so strlen(pprompt) is
more than QBUFSZ/2 and excess amount being truncated can't
exceed pprompt's length and back up to before &pprompt[0]) */
*(eos(pprompt) - (len - (QBUFSZ - 1))) = '\0';
Strcat(pprompt, parttwo);
buf[0] = prevbuf[0] = '\0'; /* clear buffer for EDIT_GETLIN */
#define TRYLIMIT 5
tryct = TRYLIMIT;
do {
if (tryct == TRYLIMIT - 1) { /* first retry */
/* change "into what?" to "into what kind of monster?" */
if (strlen(pprompt) + sizeof " kind of monster" - 1 < QBUFSZ)
Strcpy(eos(pprompt) - 1, " kind of monster?");
}
#undef TRYLIMIT
monclass = 0;
getlin(pprompt, buf);
mungspaces(buf);
/* for ESC, take form selected above (might be NON_PM) */
if (*buf == '\033')
break;
/* for "*", use NON_PM to pick an arbitrary shape below */
if (!strcmp(buf, "*") || !strcmpi(buf, "random")) {
mndx = NON_PM;
break;
}
mndx = name_to_mon(buf, (int *) 0);
if (mndx == NON_PM) {
/* didn't get a type, so check whether it's a class
(single letter or text match with def_monsyms[]) */
monclass = name_to_monclass(buf, &mndx);
if (monclass && mndx == NON_PM)
mndx = mkclass_poly(monclass);
}
if (mndx >= LOW_PM) {
/* got a specific type of monster; use it if we can */
if (validvamp(mon, &mndx, monclass))
break;
/* can't; revert to random in case we exhaust tryct */
mndx = NON_PM;
}
pline("It can't become that.");
#ifdef EDIT_GETLIN
/* EDIT_GETLIN preloads the input buffer with the previous
response but we shouldn't just keep repeating that if player
leaves it unchanged; affects retry for empty input too */
if (!strcmp(buf, prevbuf))
Strcpy(buf, "random");
Strcpy(prevbuf, buf);
#else
nhUse(prevbuf);
#endif
} while (--tryct > 0);
if (!tryct)
pline1(thats_enough_tries);
if (is_vampshifter(mon) && !validvamp(mon, &mndx, monclass))
mndx = pickvampshape(mon); /* don't resort to arbitrary */
return mndx;
}
int
select_newcham_form(struct monst* mon)
{
@@ -4676,81 +4756,8 @@ select_newcham_form(struct monst* mon)
}
/* for debugging: allow control of polymorphed monster */
if (wizard && iflags.mon_polycontrol) {
char pprompt[BUFSZ], parttwo[QBUFSZ], buf[BUFSZ], prevbuf[BUFSZ];
int monclass, len;
/* construct prompt in pieces */
Sprintf(pprompt, "Change %s", noit_mon_nam(mon));
Sprintf(parttwo, " @ %s into what?",
coord_desc((int) mon->mx, (int) mon->my, buf,
(iflags.getpos_coords != GPCOORDS_NONE)
? iflags.getpos_coords : GPCOORDS_MAP));
/* combine the two parts, not exceeding QBUFSZ-1 in overall length;
if combined length is too long it has to be due to monster's
name so we'll chop enough of that off to fit the second part */
if ((len = (int) strlen(pprompt) + (int) strlen(parttwo)) >= QBUFSZ)
/* strlen(parttwo) is less than QBUFSZ/2 so strlen(pprompt) is
more than QBUFSZ/2 and excess amount being truncated can't
exceed pprompt's length and back up to before &pprompt[0]) */
*(eos(pprompt) - (len - (QBUFSZ - 1))) = '\0';
Strcat(pprompt, parttwo);
buf[0] = prevbuf[0] = '\0'; /* clear buffer for EDIT_GETLIN */
#define TRYLIMIT 5
tryct = TRYLIMIT;
do {
if (tryct == TRYLIMIT - 1) { /* first retry */
/* change "into what?" to "into what kind of monster?" */
if (strlen(pprompt) + sizeof " kind of monster" - 1 < QBUFSZ)
Strcpy(eos(pprompt) - 1, " kind of monster?");
}
#undef TRYLIMIT
monclass = 0;
getlin(pprompt, buf);
mungspaces(buf);
/* for ESC, take form selected above (might be NON_PM) */
if (*buf == '\033')
break;
/* for "*", use NON_PM to pick an arbitrary shape below */
if (!strcmp(buf, "*") || !strcmpi(buf, "random")) {
mndx = NON_PM;
break;
}
mndx = name_to_mon(buf, (int *) 0);
if (mndx == NON_PM) {
/* didn't get a type, so check whether it's a class
(single letter or text match with def_monsyms[]) */
monclass = name_to_monclass(buf, &mndx);
if (monclass && mndx == NON_PM)
mndx = mkclass_poly(monclass);
}
if (mndx >= LOW_PM) {
/* got a specific type of monster; use it if we can */
if (validvamp(mon, &mndx, monclass))
break;
/* can't; revert to random in case we exhaust tryct */
mndx = NON_PM;
}
pline("It can't become that.");
#ifdef EDIT_GETLIN
/* EDIT_GETLIN preloads the input buffer with the previous
response but we shouldn't just keep repeating that if player
leaves it unchanged; affects retry for empty input too */
if (!strcmp(buf, prevbuf))
Strcpy(buf, "random");
Strcpy(prevbuf, buf);
#else
nhUse(prevbuf);
#endif
} while (--tryct > 0);
if (!tryct)
pline1(thats_enough_tries);
if (is_vampshifter(mon) && !validvamp(mon, &mndx, monclass))
mndx = pickvampshape(mon); /* don't resort to arbitrary */
}
if (wizard && iflags.mon_polycontrol)
mndx = wiz_force_cham_form(mon);
/* if no form was specified above, pick one at random now */
if (mndx == NON_PM) {