try to attack; return False if monster evaded; u.dx and u.dy must be set */
| 445 | /* try to attack; return False if monster evaded; |
| 446 | u.dx and u.dy must be set */ |
| 447 | boolean |
| 448 | do_attack(struct monst *mtmp) |
| 449 | { |
| 450 | struct permonst *mdat = mtmp->data; |
| 451 | |
| 452 | /* This section of code provides protection against accidentally |
| 453 | * hitting peaceful (like '@') and tame (like 'd') monsters. |
| 454 | * Protection is provided as long as player is not: blind, confused, |
| 455 | * hallucinating or stunned. |
| 456 | * changes by wwp 5/16/85 |
| 457 | * More changes 12/90, -dkh-. if its tame and safepet, (and protected |
| 458 | * 07/92) then we assume that you're not trying to attack. Instead, |
| 459 | * you'll usually just swap places if this is a movement command |
| 460 | */ |
| 461 | /* Intelligent chaotic weapons (Stormbringer) want blood */ |
| 462 | if (is_safemon(mtmp) && !svc.context.forcefight) { |
| 463 | if (!u_wield_art(ART_STORMBRINGER)) { |
| 464 | /* There are some additional considerations: this won't work |
| 465 | * if in a shop or Punished or you miss a random roll or |
| 466 | * if you can walk thru walls and your pet cannot (KAA) or |
| 467 | * if your pet is a long worm with a tail. |
| 468 | * There's also a chance of displacing a "frozen" monster: |
| 469 | * sleeping monsters might magically walk in their sleep. |
| 470 | * This block of code used to only be called for pets; now |
| 471 | * that it also applies to peacefuls, non-pets mustn't be |
| 472 | * forced to flee. |
| 473 | */ |
| 474 | boolean foo = (Punished || !rn2(7) |
| 475 | || (is_longworm(mtmp->data) && mtmp->wormno) |
| 476 | || (IS_OBSTRUCTED(levl[u.ux][u.uy].typ) |
| 477 | && !passes_walls(mtmp->data))), |
| 478 | inshop = FALSE; |
| 479 | char *p; |
| 480 | |
| 481 | /* only check for in-shop if don't already have reason to stop */ |
| 482 | if (!foo) { |
| 483 | for (p = in_rooms(mtmp->mx, mtmp->my, SHOPBASE); *p; p++) |
| 484 | if (tended_shop(&svr.rooms[*p - ROOMOFFSET])) { |
| 485 | inshop = TRUE; |
| 486 | break; |
| 487 | } |
| 488 | } |
| 489 | if (inshop || foo) { |
| 490 | char buf[BUFSZ]; |
| 491 | |
| 492 | if (!svc.context.travel && !svc.context.run) |
| 493 | if (canspotmon(mtmp) && mtmp->isshk) |
| 494 | return ECMD_TIME | dopay(); |
| 495 | |
| 496 | if (mtmp->mtame) /* see 'additional considerations' above */ |
| 497 | monflee(mtmp, rnd(6), FALSE, FALSE); |
| 498 | Strcpy(buf, y_monnam(mtmp)); |
| 499 | buf[0] = highc(buf[0]); |
| 500 | You("stop. %s is in the way!", buf); |
| 501 | end_running(TRUE); |
| 502 | return TRUE; |
| 503 | } else if (mtmp->mfrozen || helpless(mtmp) |
| 504 | || (mtmp->data->mmove == 0 && rn2(6))) { |
no test coverage detected