From 5ce14e99fcfaa55b6fc01161699a4f20b2532a07 Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Tue, 19 Dec 2006 05:07:53 +0000 Subject: [PATCH] final? multi-shot throwing (trunk only) Make worm teeth and crysknives be stackable. Positively enchanting a stack of multiple worm teeth produces a single crysknife, negatively enchanting a stack of multiple crysknives produces a single worm tooth. A dropped stack of N fixed crysknives has 90% of remaining N crysknives, 10% of becoming a stack of N worm teeth, rather than produce an average of 0.9*N crysknives and 0.1*N worm teeth. (The code which handles that transformation operates on loose objects so cannot handle stack splitting because it wouldn't have any idea of what to do with extra objects.) Terminate multi-shot volley throwing of boomerangs if one comes back and isn't caught. The sequence throw-catch-throw-catch is odd, but would take a substantial amount of code and effort to be changed to the more intuitive (for rapid volley throwing) throw-throw-catch-catch. Even if feasible, doing that for underused boomerangs would be a waste of effort. --- doc/fixes35.0 | 1 + src/do.c | 8 ++++++-- src/objects.c | 4 ++-- src/wield.c | 19 +++++++++++++++++-- src/zap.c | 7 +++++++ 5 files changed, 33 insertions(+), 6 deletions(-) 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);