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.
This commit is contained in:
nethack.rankin
2006-12-19 05:07:53 +00:00
parent 124040bcb9
commit 5ce14e99fc
5 changed files with 33 additions and 6 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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),

View File

@@ -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;
}

View File

@@ -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);