diff --git a/include/extern.h b/include/extern.h index c88f61ce9..b9a6f0952 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1225,6 +1225,7 @@ E int FDECL(hornoplenty, (struct obj *,BOOLEAN_P)); E void NDECL(obj_sanity_check); E struct obj* FDECL(obj_nexto, (struct obj*)); E struct obj* FDECL(obj_nexto_xy, (int, int, int, int)); +E struct obj* FDECL(obj_absorb, (struct obj**, struct obj**)); E struct obj* FDECL(obj_meld, (struct obj**, struct obj**)); /* ### mkroom.c ### */ diff --git a/src/invent.c b/src/invent.c index f1a38683a..c1db275c9 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,3 @@ -/* NetHack 3.5 invent.c $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ /* NetHack 3.5 invent.c $Date: 2013/11/05 00:57:55 $ $Revision: 1.125 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -168,9 +167,10 @@ struct obj **potmp, **pobj; / (otmp->quan + obj->quan); otmp->quan += obj->quan; - /* temporary special case for gold objects!!!! */ + /* temporary special case for gold objects!!!! */ if (otmp->oclass == COIN_CLASS) otmp->owt = weight(otmp); - else otmp->owt += obj->owt; + /* and puddings!!!1!!one! */ + else if (!Is_pudding(otmp)) otmp->owt += obj->owt; if(!has_oname(otmp) && has_oname(obj)) otmp = *potmp = oname(otmp, ONAME(obj)); obj_extract_self(obj); @@ -214,6 +214,15 @@ 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. */ + if (Is_pudding(obj)) { + pline("The %s coalesce.", makeplural(obj_typename(obj->otyp))); + obj_absorb(potmp, pobj); + return(1); + } + obfree(obj,otmp); /* free(obj), bill->otmp */ return(1); } @@ -313,18 +322,6 @@ struct obj *obj; addinv_core1(obj); - /* we want globby things to become one big glob whereever possible - so we need to trigger this before merged() is called */ - if (obj->globby && merge_choice(invent, obj)) { - for (prev = 0, otmp = invent; otmp; prev = otmp, otmp = otmp->nobj) { - if (otmp->otyp == obj->otyp) { - pline("The %s coalesce.", makeplural(obj_typename(obj->otyp))); - obj = obj_meld(&otmp, &obj); - goto added; - } - } - } - /* merge with quiver in preference to any other inventory slot in case quiver and wielded weapon are both eligible; adding extra to quivered stack is more useful than to wielded one */ diff --git a/src/mkobj.c b/src/mkobj.c index 25e598746..4985a87a0 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -2198,40 +2198,61 @@ obj_nexto_xy(otyp, x, y, oid) /* - * Causes one object to absorb another, smaller one of - * its own type, increasing weight accordingly. - * Returns the object that remains; frees the other. + * Causes one object to absorb another, increasing + * weight accordingly. Frees obj2; obj1 remains and + * is returned. + */ +struct obj* +obj_absorb(obj1, obj2) + struct obj **obj1, **obj2; +{ + struct obj *otmp1 = NULL, *otmp2 = NULL; + int extrawt = 0; + + /* don't let people dumb it up */ + if (obj1 && obj2) { + otmp1 = *obj1; + otmp2 = *obj2; + if (otmp1 && otmp2) { + extrawt = otmp2->oeaten ? otmp2->oeaten : otmp2->owt; + otmp1->owt += extrawt; + otmp1->oeaten += otmp1->oeaten ? extrawt : 0; + otmp1->quan = 1; + obj_extract_self(otmp2); + dealloc_obj(otmp2); + return otmp1; + } + } + + impossible("obj_absorb: not called with two actual objects"); + return NULL; +} + + +/* + * Causes the heavier object to absorb the lighter object; + * wrapper for obj_absorb so that floor_effects works more + * cleanly (since we don't know which we want to stay around) */ struct obj* obj_meld(obj1, obj2) struct obj **obj1, **obj2; { struct obj *otmp1 = NULL, *otmp2 = NULL; - int extrawt = 0; - boolean reversed = FALSE; - if (obj1 && obj2 && *obj1 && *obj2) { - otmp1 = *obj1; + if (obj1 && obj2) { + otmp1 = *obj1; otmp2 = *obj2; - - if ((otmp1->owt == otmp2->owt && rn2(2)) - || (otmp1->owt < otmp2->owt)) { - otmp2 = *obj1; otmp1 = *obj2; - reversed = TRUE; - } - - extrawt = otmp2->oeaten ? otmp2->oeaten : otmp2->owt; - otmp1->owt += extrawt; - otmp1->oeaten += otmp1->oeaten ? extrawt : 0; - obj_extract_self(otmp2); - dealloc_obj(otmp2); - if (reversed) { *obj1 = NULL; } else { *obj2 = NULL; } - return otmp1; + if (otmp1 && otmp2) { + if (otmp1->owt > otmp2->owt || rn2(2)) { + return obj_absorb(obj1, obj2); + } + return obj_absorb(obj2, obj1); + } } impossible("obj_meld: not called with two actual objects"); return NULL; } - /*mkobj.c*/ diff --git a/src/objects.c b/src/objects.c index 5dc51c695..fc1796244 100644 --- a/src/objects.c +++ b/src/objects.c @@ -676,10 +676,10 @@ OBJECT(OBJ("meat ring", (char *)0), 0, FOOD_CLASS, 0, 1, 5, 1, 0, 0, 0, 0, 5, CLR_BROWN), /* pudding 'corpses' will turn into these and combine */ -FOOD("glob of gray ooze", 0, 2, 10, 0, FLESH, 0, CLR_GRAY), -FOOD("glob of brown pudding", 0, 2, 10, 0, FLESH, 0, CLR_BROWN), -FOOD("glob of green slime", 0, 2, 10, 0, FLESH, 0, CLR_GREEN), -FOOD("glob of black pudding", 0, 2, 10, 0, FLESH, 0, CLR_BLACK), +FOOD("glob of gray ooze", 0, 2, 20, 0, FLESH, 20, CLR_GRAY), +FOOD("glob of brown pudding", 0, 2, 20, 0, FLESH, 20, CLR_BROWN), +FOOD("glob of green slime", 0, 2, 20, 0, FLESH, 20, CLR_GREEN), +FOOD("glob of black pudding", 0, 2, 20, 0, FLESH, 20, CLR_BLACK), /* fruits & veggies */ FOOD("kelp frond", 0, 1, 1, 0, VEGGY, 30, CLR_GREEN), diff --git a/src/objnam.c b/src/objnam.c index a1115f5af..55ee50c1b 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,5 +1,4 @@ /* NetHack 3.5 objnam.c $NHDT-Date: 1426470349 2015/03/16 01:45:49 $ $NHDT-Branch: derek-farming $:$NHDT-Revision: 1.108 $ */ -/* NetHack 3.5 objnam.c $Date: 2011/10/27 02:24:54 $ $Revision: 1.101 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -865,9 +864,6 @@ ring: Strcat(bp, " (laid by you)"); } } - if (wizard) { - Sprintf(eos(bp), " (%d aum)", obj->owt); - } if (obj->otyp == MEAT_RING) goto ring; break; case BALL_CLASS: @@ -942,6 +938,12 @@ ring: Strcpy(prefix, "an "); Strcpy(prefix+3, tmpbuf+2); } + + /* show weight for items (debug tourist info) + * aum is stolen from Crawl's "Arbitrary Unit of Measure" */ + if (wizard) { + Sprintf(eos(bp), " (%d aum)", obj->owt); + } bp = strprepend(bp, prefix); return(bp); } @@ -2496,22 +2498,30 @@ struct obj *no_wish; bp += 8; } - /* - * Find corpse type using "of" (figurine of an orc, tin of orc meat) - * Don't check if it's a wand or spellbook. - * (avoid "wand/finger of death" confusion). - */ - if (!strstri(bp, "wand ") - && !strstri(bp, "spellbook ") - && !strstri(bp, "finger ")) { - if (((p = strstri(bp, "tin of ")) != 0) && - (tmp = tin_variety_txt(p+7, &tinv)) && - (mntmp = name_to_mon(p+7+tmp)) >= LOW_PM) { - *(p+3) = 0; - tvariety = tinv; - } else if ((p = strstri(bp, " of ")) != 0 - && (mntmp = name_to_mon(p+4)) >= LOW_PM) - *p = 0; + /* intercept pudding globs here; they're a valid wish target, + * but we need them to not get treated like a corpse */ + if (((p = strstri(bp, "glob of ")) != 0) + && (mntmp = name_to_mon(p+8)) >= PM_GRAY_OOZE + && mntmp <= PM_BLACK_PUDDING) { + mntmp = NON_PM; /* lie to ourselves */ + } else { + /* + * Find corpse type using "of" (figurine of an orc, tin of orc meat) + * Don't check if it's a wand or spellbook. + * (avoid "wand/finger of death" confusion). + */ + if (!strstri(bp, "wand ") + && !strstri(bp, "spellbook ") + && !strstri(bp, "finger ")) { + if (((p = strstri(bp, "tin of ")) != 0) && + (tmp = tin_variety_txt(p + 7, &tinv)) && + (mntmp = name_to_mon(p + 7 + tmp)) >= LOW_PM) { + *(p + 3) = 0; + tvariety = tinv; + } else if ((p = strstri(bp, " of ")) != 0 + && (mntmp = name_to_mon(p + 4)) >= LOW_PM) + *p = 0; + } } /* Find corpse type w/o "of" (red dragon scale mail, yeti corpse) */ if (strncmpi(bp, "samurai sword", 13)) /* not the "samurai" monster! */