throw an object, NB: obj may be consumed in the process */
| 1507 | |
| 1508 | /* throw an object, NB: obj may be consumed in the process */ |
| 1509 | void |
| 1510 | throwit( |
| 1511 | struct obj *obj, |
| 1512 | long wep_mask, /* used to re-equip returning boomerang */ |
| 1513 | boolean twoweap, /* used to restore twoweapon mode if |
| 1514 | * wielded weapon returns */ |
| 1515 | struct obj *oldslot) /* for thrown-and-return used with !fixinv */ |
| 1516 | { |
| 1517 | struct monst *mon; |
| 1518 | int range, urange; |
| 1519 | const struct throw_and_return_weapon *arw = autoreturn_weapon(obj); |
| 1520 | boolean crossbowing, |
| 1521 | impaired = (Confusion || Stunned || Blind |
| 1522 | || Hallucination || Fumbling), |
| 1523 | tethered_weapon = (arw && arw->tethered && (wep_mask & W_WEP) != 0); |
| 1524 | |
| 1525 | gn.notonhead = FALSE; /* reset potentially stale value */ |
| 1526 | if ((obj->cursed || obj->greased) && (u.dx || u.dy) && !rn2(7)) { |
| 1527 | boolean slipok = TRUE; |
| 1528 | |
| 1529 | if (ammo_and_launcher(obj, uwep)) { |
| 1530 | pline("%s!", Tobjnam(obj, "misfire")); |
| 1531 | } else { |
| 1532 | /* only slip if it's greased or meant to be thrown */ |
| 1533 | if (obj->greased || throwing_weapon(obj)) |
| 1534 | /* BUG: this message is grammatically incorrect if obj has |
| 1535 | a plural name; greased gloves or boots for instance. */ |
| 1536 | pline("%s as you throw it!", Tobjnam(obj, "slip")); |
| 1537 | else |
| 1538 | slipok = FALSE; |
| 1539 | } |
| 1540 | if (slipok) { |
| 1541 | u.dx = rn2(3) - 1; |
| 1542 | u.dy = rn2(3) - 1; |
| 1543 | if (!u.dx && !u.dy) |
| 1544 | u.dz = 1; |
| 1545 | impaired = TRUE; |
| 1546 | } |
| 1547 | } |
| 1548 | |
| 1549 | if ((u.dx || u.dy || (u.dz < 1)) |
| 1550 | && calc_capacity((int) obj->owt) > SLT_ENCUMBER |
| 1551 | && (Upolyd ? (u.mh < 5 && u.mh != u.mhmax) |
| 1552 | : (u.uhp < 10 && u.uhp != u.uhpmax)) |
| 1553 | && obj->owt > (unsigned) ((Upolyd ? u.mh : u.uhp) * 2) |
| 1554 | && !Is_airlevel(&u.uz)) { |
| 1555 | You("have so little stamina, %s drops from your grasp.", |
| 1556 | the(xname(obj))); |
| 1557 | exercise(A_CON, FALSE); |
| 1558 | u.dx = u.dy = 0; |
| 1559 | u.dz = 1; |
| 1560 | } |
| 1561 | |
| 1562 | gt.thrownobj = obj; |
| 1563 | gt.thrownobj->how_lost = LOST_THROWN; |
| 1564 | iflags.returning_missile = AutoReturn(obj, wep_mask) ? (genericptr_t) obj |
| 1565 | : (genericptr_t) 0; |
| 1566 | /* NOTE: No early returns after this point or returning_missile |
no test coverage detected