B02001 - trees and monster

<Someone> noticed that the change to require axes for trees (and allow them for
doors) did not extend to monsters.  Now it does.
- added 2 new weapon check flags to handle the new cases
- added some detailed digging flags to mfndpos, based on ALLOW_DIG, and
  moved some common logic regarding that flag into mfndpos
- made the ARMS check consistent for 2-handed weapons
I also noticed that simply carrying a pick was enough to allow a monster to
dig a door; wielding wasn't required.  This is fixed as well.
This commit is contained in:
cohrs
2002-08-11 17:32:47 +00:00
parent 02c9ce9214
commit b4b5a0fe52
6 changed files with 81 additions and 33 deletions

View File

@@ -6,7 +6,7 @@
#define MONST_H
/* The weapon_check flag is used two ways:
* 1) When calling mon_wield_item, is 2, 3, or 4 depending on what is desired.
* 1) When calling mon_wield_item, is 2-6 depending on what is desired.
* 2) Between calls to mon_wield_item, is 0 or 1 depending on whether or not
* the weapon is known by the monster to be cursed (so it shouldn't bother
* trying for another weapon).
@@ -20,6 +20,8 @@
# define NEED_RANGED_WEAPON 2
# define NEED_HTH_WEAPON 3
# define NEED_PICK_AXE 4
# define NEED_AXE 5
# define NEED_PICK_OR_AXE 6
/* The following flags are used for the second argument to display_minventory
* in invent.c:

View File

@@ -565,10 +565,7 @@ register int after; /* this is extra fast monster movement */
if (m_carrying(mtmp, SKELETON_KEY)) allowflags |= BUSTDOOR;
}
if (is_giant(mtmp->data)) allowflags |= BUSTDOOR;
if (tunnels(mtmp->data) && (!needspick(mtmp->data) ||
m_carrying(mtmp, PICK_AXE) ||
m_carrying(mtmp, DWARVISH_MATTOCK)))
allowflags |= ALLOW_DIG;
if (tunnels(mtmp->data)) allowflags |= ALLOW_DIG;
cnt = mfndpos(mtmp, poss, info, allowflags);
/* Normally dogs don't step on cursed items, but if they have no
@@ -714,12 +711,22 @@ newdogpos:
}
if (!m_in_out_region(mtmp, nix, niy))
return 1;
if(IS_ROCK(levl[nix][niy].typ) && may_dig(nix,niy) &&
if (((IS_ROCK(levl[nix][niy].typ) && may_dig(nix,niy)) ||
closed_door(nix, niy)) &&
mtmp->weapon_check != NO_WEAPON_WANTED &&
tunnels(mtmp->data) && needspick(mtmp->data) &&
(!(mw_tmp = MON_WEP(mtmp)) || !is_pick(mw_tmp))) {
mtmp->weapon_check = NEED_PICK_AXE;
if (mon_wield_item(mtmp))
tunnels(mtmp->data) && needspick(mtmp->data)) {
if (closed_door(nix, niy)) {
if (!(mw_tmp = MON_WEP(mtmp)) ||
!is_pick(mw_tmp) || !is_axe(mw_tmp))
mtmp->weapon_check = NEED_PICK_OR_AXE;
} else if (IS_TREE(levl[nix][niy].typ)) {
if (!(mw_tmp = MON_WEP(mtmp)) || !is_axe(mw_tmp))
mtmp->weapon_check = NEED_AXE;
} else if (!(mw_tmp = MON_WEP(mtmp)) || !is_pick(mw_tmp)) {
mtmp->weapon_check = NEED_PICK_AXE;
}
if (mtmp->weapon_check >= NEED_PICK_AXE &&
mon_wield_item(mtmp))
return 0;
}
/* insert a worm_move() if worms ever begin to eat things */

View File

