int rndmonnum(void) /* select a random, common monster type */ { register struct permonst *ptr; register int i; /* Plan A: get a level-appropriate common monster */ ptr = rndmonst(); if (ptr) return(monsndx(ptr)); /* Plan B: get any common proper monster */ int count = 0; do { i = rn1(SPECIAL_PM - LOW_PM, LOW_PM); ptr = &mons[i]; count++; } while (((ptr->geno & G_NOGEN) || prohibited_by_generation_flags(ptr)) && count < 10000); /* Plan C: get any common monster */ do { i = rn1(SPECIAL_PM - LOW_PM, LOW_PM); ptr = &mons[i]; count++; } while(ptr->geno & G_NOGEN); return(i); }
/* select a random, common monster type */ int rndmonnum(const d_level *dlev) { const struct permonst *ptr; int i; /* Plan A: get a level-appropriate common monster */ ptr = rndmonst(dlev); if (ptr) return monsndx(ptr); /* Plan B: get any common monster */ do { i = rn1(SPECIAL_PM - LOW_PM, LOW_PM); ptr = &mons[i]; } while ((ptr->geno & G_NOGEN) || (!In_hell(dlev) && (ptr->geno & G_HELL))); return i; }
struct monst * make_familiar(struct obj *otmp, xchar x, xchar y, boolean quietly) { const struct permonst *pm; struct monst *mtmp = 0; int chance, trycnt = 100; do { if (otmp) { /* figurine; otherwise spell */ int mndx = otmp->corpsenm; pm = &mons[mndx]; /* activating a figurine provides one way to exceed the maximum number of the target critter created--unless it has a special limit (erinys, Nazgul) */ if ((mvitals[mndx].mvflags & G_EXTINCT) && mbirth_limit(mndx) != MAXMONNO) { if (!quietly) /* have just been given "You <do something with> the figurine and it transforms." message */ pline("... into a pile of dust."); break; /* mtmp is null */ } } else if (!rn2(3)) { pm = &mons[pet_type(NULL)]; } else { pm = rndmonst(&u.uz, rng_t_create_monster); if (!pm) { if (!quietly) pline ("There seems to be nothing available for a familiar."); break; } } mtmp = makemon(pm, level, x, y, MM_EDOG | MM_IGNOREWATER | (otmp ? 0 : (MM_CREATEMONSTER | MM_CMONSTER_T))); if (otmp && !mtmp) { /* monster was genocided or square occupied */ if (!quietly) pline("The figurine writhes and then shatters into pieces!"); break; } } while (!mtmp && --trycnt > 0); if (!mtmp) return NULL; if (is_pool(level, mtmp->mx, mtmp->my) && minliquid(mtmp)) return NULL; initedog(mtmp); mtmp->msleeping = 0; if (otmp) { /* figurine; resulting monster might not become a pet */ chance = rn2_on_rng(10, rng_figurine_effect); /* 0: tame, 1: peaceful, 2: hostile, 3+: matching BCU; this gives an 80% chance of the desired effect, 10% of each other effect */ if (chance > 2) chance = otmp->blessed ? 0 : !otmp->cursed ? 1 : 2; if (chance > 0) { mtmp->mtame = 0; /* not tame after all */ if (chance == 2) { /* hostile (cursed figurine) */ if (!quietly) pline("You get a bad feeling about this."); msethostility(mtmp, TRUE, TRUE); } } /* if figurine has been named, give same name to the monster */ if (otmp->onamelth) mtmp = christen_monst(mtmp, ONAME(otmp)); } set_malign(mtmp); /* more alignment changes */ newsym(mtmp->mx, mtmp->my); /* must wield weapon immediately since pets will otherwise drop it */ if (mtmp->mtame && attacktype(mtmp->data, AT_WEAP)) { mtmp->weapon_check = NEED_HTH_WEAPON; mon_wield_item(mtmp); } return mtmp; }