E boolean FDECL(is_home_elemental, (struct permonst *));
E struct monst *FDECL(clone_mon, (struct monst *,XCHAR_P,XCHAR_P));
+E void FDECL(newmonhp, (struct monst *,int));
E struct monst *FDECL(makemon, (struct permonst *,int,int,int));
E boolean FDECL(create_critters, (int,struct permonst *));
E struct permonst *NDECL(rndmonst);
-/* SCCS Id: @(#)makemon.c 3.4 2003/11/30 */
+/* SCCS Id: @(#)makemon.c 3.4 2004/05/21 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
return result;
}
+/* set up a new monster's initial level and hit points;
+ used by newcham() as well as by makemon() */
+void
+newmonhp(mon, mndx)
+struct monst *mon;
+int mndx;
+{
+ struct permonst *ptr = &mons[mndx];
+
+ mon->m_lev = adj_lev(ptr);
+ if (is_golem(ptr)) {
+ mon->mhpmax = mon->mhp = golemhp(mndx);
+ } else if (is_rider(ptr)) {
+ /* we want low HP, but a high mlevel so they can attack well */
+ mon->mhpmax = mon->mhp = d(10,8);
+ } else if (ptr->mlevel > 49) {
+ /* "special" fixed hp monster
+ * the hit points are encoded in the mlevel in a somewhat strange
+ * way to fit in the 50..127 positive range of a signed character
+ * above the 1..49 that indicate "normal" monster levels */
+ mon->mhpmax = mon->mhp = 2 * (ptr->mlevel - 6);
+ mon->m_lev = mon->mhp / 4; /* approximation */
+ } else if (ptr->mlet == S_DRAGON && mndx >= PM_GRAY_DRAGON) {
+ /* adult dragons */
+ mon->mhpmax = mon->mhp = (int) (In_endgame(&u.uz) ?
+ (8 * mon->m_lev) : (4 * mon->m_lev + d((int)mon->m_lev, 4)));
+ } else if (!mon->m_lev) {
+ mon->mhpmax = mon->mhp = rnd(4);
+ } else {
+ mon->mhpmax = mon->mhp = d((int)mon->m_lev, 8);
+ if (is_home_elemental(ptr))
+ mon->mhpmax = (mon->mhp *= 3);
+ }
+}
+
/*
* called with [x,y] = coordinates;
* [0,0] means anyplace
mtmp->mxlth = xlth;
mtmp->mnum = mndx;
- mtmp->m_lev = adj_lev(ptr);
- if (is_golem(ptr)) {
- mtmp->mhpmax = mtmp->mhp = golemhp(mndx);
- } else if (is_rider(ptr)) {
- /* We want low HP, but a high mlevel so they can attack well */
- mtmp->mhpmax = mtmp->mhp = d(10,8);
- } else if (ptr->mlevel > 49) {
- /* "special" fixed hp monster
- * the hit points are encoded in the mlevel in a somewhat strange
- * way to fit in the 50..127 positive range of a signed character
- * above the 1..49 that indicate "normal" monster levels */
- mtmp->mhpmax = mtmp->mhp = 2*(ptr->mlevel - 6);
- mtmp->m_lev = mtmp->mhp / 4; /* approximation */
- } else if (ptr->mlet == S_DRAGON && mndx >= PM_GRAY_DRAGON) {
- /* adult dragons */
- mtmp->mhpmax = mtmp->mhp = (int) (In_endgame(&u.uz) ?
- (8 * mtmp->m_lev) : (4 * mtmp->m_lev + d((int)mtmp->m_lev, 4)));
- } else if (!mtmp->m_lev) {
- mtmp->mhpmax = mtmp->mhp = rnd(4);
- } else {
- mtmp->mhpmax = mtmp->mhp = d((int)mtmp->m_lev, 8);
- if (is_home_elemental(ptr))
- mtmp->mhpmax = (mtmp->mhp *= 3);
- }
+ /* set up level and hit points */
+ newmonhp(mtmp, mndx);
if (is_female(ptr)) mtmp->female = TRUE;
else if (is_male(ptr)) mtmp->female = FALSE;
-/* SCCS Id: @(#)mon.c 3.4 2003/12/04 */
+/* SCCS Id: @(#)mon.c 3.4 2004/05/21 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
boolean polyspot; /* change is the result of wand or spell of polymorph */
boolean msg; /* "The oldmon turns into a newmon!" */
{
- int mhp, hpn, hpd;
+ int hpn, hpd;
int mndx, tryct;
struct permonst *olddata = mtmp->data;
char oldname[BUFSZ], newname[BUFSZ];
place_monster(mtmp, mtmp->mx, mtmp->my);
}
+ /* (this code used to try to adjust the monster's health based on
+ a normal one of its type but there are too many special cases
+ which need to handled in order to do that correctly, so just
+ give the new form the same proportion of HP as its old one had) */
hpn = mtmp->mhp;
- hpd = (mtmp->m_lev < 50) ? ((int)mtmp->m_lev)*8 : mdat->mlevel;
- if(!hpd) hpd = 4;
-
- mtmp->m_lev = adj_lev(mdat); /* new monster level */
-
- mhp = (mtmp->m_lev < 50) ? ((int)mtmp->m_lev)*8 : mdat->mlevel;
- if(!mhp) mhp = 4;
-
+ hpd = mtmp->mhpmax;
+ /* set level and hit points */
+ newmonhp(mtmp, monsndx(mdat));
/* new hp: same fraction of max as before */
#ifndef LINT
- mtmp->mhp = (int)(((long)hpn*(long)mhp)/(long)hpd);
+ mtmp->mhp = (int)(((long)hpn * (long)mtmp->mhp) / (long)hpd);
#endif
- if(mtmp->mhp < 0) mtmp->mhp = hpn; /* overflow */
-/* Unlikely but not impossible; a 1HD creature with 1HP that changes into a
- 0HD creature will require this statement */
+ /* sanity check (potentional overflow) */
+ if (mtmp->mhp < 0 || mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax;
+ /* unlikely but not impossible; a 1HD creature with 1HP that changes
+ into a 0HD creature will require this statement */
if (!mtmp->mhp) mtmp->mhp = 1;
-/* and the same for maximum hit points */
- hpn = mtmp->mhpmax;
-#ifndef LINT
- mtmp->mhpmax = (int)(((long)hpn*(long)mhp)/(long)hpd);
-#endif
- if(mtmp->mhpmax < 0) mtmp->mhpmax = hpn; /* overflow */
- if (!mtmp->mhpmax) mtmp->mhpmax = 1;
-
/* take on the new form... */
set_mon_data(mtmp, mdat, 0);