monster begins fleeing for the specified time, 0 means untimed flee * if first, only adds fleetime if monster isn't already fleeing * if fleemsg, prints a message about new flight, otherwise, caller should */
| 459 | * if first, only adds fleetime if monster isn't already fleeing |
| 460 | * if fleemsg, prints a message about new flight, otherwise, caller should */ |
| 461 | void |
| 462 | monflee( |
| 463 | struct monst *mtmp, |
| 464 | int fleetime, |
| 465 | boolean first, |
| 466 | boolean fleemsg) |
| 467 | { |
| 468 | /* shouldn't happen; maybe warrants impossible()? */ |
| 469 | if (DEADMONSTER(mtmp)) |
| 470 | return; |
| 471 | |
| 472 | if (mtmp == u.ustuck) |
| 473 | release_hero(mtmp); /* expels/unstuck */ |
| 474 | |
| 475 | if (!first || !mtmp->mflee) { |
| 476 | /* don't lose untimed scare */ |
| 477 | if (!fleetime) |
| 478 | mtmp->mfleetim = 0; |
| 479 | else if (!mtmp->mflee || mtmp->mfleetim) { |
| 480 | fleetime += (int) mtmp->mfleetim; |
| 481 | /* ensure monster flees long enough to visibly stop fighting */ |
| 482 | if (fleetime == 1) |
| 483 | fleetime++; |
| 484 | mtmp->mfleetim = (unsigned) min(fleetime, 127); |
| 485 | } |
| 486 | if (!mtmp->mflee && fleemsg && canseemon(mtmp) |
| 487 | && M_AP_TYPE(mtmp) != M_AP_FURNITURE |
| 488 | && M_AP_TYPE(mtmp) != M_AP_OBJECT) { |
| 489 | /* unfortunately we can't distinguish between temporary |
| 490 | sleep and temporary paralysis, so both conditions |
| 491 | receive the same alternate message */ |
| 492 | if (!mtmp->mcanmove || !mtmp->data->mmove) { |
| 493 | pline_mon(mtmp, "%s seems to flinch.", |
| 494 | Adjmonnam(mtmp, "immobile")); |
| 495 | } else if (flees_light(mtmp)) { |
| 496 | if (Unaware) { |
| 497 | /* tell the player even if the hero is unconscious */ |
| 498 | pline_mon(mtmp, "%s is frightened.", Monnam(mtmp)); |
| 499 | } else if (rn2(10) || Deaf) { |
| 500 | /* via flees_light(), will always be either via uwep |
| 501 | (Sunsword) or uarm (gold dragon scales/mail) or both; |
| 502 | TODO? check for both and describe the one which is |
| 503 | emitting light with a bigger radius */ |
| 504 | const char *lsrc = (uwep && artifact_light(uwep)) |
| 505 | ? bare_artifactname(uwep) |
| 506 | : (uarm && artifact_light(uarm)) |
| 507 | ? yname(uarm) |
| 508 | : "[its imagination?]"; |
| 509 | |
| 510 | pline_mon(mtmp, "%s flees from the painful light of %s.", |
| 511 | Monnam(mtmp), lsrc); |
| 512 | } else { |
| 513 | SetVoice(mtmp, 0, 80, 0); |
| 514 | verbalize("Bright light!"); |
| 515 | } |
| 516 | } else { |
| 517 | pline_mon(mtmp, "%s turns to flee.", Monnam(mtmp)); |
| 518 | } |
no test coverage detected