… | |
… | |
511 | dir = rv.direction; |
511 | dir = rv.direction; |
512 | |
512 | |
513 | // if the enemy is a player, we have los. if los says we |
513 | // if the enemy is a player, we have los. if los says we |
514 | // can directly reach the player, we do not deviate. |
514 | // can directly reach the player, we do not deviate. |
515 | // for non-players, we never deviate |
515 | // for non-players, we never deviate |
|
|
516 | if (op->stats.Wis >= 8 |
516 | if (enemy->contr && enemy->contr->darkness_at (op->map, op->x, op->y) == LOS_BLOCKED) |
517 | && enemy->contr && enemy->contr->darkness_at (op->map, op->x, op->y) == LOS_BLOCKED) |
517 | { |
518 | { |
518 | int sdir = 0; |
519 | int sdir = 0; |
|
|
520 | uint32_t &smell = op->ms ().smell; |
519 | |
521 | |
520 | for (int ndir = 1; ndir <= 8; ++ndir) |
522 | for (int ndir = 1; ndir <= 8; ++ndir) |
521 | { |
523 | { |
522 | mapxy pos (op); pos.move (ndir); |
524 | mapxy pos (op); pos.move (ndir); |
523 | |
525 | |
524 | if (pos.normalise ()) |
526 | if (pos.normalise ()) |
525 | { |
527 | { |
526 | mapspace &ms = pos.ms (); |
528 | mapspace &ms = pos.ms (); |
527 | |
529 | |
528 | if (ms.smell > op->ms ().smell) |
530 | if (ms.smell > smell) |
529 | { |
531 | { |
530 | //printf ("%s: found smell, following it, apparently (%d, %d)\n",& op->name,op->ms().smell,ms.smell);//D |
532 | //printf ("%s: found smell, following it, apparently (%d, %d)\n",& op->name,op->ms().smell,ms.smell);//D |
|
|
533 | if (op->stats.Wis >= 10) |
531 | op->ms ().smell = ms.smell - 1; // smarter: tell others |
534 | smell = ms.smell - 1; // smarter: tell others |
|
|
535 | |
532 | sdir = ndir; |
536 | sdir = ndir; |
533 | |
537 | |
534 | // perturbing the path might let the monster lose track, |
538 | // perturbing the path might let the monster lose track, |
535 | // but it will also widen the actual path, spreading information |
539 | // but it will also widen the actual path, spreading information |
536 | if (!rndm (20)) // even smarter, deviate and spread? |
540 | if (op->stats.Wis >= 15 && !rndm (20)) // even smarter, deviate and spread? |
537 | sdir = absdir (sdir + 1 - rndm (2) * 2); |
541 | sdir = absdir (sdir + 1 - rndm (2) * 2); |
538 | } |
542 | } |
539 | } |
543 | } |
540 | } |
544 | } |
541 | |
545 | |
542 | if (sdir) |
546 | if (sdir) |
543 | dir = sdir; |
547 | dir = sdir; |
544 | else if (op->ms ().smell) |
548 | else if (smell) |
545 | { |
549 | { |
546 | // no better smell found, so assume the player jumped, and erase this smell |
550 | // no better smell found, so assume the player jumped, and erase this smell |
547 | //printf ("erasing smell %d\n", op->ms ().smell);//D |
551 | //printf ("erasing smell %d\n", op->ms ().smell);//D |
548 | ordered_mapwalk_begin (op, -1, -1, 1, 1) |
552 | unordered_mapwalk (op, -1, -1, 1, 1) |
549 | if (m) |
|
|
550 | m->at (nx, ny).smell = 0; |
553 | m->at (nx, ny).smell = 0; |
551 | ordered_mapwalk_end |
|
|
552 | } |
554 | } |
553 | } |
555 | } |
554 | |
556 | |
555 | if (QUERY_FLAG (op, FLAG_SCARED) || QUERY_FLAG (op, FLAG_RUN_AWAY)) |
557 | if (QUERY_FLAG (op, FLAG_SCARED) || QUERY_FLAG (op, FLAG_RUN_AWAY)) |
556 | dir = absdir (dir + 4); |
558 | dir = absdir (dir + 4); |