From: PatR Date: Mon, 28 Mar 2022 17:17:01 +0000 (-0700) Subject: adjust temporary acid/stoning resistance X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e96d4ea9efb1cf19b2ac150c1e71e350086a8c82;p=nethack adjust temporary acid/stoning resistance When eating a meal that is affected by acid resistance or stoning resistance and protected by temporary resistance, increase the timeout so that the resistance doesn't expire until after the meal finishes. That avoids getting the "you no longer feel safe from {acid,stoning}" during the meal and not being affected by the dangerous food despite that message. Useful because the protection is checked at the start of the meal and not rechecked during; extending the duration hides the latter. --- diff --git a/include/extern.h b/include/extern.h index fdd2abe60..4294952a3 100644 --- a/include/extern.h +++ b/include/extern.h @@ -734,6 +734,7 @@ extern void vomit(void); extern int eaten_stat(int, struct obj *); extern void food_disappears(struct obj *); extern void food_substitution(struct obj *, struct obj *); +extern long temp_resist(int); extern void eating_conducts(struct permonst *); extern int eat_brains(struct monst *, struct monst *, boolean, int *); extern void fix_petrification(void); diff --git a/src/eat.c b/src/eat.c index b738d8028..5e8b08aeb 100644 --- a/src/eat.c +++ b/src/eat.c @@ -16,6 +16,7 @@ static void choke(struct obj *); static void recalc_wt(void); static struct obj *touchfood(struct obj *); static void do_reset_eat(void); +static void maybe_extend_timed_resist(int); static void done_eating(boolean); static void cprefx(int); static int intrinsic_possible(int, struct permonst *); @@ -404,13 +405,51 @@ do_reset_eat(void) newuhs(FALSE); } +/* return True if 'prop' has a non-zero timed value and no other source */ +long +temp_resist(int prop) +{ + struct prop *p = &u.uprops[prop]; + long timeout = p->intrinsic & TIMEOUT; + + if (timeout + /* and if not also protected by polymorph form */ + && (p->intrinsic & ~TIMEOUT) == 0L + /* and not by worn gear (dragon armor) */ + && !p->extrinsic + /* and property is not blocked; we don't expect this, but if it + is then the timeout doesn't matter so we won't extend that */ + && !p->blocked) { + return timeout; + } + return 0L; +} + +/* if temp resist against 'prop' is about to timeout, extend it slightly */ +static void +maybe_extend_timed_resist(int prop) +{ + long timeout = temp_resist(prop); + + /* if hero is being protected from nasty effects of current meal by + temporary resistance (timed acid resist or timed stoning resist), + prevent expiration from occurring while the meal is in progress + so that player doesn't get feedback about becoming more vulnerable + and then have the hero stay unharmed; has a minor side-effect of + also extending the protection against other attacks of the sort + being resisted */ + if (timeout == 1L) { + set_itimeout(&u.uprops[prop].intrinsic, 2L); + } +} + /* called each move during eating process */ static int eatfood(void) { - if (!g.context.victual.piece - || (!carried(g.context.victual.piece) - && !obj_here(g.context.victual.piece, u.ux, u.uy))) { + struct obj *food = g.context.victual.piece; + + if (!food || !(carried(food) || obj_here(food, u.ux, u.uy))) { /* maybe it was stolen? */ do_reset_eat(); return 0; @@ -418,6 +457,25 @@ eatfood(void) if (!g.context.victual.eating) return 0; + /* + * We don't want temporary acid resistance to timeout while eating + * an acidic corpse or temporary stoning resistance to do that while + * eating a cockatrice corpse. Protection is checked at the start + * of the meal and having it go away mid-meal with a message about + * increased vulnerability but no consequences is too obvously wrong, + * but also too nit-picky to deal with. + * + * (Tins aren't handled by eatfood() and wouldn't need this anyway + * because they're finished in one turn once they've been opened. + * Come to think of it, eggs are probably eaten in one turn too.) + */ + if ((food->otyp == CORPSE || food->otyp == EGG) + && food->corpsenm >= LOW_PM && acidic(&mons[food->corpsenm])) + maybe_extend_timed_resist(ACID_RES); + if ((food->otyp == CORPSE || food->otyp == EGG) + && food->corpsenm >= LOW_PM && touch_petrifies(&mons[food->corpsenm])) + maybe_extend_timed_resist(STONE_RES); + if (++g.context.victual.usedtime <= g.context.victual.reqtime) { if (bite()) return 0;