| 1162 | } |
| 1163 | |
| 1164 | staticfn void |
| 1165 | peffect_levitation(struct obj *otmp) |
| 1166 | { |
| 1167 | /* |
| 1168 | * BLevitation will be set if levitation is blocked due to being |
| 1169 | * inside rock (currently or formerly in phazing xorn form, perhaps) |
| 1170 | * but it doesn't prevent setting or incrementing Levitation timeout |
| 1171 | * (which will take effect after escaping from the rock if it hasn't |
| 1172 | * expired by then). |
| 1173 | */ |
| 1174 | if (!Levitation && !BLevitation) { |
| 1175 | /* kludge to ensure proper operation of float_up() */ |
| 1176 | set_itimeout(&HLevitation, 1L); |
| 1177 | float_up(); |
| 1178 | /* This used to set timeout back to 0, then increment it below |
| 1179 | for blessed and uncursed effects. But now we leave it so |
| 1180 | that cursed effect yields "you float down" on next turn. |
| 1181 | Blessed and uncursed get one extra turn duration. */ |
| 1182 | } else /* already levitating, or can't levitate */ |
| 1183 | gp.potion_nothing++; |
| 1184 | |
| 1185 | if (otmp->cursed) { |
| 1186 | stairway *stway; |
| 1187 | |
| 1188 | /* 'already levitating' used to block the cursed effect(s) |
| 1189 | aside from ~I_SPECIAL; it was not clear whether that was |
| 1190 | intentional; either way, it no longer does (as of 3.6.1) */ |
| 1191 | HLevitation &= ~I_SPECIAL; /* can't descend upon demand */ |
| 1192 | if (BLevitation) { |
| 1193 | ; /* rising via levitation is blocked */ |
| 1194 | } else if ((stway = stairway_at(u.ux, u.uy)) != 0 && stway->up) { |
| 1195 | (void) doup(); |
| 1196 | /* in case we're already Levitating, which would have |
| 1197 | resulted in incrementing 'nothing' */ |
| 1198 | gp.potion_nothing = 0; /* not nothing after all */ |
| 1199 | } else if (has_ceiling(&u.uz)) { |
| 1200 | int dmg = rnd(!uarmh ? 10 : !hard_helmet(uarmh) ? 6 : 3); |
| 1201 | |
| 1202 | You("hit your %s on the %s.", body_part(HEAD), |
| 1203 | ceiling(u.ux, u.uy)); |
| 1204 | losehp(Maybe_Half_Phys(dmg), "colliding with the ceiling", |
| 1205 | KILLED_BY); |
| 1206 | gp.potion_nothing = 0; /* not nothing after all */ |
| 1207 | } |
| 1208 | } else if (otmp->blessed) { |
| 1209 | /* at this point, timeout is already at least 1 */ |
| 1210 | incr_itimeout(&HLevitation, rn1(50, 250)); |
| 1211 | /* can descend at will (stop levitating via '>') provided timeout |
| 1212 | is the only factor (ie, not also wearing Lev ring or boots) */ |
| 1213 | HLevitation |= I_SPECIAL; |
| 1214 | } else /* timeout is already at least 1 */ |
| 1215 | incr_itimeout(&HLevitation, rn1(140, 10)); |
| 1216 | |
| 1217 | if (Levitation && IS_SINK(levl[u.ux][u.uy].typ)) |
| 1218 | spoteffects(FALSE); |
| 1219 | /* levitating blocks flying */ |
| 1220 | float_vs_flight(); |
| 1221 | } |
no test coverage detected