diff --git a/include/extern.h b/include/extern.h index 2e9f0250e..3c0abfaab 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1453514592 2016/01/23 02:03:12 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.542 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1454033598 2016/01/29 02:13:18 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.543 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -943,6 +943,7 @@ E int NDECL(dolook); E boolean FDECL(will_feel_cockatrice, (struct obj *, BOOLEAN_P)); E void FDECL(feel_cockatrice, (struct obj *, BOOLEAN_P)); E void FDECL(stackobj, (struct obj *)); +E boolean FDECL(mergable, (struct obj *, struct obj *)); E int NDECL(doprgold); E int NDECL(doprwep); E int NDECL(doprarm); @@ -1275,7 +1276,7 @@ E long FDECL(peek_at_iced_corpse_age, (struct obj *)); 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, unsigned)); +E struct obj *FDECL(obj_nexto_xy, (struct obj *, int, int, BOOLEAN_P)); E struct obj *FDECL(obj_absorb, (struct obj **, struct obj **)); E struct obj *FDECL(obj_meld, (struct obj **, struct obj **)); diff --git a/src/do.c b/src/do.c index 4b2ac5071..f6058eabd 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do.c $NHDT-Date: 1446975464 2015/11/08 09:37:44 $ $NHDT-Branch: master $:$NHDT-Revision: 1.149 $ */ +/* NetHack 3.6 do.c $NHDT-Date: 1454033599 2016/01/29 02:13:19 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.153 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -215,15 +215,13 @@ const char *verb; otense(obj, "tumble"), the_your[t->madeby_u]); } else if (obj->globby) { /* Globby things like puddings might stick together */ - while (obj - && (otmp = obj_nexto_xy(obj->otyp, x, y, obj->o_id)) - != (struct obj *) 0) { + while (obj && (otmp = obj_nexto_xy(obj, x, y, TRUE)) != 0) { pudding_merge_message(obj, otmp); /* intentionally not getting the melded object; obj_meld may set * obj to null. */ (void) obj_meld(&obj, &otmp); } - return (boolean) (obj == NULL); + return (boolean) !obj; } return FALSE; } diff --git a/src/invent.c b/src/invent.c index 504f02722..3d46f692b 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 invent.c $NHDT-Date: 1452650438 2016/01/13 02:00:38 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.188 $ */ +/* NetHack 3.6 invent.c $NHDT-Date: 1454033599 2016/01/29 02:13:19 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.192 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -9,7 +9,6 @@ STATIC_DCL int FDECL(CFDECLSPEC sortloot_cmp, (struct obj *, struct obj *)); STATIC_DCL void NDECL(reorder_invent); -STATIC_DCL boolean FDECL(mergable, (struct obj *, struct obj *)); STATIC_DCL void FDECL(noarmor, (BOOLEAN_P)); STATIC_DCL void FDECL(invdisp_nothing, (const char *, const char *)); STATIC_DCL boolean FDECL(worn_wield_only, (struct obj *)); @@ -335,7 +334,7 @@ struct obj **potmp, **pobj; /* handle puddings a bit differently; absorption will * free the other object automatically so we can just * return out from here. */ - if (Is_pudding(obj)) { + if (obj->globby) { pudding_merge_message(otmp, obj); obj_absorb(potmp, pobj); return 1; @@ -2889,8 +2888,8 @@ struct obj *obj; return; } -/* returns TRUE if obj & otmp can be merged */ -STATIC_OVL boolean +/* returns TRUE if obj & otmp can be merged; used in invent.c and mkobj.c */ +boolean mergable(otmp, obj) register struct obj *otmp, *obj; { @@ -2908,31 +2907,24 @@ register struct obj *otmp, *obj; return TRUE; if (obj->unpaid != otmp->unpaid || obj->spe != otmp->spe - || obj->dknown != otmp->dknown || obj->cursed != otmp->cursed || obj->blessed != otmp->blessed || obj->no_charge != otmp->no_charge || obj->obroken != otmp->obroken || obj->otrapped != otmp->otrapped || obj->lamplit != otmp->lamplit || obj->bypass != otmp->bypass) return FALSE; + if (obj->globby) + return TRUE; + /* Checks beyond this point either aren't applicable to globs + * or don't inhibit their merger. + */ + if (obj->oclass == FOOD_CLASS && (obj->oeaten != otmp->oeaten || obj->orotten != otmp->orotten)) return FALSE; - if (obj->globby) { - /* globs won't merge if they have different bless/curse - state, but will merge non-bknown with bknown */ - if (obj->bknown != otmp->bknown) - obj->bknown = otmp->bknown = 0; - if (obj->rknown != otmp->rknown) - obj->rknown = otmp->rknown = 0; - if (obj->greased != otmp->greased) - obj->greased = otmp->greased = 0; - /* checks beyond this point aren't applicable to globs */ - return TRUE; - } - - if ((obj->bknown != otmp->bknown && !Role_if(PM_PRIEST)) + if (obj->dknown != otmp->dknown + || (obj->bknown != otmp->bknown && !Role_if(PM_PRIEST)) || obj->oeroded != otmp->oeroded || obj->oeroded2 != otmp->oeroded2 || obj->greased != otmp->greased) return FALSE; diff --git a/src/mkobj.c b/src/mkobj.c index a6f8bfd29..1c664127d 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkobj.c $NHDT-Date: 1447475943 2015/11/14 04:39:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.113 $ */ +/* NetHack 3.6 mkobj.c $NHDT-Date: 1454033600 2016/01/29 02:13:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.116 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2578,15 +2578,10 @@ struct obj * obj_nexto(otmp) struct obj *otmp; { - struct obj *otmp2 = (struct obj *) 0; - - if (otmp) { - otmp2 = obj_nexto_xy(otmp->otyp, otmp->ox, otmp->oy, otmp->o_id); - } else { + if (!otmp) impossible("obj_nexto: wasn't given an object to check"); - } - return otmp2; + return obj_nexto_xy(otmp, otmp->ox, otmp->oy, TRUE); } /* @@ -2598,24 +2593,27 @@ struct obj *otmp; * reliably predict which one we want to 'find' first */ struct obj * -obj_nexto_xy(otyp, x, y, oid) -int otyp, x, y; -unsigned oid; +obj_nexto_xy(obj, x, y, recurs) +struct obj *obj; +int x, y; +boolean recurs; { struct obj *otmp; - int fx, fy, ex, ey; + int fx, fy, ex, ey, otyp = obj->otyp; short dx, dy; /* check under our "feet" first */ otmp = sobj_at(otyp, x, y); while (otmp) { /* don't be clever and find ourselves */ - if (otmp->o_id != oid) { + if (otmp != obj && mergable(otmp, obj)) return otmp; - } otmp = nxtobj(otmp, otyp, TRUE); } + if (!recurs) + return (struct obj *) 0; + /* search in a random order */ dx = (rn2(2) ? -1 : 1); dy = (rn2(2) ? -1 : 1); @@ -2626,9 +2624,8 @@ unsigned oid; for (fy = ey; abs(fy - ey) < 3; fy += dy) { /* 0, 0 was checked above */ if (isok(fx, fy) && (fx != x || fy != y)) { - if ((otmp = sobj_at(otyp, fx, fy)) != 0) { + if ((otmp = obj_nexto_xy(obj, fx, fy, FALSE)) != 0) return otmp; - } } } } @@ -2644,14 +2641,22 @@ struct obj * obj_absorb(obj1, obj2) struct obj **obj1, **obj2; { - struct obj *otmp1 = (struct obj *) 0, *otmp2 = (struct obj *) 0; - int extrawt = 0; + struct obj *otmp1, *otmp2; + int extrawt; /* don't let people dumb it up */ if (obj1 && obj2) { otmp1 = *obj1; otmp2 = *obj2; - if (otmp1 && otmp2) { + if (otmp1 && otmp2 && otmp1 != otmp2) { + if (otmp1->bknown != otmp2->bknown) + otmp1->bknown = otmp2->bknown = 0; + if (otmp1->rknown != otmp2->rknown) + otmp1->rknown = otmp2->rknown = 0; + if (otmp1->greased != otmp2->greased) + 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; @@ -2677,13 +2682,14 @@ struct obj * obj_meld(obj1, obj2) struct obj **obj1, **obj2; { - struct obj *otmp1 = (struct obj *) 0, *otmp2 = (struct obj *) 0; + struct obj *otmp1, *otmp2; if (obj1 && obj2) { otmp1 = *obj1; otmp2 = *obj2; - if (otmp1 && otmp2) { - if (otmp1->owt > otmp2->owt || rn2(2)) { + if (otmp1 && otmp2 && otmp1 != otmp2) { + if (otmp1->owt > otmp2->owt + || (otmp1->owt == otmp2->owt && rn2(2))) { return obj_absorb(obj1, obj2); } return obj_absorb(obj2, obj1);