used for hero vs monster and monster vs monster; also handles monster vs hero but that won't happen because hero can't be a shade */
| 2013 | /* used for hero vs monster and monster vs monster; also handles |
| 2014 | monster vs hero but that won't happen because hero can't be a shade */ |
| 2015 | boolean |
| 2016 | shade_miss( |
| 2017 | struct monst *magr, |
| 2018 | struct monst *mdef, |
| 2019 | struct obj *obj, |
| 2020 | boolean thrown, |
| 2021 | boolean verbose) |
| 2022 | { |
| 2023 | const char *what, *whose, *target; |
| 2024 | boolean youagr = (magr == &gy.youmonst), youdef = (mdef == &gy.youmonst); |
| 2025 | |
| 2026 | /* we're using dmgval() for zero/not-zero, not for actual damage amount */ |
| 2027 | if (mdef->data != &mons[PM_SHADE] || (obj && dmgval(obj, mdef))) |
| 2028 | return FALSE; |
| 2029 | |
| 2030 | if (verbose |
| 2031 | && ((youdef || cansee(mdef->mx, mdef->my) || sensemon(mdef)) |
| 2032 | || (magr == &gy.youmonst && m_next2u(mdef)))) { |
| 2033 | static const char harmlessly_thru[] = " harmlessly through "; |
| 2034 | |
| 2035 | what = (!obj || shade_aware(obj)) ? "attack" : cxname(obj); |
| 2036 | target = youdef ? "you" : mon_nam(mdef); |
| 2037 | if (!thrown) { |
| 2038 | whose = youagr ? "Your" : s_suffix(Monnam(magr)); |
| 2039 | pline("%s %s %s%s%s.", whose, what, |
| 2040 | vtense(what, "pass"), harmlessly_thru, target); |
| 2041 | } else { |
| 2042 | pline("%s %s%s%s.", The(what), /* note: not pline_The() */ |
| 2043 | vtense(what, "pass"), harmlessly_thru, target); |
| 2044 | } |
| 2045 | if (!youdef && !canspotmon(mdef)) |
| 2046 | map_invisible(mdef->mx, mdef->my); |
| 2047 | } |
| 2048 | if (!youdef) |
| 2049 | mdef->msleeping = 0; |
| 2050 | return TRUE; |
| 2051 | } |
| 2052 | |
| 2053 | /* check whether slippery clothing protects from hug or wrap attack */ |
| 2054 | /* [currently assumes that you are the attacker] */ |
no test coverage detected