more #U1233 - specifying mon class instead type for polyself (trunk only)
Another item from the Dec'04 report sent in by <email deleted>. When prompted for a type of monster to polymorph
into, giving a monster class description like "dog or other canine" (or
single letter like 'd'), triggered "I've never heard of such monsters".
Instead of adjusting the message, this chooses a member from the class.
I put this into the fixes file as a new feature.
This commit is contained in:
@@ -311,6 +311,7 @@ improved container interface
|
||||
acid can destroy iron bars
|
||||
OPTIONS=playmode:normal|explore|debug to choose mode without command-line
|
||||
score bonus for ascending is reduced or denied for changing alignment
|
||||
player can give a monster class when asked for type of monster to poly into
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific New Features
|
||||
|
||||
@@ -1050,6 +1050,7 @@ E boolean FDECL(create_critters, (int,struct permonst *,BOOLEAN_P));
|
||||
E struct permonst *NDECL(rndmonst);
|
||||
E void FDECL(reset_rndmonst, (int));
|
||||
E struct permonst *FDECL(mkclass, (CHAR_P,int));
|
||||
E int FDECL(mkclass_poly, (int));
|
||||
E int FDECL(adj_lev, (struct permonst *));
|
||||
E struct permonst *FDECL(grow_up, (struct monst *,struct monst *));
|
||||
E int FDECL(mongets, (struct monst *,int));
|
||||
|
||||
@@ -1415,6 +1415,37 @@ int spc;
|
||||
return(&mons[first]);
|
||||
}
|
||||
|
||||
/* like mkclass(), but excludes difficulty considerations; used when
|
||||
player with polycontrol picks a class instead of a specific type;
|
||||
genocided types are avoided but extinct ones are acceptable */
|
||||
int
|
||||
mkclass_poly(class)
|
||||
int class;
|
||||
{
|
||||
register int first, last, num = 0;
|
||||
|
||||
for (first = LOW_PM; first < SPECIAL_PM; first++)
|
||||
if (mons[first].mlet == class) break;
|
||||
if (first == SPECIAL_PM) return NON_PM;
|
||||
|
||||
for (last = first;
|
||||
last < SPECIAL_PM && mons[last].mlet == class; last++)
|
||||
if (!(mvitals[last].mvflags & G_GENOD) &&
|
||||
!(mons[last].geno & (G_NOGEN|G_UNIQ)) &&
|
||||
!is_placeholder(&mons[last]))
|
||||
num += mons[last].geno & G_FREQ;
|
||||
if (!num) return NON_PM;
|
||||
|
||||
for (num = rnd(num); num > 0; first++)
|
||||
if (!(mvitals[first].mvflags & G_GENOD) &&
|
||||
!(mons[first].geno & (G_NOGEN|G_UNIQ)) &&
|
||||
!is_placeholder(&mons[first]))
|
||||
num -= mons[first].geno & G_FREQ;
|
||||
first--; /* correct an off-by-one error */
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
int
|
||||
adj_lev(ptr) /* adjust strength of monsters based on u.uz and u.ulevel */
|
||||
register struct permonst *ptr;
|
||||
|
||||
@@ -664,10 +664,15 @@ int *mndx_p;
|
||||
/* multiple-letter input which matches any of these gets rejected */
|
||||
"an", "the", "or", "other", "or other", 0
|
||||
};
|
||||
/* positive pm_val => specific monster; negative => class */
|
||||
static NEARDATA const struct alt_spl truematch[] = {
|
||||
/* "long worm" won't match "worm" class but would accidentally match
|
||||
"long worm tail" class before the comparison with monster types */
|
||||
{ "long worm", PM_LONG_WORM },
|
||||
/* matches wrong--or at least suboptimal--class */
|
||||
{ "demon", -S_DEMON }, /* hits "imp or minor demon" */
|
||||
/* matches specific monster (overly restrictive) */
|
||||
{ "devil", -S_DEMON }, /* always "horned devil" */
|
||||
/* some plausible guesses which need help */
|
||||
{ "bug", -S_XAN }, /* would match bugbear... */
|
||||
{ "fish", -S_EEL }, /* wouldn't match anything */
|
||||
@@ -685,7 +690,12 @@ int *mndx_p;
|
||||
} else if (!in_str[1]) {
|
||||
/* single character */
|
||||
i = def_char_to_monclass(*in_str);
|
||||
if (i == MAXMCLASSES)
|
||||
if (i == S_MIMIC_DEF) { /* ']' -> 'm' */
|
||||
i = S_MIMIC;
|
||||
} else if (i == S_WORM_TAIL) { /* '~' -> 'w' */
|
||||
i = S_WORM;
|
||||
if (mndx_p) *mndx_p = PM_LONG_WORM;
|
||||
} else if (i == MAXMCLASSES) /* maybe 'I' */
|
||||
i = (*in_str == DEF_INVISIBLE) ? S_invisible : 0;
|
||||
return i;
|
||||
} else {
|
||||
|
||||
@@ -255,7 +255,7 @@ polyself(psflags)
|
||||
int psflags;
|
||||
{
|
||||
char buf[BUFSZ];
|
||||
int old_light, new_light, mntmp, tryct;
|
||||
int old_light, new_light, mntmp, class, tryct;
|
||||
boolean forcecontrol = (psflags == 1),
|
||||
monsterpoly = (psflags == 2),
|
||||
draconian = (uarm && Is_dragon_armor(uarm)),
|
||||
@@ -286,9 +286,18 @@ int psflags;
|
||||
do {
|
||||
getlin("Become what kind of monster? [type the name]",
|
||||
buf);
|
||||
class = 0;
|
||||
mntmp = name_to_mon(buf);
|
||||
if (mntmp < LOW_PM) {
|
||||
class = name_to_monclass(buf, &mntmp);
|
||||
if (class && mntmp == NON_PM)
|
||||
mntmp = mkclass_poly(class);
|
||||
}
|
||||
if (mntmp < LOW_PM)
|
||||
if (!class)
|
||||
pline("I've never heard of such monsters.");
|
||||
else
|
||||
You_cant("polymorph into any of those.");
|
||||
else if (iswere && (were_beastie(mntmp) == u.ulycn ||
|
||||
mntmp == counter_were(u.ulycn) ||
|
||||
(Upolyd && mntmp == PM_HUMAN)))
|
||||
@@ -301,7 +310,7 @@ int psflags;
|
||||
your_race(&mons[mntmp]) ||
|
||||
mntmp == urole.malenum ||
|
||||
mntmp == urole.femalenum))
|
||||
You("cannot polymorph into that.");
|
||||
You_cant("polymorph into that.");
|
||||
else break;
|
||||
} while (--tryct > 0);
|
||||
if (!tryct) pline(thats_enough_tries);
|
||||
|
||||
Reference in New Issue
Block a user