diff --git a/doc/fixes35.0 b/doc/fixes35.0 index b6f6a320d..405cfe437 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -270,6 +270,7 @@ anti-magic traps have alternate effect on targets who have magic resistance the Amulet can be offered to Moloch javelins and spears now share the same weapon skill all stackable weapons are capable of being thrown/shot for multi-shot volleys +worm teeth and crysknives have become stackable Platform- and/or Interface-Specific New Features diff --git a/src/do.c b/src/do.c index 5b137dfb2..6cedf77b1 100644 --- a/src/do.c +++ b/src/do.c @@ -598,8 +598,12 @@ struct obj *obj; } switch (obj->otyp) { case CRYSKNIFE: - /* KMH -- Fixed crysknives have only 10% chance of reverting */ - /* only changes when not held by player or monster */ + /* Normal crysknife reverts to worm tooth when not held by hero + * or monster; fixed crysknife has only 10% chance of reverting. + * When a stack of the latter is involved, it could be worthwhile + * to give each individual crysknife its own separate 10% chance, + * but we aren't in any position to handle stack splitting here. + */ if (!obj->oerodeproof || !rn2(10)) { /* if monsters aren't moving, assume player is responsible */ if (!context.mon_moving && !program_state.gameover) diff --git a/src/objects.c b/src/objects.c index d9504bbe2..beb88415d 100644 --- a/src/objects.c +++ b/src/objects.c @@ -140,9 +140,9 @@ WEAPON("knife", (char *)0, WEAPON("stiletto", (char *)0, 1, 1, 0, 5, 5, 4, 3, 2, 0, P|S, P_KNIFE, IRON, HI_METAL), WEAPON("worm tooth", (char *)0, - 1, 0, 0, 0, 20, 2, 2, 2, 0, 0, P_KNIFE, 0, CLR_WHITE), + 1, 1, 0, 0, 20, 2, 2, 2, 0, 0, P_KNIFE, 0, CLR_WHITE), WEAPON("crysknife", (char *)0, - 1, 0, 0, 0, 20,100, 10, 10, 3, P, P_KNIFE, MINERAL, CLR_WHITE), + 1, 1, 0, 0, 20,100, 10, 10, 3, P, P_KNIFE, MINERAL, CLR_WHITE), WEAPON("axe", (char *)0, 1, 0, 0, 40, 60, 8, 6, 4, 0, S, P_AXE, IRON, HI_METAL), diff --git a/src/wield.c b/src/wield.c index f37dd0607..1c4bd3c54 100644 --- a/src/wield.c +++ b/src/wield.c @@ -719,6 +719,7 @@ register int amount; { const char *color = hcolor((amount < 0) ? NH_BLACK : NH_BLUE); const char *xtime, *wepname = ""; + boolean multiple; int otyp = STRANGE_OBJECT; if(!uwep || (uwep->oclass != WEAPON_CLASS && !is_weptool(uwep))) { @@ -734,22 +735,36 @@ register int amount; if (otmp && otmp->oclass == SCROLL_CLASS) otyp = otmp->otyp; if (uwep->otyp == WORM_TOOTH && amount >= 0) { + multiple = (uwep->quan > 1L); /* order: message, transformation, shop handling */ - Your("%s is much sharper now.", simple_typename(WORM_TOOTH)); + Your("%s %s much sharper now.", simpleonames(uwep), + multiple ? "fuse, and become" : "is"); uwep->otyp = CRYSKNIFE; uwep->oerodeproof = 0; + if (multiple) { + uwep->quan = 1L; + uwep->owt = weight(uwep); + } if (uwep->cursed) uncurse(uwep); /* update shop bill to reflect new higher value */ if (uwep->unpaid) alter_cost(uwep, 0L); if (otyp != STRANGE_OBJECT) makeknown(otyp); + if (multiple) encumber_msg(); return 1; } else if (uwep->otyp == CRYSKNIFE && amount < 0) { + multiple = (uwep->quan > 1L); /* order matters: message, shop handling, transformation */ - Your("%s is much duller now.", simple_typename(CRYSKNIFE)); + Your("%s %s much duller now.", simpleonames(uwep), + multiple ? "fuse, and become" : "is"); costly_alteration(uwep, COST_DEGRD); /* DECHNT? other? */ uwep->otyp = WORM_TOOTH; uwep->oerodeproof = 0; + if (multiple) { + uwep->quan = 1L; + uwep->owt = weight(uwep); + } if (otyp != STRANGE_OBJECT && otmp->bknown) makeknown(otyp); + if (multiple) encumber_msg(); return 1; } diff --git a/src/zap.c b/src/zap.c index 9c5116e3c..adce79186 100644 --- a/src/zap.c +++ b/src/zap.c @@ -3070,6 +3070,12 @@ struct obj **pobj; /* object tossed/used, set to NULL return (struct monst *)0; } +/* process thrown boomerang, which travels a curving path... + * A multi-shot volley ought to have all missiles in flight at once, + * but we're called separately for each one. We terminate the volley + * early on a failed catch since continuing to throw after being hit + * is too obviously silly. + */ struct monst * boomhit(obj, dx, dy) struct obj *obj; @@ -3110,6 +3116,7 @@ int dx, dy; (void) thitu(10 + obj->spe, dmgval(obj, &youmonst), obj, "boomerang"); + endmultishot(TRUE); break; } else { /* we catch it */ tmp_at(DISP_END, 0);