diff -Ndru nethack-3.4.3/include/extern.h nethack-patched/include/extern.h --- nethack-3.4.3/include/extern.h 2006-12-04 21:58:58.000000000 +0000 +++ nethack-patched/include/extern.h 2007-01-25 22:22:10.000000000 +0000 @@ -863,6 +863,7 @@ E int NDECL(doforce); E boolean FDECL(boxlock, (struct obj *,struct obj *)); E boolean FDECL(doorlock, (struct obj *,int,int)); +E void FDECL(chest_shatter_msg, (struct obj *)); E int NDECL(doopen); E int NDECL(doclose); @@ -1961,6 +1962,7 @@ E void FDECL(fall_asleep, (int, BOOLEAN_P)); E void FDECL(attach_egg_hatch_timeout, (struct obj *)); E void FDECL(attach_fig_transform_timeout, (struct obj *)); +E void FDECL(incubate_egg, (struct obj *)); E void FDECL(kill_egg, (struct obj *)); E void FDECL(hatch_egg, (genericptr_t, long)); E void FDECL(learn_egg_type, (int)); diff -Ndru nethack-3.4.3/include/hack.h nethack-patched/include/hack.h --- nethack-3.4.3/include/hack.h 2006-12-04 21:59:00.000000000 +0000 +++ nethack-patched/include/hack.h 2007-01-25 21:40:36.000000000 +0000 @@ -243,6 +243,7 @@ #define LUNG 16 #define NOSE 17 #define STOMACH 18 +#define RUMP 19 /* Flags to control menus */ #define MENUTYPELEN sizeof("traditional ") diff -Ndru nethack-3.4.3/src/lock.c nethack-patched/src/lock.c --- nethack-3.4.3/src/lock.c 2006-12-04 21:59:02.000000000 +0000 +++ nethack-patched/src/lock.c 2007-01-25 21:31:36.000000000 +0000 @@ -18,7 +18,6 @@ STATIC_DCL const char *NDECL(lock_action); STATIC_DCL boolean FDECL(obstructed,(int,int)); -STATIC_DCL void FDECL(chest_shatter_msg, (struct obj *)); boolean picking_lock(x, y) @@ -877,7 +876,7 @@ return res; } -STATIC_OVL void +void chest_shatter_msg(otmp) struct obj *otmp; { diff -Ndru nethack-3.4.3/src/polyself.c nethack-patched/src/polyself.c --- nethack-3.4.3/src/polyself.c 2006-12-04 21:59:04.000000000 +0000 +++ nethack-patched/src/polyself.c 2007-01-25 21:49:32.000000000 +0000 @@ -1137,47 +1137,48 @@ *humanoid_parts[] = { "arm", "eye", "face", "finger", "fingertip", "foot", "hand", "handed", "head", "leg", "light headed", "neck", "spine", "toe", "hair", - "blood", "lung", "nose", "stomach"}, + "blood", "lung", "nose", "stomach", "rump"}, *jelly_parts[] = { "pseudopod", "dark spot", "front", "pseudopod extension", "pseudopod extremity", "pseudopod root", "grasp", "grasped", "cerebral area", "lower pseudopod", "viscous", "middle", "surface", "pseudopod extremity", "ripples", "juices", - "surface", "sensor", "stomach" }, + "surface", "sensor", "stomach", "underside"}, *animal_parts[] = { "forelimb", "eye", "face", "foreclaw", "claw tip", "rear claw", "foreclaw", "clawed", "head", "rear limb", "light headed", "neck", "spine", "rear claw tip", - "fur", "blood", "lung", "nose", "stomach" }, + "fur", "blood", "lung", "nose", "stomach", "rump"}, *bird_parts[] = { "wing", "eye", "face", "wing", "wing tip", "foot", "wing", "winged", "head", "leg", "light headed", "neck", "spine", "toe", - "feathers", "blood", "lung", "bill", "stomach" }, + "feathers", "blood", "lung", "bill", "stomach", "underside"}, *horse_parts[] = { "foreleg", "eye", "face", "forehoof", "hoof tip", "rear hoof", "foreclaw", "hooved", "head", "rear leg", "light headed", "neck", "backbone", "rear hoof tip", - "mane", "blood", "lung", "nose", "stomach"}, + "mane", "blood", "lung", "nose", "stomach", "rump"}, *sphere_parts[] = { "appendage", "optic nerve", "body", "tentacle", "tentacle tip", "lower appendage", "tentacle", "tentacled", "body", "lower tentacle", "rotational", "equator", "body", "lower tentacle tip", "cilia", "life force", "retina", - "olfactory nerve", "interior" }, + "olfactory nerve", "interior", "underside"}, *fungus_parts[] = { "mycelium", "visual area", "front", "hypha", "hypha", "root", "strand", "stranded", "cap area", "rhizome", "sporulated", "stalk", "root", "rhizome tip", - "spores", "juices", "gill", "gill", "interior" }, + "spores", "juices", "gill", "gill", "interior", "underside"}, *vortex_parts[] = { "region", "eye", "front", "minor current", "minor current", "lower current", "swirl", "swirled", "central core", "lower current", "addled", "center", "currents", "edge", "currents", "life force", - "center", "leading edge", "interior" }, + "center", "leading edge", "interior", "base"}, *snake_parts[] = { "vestigial limb", "eye", "face", "large scale", "large scale tip", "rear region", "scale gap", "scale gapped", "head", "rear region", "light headed", "neck", "length", - "rear scale", "scales", "blood", "lung", "forked tongue", "stomach" }, + "rear scale", "scales", "blood", "lung", "forked tongue", + "stomach", "underside"}, *fish_parts[] = { "fin", "eye", "premaxillary", "pelvic axillary", - "pelvic fin", "anal fin", "pectoral fin", "finned", "head", "peduncle", - "played out", "gills", "dorsal fin", "caudal fin", - "scales", "blood", "gill", "nostril", "stomach" }; + "pelvic fin", "anal fin", "pectoral fin", "finned", "head", + "peduncle", "played out", "gills", "dorsal fin", "caudal fin", + "scales", "blood", "gill", "nostril", "stomach", "underside"}; /* claw attacks are overloaded in mons[]; most humanoids with such attacks should still reference hands rather than claws */ static const char not_claws[] = { diff -Ndru nethack-3.4.3/src/sit.c nethack-patched/src/sit.c --- nethack-3.4.3/src/sit.c 2006-12-04 21:59:04.000000000 +0000 +++ nethack-patched/src/sit.c 2007-01-25 22:46:26.000000000 +0000 @@ -39,7 +39,7 @@ dosit() { static const char sit_message[] = "sit on the %s."; - register struct trap *trap; + register struct trap *trap = t_at(u.ux, u.uy); register int typ = levl[u.ux][u.uy].typ; @@ -60,16 +60,87 @@ goto in_water; } - if(OBJ_AT(u.ux, u.uy)) { + if (!u.utrap && trap && (trap->ttyp == SPIKED_PIT || trap->ttyp == PIT)) + { + You("sit at the edge of the %spit%s.", + (trap->ttyp == SPIKED_PIT) ? "spiked " : "", + (Hallucination) ? " and contemplate the meaning of life" : ""); + } else if(OBJ_AT(u.ux, u.uy)) { register struct obj *obj; obj = level.objects[u.ux][u.uy]; You("sit on %s.", the(xname(obj))); - if (!(Is_box(obj) || objects[obj->otyp].oc_material == CLOTH)) + + if (obj->otyp == CREAM_PIE) { + pline("Yecch!"); + delobj(obj); + } else if (obj->otyp == EGG) { + int mnum = obj->corpsenm; + boolean righttype = (youmonst.data == &mons[mnum]); + boolean yours = obj->spe; + if (youmonst.data->cwt >= 2600 && !righttype) { + /* note that a blue dragon will splat a red dragon's egg */ + pline("Splat!"); + delobj(obj); + } else if (mnum == NON_PM && yours) { + /* your egg is dead */ + You("feel sad for a moment."); + } else if (righttype && flags.female) { + if (!yours) + You_feel("somehow out of place..."); + /* else no special message */ + incubate_egg(obj); + } else + pline("It's not very comfortable..."); + } + else if (!(Is_box(obj) || objects[obj->otyp].oc_material == CLOTH)) pline("It's not very comfortable..."); - } else if ((trap = t_at(u.ux, u.uy)) != 0 || - (u.utrap && (u.utraptype >= TT_LAVA))) { + /* + Heavy monsters (dragons, titanotheres, etc.) have an + 80% chance of breaking open a box by sitting on it. + */ + if(Is_box(obj) && youmonst.data->cwt >= 2600 && rn2(5)) { + struct monst *shkp; + boolean costly = (*u.ushops && costly_spot(u.ux, u.uy)); + long loss = 0L; + boolean otrp = obj->otrapped; + struct obj *otmp; + + shkp = costly ? shop_keeper(*u.ushops) : 0; + + pline("%s shatters under your weight!", The(xname(obj))); + if (otrp) (void) chest_trap(obj, RUMP, FALSE); + + /* Put the contents on ground at the hero's feet. */ + while ((otmp = obj->cobj) != 0) { + obj_extract_self(otmp); + if(otmp->oclass == POTION_CLASS || + (objects[otmp->otyp].oc_material != PAPER && !rn2(3))) + { + chest_shatter_msg(otmp); + if (costly) + loss += stolen_value(otmp, u.ux, u.uy, + (boolean)shkp->mpeaceful, TRUE); + if (otmp->quan == 1L) { + obfree(otmp, (struct obj *) 0); + continue; + } + useup(otmp); + } + place_object(otmp, u.ux, u.uy); + stackobj(otmp); + } + + if (costly) + loss += stolen_value(obj, u.ux, u.uy, + (boolean)shkp->mpeaceful, TRUE); + if(loss) + You("owe %ld %s for objects destroyed.", loss, currency(loss)); + delobj(obj); + } + + } else if (trap || (u.utrap && (u.utraptype >= TT_LAVA))) { if (u.utrap) { exercise(A_WIS, FALSE); /* you're getting stuck longer */ @@ -116,7 +187,7 @@ } else if(IS_SINK(typ)) { You(sit_message, defsyms[S_sink].explanation); - Your("%s gets wet.", humanoid(youmonst.data) ? "rump" : "underside"); + Your("%s gets wet.", mbodypart(&youmonst, RUMP)); #endif } else if(IS_ALTAR(typ)) { diff -Ndru nethack-3.4.3/src/timeout.c nethack-patched/src/timeout.c --- nethack-3.4.3/src/timeout.c 2006-12-04 21:59:04.000000000 +0000 +++ nethack-patched/src/timeout.c 2007-01-25 23:46:42.000000000 +0000 @@ -400,6 +400,20 @@ } } +/* speed up an egg's hatching by moving its timer forward */ +void +incubate_egg(egg) +struct obj *egg; +{ + int oldtime, newtime; + oldtime = stop_timer(HATCH_EGG, (genericptr_t) egg); + if (oldtime == 0) impossible("incubate_egg"); + if (oldtime > 20) newtime = oldtime - rnd(20); + else newtime = oldtime; + (void) start_timer((long)newtime, TIMER_OBJECT, + HATCH_EGG, (genericptr_t)egg); +} + /* prevent an egg from ever hatching */ void kill_egg(egg) diff -Ndru nethack-3.4.3/src/trap.c nethack-patched/src/trap.c --- nethack-3.4.3/src/trap.c 2006-12-04 21:59:04.000000000 +0000 +++ nethack-patched/src/trap.c 2007-01-25 21:43:18.000000000 +0000 @@ -3625,7 +3625,11 @@ case 7: msg = "flame fizzles out"; break; case 6: case 5: - case 4: msg = "poisoned needle misses"; break; + case 4: if (bodypart != RUMP) { + /* If you sit on a needle, it doesn't miss. + Fall through to next case. */ + msg = "poisoned needle misses"; break; + } case 3: case 2: case 1: