nerf potion alchemy (trunk only)

Something I've had in mind for a long time:  make it harder to acquire
dozens of potions of full healing and thereby (8 * dozens) of extra hit
points.  When dipping a stack of more than 2 potions into another potion
other than water, first split the stack so that 2 to 9 potions are dipped
rather than all of them.  Alchemy still works but it will take more dips
(hence need more resources) to convert large amounts.  Dipping into water
isn't affected, nor is dipping non-potions.

     Also fix a bug where dipping a stack--now perhaps a subset stack after
splitting--which triggered an explosion was only using up one of the dipped
potions (plus the one being dipped into) instead of the whole stack.
This commit is contained in:
nethack.rankin
2012-02-19 02:06:43 +00:00
parent ec966362a6
commit 6a9217d568
2 changed files with 97 additions and 62 deletions
+3
View File
@@ -409,6 +409,8 @@ theft of worn armor with wear/unwear delay would interfere with completion of
(disrupted wear attempt for +N helm of brilliance would result in loss (disrupted wear attempt for +N helm of brilliance would result in loss
of N points of Int and Wis; gauntlets of dexterity had similar problem) of N points of Int and Wis; gauntlets of dexterity had similar problem)
#sit while swallowed would give the wrong message #sit while swallowed would give the wrong message
alchemical explosion or evaporation only used up one potion instead of all
the potions being dipped
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
@@ -558,6 +560,7 @@ display version and build information at startup
repeatedly setting the fruit option will check to see if fruits have been repeatedly setting the fruit option will check to see if fruits have been
created, so the user can't easily overflow the maximum this way created, so the user can't easily overflow the maximum this way
bones files now include extra data to identify dead hero and reason for death bones files now include extra data to identify dead hero and reason for death
dipping multiple potions in another potion may only dip part of their stack
Platform- and/or Interface-Specific New Features Platform- and/or Interface-Specific New Features
+94 -62
View File
@@ -1815,14 +1815,14 @@ dodip()
potion : obj, 5, 95)) { potion : obj, 5, 95)) {
pline1(nothing_happens); pline1(nothing_happens);
} else { } else {
boolean was_wep = FALSE, was_swapwep = FALSE, was_quiver = FALSE; boolean was_wep, was_swapwep, was_quiver;
short save_otyp = obj->otyp; short save_otyp = obj->otyp;
/* KMH, conduct */ /* KMH, conduct */
u.uconduct.polypiles++; u.uconduct.polypiles++;
if (obj == uwep) was_wep = TRUE; was_wep = (obj == uwep);
else if (obj == uswapwep) was_swapwep = TRUE; was_swapwep = (obj == uswapwep);
else if (obj == uquiver) was_quiver = TRUE; was_quiver = (obj == uquiver);
obj = poly_obj(obj, STRANGE_OBJECT); obj = poly_obj(obj, STRANGE_OBJECT);
@@ -1842,66 +1842,98 @@ dodip()
} }
potion->in_use = FALSE; /* didn't go poof */ potion->in_use = FALSE; /* didn't go poof */
return(1); return(1);
} else if(obj->oclass == POTION_CLASS && obj->otyp != potion->otyp) { } else if (obj->oclass == POTION_CLASS && obj->otyp != potion->otyp) {
/* Mixing potions is dangerous... */ long amt = obj->quan;
pline_The("potions mix...");
/* KMH, balance patch -- acid is particularly unstable */ Strcpy(qbuf, "The");
if (obj->cursed || obj->otyp == POT_ACID || !rn2(10)) { if (amt > (objects[potion->otyp].oc_magic ? 2L : 9L)) {
pline("BOOM! They explode!"); /* trying to dip multiple potions will usually affect only a
wake_nearto(u.ux, u.uy, (BOLT_LIM+1)*(BOLT_LIM+1)); subset; pick an amount between 2 and min(N,9), inclusive */
exercise(A_STR, FALSE); amt -= 1L;
if (!breathless(youmonst.data) || haseyes(youmonst.data)) do {
potionbreathe(obj); amt = (long)rnd((int)amt);
useup(obj); } while (amt >= 9L);
useup(potion); amt += 1L;
losehp(rnd(10), "alchemic blast", /* not physical damage */ if (amt < obj->quan) {
KILLED_BY_AN); obj = splitobj(obj, amt);
return(1); Sprintf(qbuf, "%ld of the", obj->quan);
} }
}
obj->blessed = obj->cursed = obj->bknown = 0; /* [N of] the {obj(s)} mix(es) with [one of] {the potion}... */
if (Blind || Hallucination) obj->dknown = 0; pline("%s %s %s with %s%s...", qbuf,
simpleonames(obj), otense(obj, "mix"),
if ((mixture = mixtype(obj, potion)) != 0) { (potion->quan > 1L) ? "one of " : "",
obj->otyp = mixture; thesimpleoname(potion));
} else { /* Mixing potions is dangerous...
switch (obj->odiluted ? 1 : rnd(8)) { KMH, balance patch -- acid is particularly unstable */
case 1: if (obj->cursed || obj->otyp == POT_ACID || !rn2(10)) {
obj->otyp = POT_WATER; /* it would be better to use up the whole stack in advance
break; of the message, but we can't because we need to keep it
case 2: around for potionbreathe() [and we can't set obj->in_use
case 3: to 'amt' because that's not implemented] */
obj->otyp = POT_SICKNESS; obj->in_use = 1;
break; pline("BOOM! They explode!");
case 4: wake_nearto(u.ux, u.uy, (BOLT_LIM+1)*(BOLT_LIM+1));
{ exercise(A_STR, FALSE);
struct obj *otmp; if (!breathless(youmonst.data) || haseyes(youmonst.data))
otmp = mkobj(POTION_CLASS,FALSE); potionbreathe(obj);
obj->otyp = otmp->otyp; useupall(obj);
obfree(otmp, (struct obj *)0);
}
break;
default:
if (!Blind)
pline_The("mixture glows brightly and evaporates.");
useup(obj);
useup(potion);
return(1);
}
}
obj->odiluted = (obj->otyp != POT_WATER);
if (obj->otyp == POT_WATER && !Hallucination) {
pline_The("mixture bubbles%s.",
Blind ? "" : ", then clears");
} else if (!Blind) {
pline_The("mixture looks %s.",
hcolor(OBJ_DESCR(objects[obj->otyp])));
}
useup(potion); useup(potion);
return(1); losehp((int)(amt + rnd(9)), /* not physical damage */
"alchemic blast", KILLED_BY_AN);
return 1;
}
obj->blessed = obj->cursed = obj->bknown = 0;
if (Blind || Hallucination) obj->dknown = 0;
if ((mixture = mixtype(obj, potion)) != 0) {
obj->otyp = mixture;
} else {
switch (obj->odiluted ? 1 : rnd(8)) {
case 1:
obj->otyp = POT_WATER;
break;
case 2:
case 3:
obj->otyp = POT_SICKNESS;
break;
case 4:
{
struct obj *otmp = mkobj(POTION_CLASS, FALSE);
obj->otyp = otmp->otyp;
obfree(otmp, (struct obj *)0);
}
break;
default:
useupall(obj);
useup(potion);
if (!Blind)
pline_The("mixture glows brightly and evaporates.");
return 1;
}
}
obj->odiluted = (obj->otyp != POT_WATER);
if (obj->otyp == POT_WATER && !Hallucination) {
pline_The("mixture bubbles%s.", Blind ? "" : ", then clears");
} else if (!Blind) {
pline_The("mixture looks %s.",
hcolor(OBJ_DESCR(objects[obj->otyp])));
}
useup(potion);
/* this is required when 'obj' was split off from a bigger stack,
so that 'obj' will now be assigned its own inventory slot;
it has a side-effect of merging 'obj' into another compatible
stack if there is one, so we do it even when no split has
been made in order to get the merge result for both cases;
as a consequence, mixing while Fumbling drops the mixture */
freeinv(obj);
(void) hold_another_object(obj, "You drop %s!", doname(obj),
(const char *)0);
return 1;
} }
#ifdef INVISIBLE_OBJECTS #ifdef INVISIBLE_OBJECTS