-/* NetHack 3.6 context.h $NHDT-Date: 1434421363 2015/06/16 02:22:43 $ $NHDT-Branch: master $:$NHDT-Revision: 1.26 $ */
+/* NetHack 3.6 context.h $NHDT-Date: 1445215010 2015/10/19 00:36:50 $ $NHDT-Branch: master $:$NHDT-Revision: 1.27 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
unsigned m_id; /* monster id of hitmon, in save file */
};
+struct obj_split {
+ unsigned parent_oid, /* set: splitobj(), */
+ child_oid; /* reset: clear_splitobjs() */
+};
+
struct tribute_info {
size_t tributesz; /* make it possible to skip this in future */
boolean enabled; /* Do we have tributes turned on? */
struct takeoff_info takeoff;
struct warntype_info warntype;
struct polearm_info polearm;
+ struct obj_split objsplit; /* track most recently split object stack */
struct tribute_info tribute;
};
-/* NetHack 3.6 extern.h $NHDT-Date: 1445126411 2015/10/18 00:00:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.508 $ */
+/* NetHack 3.6 extern.h $NHDT-Date: 1445215014 2015/10/19 00:36:54 $ $NHDT-Branch: master $:$NHDT-Revision: 1.509 $ */
/* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */
E int NDECL(rndmonnum);
E boolean FDECL(bogon_is_pname, (CHAR_P));
E struct obj *FDECL(splitobj, (struct obj *, long));
+E struct obj *FDECL(unsplitobj, (struct obj *));
+E void NDECL(clear_splitobjs);
E void FDECL(replace_object, (struct obj *, struct obj *));
E void FDECL(bill_dummy_object, (struct obj *));
E void FDECL(costly_alteration, (struct obj *, int));
-/* NetHack 3.6 patchlevel.h $NHDT-Date: 1432512782 2015/05/25 00:13:02 $ $NHDT-Branch: master $:$NHDT-Revision: 1.107 $ */
+/* NetHack 3.6 patchlevel.h $NHDT-Date: 1445215015 2015/10/19 00:36:55 $ $NHDT-Branch: master $:$NHDT-Revision: 1.109 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
/*
* PATCHLEVEL is updated for each release.
*/
-#define PATCHLEVEL 0
+#define PATCHLEVEL 1
/*
* Incrementing EDITLEVEL can be used to force invalidation of old bones
* and save files.
-/* NetHack 3.6 allmain.c $NHDT-Date: 1438505671 2015/08/02 08:54:31 $ $NHDT-Branch: master $:$NHDT-Revision: 1.62 $ */
+/* NetHack 3.6 allmain.c $NHDT-Date: 1445215016 2015/10/19 00:36:56 $ $NHDT-Branch: master $:$NHDT-Revision: 1.65 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
/* once-per-player-input things go here */
/****************************************/
+ clear_splitobjs();
find_ac();
if (!context.mv || Blind) {
/* redo monsters if hallu or wearing a helm of telepathy */
-/* NetHack 3.6 dothrow.c $NHDT-Date: 1444772016 2015/10/13 21:33:36 $ $NHDT-Branch: master $:$NHDT-Revision: 1.106 $ */
+/* NetHack 3.6 dothrow.c $NHDT-Date: 1445215018 2015/10/19 00:36:58 $ $NHDT-Branch: master $:$NHDT-Revision: 1.110 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
* merge obj into another stack--usually quiver--even if it hadn't
* been split from there (possibly triggering a panic in addinv),
* and freeinv+addinv potentially has other side-effects.
- *
- * If obj came from splitobj(), it has been split from the item
- * which precedes it in inventory and shares same inv letter.
- * (This could get a false match if obj wasn't split from the
- * preceding item and they're both using the overflow letter '#',
- * but merging to have fewer '#' items should be a good thing,
- * and we're not using addinv() so can't trigger its panic.)
*/
- for (otmp = invent; otmp; otmp = otmp->nobj)
- if (otmp == obj) {
- /* obj wasn't the result of splitobj, so we're done */
- break;
- } else if (otmp->nobj == obj) {
- if (otmp->invlet == obj->invlet)
- (void) merged(&otmp, &obj);
- /* found obj's preceding item, so no need to look further */
- break;
- }
+ if (obj->o_id == context.objsplit.parent_oid
+ || obj->o_id == context.objsplit.child_oid)
+ (void) unsplitobj(obj);
return 0; /* no time passes */
}
Sprintf(killer.name, "throwing %s bare-handed", killer_xname(obj));
instapetrify(killer.name);
}
- if (obj->otyp == TOWEL && obj->spe > 0) obj->spe--;
if (welded(obj)) {
weldmsg(obj);
return 1;
}
+ if (is_wet_towel(obj))
+ dry_a_towel(obj, -1, FALSE);
/* Multishot calculations
* (potential volley of up to N missiles; default for N is 1)
for (otmp = invent; otmp; otmp = otmp->nobj) {
if (otmp->owornmask || otmp->oartifact || !otmp->dknown) {
; /* Skip it */
- } else if (otmp->otyp == ROCK ||
+ } else if (otmp->otyp == ROCK
/* seen rocks or known flint or known glass */
- (objects[otmp->otyp].oc_name_known && otmp->otyp == FLINT)
- || (objects[otmp->otyp].oc_name_known
- && otmp->oclass == GEM_CLASS
- && objects[otmp->otyp].oc_material == GLASS)) {
+ || (otmp->otyp == FLINT
+ && objects[otmp->otyp].oc_name_known)
+ || (otmp->oclass == GEM_CLASS
+ && objects[otmp->otyp].oc_material == GLASS
+ && objects[otmp->otyp].oc_name_known)) {
if (uslinging())
oammo = otmp;
else if (ammo_and_launcher(otmp, uswapwep))
player has to select them explicitly */
} else if (is_ammo(otmp)) {
if (ammo_and_launcher(otmp, uwep))
- /* Ammo matched with launcher (bow and arrow, crossbow and
- * bolt) */
+ /* Ammo matched with launcher (bow+arrow, crossbow+bolt) */
oammo = otmp;
else if (ammo_and_launcher(otmp, uswapwep))
altammo = otmp;
-/* NetHack 3.6 invent.c $NHDT-Date: 1438652306 2015/08/04 01:38:26 $ $NHDT-Branch: master $:$NHDT-Revision: 1.170 $ */
+/* NetHack 3.6 invent.c $NHDT-Date: 1445215019 2015/10/19 00:36:59 $ $NHDT-Branch: master $:$NHDT-Revision: 1.174 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
}
/*
-Adjust hero intrinsics as if this object was being added to the hero's
-inventory. Called _before_ the object has been added to the hero's
-inventory.
-
-This is called when adding objects to the hero's inventory normally (via
-addinv) or when an object in the hero's inventory has been polymorphed
-in-place.
-
-It may be valid to merge this code with with addinv_core2().
-*/
+ * Adjust hero intrinsics as if this object was being added to the hero's
+ * inventory. Called _before_ the object has been added to the hero's
+ * inventory.
+ *
+ * This is called when adding objects to the hero's inventory normally (via
+ * addinv) or when an object in the hero's inventory has been polymorphed
+ * in-place.
+ *
+ * It may be valid to merge this code with with addinv_core2().
+ */
void
addinv_core1(obj)
struct obj *obj;
}
/*
-Adjust hero intrinsics as if this object was being added to the hero's
-inventory. Called _after_ the object has been added to the hero's
-inventory.
-
-This is called when adding objects to the hero's inventory normally (via
-addinv) or when an object in the hero's inventory has been polymorphed
-in-place.
-*/
+ * Adjust hero intrinsics as if this object was being added to the hero's
+ * inventory. Called _after_ the object has been added to the hero's
+ * inventory.
+ *
+ * This is called when adding objects to the hero's inventory normally (via
+ * addinv) or when an object in the hero's inventory has been polymorphed
+ * in-place.
+ */
void
addinv_core2(obj)
struct obj *obj;
}
/*
-Add obj to the hero's inventory. Make sure the object is "free".
-Adjust hero attributes as necessary.
-*/
+ * Add obj to the hero's inventory. Make sure the object is "free".
+ * Adjust hero attributes as necessary.
+ */
struct obj *
addinv(obj)
struct obj *obj;
}
/*
-Adjust hero's attributes as if this object was being removed from the
-hero's inventory. This should only be called from freeinv() and
-where we are polymorphing an object already in the hero's inventory.
-
-Should think of a better name...
-*/
+ * Adjust hero's attributes as if this object was being removed from the
+ * hero's inventory. This should only be called from freeinv() and
+ * where we are polymorphing an object already in the hero's inventory.
+ *
+ * Should think of a better name...
+ */
void
freeinv_core(obj)
struct obj *obj;
"Hong Kong Luna Dollar", /* The Moon is a Harsh Mistress */
"kongbuck", /* Snow Crash */
"nanite", /* System Shock 2 */
- "quatloo", /* Sim City */
+ "quatloo", /* Star Trek, Sim City */
"simoleon", /* Sim City */
"solari", /* Spaceballs */
"spacebuck", /* Spaceballs */
"sporebuck", /* Spore */
"Triganic Pu", /* The Hitchhiker's Guide to the Galaxy */
"woolong", /* Cowboy Bebop */
+ "zorkmid", /* Zork, NetHack */
};
const char *
currency(amount)
long amount;
{
- if (amount == 1L)
- return (Hallucination ? currencies[rn2(SIZE(currencies))]
- : "zorkmid");
- else
- return (Hallucination ? makeplural(currencies[rn2(SIZE(currencies))])
- : "zorkmids");
+ const char *res;
+
+ res = Hallucination ? currencies[rn2(SIZE(currencies))] : "zorkmid";
+ if (amount != 1L)
+ res = makeplural(res);
+ return res;
}
boolean
return ((struct obj *) 0);
}
+/* compact a string of inventory letters by dashing runs of letters */
STATIC_OVL void
compactify(buf)
register char *buf;
-/* compact a string of inventory letters by dashing runs of letters */
{
register int i1 = 1, i2 = 1;
register char ilet, ilet1, ilet2;
ilet = 'a' - 1;
if (*objchn && (*objchn)->oclass == COIN_CLASS)
ilet--; /* extra iteration */
- /*
- * Multiple Drop can change the invent chain while it operates
- * (dropping a burning potion of oil while levitating creates
- * an explosion which can destroy inventory items), so simple
- * list traversal
- * for (otmp = *objchn; otmp; otmp = otmp2) {
- * otmp2 = otmp->nobj;
- * ...
- * }
- * is inadequate here. Use each object's bypass bit to keep
- * track of which list elements have already been processed.
- */
+ /*
+ * Multiple Drop can change the invent chain while it operates
+ * (dropping a burning potion of oil while levitating creates
+ * an explosion which can destroy inventory items), so simple
+ * list traversal
+ * for (otmp = *objchn; otmp; otmp = otmp2) {
+ * otmp2 = otmp->nobj;
+ * ...
+ * }
+ * is inadequate here. Use each object's bypass bit to keep
+ * track of which list elements have already been processed.
+ */
bypass_objlist(*objchn, FALSE); /* clear chain's bypass bits */
while ((otmp = nxt_unbypassed_obj(*objchn)) != 0) {
if (ilet == 'z')
* user-assigned names, the 'count' portion being moved is
* effectively renamed so that it will merge with 'to' stack.
*/
-int doorganize() /* inventory organizer by Del Lamb */
+int
+doorganize() /* inventory organizer by Del Lamb */
{
struct obj *obj, *otmp, *splitting, *bumped;
int ix, cur, trycnt;
prinv(adj_type, obj, 0L);
if (bumped)
prinv("Moving:", bumped, 0L);
+ if (splitting)
+ clear_splitobjs(); /* reset splitobj context */
update_inventory();
return (0);
}
-/* NetHack 3.6 mkobj.c $NHDT-Date: 1444617220 2015/10/12 02:33:40 $ $NHDT-Branch: master $:$NHDT-Revision: 1.110 $ */
+/* NetHack 3.6 mkobj.c $NHDT-Date: 1445215021 2015/10/19 00:37:01 $ $NHDT-Branch: master $:$NHDT-Revision: 1.111 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
obj->owt = weight(obj);
otmp->quan = num;
otmp->owt = weight(otmp); /* -= obj->owt ? */
+
+ context.objsplit.parent_oid = obj->o_id;
+ context.objsplit.child_oid = otmp->o_id;
obj->nobj = otmp;
/* Only set nexthere when on the floor, nexthere is also used */
/* as a back pointer to the container object when contained. */
return otmp;
}
+/* try to find the stack obj was split from, then merge them back together;
+ returns the combined object if unsplit is successful, null otherwise */
+struct obj *
+unsplitobj(obj)
+struct obj *obj;
+{
+ unsigned target_oid = 0;
+ struct obj *oparent = 0, *ochild = 0, *list = 0;
+
+ /*
+ * We don't operate on floor objects (we're following o->nobj rather
+ * than o->nexthere), on free objects (don't know which list to use when
+ * looking for obj's parent or child), on bill objects (too complicated,
+ * not needed), or on buried or migrating objects (not needed).
+ * [This could be improved, but at present additional generality isn't
+ * necessary.]
+ */
+ switch (obj->where) {
+ case OBJ_FREE:
+ case OBJ_FLOOR:
+ case OBJ_ONBILL:
+ case OBJ_MIGRATING:
+ case OBJ_BURIED:
+ default:
+ return (struct obj *) 0;
+ case OBJ_INVENT:
+ list = invent;
+ break;
+ case OBJ_MINVENT:
+ list = obj->ocarry->minvent;
+ break;
+ case OBJ_CONTAINED:
+ list = obj->ocontainer->cobj;
+ break;
+ }
+
+ /* first try the expected case; obj is split from another stack */
+ if (obj->o_id == context.objsplit.child_oid) {
+ /* parent probably precedes child and will require list traversal */
+ ochild = obj;
+ target_oid = context.objsplit.parent_oid;
+ if (obj->nobj && obj->nobj->o_id == target_oid)
+ oparent = obj->nobj;
+ } else if (obj->o_id == context.objsplit.parent_oid) {
+ /* alternate scenario: another stack was split from obj;
+ child probably follows parent and will be found here */
+ oparent = obj;
+ target_oid = context.objsplit.child_oid;
+ if (obj->nobj && obj->nobj->o_id == target_oid)
+ ochild = obj->nobj;
+ }
+ /* if we have only half the split, scan obj's list to find other half */
+ if (ochild && !oparent) {
+ /* expected case */
+ for (obj = list; obj; obj = obj->nobj)
+ if (obj->o_id == target_oid) {
+ oparent = obj;
+ break;
+ }
+ } else if (oparent && !ochild) {
+ /* alternate scenario */
+ for (obj = list; obj; obj = obj->nobj)
+ if (obj->o_id == target_oid) {
+ ochild = obj;
+ break;
+ }
+ }
+ /* if we have both parent and child, try to merge them;
+ if successful, return the combined stack, otherwise return null */
+ return (oparent && ochild && merged(&oparent, &ochild)) ? oparent : 0;
+}
+
+/* reset splitobj()/unsplitobj() context */
+void
+clear_splitobjs()
+{
+ context.objsplit.parent_oid = context.objsplit.child_oid = 0;
+}
+
/*
* Insert otmp right after obj in whatever chain(s) it is on. Then extract
* obj from the chain(s). This function does a literal swap. It is up to
-/* NetHack 3.6 mon.c $NHDT-Date: 1444095155 2015/10/06 01:32:35 $ $NHDT-Branch: master $:$NHDT-Revision: 1.183 $ */
+/* NetHack 3.6 mon.c $NHDT-Date: 1445215021 2015/10/19 00:37:01 $ $NHDT-Branch: master $:$NHDT-Revision: 1.190 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
/* reset obj bypasses before next monster moves */
if (context.bypasses)
clear_bypasses();
+ clear_splitobjs();
if (minliquid(mtmp))
continue;
/* reset obj bypasses after last monster has moved */
if (context.bypasses)
clear_bypasses();
- dmonsfree(); /* remove all dead monsters */
+ clear_splitobjs();
+ /* remove dead monsters; dead vault guard will be left at <0,0>
+ if temporary corridor out of vault hasn't been removed yet */
+ dmonsfree();
/* a monster may have levteleported player -dlc */
if (u.utotype) {