more github issue #679 - orc strength

Handle alternate values for hero poly'd into a 'strongmonst' form
more thoroughly by propagating max values other than 18/100 to the
attribute manipulation routines.

ATTRMAX(A_STR), which used to be a relatively simple expression, now
contains a function call.

Along the way, change the races[] terminator's value for 'mnum' from
0 (giant ant) to NON_PM.
This commit is contained in:
PatR
2022-10-12 02:05:32 -07:00
parent b01fd1b849
commit 02cfdfee30
4 changed files with 90 additions and 50 deletions

View File

@@ -683,7 +683,7 @@ polymon(int mntmp)
char buf[BUFSZ];
boolean sticky = sticks(g.youmonst.data) && u.ustuck && !u.uswallow,
was_blind = !!Blind, dochange = FALSE;
int mlvl;
int mlvl, newMaxStr;
if (g.mvitals[mntmp].mvflags & G_GENOD) { /* allow G_EXTINCT */
You_feel("rather %s-ish.",
@@ -760,33 +760,16 @@ polymon(int mntmp)
/* New stats for monster, to last only as long as polymorphed.
* Currently only strength gets changed.
*/
if (strongmonst(&mons[mntmp]) && !is_elf(&mons[mntmp])) {
/* ettins, titans and minotaurs don't pass the is_giant() test;
giant mummies and giant zombies do but we throttle those;
Lord Surtur and Cyclops pass the test but can't be poly'd into */
boolean live_H = is_giant(&mons[mntmp]) && !is_undead(&mons[mntmp]);
int newStr = live_H ? STR19(19) : STR18(100);
/* hero orcs are limited to 18/50 for maximum strength, so treat
hero poly'd into an orc the same; goblins, orc shamans, and orc
zombies don't have strongmonst() attribute so won't get here;
hobgoblins and orc mummies do get here and are limited to 18/50
like normal orcs; however, Uruk-hai retain 18/100 strength;
hero gnomes are also limited to 18/50; hero elves are limited to
18/00 so we treat strongmonst elves (elf-noble, elven monarch)
as if they're not (in 'if' above, so they don't get here) */
if ((is_orc(&mons[mntmp])
&& !strstri(pmname(&mons[mntmp], NEUTRAL), "Uruk"))
|| is_gnome(&mons[mntmp]))
newStr = STR18(50);
ABASE(A_STR) = AMAX(A_STR) = newStr;
newMaxStr = uasmon_maxStr();
if (strongmonst(&mons[mntmp])) {
ABASE(A_STR) = AMAX(A_STR) = (schar) newMaxStr;
} else {
/* not a strongmonst(); if hero has exceptional strength, remove it
(note: removal is temporary until returning to original form);
we don't attempt to enforce lower maximum for wimpy forms;
we do avoid boosting current strength to 18 if presently less */
AMAX(A_STR) = 18; /* same as STR18(0) */
unlike for strongmonst, current strength does not get set to max */
AMAX(A_STR) = (schar) newMaxStr;
/* make sure current is not higher than max (strip exceptional Str) */
if (ABASE(A_STR) > AMAX(A_STR))
ABASE(A_STR) = AMAX(A_STR);
}
@@ -981,6 +964,54 @@ polymon(int mntmp)
return 1;
}
/* determine hero's temporary strength value used while polymorphed;
hero poly'd into M2_STRONG monster usually gets 18/100 strength but
there are exceptions; non-M2_STRONG get maximum strength set to 18 */
schar
uasmon_maxStr(void)
{
const struct Race *R;
int newMaxStr;
int mndx = u.umonnum;
struct permonst *ptr = &mons[mndx];
if (is_orc(ptr)) {
if (mndx != PM_URUK_HAI)
mndx = PM_ORC;
} else if (is_elf(ptr)) {
mndx = PM_ELF;
} else if (is_dwarf(ptr)) {
mndx = PM_DWARF;
} else if (is_gnome(ptr)) {
mndx = PM_GNOME;
#if 0 /* use the mons[] value for humans */
} else if (is_human(ptr)) {
mndx = PM_HUMAN;
#endif
}
R = character_race(mndx);
if (strongmonst(ptr)) {
/* ettins, titans and minotaurs don't pass the is_giant() test;
giant mummies and giant zombies do but we throttle those */
boolean live_H = is_giant(ptr) && !is_undead(ptr);
/* hero orcs are limited to 18/50 for maximum strength, so treat
hero poly'd into an orc the same; goblins, orc shamans, and orc
zombies don't have strongmonst() attribute so won't get here;
hobgoblins and orc mummies do get here and are limited to 18/50
like normal orcs; however, Uruk-hai retain 18/100 strength;
hero gnomes are also limited to 18/50; hero elves are limited
to 18/00 regardless of whether they're strongmonst, but the two
strongmonst types (monarchs and nobles) have current strength
set to 18 [by polymon()], the others don't */
newMaxStr = R ? R->attrmax[A_STR] : live_H ? STR19(19) : STR18(100);
} else {
newMaxStr = R ? R->attrmax[A_STR] : 18; /* 18 is same as STR18(0) */
}
return (schar) newMaxStr;
}
/* dropx() jacket for break_armor() */
static void
dropp(struct obj *obj)