Monster movement and object pickup cleanup

Clean up some of the code for monster deciding what objects
to pick up, removing duplicate code.  There should be no real
difference in behaviour, other than monsters now can pick up
one stack of items at a time; previously monster could pick up
gold, then a practical item, followed by a magical item all
in a single turn, although this very rarely mattered.

Not extensively tested.

Code originally from NetHack4.
This commit is contained in:
Pasi Kallinen
2023-02-01 10:23:23 +02:00
parent 56d4822f4e
commit 6c9700ab25
3 changed files with 72 additions and 105 deletions
+14 -8
View File
@@ -11,7 +11,6 @@ static void sanity_check_single_mon(struct monst *, boolean, const char *);
static struct obj *make_corpse(struct monst *, unsigned);
static int minliquid_core(struct monst *);
static void m_calcdistress(struct monst *);
static boolean can_touch_safely(struct monst *, struct obj *);
static boolean monlineu(struct monst *, int, int);
static long mm_2way_aggression(struct monst *, struct monst *);
static long mm_aggression(struct monst *, struct monst *);
@@ -1577,8 +1576,9 @@ mpickgold(register struct monst* mtmp)
}
}
/* monster picks up one item stack from the map location they are at */
boolean
mpickstuff(struct monst *mtmp, const char *str)
mpickstuff(struct monst *mtmp)
{
register struct obj *otmp, *otmp2, *otmp3;
int carryamt = 0;
@@ -1587,6 +1587,14 @@ mpickstuff(struct monst *mtmp, const char *str)
if (mtmp->isshk && inhishop(mtmp))
return FALSE;
/* non-tame monsters normally don't go shopping */
if (!mtmp->mtame && *in_rooms(mtmp->mx, mtmp->my, SHOPBASE) && rn2(25))
return FALSE;
/* item in a pool, but monster can't swim */
if (!could_reach_item(mtmp, mtmp->mx, mtmp->my))
return FALSE;
for (otmp = gl.level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) {
otmp2 = otmp->nexthere;
@@ -1596,21 +1604,19 @@ mpickstuff(struct monst *mtmp, const char *str)
continue;
/* Nymphs take everything. Most monsters don't pick up corpses. */
if (!str ? searches_for_item(mtmp, otmp)
: !!(strchr(str, otmp->oclass))) {
if (mon_would_take_item(mtmp, otmp)) {
if (otmp->otyp == CORPSE && mtmp->data->mlet != S_NYMPH
/* let a handful of corpse types thru to can_carry() */
&& !touch_petrifies(&mons[otmp->corpsenm])
&& otmp->corpsenm != PM_LIZARD
&& !acidic(&mons[otmp->corpsenm]))
continue;
if (!touch_artifact(otmp, mtmp))
if (!can_touch_safely(mtmp, otmp))
continue;
carryamt = can_carry(mtmp, otmp);
if (carryamt == 0)
continue;
if (is_pool(mtmp->mx, mtmp->my))
continue;
/* handle cases where the critter can only get some */
otmp3 = otmp;
if (carryamt != otmp->quan) {
@@ -1681,7 +1687,7 @@ max_mon_load(struct monst* mtmp)
}
/* can monster touch object safely? */
static boolean
boolean
can_touch_safely(struct monst *mtmp, struct obj *otmp)
{
int otyp = otmp->otyp;