MCPcopy Index your code
hub / github.com/NetHack/NetHack / dosinkfall

Function dosinkfall

src/hack.c:835–919  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

833}
834
835staticfn void
836dosinkfall(void)
837{
838 static const char fell_on_sink[] = "fell onto a sink";
839 struct obj *obj;
840 int dmg;
841 boolean lev_boots = (uarmf && uarmf->otyp == LEVITATION_BOOTS),
842 innate_lev = ((HLevitation & (FROMOUTSIDE | FROMFORM)) != 0L),
843 /* to handle being chained to buried iron ball, trying to
844 levitate but being blocked, then moving onto adjacent sink;
845 no need to worry about being blocked by terrain because we
846 couldn't be over a sink at the same time */
847 blockd_lev = (BLevitation == I_SPECIAL),
848 ufall = (!innate_lev && !blockd_lev
849 && !(HFlying || EFlying)); /* BFlying */
850
851 if (!ufall) {
852 You((innate_lev || blockd_lev) ? "wobble unsteadily for a moment."
853 : "gain control of your flight.");
854 } else {
855 long save_ELev = ELevitation, save_HLev = HLevitation;
856
857 /* fake removal of levitation in advance so that final
858 disclosure will be right in case this turns out to
859 be fatal; fortunately the fact that rings and boots
860 are really still worn has no effect on bones data */
861 ELevitation = HLevitation = 0L;
862 You("crash to the floor!");
863 dmg = rn1(8, 25 - (int) ACURR(A_CON));
864 losehp(Maybe_Half_Phys(dmg), fell_on_sink, NO_KILLER_PREFIX);
865 exercise(A_DEX, FALSE);
866 selftouch("Falling, you");
867 for (obj = svl.level.objects[u.ux][u.uy]; obj; obj = obj->nexthere)
868 if (obj->oclass == WEAPON_CLASS || is_weptool(obj)) {
869 You("fell on %s.", doname(obj));
870 losehp(Maybe_Half_Phys(rnd(3)), fell_on_sink,
871 NO_KILLER_PREFIX);
872 exercise(A_CON, FALSE);
873 }
874 ELevitation = save_ELev;
875 HLevitation = save_HLev;
876 }
877
878 /*
879 * Interrupt multi-turn putting on/taking off of armor (in which
880 * case we reached the sink due to being teleported while busy;
881 * in 3.4.3, Boots_on()/Boots_off() [called via (*afternmv)() when
882 * 'multi' reaches 0] triggered a crash if we were donning/doffing
883 * levitation boots [because the Boots_off() below causes 'uarmf'
884 * to be null by the time 'afternmv' gets called]).
885 *
886 * Interrupt donning/doffing if we fall onto the sink, or if the
887 * code below is going to remove levitation boots even when we
888 * haven't fallen (innate floating or flying becoming unblocked).
889 */
890 if (ufall || lev_boots) {
891 (void) stop_donning(lev_boots ? uarmf : (struct obj *) 0);
892 /* recalculate in case uarmf just got set to null */

Callers 1

spoteffectsFunction · 0.85

Calls 11

YouFunction · 0.85
losehpFunction · 0.85
exerciseFunction · 0.85
selftouchFunction · 0.85
donameFunction · 0.85
rndFunction · 0.85
stop_donningFunction · 0.85
Ring_offFunction · 0.85
off_msgFunction · 0.85
Boots_offFunction · 0.85
float_vs_flightFunction · 0.85

Tested by

no test coverage detected