From: PatR Date: Fri, 29 Jan 2016 10:07:09 +0000 (-0800) Subject: more globs... much more globs X-Git-Tag: NetHack-3.6.1_RC01~974 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b606aea919f5ea54df36f5907fd1d81f7e3b5d74;p=nethack more globs... much more globs Fix a bunch of glob bugs, probably introduce one or two new ones. --- diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 738f2f451..ea201a07d 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -88,6 +88,7 @@ requiver pickup_thrown objects if quiver is empty make mimics mimicing walls or trees also block light stepping onto lava destroyed non-fireproof water walking boots but left other vulnerable boot types intact +fix eating messages which referred to globs as corpses fix death reason when eating tainted glob of (not corpse) fix death reason when petrified (avoid redundant 'while getting stoned') use appropriate place name for drum of earthquake shakes @@ -109,6 +110,11 @@ don't create globs of ooze/slime/pudding with bknown flag set so pre-known to be "uncursed" do allow globs with same curse/bless state to merge even when that state is known for one and unknown for the other; result will have bknown clear +make glob merging on floor behave the same as glob merging in inventory +track age of merged globs +support globs for edibility temporary intrinsic +handle eating partly eaten glob that has increased in weight since prior eat +restore ability to gain intrinsics from black puddings (pass globs to cpostfx) fix pile mark after killing a monster carrying a potion which is destroyed don't list suit as likely candidate for Take-off if cloak blocks it only list known blank scrolls and known blank spellbooks as likely candidates diff --git a/src/eat.c b/src/eat.c index 265a868c3..9601e1cdb 100644 --- a/src/eat.c +++ b/src/eat.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 eat.c $NHDT-Date: 1452660191 2016/01/13 04:43:11 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.161 $ */ +/* NetHack 3.6 eat.c $NHDT-Date: 1454061992 2016/01/29 10:06:32 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.162 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -310,9 +310,9 @@ struct obj *otmp; if (!otmp->oeaten) { costly_alteration(otmp, COST_BITE); - otmp->oeaten = - (otmp->otyp == CORPSE ? mons[otmp->corpsenm].cnutrit - : objects[otmp->otyp].oc_nutrition); + otmp->oeaten = (otmp->otyp == CORPSE) ? mons[otmp->corpsenm].cnutrit + : otmp->globby ? otmp->owt + : objects[otmp->otyp].oc_nutrition; } if (carried(otmp)) { @@ -414,7 +414,9 @@ STATIC_OVL void done_eating(message) boolean message; { - context.victual.piece->in_use = TRUE; + struct obj *piece = context.victual.piece; + + piece->in_use = TRUE; occupation = 0; /* do this early, so newuhs() knows we're done */ newuhs(FALSE); if (nomovemsg) { @@ -422,17 +424,17 @@ boolean message; pline1(nomovemsg); nomovemsg = 0; } else if (message) - You("finish eating %s.", food_xname(context.victual.piece, TRUE)); + You("finish eating %s.", food_xname(piece, TRUE)); - if (context.victual.piece->otyp == CORPSE) - cpostfx(context.victual.piece->corpsenm); + if (piece->otyp == CORPSE || piece->globby) + cpostfx(piece->corpsenm); else - fpostfx(context.victual.piece); + fpostfx(piece); - if (carried(context.victual.piece)) - useup(context.victual.piece); + if (carried(piece)) + useup(piece); else - useupf(context.victual.piece, 1L); + useupf(piece, 1L); context.victual.piece = (struct obj *) 0; context.victual.o_id = 0; context.victual.fullwarn = context.victual.eating = @@ -1531,11 +1533,13 @@ STATIC_OVL int eatcorpse(otmp) struct obj *otmp; { - int tp = 0, mnum = otmp->corpsenm; + int retcode = 0, tp = 0, mnum = otmp->corpsenm; long rotted = 0L; - int retcode = 0; boolean stoneable = (flesh_petrifies(&mons[mnum]) && !Stone_resistance - && !poly_when_stoned(youmonst.data)); + && !poly_when_stoned(youmonst.data)), + slimeable = (mnum == PM_GREEN_SLIME && !Slimed && !Unchanging + && !slimeproof(youmonst.data)), + glob = otmp->globby ? TRUE : FALSE; /* KMH, conduct */ if (!vegan(&mons[mnum])) @@ -1553,13 +1557,14 @@ struct obj *otmp; rotted -= 2L; } - if (mnum != PM_ACID_BLOB && !stoneable && rotted > 5L) { + if (mnum != PM_ACID_BLOB && !stoneable && !slimeable && rotted > 5L) { boolean cannibal = maybe_cannibal(mnum, FALSE); pline("Ulch - that %s was tainted%s!", - mons[mnum].mlet == S_FUNGUS - ? "fungoid vegetation" - : !vegetarian(&mons[mnum]) ? "meat" : "protoplasm", + (mons[mnum].mlet == S_FUNGUS) ? "fungoid vegetation" + : glob ? "glob" + : vegetarian(&mons[mnum]) ? "protoplasm" + : "meat", cannibal ? ", you cannibal" : ""); if (Sick_resistance) { pline("It doesn't seem at all sickening, though..."); @@ -1581,24 +1586,26 @@ struct obj *otmp; } else if (acidic(&mons[mnum]) && !Acid_resistance) { tp++; You("have a very bad case of stomach acid."); /* not body_part() */ - losehp(rnd(15), "acidic corpse", KILLED_BY_AN); /* acid damage */ + losehp(rnd(15), !glob ? "acidic corpse" : "acidic glob", + KILLED_BY_AN); /* acid damage */ } else if (poisonous(&mons[mnum]) && rn2(5)) { tp++; pline("Ecch - that must have been poisonous!"); if (!Poison_resistance) { losestr(rnd(4)); - losehp(rnd(15), "poisonous corpse", KILLED_BY_AN); + losehp(rnd(15), !glob ? "poisonous corpse" : "posionous glob", + KILLED_BY_AN); } else You("seem unaffected by the poison."); - /* now any corpse left too long will make you mildly ill */ + /* now any corpse left too long will make you mildly ill */ } else if ((rotted > 5L || (rotted > 3L && rn2(5))) && !Sick_resistance) { tp++; You_feel("%ssick.", (Sick) ? "very " : ""); - losehp(rnd(8), "cadaver", KILLED_BY_AN); + losehp(rnd(8), !glob ? "cadaver" : "rotted glob", KILLED_BY_AN); } /* delay is weight dependent */ - context.victual.reqtime = 3 + (mons[mnum].cwt >> 6); + context.victual.reqtime = 3 + ((!glob ? mons[mnum].cwt : otmp->owt) >> 6); if (!tp && !nonrotting_corpse(mnum) && (otmp->orotten || !rn2(7))) { if (rottenfood(otmp)) { @@ -2186,7 +2193,8 @@ struct obj *otmp; */ char buf[BUFSZ], foodsmell[BUFSZ], it_or_they[QBUFSZ], eat_it_anyway[QBUFSZ]; - boolean cadaver = (otmp->otyp == CORPSE), stoneorslime = FALSE; + boolean cadaver = (otmp->otyp == CORPSE || otmp->globby), + stoneorslime = FALSE; int material = objects[otmp->otyp].oc_material, mnum = otmp->corpsenm; long rotted = 0L; @@ -2205,6 +2213,7 @@ struct obj *otmp; if (cadaver && !nonrotting_corpse(mnum)) { long age = peek_at_iced_corpse_age(otmp); + /* worst case rather than random in this calculation to force prompt */ rotted = (monstermoves - age) / (10L + 0 /* was rn2(20) */); @@ -2547,20 +2556,18 @@ doeat() } /* re-calc the nutrition */ - if (otmp->otyp == CORPSE) - basenutrit = mons[otmp->corpsenm].cnutrit; - else - basenutrit = objects[otmp->otyp].oc_nutrition; + basenutrit = (otmp->otyp == CORPSE) ? mons[otmp->corpsenm].cnutrit + : otmp->globby ? otmp->owt + : objects[otmp->otyp].oc_nutrition; - debugpline1("before rounddiv: context.victual.reqtime == %d", - context.victual.reqtime); - debugpline2("oeaten == %d, basenutrit == %d", otmp->oeaten, basenutrit); - context.victual.reqtime = (basenutrit == 0) - ? 0 - : rounddiv(context.victual.reqtime - * (long) otmp->oeaten, - basenutrit); - debugpline1("after rounddiv: context.victual.reqtime == %d", + debugpline3( + "before rounddiv: victual.reqtime == %d, oeaten == %d, basenutrit == %d", + context.victual.reqtime, otmp->oeaten, basenutrit); + + context.victual.reqtime = (basenutrit == 0) ? 0 + : rounddiv(context.victual.reqtime * (long) otmp->oeaten, basenutrit); + + debugpline1("after rounddiv: victual.reqtime == %d", context.victual.reqtime); /* * calculate the modulo value (nutrit. units per round eating) @@ -3035,9 +3042,9 @@ struct obj *obj; long uneaten_amt, full_amount; uneaten_amt = (long) obj->oeaten; - full_amount = (obj->otyp == CORPSE) - ? (long) mons[obj->corpsenm].cnutrit - : (long) objects[obj->otyp].oc_nutrition; + full_amount = (obj->otyp == CORPSE) ? (long) mons[obj->corpsenm].cnutrit + : obj->globby ? obj->owt + : (long) objects[obj->otyp].oc_nutrition; if (uneaten_amt > full_amount) { impossible( "partly eaten food (%ld) more nutritious than untouched food (%ld)", diff --git a/src/invent.c b/src/invent.c index 3d46f692b..dfd3a9478 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 invent.c $NHDT-Date: 1454033599 2016/01/29 02:13:19 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.192 $ */ +/* NetHack 3.6 invent.c $NHDT-Date: 1454061993 2016/01/29 10:06:33 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.193 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -270,9 +270,11 @@ struct obj **potmp, **pobj; * * Don't do the age manipulation if lit. We would need * to stop the burn on both items, then merge the age, - * then restart the burn. + * then restart the burn. Glob ages are averaged in the + * absorb routine, which uses weight rather than quantity + * to adjust for proportion (glob quantity is always 1). */ - if (!obj->lamplit) + if (!obj->lamplit && !obj->globby) otmp->age = ((otmp->age * otmp->quan) + (obj->age * obj->quan)) / (otmp->quan + obj->quan); @@ -331,9 +333,8 @@ struct obj **potmp, **pobj; #endif /*0*/ } - /* handle puddings a bit differently; absorption will - * free the other object automatically so we can just - * return out from here. */ + /* handle puddings a bit differently; absorption will free the + other object automatically so we can just return out from here */ if (obj->globby) { pudding_merge_message(otmp, obj); obj_absorb(potmp, pobj); diff --git a/src/mkobj.c b/src/mkobj.c index 1c664127d..277fe8b46 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkobj.c $NHDT-Date: 1454033600 2016/01/29 02:13:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.116 $ */ +/* NetHack 3.6 mkobj.c $NHDT-Date: 1454061995 2016/01/29 10:06:35 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.117 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2642,7 +2642,8 @@ obj_absorb(obj1, obj2) struct obj **obj1, **obj2; { struct obj *otmp1, *otmp2; - int extrawt; + int o1wt, o2wt; + long agetmp; /* don't let people dumb it up */ if (obj1 && obj2) { @@ -2657,10 +2658,18 @@ struct obj **obj1, **obj2; otmp1->greased = otmp2->greased = 0; if (otmp1->orotten || otmp2->orotten) otmp1->orotten = otmp2->orotten = 1; - extrawt = otmp2->oeaten ? otmp2->oeaten : otmp2->owt; - otmp1->owt += extrawt; - otmp1->oeaten += otmp1->oeaten ? extrawt : 0; - otmp1->quan = 1; + o1wt = otmp1->oeaten ? otmp1->oeaten : otmp1->owt; + o2wt = otmp2->oeaten ? otmp2->oeaten : otmp2->owt; + /* averaging the relative ages is less likely to overflow + than averaging the absolute ages directly */ + agetmp = (((moves - otmp1->age) * o1wt + + (moves - otmp2->age) * o2wt) + / (o1wt + o2wt)); + otmp1->age = moves - agetmp; /* conv. relative back to absolute */ + otmp1->owt += o2wt; + if (otmp1->oeaten) + otmp1->oeaten += o2wt; + otmp1->quan = 1L; obj_extract_self(otmp2); newsym(otmp2->ox, otmp2->oy); /* in case of floor */ dealloc_obj(otmp2);