Move a monster through the air for a few squares. */
| 1127 | |
| 1128 | /* Move a monster through the air for a few squares. */ |
| 1129 | void |
| 1130 | mhurtle(struct monst *mon, int dx, int dy, int range) |
| 1131 | { |
| 1132 | coord mc, cc; |
| 1133 | |
| 1134 | wakeup(mon, !svc.context.mon_moving); |
| 1135 | /* At the very least, debilitate the monster */ |
| 1136 | mon->movement = 0; |
| 1137 | mon->mstun = 1; |
| 1138 | |
| 1139 | /* Is the monster stuck or too heavy to push? |
| 1140 | * (very large monsters have too much inertia, even floaters and flyers) |
| 1141 | */ |
| 1142 | if (mon->data->msize >= MZ_HUGE || mon == u.ustuck || mon->mtrapped) { |
| 1143 | if (canseemon(mon)) |
| 1144 | pline("%s doesn't budge!", Monnam(mon)); |
| 1145 | return; |
| 1146 | } |
| 1147 | |
| 1148 | /* Make sure dx and dy are [-1,0,1] */ |
| 1149 | dx = sgn(dx); |
| 1150 | dy = sgn(dy); |
| 1151 | if (!range || (!dx && !dy)) |
| 1152 | return; /* paranoia */ |
| 1153 | /* don't let grid bugs be hurtled diagonally */ |
| 1154 | if (dx && dy && NODIAG(monsndx(mon->data))) |
| 1155 | return; |
| 1156 | |
| 1157 | /* undetected monster can be moved by your strike */ |
| 1158 | if (mon->mundetected) { |
| 1159 | mon->mundetected = 0; |
| 1160 | newsym(mon->mx, mon->my); |
| 1161 | } |
| 1162 | if (M_AP_TYPE(mon)) |
| 1163 | seemimic(mon); |
| 1164 | |
| 1165 | /* Send the monster along the path */ |
| 1166 | mc.x = mon->mx; |
| 1167 | mc.y = mon->my; |
| 1168 | cc.x = mon->mx + (dx * range); |
| 1169 | cc.y = mon->my + (dy * range); |
| 1170 | (void) walk_path(&mc, &cc, mhurtle_step, (genericptr_t) mon); |
| 1171 | if (!DEADMONSTER(mon)) { |
| 1172 | if (t_at(mon->mx, mon->my)) |
| 1173 | (void) mintrap(mon, FORCEBUNGLE); |
| 1174 | else |
| 1175 | (void) minliquid(mon); |
| 1176 | } |
| 1177 | return; |
| 1178 | } |
| 1179 | |
| 1180 | staticfn void |
| 1181 | check_shop_obj(struct obj *obj, coordxy x, coordxy y, boolean broken) |
no test coverage detected