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:
@@ -40,10 +40,8 @@ struct attribs {
|
||||
schar a[A_MAX];
|
||||
};
|
||||
|
||||
#define ATTRMAX(x) \
|
||||
((x == A_STR && Upolyd && strongmonst(g.youmonst.data)) \
|
||||
? STR18(100) \
|
||||
: g.urace.attrmax[x])
|
||||
#define ATTRMAX(x) \
|
||||
((x == A_STR && Upolyd) ? uasmon_maxStr() : g.urace.attrmax[x])
|
||||
#define ATTRMIN(x) (g.urace.attrmin[x])
|
||||
|
||||
#endif /* ATTRIB_H */
|
||||
|
||||
@@ -2152,6 +2152,7 @@ extern void change_sex(void);
|
||||
extern void livelog_newform(boolean, int, int);
|
||||
extern void polyself(int);
|
||||
extern int polymon(int);
|
||||
extern schar uasmon_maxStr(void);
|
||||
extern void rehumanize(void);
|
||||
extern int dobreathe(void);
|
||||
extern int dospit(void);
|
||||
@@ -2398,14 +2399,15 @@ extern void rigid_role_checks(void);
|
||||
extern boolean setrolefilter(const char *);
|
||||
extern boolean gotrolefilter(void);
|
||||
extern void clearrolefilter(void);
|
||||
extern char *build_plselection_prompt(char *, int, int, int, int, int);
|
||||
extern char *root_plselection_prompt(char *, int, int, int, int, int);
|
||||
extern char *build_plselection_prompt(char *, int, int, int, int, int);
|
||||
extern void plnamesuffix(void);
|
||||
extern void role_selection_prolog(int, winid);
|
||||
extern void role_menu_extra(int, winid, boolean);
|
||||
extern void role_init(void);
|
||||
extern const char *Hello(struct monst *);
|
||||
extern const char *Goodbye(void);
|
||||
extern const struct Race *character_race(short);
|
||||
|
||||
/* ### rumors.c ### */
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
51
src/role.c
51
src/role.c
@@ -676,7 +676,7 @@ const struct Race races[] = {
|
||||
{ 1, 0, 1, 0, 1, 0 } /* Energy */
|
||||
},
|
||||
/* Array terminator */
|
||||
{ 0, 0, 0, 0 }
|
||||
{ 0, 0, 0, 0, { 0, 0 }, NON_PM }
|
||||
};
|
||||
|
||||
/* Table of all genders */
|
||||
@@ -1697,11 +1697,10 @@ role_selection_prolog(int which, winid where)
|
||||
: !*g.plname ? not_yet : g.plname);
|
||||
putstr(where, 0, buf);
|
||||
Sprintf(buf, "%12s ", "role:");
|
||||
Strcat(buf, (which == RS_ROLE) ? choosing : (r == ROLE_NONE)
|
||||
? not_yet
|
||||
: (r == ROLE_RANDOM)
|
||||
? rand_choice
|
||||
: roles[r].name.m);
|
||||
Strcat(buf, (which == RS_ROLE) ? choosing
|
||||
: (r == ROLE_NONE) ? not_yet
|
||||
: (r == ROLE_RANDOM) ? rand_choice
|
||||
: roles[r].name.m);
|
||||
if (r >= 0 && roles[r].name.f) {
|
||||
/* distinct female name [caveman/cavewoman, priest/priestess] */
|
||||
if (gend == 1)
|
||||
@@ -1713,25 +1712,22 @@ role_selection_prolog(int which, winid where)
|
||||
}
|
||||
putstr(where, 0, buf);
|
||||
Sprintf(buf, "%12s ", "race:");
|
||||
Strcat(buf, (which == RS_RACE) ? choosing : (c == ROLE_NONE)
|
||||
? not_yet
|
||||
: (c == ROLE_RANDOM)
|
||||
? rand_choice
|
||||
: races[c].noun);
|
||||
Strcat(buf, (which == RS_RACE) ? choosing
|
||||
: (c == ROLE_NONE) ? not_yet
|
||||
: (c == ROLE_RANDOM) ? rand_choice
|
||||
: races[c].noun);
|
||||
putstr(where, 0, buf);
|
||||
Sprintf(buf, "%12s ", "gender:");
|
||||
Strcat(buf, (which == RS_GENDER) ? choosing : (gend == ROLE_NONE)
|
||||
? not_yet
|
||||
: (gend == ROLE_RANDOM)
|
||||
? rand_choice
|
||||
: genders[gend].adj);
|
||||
Strcat(buf, (which == RS_GENDER) ? choosing
|
||||
: (gend == ROLE_NONE) ? not_yet
|
||||
: (gend == ROLE_RANDOM) ? rand_choice
|
||||
: genders[gend].adj);
|
||||
putstr(where, 0, buf);
|
||||
Sprintf(buf, "%12s ", "alignment:");
|
||||
Strcat(buf, (which == RS_ALGNMNT) ? choosing : (a == ROLE_NONE)
|
||||
? not_yet
|
||||
: (a == ROLE_RANDOM)
|
||||
? rand_choice
|
||||
: aligns[a].adj);
|
||||
Strcat(buf, (which == RS_ALGNMNT) ? choosing
|
||||
: (a == ROLE_NONE) ? not_yet
|
||||
: (a == ROLE_RANDOM) ? rand_choice
|
||||
: aligns[a].adj);
|
||||
putstr(where, 0, buf);
|
||||
}
|
||||
|
||||
@@ -2078,4 +2074,17 @@ Goodbye(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* if pmindex is any player race (not necessarily the hero's),
|
||||
return a pointer to the races[] entry for it */
|
||||
const struct Race *
|
||||
character_race(short pmindex)
|
||||
{
|
||||
const struct Race *r;
|
||||
|
||||
for (r = races; r->mnum >= LOW_PM; ++r)
|
||||
if (r->mnum == pmindex)
|
||||
return r;
|
||||
return (const struct Race *) NULL;
|
||||
}
|
||||
|
||||
/* role.c */
|
||||
|
||||
Reference in New Issue
Block a user