* Hero tosses an object upwards with appropriate consequences. * * Returns FALSE if the object is gone. */
| 1253 | * Returns FALSE if the object is gone. |
| 1254 | */ |
| 1255 | staticfn boolean |
| 1256 | toss_up(struct obj *obj, boolean hitsroof) |
| 1257 | { |
| 1258 | const char *action; |
| 1259 | int otyp = obj->otyp; |
| 1260 | boolean petrifier = ((otyp == EGG || otyp == CORPSE) |
| 1261 | && ismnum(obj->corpsenm) |
| 1262 | && touch_petrifies(&mons[obj->corpsenm])); |
| 1263 | /* note: obj->quan == 1 */ |
| 1264 | |
| 1265 | if (!has_ceiling(&u.uz)) { |
| 1266 | action = "flies up into"; /* into "the sky" or "the water above" */ |
| 1267 | } else if (hitsroof) { |
| 1268 | if (breaktest(obj)) { |
| 1269 | pline("%s hits the %s.", Doname2(obj), ceiling(u.ux, u.uy)); |
| 1270 | breakmsg(obj, !Blind); |
| 1271 | /* crackable armor will return True for breaktest() but will |
| 1272 | usually return False for breakobj() */ |
| 1273 | if (!breakobj(obj, u.ux, u.uy, TRUE, TRUE)) { |
| 1274 | hitfloor(obj, FALSE); |
| 1275 | gt.thrownobj = 0; |
| 1276 | return TRUE; |
| 1277 | } |
| 1278 | return FALSE; |
| 1279 | } |
| 1280 | action = "hits"; |
| 1281 | } else { |
| 1282 | action = "almost hits"; |
| 1283 | } |
| 1284 | pline("%s %s the %s, then falls back on top of your %s.", Doname2(obj), |
| 1285 | action, ceiling(u.ux, u.uy), body_part(HEAD)); |
| 1286 | |
| 1287 | /* object now hits you */ |
| 1288 | |
| 1289 | if (obj->oclass == POTION_CLASS) { |
| 1290 | potionhit(&gy.youmonst, obj, POTHIT_HERO_THROW); |
| 1291 | } else if (breaktest(obj)) { |
| 1292 | int blindinc; |
| 1293 | |
| 1294 | /* need to check for blindness result prior to destroying obj */ |
| 1295 | blindinc = ((otyp == CREAM_PIE || otyp == BLINDING_VENOM) |
| 1296 | /* AT_WEAP is ok here even if attack type was AT_SPIT */ |
| 1297 | && can_blnd(&gy.youmonst, &gy.youmonst, AT_WEAP, obj)) |
| 1298 | ? rnd(25) |
| 1299 | : 0; |
| 1300 | breakmsg(obj, !Blind); |
| 1301 | if (breakobj(obj, u.ux, u.uy, TRUE, TRUE)) |
| 1302 | obj = 0; /* it's now gone */ |
| 1303 | |
| 1304 | switch (otyp) { |
| 1305 | case EGG: |
| 1306 | if (petrifier && !Stone_resistance |
| 1307 | && !(poly_when_stoned(gy.youmonst.data) |
| 1308 | && polymon(PM_STONE_GOLEM))) { |
| 1309 | /* egg ends up "all over your face"; perhaps |
| 1310 | visored helmet should still save you here */ |
| 1311 | if (uarmh) |
| 1312 | Your("%s fails to protect you.", helm_simple_name(uarmh)); |
no test coverage detected