Refactor mongets to return the object it creates

The impetus for this was to avoid ugly constructions such as the one
below (none of which currently appear in vanilla NetHack):

mongets(mtmp, LONG_SWORD);
struct obj* sword = m_carrying(mtmp, LONG_SWORD);
if (sword)
  /* do thing to sword */

Most cases where mongets is used discard the returned value (which used
to be the created object's spe); the only places that do use it are the
series of statements that give various human monsters armor and prevent
them from getting too much armor. These statements included hardcoded
constants representing the base AC of the armor, which would have caused
discrepancies if armor's base AC were ever changed.

With mongets now returning a pointer to the created object, it can just
be passed into ARM_BONUS instead, which covers both the base AC and the
enchantment. (It will also cover erosion, if anyone ever decides that
armor should rarely generate as pre-eroded).

The overall algorithm is not changed by this; human monsters should
receive armor with the same probabilities as before.
This commit is contained in:
copperwater
2019-09-18 11:12:09 -04:00
committed by Pasi Kallinen
parent a9dd7a5a46
commit 4b7f34f5f8
2 changed files with 46 additions and 29 deletions

View File

@@ -1227,7 +1227,7 @@ E struct permonst *FDECL(mkclass_aligned, (CHAR_P, int, ALIGNTYP_P));
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));
E struct obj* FDECL(mongets, (struct monst *, int));
E int FDECL(golemhp, (int));
E boolean FDECL(peace_minded, (struct permonst *));
E void FDECL(set_malign, (struct monst *));

View File

@@ -616,35 +616,52 @@ register struct monst *mtmp;
break;
}
#define add_ac(otmp) \
if (otmp) { mac += ARM_BONUS(otmp); } \
otmp = (struct obj *) 0;
/* round 1: give them body armor */
if (mac < -1 && rn2(5))
mac += 7 + mongets(mtmp, (rn2(5)) ? PLATE_MAIL
: CRYSTAL_PLATE_MAIL);
otmp = mongets(mtmp, (rn2(5)) ? PLATE_MAIL
: CRYSTAL_PLATE_MAIL);
else if (mac < 3 && rn2(5))
mac +=
6 + mongets(mtmp, (rn2(3)) ? SPLINT_MAIL : BANDED_MAIL);
otmp = mongets(mtmp, (rn2(3)) ? SPLINT_MAIL : BANDED_MAIL);
else if (rn2(5))
mac += 3 + mongets(mtmp, (rn2(3)) ? RING_MAIL
: STUDDED_LEATHER_ARMOR);
otmp = mongets(mtmp, (rn2(3)) ? RING_MAIL
: STUDDED_LEATHER_ARMOR);
else
mac += 2 + mongets(mtmp, LEATHER_ARMOR);
otmp = mongets(mtmp, LEATHER_ARMOR);
add_ac(otmp);
/* round 2: helmets */
if (mac < 10 && rn2(3))
mac += 1 + mongets(mtmp, HELMET);
otmp = mongets(mtmp, HELMET);
else if (mac < 10 && rn2(2))
mac += 1 + mongets(mtmp, DENTED_POT);
if (mac < 10 && rn2(3))
mac += 1 + mongets(mtmp, SMALL_SHIELD);
else if (mac < 10 && rn2(2))
mac += 2 + mongets(mtmp, LARGE_SHIELD);
if (mac < 10 && rn2(3))
mac += 1 + mongets(mtmp, LOW_BOOTS);
else if (mac < 10 && rn2(2))
mac += 2 + mongets(mtmp, HIGH_BOOTS);
if (mac < 10 && rn2(3))
mac += 1 + mongets(mtmp, LEATHER_GLOVES);
else if (mac < 10 && rn2(2))
mac += 1 + mongets(mtmp, LEATHER_CLOAK);
otmp = mongets(mtmp, DENTED_POT);
add_ac(otmp);
/* round 3: shields */
if (mac < 10 && rn2(3))
otmp = mongets(mtmp, SMALL_SHIELD);
else if (mac < 10 && rn2(2))
otmp = mongets(mtmp, LARGE_SHIELD);
add_ac(otmp);
/* round 4: boots */
if (mac < 10 && rn2(3))
otmp = mongets(mtmp, LOW_BOOTS);
else if (mac < 10 && rn2(2))
otmp = mongets(mtmp, HIGH_BOOTS);
add_ac(otmp);
/* round 5: gloves + cloak */
if (mac < 10 && rn2(3))
otmp = mongets(mtmp, LEATHER_GLOVES);
else if (mac < 10 && rn2(2))
otmp = mongets(mtmp, LEATHER_CLOAK);
add_ac(otmp); /* not technically needed */
#undef add_ac
nhUse(mac); /* suppress 'dead increment' from static analyzer */
if (ptr == &mons[PM_WATCH_CAPTAIN]) {
@@ -1903,16 +1920,15 @@ struct monst *mtmp, *victim;
return ptr;
}
int
struct obj *
mongets(mtmp, otyp)
register struct monst *mtmp;
int otyp;
{
register struct obj *otmp;
int spe;
if (!otyp)
return 0;
return (struct obj *) 0;
otmp = mksobj(otyp, TRUE, FALSE);
if (otmp) {
if (mtmp->data->mlet == S_DEMON) {
@@ -1949,11 +1965,12 @@ int otyp;
otmp->spe = 0;
}
spe = otmp->spe;
(void) mpickobj(mtmp, otmp); /* might free otmp */
return spe;
if (mpickobj(mtmp, otmp)) {
/* otmp was freed via merging with something else */
otmp = (struct obj *) 0;
}
}
return 0;
return otmp;
}
int