… | |
… | |
231 | * Currently, this is only called from move_monster, and |
231 | * Currently, this is only called from move_monster, and |
232 | * if enemy is set, then so should be rv. |
232 | * if enemy is set, then so should be rv. |
233 | * returns 1 if the monster should wake up, 0 otherwise. |
233 | * returns 1 if the monster should wake up, 0 otherwise. |
234 | */ |
234 | */ |
235 | int |
235 | int |
236 | check_wakeup (object *op, object *enemy, rv_vector * rv) |
236 | check_wakeup (object *op, object *enemy, rv_vector *rv) |
237 | { |
237 | { |
238 | int radius = op->stats.Wis > MIN_MON_RADIUS ? op->stats.Wis : MIN_MON_RADIUS; |
|
|
239 | |
|
|
240 | /* Trim work - if no enemy, no need to do anything below */ |
238 | /* Trim work - if no enemy, no need to do anything below */ |
241 | if (!enemy) |
239 | if (!enemy) |
242 | return 0; |
240 | return 0; |
243 | |
241 | |
|
|
242 | int radius = max (op->stats.Wis, MIN_MON_RADIUS); |
|
|
243 | |
|
|
244 | if (op->flag [FLAG_BLIND]) |
244 | /* blinded monsters can only find nearby objects to attack */ |
245 | /* blinded monsters can only find nearby objects to attack */ |
245 | if (QUERY_FLAG (op, FLAG_BLIND)) |
|
|
246 | radius = MIN_MON_RADIUS; |
246 | radius = MIN_MON_RADIUS; |
247 | |
247 | else if (op->map |
|
|
248 | && !enemy->invisible |
|
|
249 | && !stand_in_light (enemy) |
|
|
250 | && (!op->flag[FLAG_SEE_IN_DARK] || !op->flag [FLAG_SEE_INVISIBLE])) |
248 | /* This covers the situation where the monster is in the dark |
251 | /* This covers the situation where the monster is in the dark |
249 | * and has an enemy. If the enemy has no carried light (or isnt |
252 | * and has an enemy. If the enemy has no carried light (or isnt |
250 | * glowing!) then the monster has trouble finding the enemy. |
253 | * glowing!) then the monster has trouble finding the enemy. |
251 | * Remember we already checked to see if the monster can see in |
254 | * Remember we already checked to see if the monster can see in |
252 | * the dark. */ |
255 | * the dark. */ |
253 | |
256 | radius = min (radius, MIN_MON_RADIUS + MAX_DARKNESS - op->map->darklevel ()); |
254 | else if (op->map && op->map->darkness > 0 && enemy && !enemy->invisible && |
257 | else if (!op->flag [FLAG_SLEEP]) |
255 | !stand_in_light (enemy) && (!QUERY_FLAG (op, FLAG_SEE_IN_DARK) || !QUERY_FLAG (op, FLAG_SEE_INVISIBLE))) |
|
|
256 | { |
|
|
257 | int dark = radius / (op->map->darkness); |
|
|
258 | |
|
|
259 | radius = (dark > MIN_MON_RADIUS) ? (dark + 1) : MIN_MON_RADIUS; |
|
|
260 | } |
|
|
261 | else if (!QUERY_FLAG (op, FLAG_SLEEP)) |
|
|
262 | return 1; |
258 | return 1; |
|
|
259 | |
|
|
260 | if (enemy->flag [FLAG_STEALTH]) |
|
|
261 | radius = radius / 2 + 1; |
263 | |
262 | |
264 | /* enemy should already be on this map, so don't really need to check |
263 | /* enemy should already be on this map, so don't really need to check |
265 | * for that. |
264 | * for that. |
266 | */ |
265 | */ |
267 | if (rv->distance < (unsigned int) (QUERY_FLAG (enemy, FLAG_STEALTH) ? (radius / 2) + 1 : radius)) |
266 | if (rv->distance <= radius) |
268 | { |
267 | { |
269 | CLEAR_FLAG (op, FLAG_SLEEP); |
268 | CLEAR_FLAG (op, FLAG_SLEEP); |
270 | return 1; |
269 | return 1; |
271 | } |
270 | } |
|
|
271 | |
272 | return 0; |
272 | return 0; |
273 | } |
273 | } |
274 | |
274 | |
275 | int |
275 | int |
276 | move_randomly (object *op) |
276 | move_randomly (object *op) |
… | |
… | |
444 | && !on_same_map (op, owner) |
444 | && !on_same_map (op, owner) |
445 | && !owner->flag [FLAG_REMOVED]) |
445 | && !owner->flag [FLAG_REMOVED]) |
446 | return follow_owner (op, owner); |
446 | return follow_owner (op, owner); |
447 | |
447 | |
448 | /* doppleganger code to change monster facing to that of the nearest |
448 | /* doppleganger code to change monster facing to that of the nearest |
449 | * player. Hmm. The code is here, but no monster in the current |
449 | * player. Hmm. The code is here, but no monster in the current |
450 | * arch set uses it. |
450 | * arch set uses it. |
451 | */ |
451 | */ |
452 | if ((op->race != NULL) && strcmp (op->race, "doppleganger") == 0) |
452 | if (op->race && strcmp (op->race, "doppleganger") == 0) |
453 | { |
453 | { |
454 | op->face = enemy->face; |
454 | op->face = enemy->face; |
455 | op->name = enemy->name; |
455 | op->name = enemy->name; |
456 | } |
456 | } |
457 | |
457 | |
… | |
… | |
613 | { |
613 | { |
614 | object *nearest_player = get_nearest_player (op); |
614 | object *nearest_player = get_nearest_player (op); |
615 | |
615 | |
616 | if (nearest_player && nearest_player != enemy && !can_hit (part, enemy, &rv)) |
616 | if (nearest_player && nearest_player != enemy && !can_hit (part, enemy, &rv)) |
617 | { |
617 | { |
618 | op->enemy = NULL; |
618 | op->enemy = 0; |
619 | enemy = nearest_player; |
619 | enemy = nearest_player; |
620 | } |
620 | } |
621 | } |
621 | } |
622 | |
622 | |
623 | if (!QUERY_FLAG (op, FLAG_SCARED) && can_hit (part, enemy, &rv)) |
623 | if (!QUERY_FLAG (op, FLAG_SCARED) && can_hit (part, enemy, &rv)) |