Note: for long worms, always call cutworm (cutworm calls clone_mon) */
| 834 | |
| 835 | /* Note: for long worms, always call cutworm (cutworm calls clone_mon) */ |
| 836 | struct monst * |
| 837 | clone_mon( |
| 838 | struct monst *mon, |
| 839 | coordxy x, coordxy y) /* clone's preferred location or 0 (near mon) */ |
| 840 | { |
| 841 | coord mm; |
| 842 | struct monst *m2; |
| 843 | |
| 844 | /* may be too weak or have been extinguished for population control */ |
| 845 | if (mon->mhp <= 1 |
| 846 | || (svm.mvitals[monsndx(mon->data)].mvflags & G_EXTINCT) != 0) |
| 847 | return (struct monst *) 0; |
| 848 | |
| 849 | if (x == 0) { |
| 850 | mm.x = mon->mx; |
| 851 | mm.y = mon->my; |
| 852 | } else { |
| 853 | mm.x = x; |
| 854 | mm.y = y; |
| 855 | } |
| 856 | if (!isok(mm.x, mm.y)) { /* paranoia */ |
| 857 | impossible("clone_mon trying to create a monster at <%d,%d>?", |
| 858 | mm.x, mm.y); |
| 859 | return (struct monst *) 0; |
| 860 | } |
| 861 | if (MON_AT(mm.x, mm.y)) { /* (always True for the x==0 case) */ |
| 862 | if (!enexto(&mm, mm.x, mm.y, mon->data) || MON_AT(mm.x, mm.y)) |
| 863 | return (struct monst *) 0; |
| 864 | } |
| 865 | |
| 866 | m2 = newmonst(); |
| 867 | *m2 = *mon; /* copy condition of old monster */ |
| 868 | m2->mextra = (struct mextra *) 0; |
| 869 | m2->nmon = fmon; |
| 870 | fmon = m2; |
| 871 | m2->m_id = next_ident(); |
| 872 | m2->mx = mm.x; |
| 873 | m2->my = mm.y; |
| 874 | |
| 875 | m2->mundetected = 0; |
| 876 | m2->mtrapped = 0; |
| 877 | m2->mcloned = 1; |
| 878 | m2->minvent = (struct obj *) 0; /* objects don't clone */ |
| 879 | m2->mleashed = 0; |
| 880 | /* Max HP the same, but current HP halved for both. The caller |
| 881 | * might want to override this by halving the max HP also. |
| 882 | * When current HP is odd, the original keeps the extra point. |
| 883 | * We know original has more than 1 HP, so both end up with at least 1. |
| 884 | */ |
| 885 | m2->mhpmax = mon->mhpmax; |
| 886 | m2->mhp = mon->mhp / 2; |
| 887 | mon->mhp -= m2->mhp; |
| 888 | |
| 889 | /* clone doesn't have mextra so mustn't retain special monster flags */ |
| 890 | m2->isshk = 0; |
| 891 | m2->isgd = 0; |
| 892 | m2->ispriest = 0; |
| 893 | /* ms->isminion handled below */ |
no test coverage detected