@@ -952,6 +952,7 @@ mfndpos(mon, poss, info, flag)
register uchar ntyp;
uchar nowtyp;
boolean wantpool,poolok,lavaok,nodiag;
boolean rockok = FALSE, treeok = FALSE, thrudoor;
int maxx, maxy;
x = mon->mx;
@@ -963,6 +964,27 @@ mfndpos(mon, poss, info, flag)
poolok = is_flyer(mdat) || is_clinger(mdat) ||
(is_swimmer(mdat) && !wantpool);
lavaok = is_flyer(mdat) || is_clinger(mdat) || likes_lava(mdat);
thrudoor = (flag & (ALLOW_WALL|BUSTDOOR));
if (flag & ALLOW_DIG) {
struct obj *mw_tmp;
/* need to be specific about what can currently be dug */
if (!needspick(mdat)) {
rockok = treeok = TRUE;
} else if ((mw_tmp = MON_WEP(mon)) && mw_tmp->cursed &&
mon->weapon_check == NO_WEAPON_WANTED) {
rockok = is_pick(mw_tmp);
treeok = is_axe(mw_tmp);
} else {
rockok = (m_carrying(mon, PICK_AXE) ||
(m_carrying(mon, DWARVISH_MATTOCK) &&
!which_armor(mon, W_ARMS)));
treeok = (m_carrying(mon, AXE) ||
(m_carrying(mon, BATTLE_AXE) &&
!which_armor(mon, W_ARMS)));
}
thrudoor |= rockok || treeok;
}
nexttry: /* eels prefer the water, but if there is no water nearby,
they will crawl over land */
@@ -979,13 +1001,13 @@ nexttry: /* eels prefer the water, but if there is no water nearby,
if(nx == x && ny == y) continue;
if(IS_ROCK(ntyp = levl[nx][ny].typ) &&
!((flag & ALLOW_WALL) && may_passwall(nx,ny)) &&
!((flag & ALLOW_DIG) && may_dig(nx,ny))) continue;
!((IS_TREE(ntyp) ? treeok : rockok) && may_dig(nx,ny))) continue;
/* KMH -- Added iron bars */
if (ntyp == IRONBARS && !(flag & ALLOW_BARS)) continue;
if(IS_DOOR(ntyp) && !amorphous(mdat) &&
((levl[nx][ny].doormask & D_CLOSED && !(flag & OPENDOOR)) ||
(levl[nx][ny].doormask & D_LOCKED && !(flag & UNLOCKDOOR))
) && !(flag & (ALLOW_WALL|ALLOW_DIG|BUSTDOOR))) continue;
(levl[nx][ny].doormask & D_LOCKED && !(flag & UNLOCKDOOR))) &&
!thrudoor) continue;
if(nx != x && ny != y && (nodiag ||
#ifdef REINCARNATION
((IS_DOOR(nowtyp) &&

View File

@@ -624,12 +624,10 @@ register int after;
/* Not necessary if m_move called from this file, but necessary in
* other calls of m_move (ex. leprechauns dodging)
*/
can_tunnel = tunnels(ptr) &&
#ifdef REINCARNATION
!Is_rogue_level(&u.uz) &&
if (!Is_rogue_level(&u.uz))
#endif
(!needspick(ptr) || m_carrying(mtmp, PICK_AXE) ||
(m_carrying(mtmp, DWARVISH_MATTOCK) && !which_armor(mtmp, W_ARMS)));
can_tunnel = tunnels(ptr);
can_open = !(nohands(ptr) || verysmall(ptr));
can_unlock = ((can_open && m_carrying(mtmp, SKELETON_KEY)) ||
mtmp->iswiz || is_rider(ptr));
@@ -874,13 +872,10 @@ not_special:
}
}
/* don't tunnel if needspick and wielding a non-pick that is known
* cursed or hostile and close enough to prefer a weapon */
/* don't tunnel if hostile and close enough to prefer a weapon */
if (can_tunnel && needspick(ptr) &&
(mw_tmp = MON_WEP(mtmp)) != 0 && !is_pick(mw_tmp) &&
((mw_tmp->cursed && mtmp->weapon_check == NO_WEAPON_WANTED) ||
((!mtmp->mpeaceful || Conflict) &&
dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 8)))
((!mtmp->mpeaceful || Conflict) &&
dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 8))
can_tunnel = FALSE;
nix = omx;
@@ -955,11 +950,20 @@ not_special:
if (mmoved==1 && (u.ux != nix || u.uy != niy) && itsstuck(mtmp))
return(3);
if(IS_ROCK(levl[nix][niy].typ) && may_dig(nix,niy) &&
mmoved==1 && can_tunnel && needspick(ptr) &&
(!(mw_tmp = MON_WEP(mtmp)) || !is_pick(mw_tmp))) {
mtmp->weapon_check = NEED_PICK_AXE;
if (mon_wield_item(mtmp))
if (((IS_ROCK(levl[nix][niy].typ) && may_dig(nix,niy)) ||
closed_door(nix, niy)) &&
mmoved==1 && can_tunnel && needspick(ptr)) {
if (closed_door(nix, niy)) {
if (!(mw_tmp = MON_WEP(mtmp)) ||
!is_pick(mw_tmp) || !is_axe(mw_tmp))
mtmp->weapon_check = NEED_PICK_OR_AXE;
} else if (IS_TREE(levl[nix][niy].typ)) {
if (!(mw_tmp = MON_WEP(mtmp)) || !is_axe(mw_tmp))
mtmp->weapon_check = NEED_AXE;
} else if (!(mw_tmp = MON_WEP(mtmp)) || !is_pick(mw_tmp)) {
mtmp->weapon_check = NEED_PICK_AXE;
}
if (mtmp->weapon_check >= NEED_PICK_AXE && mon_wield_item(mtmp))
return(3);
}
/* If ALLOW_U is set, either it's trying to attack you, or it

View File

@@ -49,10 +49,7 @@ register xchar omx,omy,gx,gy;
else allowflags = ALLOW_SSM | ALLOW_SANCT;
if (passes_walls(mtmp->data)) allowflags |= (ALLOW_ROCK|ALLOW_WALL);
if (throws_rocks(mtmp->data)) allowflags |= ALLOW_ROCK;
if (tunnels(mtmp->data) &&
(!needspick(mtmp->data) || m_carrying(mtmp, PICK_AXE) ||
m_carrying(mtmp, DWARVISH_MATTOCK)))
allowflags |= ALLOW_DIG;
if (tunnels(mtmp->data)) allowflags |= ALLOW_DIG;
if (!nohands(mtmp->data) && !verysmall(mtmp->data)) {
allowflags |= OPENDOOR;
if (m_carrying(mtmp, SKELETON_KEY)) allowflags |= BUSTDOOR;

View File

@@ -599,7 +599,23 @@ register struct monst *mon;
case NEED_PICK_AXE:
obj = m_carrying(mon, PICK_AXE);
/* KMH -- allow other picks */
if (!obj) obj = m_carrying(mon, DWARVISH_MATTOCK);
if (!obj && !which_armor(mon, W_ARMS))
obj = m_carrying(mon, DWARVISH_MATTOCK);
break;
case NEED_AXE:
/* currently, only 2 types of axe */
obj = m_carrying(mon, BATTLE_AXE);
if (!obj || which_armor(mon, W_ARMS))
obj = m_carrying(mon, AXE);
break;
case NEED_PICK_OR_AXE:
/* prefer pick for fewer switches on most levels */
obj = m_carrying(mon, DWARVISH_MATTOCK);
if (!obj) obj = m_carrying(mon, BATTLE_AXE);
if (!obj || which_armor(mon, W_ARMS)) {
obj = m_carrying(mon, PICK_AXE);
if (!obj) obj = m_carrying(mon, AXE);
}
break;
default: impossible("weapon_check %d for %s?",
mon->weapon_check, mon_nam(mon));