-/* NetHack 3.6 uhitm.c $NHDT-Date: 1547680084 2019/01/16 23:08:04 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.199 $ */
+/* NetHack 3.6 uhitm.c $NHDT-Date: 1547846557 2019/01/18 21:22:37 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.200 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
wakeup(mdef, TRUE);
}
-/* attack monster as a monster. */
+/* attack monster as a monster; returns True if mon survives */
STATIC_OVL boolean
hmonas(mon)
register struct monst *mon;
switch (mattk->aatyp) {
case AT_WEAP:
use_weapon:
+ /* if we've already hit with a two-handed weapon, we don't
+ get to make another weapon attack (note: monsters who
+ use weapons do not have this restriction, but they also
+ never have the opportunity to use two weapons) */
+ if (weapon_used && sum[i - 1] && uwep && bimanual(uwep))
+ continue;
/* Certain monsters don't use weapons when encountered as enemies,
* but players who polymorph into them have hands or claws and
* thus should be able to use weapons. This shouldn't prohibit
be Null, and we want to track that for passive() */
originalweapon = (altwep && uswapwep) ? &uswapwep : &uwep;
if (uswapwep /* set up 'altwep' flag for next iteration */
+ /* only consider seconary when wielding one-handed primary */
+ && uwep && !bimanual(uwep)
+ /* only switch if not wearing shield and not at artifact;
+ shield limitation is iffy since still get extra swings
+ if polyform has them, but it matches twoweap behavior;
+ twoweap also only allows primary to be an artifact, so
+ if alternate weapon is one, don't use it */
+ && !uarms && !uswapwep->oartifact
/* only switch to uswapwep if it's a weapon */
&& (uswapwep->oclass == WEAPON_CLASS || is_weptool(uswapwep))
/* only switch if uswapwep is not bow, arrows, or darts */
&& !(is_launcher(uswapwep) || is_ammo(uswapwep)
- || is_missile(uswapwep))) /* dart, shuriken, boomerang */
+ || is_missile(uswapwep)) /* dart, shuriken, boomerang */
+ /* and not two-handed and not incapable of being wielded */
+ && !bimanual(uswapwep)
+ && !(objects[uswapwep->otyp].oc_material == SILVER
+ && Hate_silver))
altwep = !altwep; /* toggle for next attack */
weapon = *originalweapon;
if (!weapon) /* no need to go beyond no-gloves to rings; not ...*/
&armorpenalty);
dieroll = rnd(20);
dhit = (tmp > dieroll || u.uswallow);
- /* Enemy dead, before any special abilities used */
if (!known_hitum(mon, weapon, &dhit, tmp,
armorpenalty, mattk, dieroll)) {
+ /* enemy dead, before any special abilities used */
sum[i] = 2;
break;
} else
now be empty if the weapon was destroyed during the hit;
passive(,weapon,...) won't call passive_obj() in that case */
weapon = *originalweapon; /* might receive passive erosion */
- /* might be a worm that gets cut in half */
- if (m_at(u.ux + u.dx, u.uy + u.dy) != mon)
- return (boolean) (nsum != 0);
- /* Do not print "You hit" message, since known_hitum
- * already did it.
- */
+ /* might be a worm that gets cut in half; if so, early return */
+ if (m_at(u.ux + u.dx, u.uy + u.dy) != mon) {
+ i = NATTK; /* skip additional attacks */
+ /* proceed with uswapwep->cursed check, then exit loop */
+ goto passivedone;
+ }
+ /* Do not print "You hit" message; known_hitum already did it. */
if (dhit && mattk->adtyp != AD_SPEL && mattk->adtyp != AD_PHYS)
sum[i] = damageum(mon, mattk);
break;
}
if (sum[i] == 2) {
/* defender dead */
- return (boolean) passive(mon, weapon, 1, 0, mattk->aatyp, FALSE);
+ (void) passive(mon, weapon, 1, 0, mattk->aatyp, FALSE);
+ nsum = 0; /* return value below used to be 'nsum > 0' */
} else {
(void) passive(mon, weapon, sum[i], 1, mattk->aatyp, FALSE);
nsum |= sum[i];
}
+
+ /* don't use sum[i] beyond this point;
+ 'i' will be out of bounds if we get here via 'goto' */
+ passivedone:
+ /* when using dual weapons, cursed secondary weapon doesn't weld,
+ it gets dropped; do the same when multiple AT_WEAP attacks
+ simulate twoweap */
+ if (uswapwep && weapon == uswapwep && weapon->cursed) {
+ drop_uswapwep();
+ break; /* don't proceed with additional attacks */
+ }
+ /* stop attacking if defender has died;
+ needed to defer this until after uswapwep->cursed check */
+ if (DEADMONSTER(mon))
+ break;
if (!Upolyd)
break; /* No extra attacks if no longer a monster */
if (multi < 0)
break; /* If paralyzed while attacking, i.e. floating eye */
}
- return (boolean) (nsum != 0);
+ /* return value isn't used, but make it match hitum()'s */
+ return !DEADMONSTER(mon);
}
/* Special (passive) attacks on you by monsters done here.