diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 118ba60c8..8aef6e126 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -848,6 +848,8 @@ entering an untended shop while blind gave an inappropriate message engraving feedback about partial text when weapon became too dull to finish was lacking sentence-ending period impossible() might display inaccurate feedback after updating paniclog +fix crash which occurred if hero was teleported onto a sink while busy putting + on or taking off levitation boots Platform- and/or Interface-Specific Fixes diff --git a/src/hack.c b/src/hack.c index 055930d9f..728e75774 100644 --- a/src/hack.c +++ b/src/hack.c @@ -497,9 +497,13 @@ dosinkfall() { register struct obj *obj; int dmg; + boolean lev_boots = (uarmf && uarmf->otyp == LEVITATION_BOOTS), + innate_lev = ((HLevitation & (FROMOUTSIDE|FROMFORM)) != 0L), + ufall = (!innate_lev && !(HFlying || EFlying)); /* BFlying */ - if (HLevitation & (FROMOUTSIDE|FROMFORM)) { - You("wobble unsteadily for a moment."); + if (!ufall) { + You(innate_lev ? "wobble unsteadily for a moment." : + "gain control of your flight."); } else { long save_ELev = ELevitation, save_HLev = HLevitation; @@ -524,6 +528,25 @@ dosinkfall() HLevitation = save_HLev; } + /* + * Interrupt multi-turn putting on/taking off of armor (in which + * case we reached the sink due to being teleported while busy; + * in 3.4.3, Boots_on()/Boots_off() [called via (*aftermv)() when + * 'multi' reaches 0] triggered a crash if we were donning/doffing + * levitation boots [because the Boots_off() below causes 'uarmf' + * to be null by the time 'aftermv' gets called]). + * + * Interrupt donning/doffing if we fall onto the sink, or if the + * code below is going to remove levitation boots even when we + * haven't fallen (innate floating or flying becoming unblocked). + */ + if (ufall || lev_boots) { + (void) stop_donning(lev_boots ? uarmf : (struct obj *)0); + /* recalculate in case uarmf just got set to null */ + lev_boots = (uarmf && uarmf->otyp == LEVITATION_BOOTS); + } + + /* remove worn levitation items */ ELevitation &= ~W_ARTI; HLevitation &= ~(I_SPECIAL|TIMEOUT); HLevitation++; @@ -537,7 +560,7 @@ dosinkfall() Ring_off(obj); off_msg(obj); } - if(uarmf && uarmf->otyp == LEVITATION_BOOTS) { + if (lev_boots) { obj = uarmf; (void)Boots_off(); off_msg(obj);