void summon_minion(aligntyp alignment, boolean talk) { struct monst *mon; int mnum; switch ((int)alignment) { case A_LAWFUL: mnum = lminion(); break; case A_NEUTRAL: mnum = PM_AIR_ELEMENTAL + rn2(4); break; case A_CHAOTIC: case A_NONE: mnum = ndemon(&u.uz, alignment); break; default: impossible("unaligned player?"); mnum = ndemon(&u.uz, A_NONE); break; } if (mnum == NON_PM) { mon = 0; } else if (mons[mnum].pxtyp == MX_NONE) { const struct permonst *pm = &mons[mnum]; mon = makemon(pm, level, u.ux, u.uy, MM_EMIN); if (mon) { mon->isminion = TRUE; EMIN(mon)->min_align = alignment; } } else if (roamer_type(&mons[mnum])) { mon = makemon(&mons[mnum], level, u.ux, u.uy, NO_MM_FLAGS); if (mon) { mon->isminion = TRUE; EPRI(mon)->shralign = alignment; } } else mon = makemon(&mons[mnum], level, u.ux, u.uy, NO_MM_FLAGS); if (mon) { if (talk) { pline("The voice of %s booms:", align_gname(alignment)); verbalize("Thou shalt pay for thy indiscretion!"); if (!Blind) pline("%s appears before you.", Amonnam(mon)); } mon->mpeaceful = FALSE; /* don't call set_malign(); player was naughty */ } }
int dlord(aligntyp atyp) { int tryct, pm; for (tryct = 0; tryct < 20; tryct++) { pm = rn1(PM_YEENOGHU + 1 - PM_JUIBLEX, PM_JUIBLEX); if (!(mvitals[pm].mvflags & G_GONE) && (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp))) return pm; } return ndemon(&u.uz, atyp); /* approximate */ }
static struct permonst * morguemon (void) { int i = rn2(100), hd = rn2(level_difficulty()); if(hd > 10 && i < 10) return((Inhell || In_endgame(&u.uz)) ? mkclass(S_DEMON,0) : &mons[ndemon(A_NONE)]); if(hd > 8 && i > 85) return(mkclass(S_VAMPIRE,0)); return((i < 20) ? &mons[PM_GHOST] : (i < 40) ? &mons[PM_WRAITH] : mkclass(S_ZOMBIE,0)); }
static const struct permonst * morguemon(const d_level * dlev) { int i = rn2(100), hd = rn2(level_difficulty(dlev)); if (hd > 10 && i < 10) return (In_hell(dlev) || In_endgame(dlev)) ? mkclass(dlev, S_DEMON, 0) : &mons[ndemon(dlev, A_NONE)]; if (hd > 8 && i > 85) return mkclass(dlev, S_VAMPIRE, 0); return (i < 20) ? &mons[PM_GHOST] : (i < 40) ? &mons[PM_WRAITH] : mkclass(dlev, S_ZOMBIE, 0); }
static const struct permonst * morguemon(const d_level *dlev, enum rng rng) { int i = rn2_on_rng(100, rng); int hd = rn2_on_rng(level_difficulty(dlev), rng); if (hd > 10 && i < 10) { if (In_hell(dlev) || In_endgame(dlev)) return mkclass(dlev, S_DEMON, 0, rng); else { int mnum = ndemon(dlev, A_NONE); if (mnum != NON_PM) return &mons[mnum]; /* otherwise fall through */ } } else if (hd > 8 && i > 85) return mkclass(dlev, S_VAMPIRE, 0, rng); return (i < 20) ? &mons[PM_GHOST] : (i < 40) ? &mons[PM_WRAITH] : mkclass(dlev, S_ZOMBIE, 0, rng); }
/* mon summons a monster */ void msummon(struct monst *mon) { const struct permonst *ptr; int dtype = NON_PM, cnt = 0; aligntyp atyp; struct monst *mtmp; struct d_level *dlev; if (mon) { ptr = mon->data; dlev = &mon->dlevel->z; atyp = (ptr->maligntyp == A_NONE) ? A_NONE : sgn(ptr->maligntyp); if (mon->ispriest || roamer_type(mon->data)) atyp = EPRI(mon)->shralign; } else { ptr = &mons[PM_WIZARD_OF_YENDOR]; atyp = (ptr->maligntyp == A_NONE) ? A_NONE : sgn(ptr->maligntyp); dlev = &u.uz; } if (is_dprince(ptr) || (ptr == &mons[PM_WIZARD_OF_YENDOR])) { dtype = (!rn2(20)) ? dprince(atyp) : (!rn2(4)) ? dlord(atyp) : ndemon(dlev, atyp); cnt = (!rn2(4) && is_ndemon(&mons[dtype])) ? 2 : 1; } else if (is_dlord(ptr)) { dtype = (!rn2(50)) ? dprince(atyp) : (!rn2(20)) ? dlord(atyp) : ndemon(dlev, atyp); cnt = (!rn2(4) && is_ndemon(&mons[dtype])) ? 2 : 1; } else if (is_ndemon(ptr)) { dtype = (!rn2(20)) ? dlord(atyp) : (!rn2(6)) ? ndemon(dlev, atyp) : monsndx(ptr); cnt = 1; } else if (mon && is_lminion(mon)) { dtype = (is_lord(ptr) && !rn2(20)) ? llord() : (is_lord(ptr) || !rn2(6)) ? lminion() : monsndx(ptr); cnt = (!rn2(4) && !is_lord(&mons[dtype])) ? 2 : 1; } else if (ptr == &mons[PM_ANGEL]) { /* non-lawful angels can also summon */ if (!rn2(6)) { switch (atyp) { /* see summon_minion */ case A_NEUTRAL: dtype = PM_AIR_ELEMENTAL + rn2(4); break; case A_CHAOTIC: case A_NONE: dtype = ndemon(dlev, atyp); break; } } else { dtype = PM_ANGEL; } cnt = (!rn2(4) && !is_lord(&mons[dtype])) ? 2 : 1; } if (dtype == NON_PM) return; /* sanity checks */ if (cnt > 1 && (mons[dtype].geno & G_UNIQ)) cnt = 1; /* * If this daemon is unique and being re-summoned (the only way we * could get this far with an extinct dtype), try another. */ if (mvitals[dtype].mvflags & G_GONE) { dtype = ndemon(dlev, atyp); if (dtype == NON_PM) return; } while (cnt > 0) { mtmp = makemon(&mons[dtype], level, u.ux, u.uy, NO_MM_FLAGS); if (mtmp && roamer_type(&mons[dtype])) { /* alignment should match the summoner */ EPRI(mtmp)->shralign = atyp; } cnt--; } }