From fae75f5930bf8e7707a31b019f7fe415c6705cdd Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 26 Jul 2020 11:13:43 -0700 Subject: [PATCH] troll corpse revival Prevent corpses left by cancelled trolls from reviving. Their revival is an innate ability but is clearly a magical one, so make that be subject to cancellation magic. Change existing corpses that are scheduled to revive to rot instead if they get cancelled as objects. Rider corpses are excluded. Uncancel an ice troll whose corpse is put into an ice box. Commit e9f53ab7f677656be530bf30c65bc3ff14d0c467 at the end of May to fix corpses taken out of ice boxes by monsters changed removing corpses from ice boxes by anybody to always give them rot-away timers, even for trolls. Make an exception for ice troll corpses: give those revive timers instead. --- doc/fixes37.0 | 6 +++++- src/mkobj.c | 7 ++++++- src/pickup.c | 24 +++++++++++++++++------- src/zap.c | 15 ++++++++++++++- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 72352f307..574729ed2 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.257 $ $NHDT-Date: 1595774758 2020/07/26 14:45:58 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.258 $ $NHDT-Date: 1595787211 2020/07/26 18:13:31 $ General Fixes and Modified Features ----------------------------------- @@ -229,6 +229,10 @@ some hero attacks that should have gotten a skill bonus or penalty didn't change internal name of " venom" to "splash of venom" singularize "splashes" to "splash" instead of "splashe" treat slinging gems and tossing or slinging stones at unicorns as attacks +give rot-away timer instead of revive timer to corpses of cancelled trolls +switch revive timer to rot-away timer if a troll corpse gets cancelled +uncancel an ice troll if its corpse is put into an ice box; give corpse a + revive timer if later taken out Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/mkobj.c b/src/mkobj.c index b439461b4..4d5b5cc03 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkobj.c $NHDT-Date: 1593306908 2020/06/28 01:15:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.181 $ */ +/* NetHack 3.6 mkobj.c $NHDT-Date: 1595787211 2020/07/26 18:13:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.182 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1516,6 +1516,10 @@ unsigned corpstatflags; if (!ptr) ptr = mtmp->data; + + /* don't give a revive timer to a cancelled troll's corpse */ + if (mtmp->mcan && !is_rider(ptr)) + otmp->norevive = 1; } /* when 'ptr' is non-null it comes from our caller or from 'mtmp'; @@ -1639,6 +1643,7 @@ boolean copyof; /* Never insert this returned pointer into mon chains! */ mnew = mtmp; } + mnew->data = &mons[mnew->mnum]; } return mnew; } diff --git a/src/pickup.c b/src/pickup.c index bd17ab0f9..38ced3f1a 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pickup.c $NHDT-Date: 1590870789 2020/05/30 20:33:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.269 $ */ +/* NetHack 3.6 pickup.c $NHDT-Date: 1595787212 2020/07/26 18:13:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.270 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2351,9 +2351,14 @@ register struct obj *obj; if (Icebox && !age_is_relative(obj)) { obj->age = g.monstermoves - obj->age; /* actual age */ /* stop any corpse timeouts when frozen */ - if (obj->otyp == CORPSE && obj->timed) { - (void) stop_timer(ROT_CORPSE, obj_to_any(obj)); - (void) stop_timer(REVIVE_MON, obj_to_any(obj)); + if (obj->otyp == CORPSE) { + if (obj->timed) { + (void) stop_timer(ROT_CORPSE, obj_to_any(obj)); + (void) stop_timer(REVIVE_MON, obj_to_any(obj)); + } + /* if this is the corpse of a cancelled ice troll, uncancel it */ + if (obj->corpsenm == PM_ICE_TROLL && has_omonst(obj)) + OMONST(obj)->mcan = 0; } } else if (Is_mbag(g.current_container) && mbag_explodes(obj, 0)) { /* explicitly mention what item is triggering the explosion */ @@ -2362,7 +2367,7 @@ register struct obj *obj; /* did not actually insert obj yet */ if (was_unpaid) addtobill(obj, FALSE, FALSE, TRUE); - if (obj->otyp == BAG_OF_HOLDING) /* putting bag of holding into another */ + if (obj->otyp == BAG_OF_HOLDING) /* one bag of holding into another */ do_boh_explosion(obj, (obj->where == OBJ_FLOOR)); obfree(obj, (struct obj *) 0); /* if carried, shop goods will be flagged 'unpaid' and obfree() will @@ -2489,8 +2494,13 @@ struct obj *obj; if (!age_is_relative(obj)) { obj->age = g.monstermoves - obj->age; /* actual age */ if (obj->otyp == CORPSE) { - /* start a rot-away timer but not a troll's revive timer */ - obj->norevive = 1; + struct monst *m = get_mtraits(obj, FALSE); + boolean iceT = m ? (m->data == &mons[PM_ICE_TROLL]) + : (obj->corpsenm == PM_ICE_TROLL); + + /* start a revive timer if this corpse is for an ice troll, + otherwise start a rot-away timer (even for other trolls) */ + obj->norevive = iceT ? 0 : 1; start_corpse_timeout(obj); } } diff --git a/src/zap.c b/src/zap.c index 35bdfd6bb..50c1e0e32 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 zap.c $NHDT-Date: 1593772051 2020/07/03 10:27:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.344 $ */ +/* NetHack 3.6 zap.c $NHDT-Date: 1595787213 2020/07/26 18:13:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.345 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1152,6 +1152,19 @@ register struct obj *obj; break; } } + /* cancelling a troll's corpse prevents it from reviving (on its own; + does not affect undead turning induced revival) */ + if (obj->otyp == CORPSE && obj->timed + && !is_rider(&mons[obj->corpsenm])) { + anything a = *obj_to_any(obj); + long timout = peek_timer(REVIVE_MON, &a); + + if (timout) { + (void) stop_timer(REVIVE_MON, &a); + (void) start_timer(timout, TIMER_OBJECT, ROT_CORPSE, &a); + } + } + unbless(obj); uncurse(obj); return;