From 2c08eecda52d2336c827dcb3bf080a31086b2c3e Mon Sep 17 00:00:00 2001 From: jwalz Date: Sat, 5 Jan 2002 21:05:49 +0000 Subject: [PATCH] *** empty log message *** --- src/minion.c | 278 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 src/minion.c diff --git a/src/minion.c b/src/minion.c new file mode 100644 index 000000000..551c39174 --- /dev/null +++ b/src/minion.c @@ -0,0 +1,278 @@ +/* SCCS Id: @(#)minion.c 3.3 2000/09/14 */ +/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ +/* NetHack may be freely redistributed. See license for details. */ + +#include "hack.h" +#include "emin.h" +#include "epri.h" + +void +msummon(ptr) /* ptr summons a monster */ +register struct permonst *ptr; +{ + register int dtype = NON_PM, cnt = 0; + aligntyp atyp = sgn(ptr->maligntyp); + + if (is_dprince(ptr) || (ptr == &mons[PM_WIZARD_OF_YENDOR])) { + dtype = (!rn2(20)) ? dprince(atyp) : + (!rn2(4)) ? dlord(atyp) : ndemon(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(atyp); + cnt = (!rn2(4) && is_ndemon(&mons[dtype])) ? 2 : 1; + } else if (is_ndemon(ptr)) { + dtype = (!rn2(20)) ? dlord(atyp) : + (!rn2(6)) ? ndemon(atyp) : monsndx(ptr); + cnt = 1; + } else if (is_lminion(ptr)) { + dtype = (is_lord(ptr) && !rn2(20)) ? llord() : + (is_lord(ptr) || !rn2(6)) ? lminion() : monsndx(ptr); + 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(atyp); + if (dtype == NON_PM) return; + } + + while (cnt > 0) { + (void)makemon(&mons[dtype], u.ux, u.uy, NO_MM_FLAGS); + cnt--; + } + return; +} + +void +summon_minion(alignment, talk) +aligntyp alignment; +boolean talk; +{ + register 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(alignment); + break; + default: + impossible("unaligned player?"); + mnum = ndemon(A_NONE); + break; + } + if (mnum == NON_PM) { + mon = 0; + } else if (mons[mnum].pxlth == 0) { + struct permonst *pm = &mons[mnum]; + mon = makemon(pm, u.ux, u.uy, MM_EMIN); + if (mon) { + mon->isminion = TRUE; + EMIN(mon)->min_align = alignment; + } + } else if (mnum == PM_ANGEL) { + mon = makemon(&mons[mnum], u.ux, u.uy, NO_MM_FLAGS); + if (mon) { + mon->isminion = TRUE; + EPRI(mon)->shralign = alignment; /* always A_LAWFUL here */ + } + } else + mon = makemon(&mons[mnum], 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 */ + } +} + +#define Athome (Inhell && !mtmp->cham) + +int +demon_talk(mtmp) /* returns 1 if it won't attack. */ +register struct monst *mtmp; +{ + long demand, offer; + + if (uwep && uwep->oartifact == ART_EXCALIBUR) { + pline("%s looks very angry.", Amonnam(mtmp)); + mtmp->mpeaceful = mtmp->mtame = 0; + newsym(mtmp->mx, mtmp->my); + return 0; + } + + /* Slight advantage given. */ + if (is_dprince(mtmp->data) && mtmp->minvis) { + mtmp->minvis = mtmp->perminvis = 0; + if (!Blind) pline("%s appears before you.", Amonnam(mtmp)); + newsym(mtmp->mx,mtmp->my); + } + if (youmonst.data->mlet == S_DEMON) { /* Won't blackmail their own. */ + pline("%s says, \"Good hunting, %s.\"", + Amonnam(mtmp), flags.female ? "Sister" : "Brother"); + if (!tele_restrict(mtmp)) rloc(mtmp); + return(1); + } +#ifndef GOLDOBJ + demand = (u.ugold * (rnd(80) + 20 * Athome)) / +#else + demand = (money_cnt(invent) * (rnd(80) + 20 * Athome)) / +#endif + (100 * (1 + (sgn(u.ualign.type) == sgn(mtmp->data->maligntyp)))); + if (!demand) /* you have no gold */ + return mtmp->mpeaceful = 0; + else { + pline("%s demands %ld zorkmid%s for safe passage.", + Amonnam(mtmp), demand, plur(demand)); + + if ((offer = bribe(mtmp)) >= demand) { + pline("%s vanishes, laughing about cowardly mortals.", + Amonnam(mtmp)); + } else { + if ((long)rnd(40) > (demand - offer)) { + pline("%s scowls at you menacingly, then vanishes.", + Amonnam(mtmp)); + } else { + pline("%s gets angry...", Amonnam(mtmp)); + return mtmp->mpeaceful = 0; + } + } + } + mongone(mtmp); + return(1); +} + +long +bribe(mtmp) +struct monst *mtmp; +{ + char buf[BUFSZ]; + long offer; +#ifdef GOLDOBJ + long umoney = money_cnt(invent); +#endif + + getlin("How much will you offer?", buf); + if (sscanf(buf, "%ld", &offer) != 1) offer = 0L; + + /*Michael Paddon -- fix for negative offer to monster*/ + /*JAR880815 - */ + if (offer < 0L) { + You("try to shortchange %s, but fumble.", + mon_nam(mtmp)); + offer = 0L; + } else if (offer == 0L) { + You("refuse."); +#ifndef GOLDOBJ + } else if (offer >= u.ugold) { + You("give %s all your gold.", mon_nam(mtmp)); + offer = u.ugold; + } else You("give %s %ld zorkmid%s.", mon_nam(mtmp), offer, + plur(offer)); + + u.ugold -= offer; + mtmp->mgold += offer; +#else + } else if (offer >= umoney) { + You("give %s all your gold.", mon_nam(mtmp)); + offer = umoney; + } else You("give %s %ld zorkmid%s.", mon_nam(mtmp), offer, + plur(offer)); + + money2mon(mtmp, offer); +#endif + flags.botl = 1; + return(offer); +} + +int +dprince(atyp) +aligntyp atyp; +{ + int tryct, pm; + + for (tryct = 0; tryct < 20; tryct++) { + pm = rn1(PM_DEMOGORGON + 1 - PM_ORCUS, PM_ORCUS); + if (!(mvitals[pm].mvflags & G_GONE) && + (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp))) + return(pm); + } + return(dlord(atyp)); /* approximate */ +} + +int +dlord(atyp) +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(atyp)); /* approximate */ +} + +/* create lawful (good) lord */ +int +llord() +{ + if (!(mvitals[PM_ARCHON].mvflags & G_GONE)) + return(PM_ARCHON); + + return(lminion()); /* approximate */ +} + +int +lminion() +{ + int tryct; + struct permonst *ptr; + + for (tryct = 0; tryct < 20; tryct++) { + ptr = mkclass(S_ANGEL,0); + if (ptr && !is_lord(ptr)) + return(monsndx(ptr)); + } + + return NON_PM; +} + +int +ndemon(atyp) +aligntyp atyp; +{ + int tryct; + struct permonst *ptr; + + for (tryct = 0; tryct < 20; tryct++) { + ptr = mkclass(S_DEMON, 0); + if (ptr && is_ndemon(ptr) && + (atyp == A_NONE || sgn(ptr->maligntyp) == sgn(atyp))) + return(monsndx(ptr)); + } + + return NON_PM; +} + +/*minion.c*/