| 4869 | } |
| 4870 | |
| 4871 | void |
| 4872 | decide_to_shapeshift(struct monst *mon) |
| 4873 | { |
| 4874 | struct permonst *ptr = 0; |
| 4875 | int mndx; |
| 4876 | unsigned was_female = mon->female; |
| 4877 | boolean dochng = FALSE; |
| 4878 | |
| 4879 | if (!is_vampshifter(mon)) { |
| 4880 | /* regular shapeshifter; 'ptr' is Null */ |
| 4881 | if (!mon->mspec_used && !rn2(6)) { |
| 4882 | dochng = TRUE; |
| 4883 | mon->mspec_used = 3 + rn2(10); |
| 4884 | } |
| 4885 | } else if (!(mon->mstrategy & STRAT_WAITFORU)) { |
| 4886 | /* The vampire has to be in good health (mhp) to maintain |
| 4887 | * its shifted form. |
| 4888 | * |
| 4889 | * If we're shifted and getting low on hp, maybe shift back, or |
| 4890 | * if we're a fog cloud at full hp, maybe pick a different shape. |
| 4891 | * If we're not already shifted and in good health, maybe shift. |
| 4892 | */ |
| 4893 | if (mon->data->mlet != S_VAMPIRE) { |
| 4894 | if ((mon->mhp <= (mon->mhpmax + 5) / 6) && rn2(4) |
| 4895 | && ismnum(mon->cham)) { |
| 4896 | ptr = &mons[mon->cham]; |
| 4897 | dochng = TRUE; |
| 4898 | } else if (mon->data == &mons[PM_FOG_CLOUD] |
| 4899 | && mon->mhp == mon->mhpmax && !rn2(4) |
| 4900 | && (!canseemon(mon) |
| 4901 | || mdistu(mon) > BOLT_LIM * BOLT_LIM)) { |
| 4902 | /* if a fog cloud, maybe change to wolf or vampire bat; |
| 4903 | those are more likely to take damage--at least when |
| 4904 | tame--and then switch back to vampire; they'll also |
| 4905 | switch to fog cloud if they encounter a closed door */ |
| 4906 | mndx = pickvampshape(mon); |
| 4907 | if (ismnum(mndx)) { |
| 4908 | ptr = &mons[mndx]; |
| 4909 | dochng = (ptr != mon->data); |
| 4910 | } |
| 4911 | } |
| 4912 | if (dochng && amorphous(mon->data) |
| 4913 | && closed_door(mon->mx, mon->my)) { |
| 4914 | coord new_xy; |
| 4915 | |
| 4916 | if (enexto(&new_xy, mon->mx, mon->my, ptr)) { |
| 4917 | rloc_to(mon, new_xy.x, new_xy.y); |
| 4918 | } |
| 4919 | } |
| 4920 | } else { |
| 4921 | if (mon->mhp >= 9 * mon->mhpmax / 10 && !rn2(6) |
| 4922 | && (!canseemon(mon) |
| 4923 | || mdistu(mon) > BOLT_LIM * BOLT_LIM)) |
| 4924 | dochng = TRUE; /* 'ptr' stays Null */ |
| 4925 | } |
| 4926 | } |
| 4927 | if (dochng) { |
| 4928 | if (newcham(mon, ptr, NC_SHOW_MSG)) { |
no test coverage detected