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:
@@ -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:
|
||||
|
||||
@@ -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 */
|
||||
|
||||
28
src/mon.c
28
src/mon.c
@@ -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) &&
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
18
src/weapon.c
18
src/weapon.c
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user