* fightm() -- fight some other monster * * Returns: * 0 - Monster did nothing. * 1 - If the monster made an attack. The monster might have died. * * There is an exception to the above. If mtmp has the hero swallowed, * then we report that the monster did nothing so it will continue to * digest the hero. */ have monsters fight each other */
| 103 | */ |
| 104 | /* have monsters fight each other */ |
| 105 | int |
| 106 | fightm(struct monst *mtmp) |
| 107 | { |
| 108 | struct monst *mon, *nmon; |
| 109 | int result, has_u_swallowed; |
| 110 | /* perhaps the monster will resist Conflict */ |
| 111 | if (resist_conflict(mtmp)) |
| 112 | return 0; |
| 113 | |
| 114 | if (u.ustuck == mtmp) { |
| 115 | /* perhaps we're holding it... */ |
| 116 | if (itsstuck(mtmp)) |
| 117 | return 0; |
| 118 | } |
| 119 | has_u_swallowed = engulfing_u(mtmp); |
| 120 | |
| 121 | for (mon = fmon; mon; mon = nmon) { |
| 122 | nmon = mon->nmon; |
| 123 | if (nmon == mtmp) |
| 124 | nmon = mtmp->nmon; |
| 125 | /* Be careful to ignore monsters that are already dead, since we |
| 126 | * might be calling this before we've cleaned them up. This can |
| 127 | * happen if the monster attacked a cockatrice bare-handedly, for |
| 128 | * instance. |
| 129 | */ |
| 130 | if (mon != mtmp && !DEADMONSTER(mon)) { |
| 131 | if (monnear(mtmp, mon->mx, mon->my)) { |
| 132 | if (!u.uswallow && (mtmp == u.ustuck)) { |
| 133 | if (!rn2(4)) { |
| 134 | set_ustuck((struct monst *) 0); |
| 135 | pline("%s releases you!", Monnam(mtmp)); |
| 136 | } else |
| 137 | break; |
| 138 | } |
| 139 | |
| 140 | /* mtmp can be killed */ |
| 141 | gb.bhitpos.x = mon->mx, gb.bhitpos.y = mon->my; |
| 142 | gn.notonhead = FALSE; |
| 143 | result = mattackm(mtmp, mon); |
| 144 | |
| 145 | if (result & M_ATTK_AGR_DIED) |
| 146 | return 1; /* mtmp died */ |
| 147 | /* |
| 148 | * If mtmp has the hero swallowed, lie and say there |
| 149 | * was no attack (this allows mtmp to digest the hero). |
| 150 | */ |
| 151 | if (has_u_swallowed) |
| 152 | return 0; |
| 153 | |
| 154 | /* allow attacked monsters a chance to hit back, primarily |
| 155 | to allow monsters that resist conflict to respond */ |
| 156 | if ((result & (M_ATTK_HIT | M_ATTK_DEF_DIED)) == M_ATTK_HIT |
| 157 | && rn2(4) && mon->movement > rn2(NORMAL_SPEED)) { |
| 158 | if (mon->movement > NORMAL_SPEED) |
| 159 | mon->movement -= NORMAL_SPEED; |
| 160 | else |
| 161 | mon->movement = 0; |
| 162 | gb.bhitpos.x = mtmp->mx, gb.bhitpos.y = mtmp->my; |
no test coverage detected