static void mkswamp(struct level *lev) { struct mkroom *sroom; int sx, sy, i, eelct = 0; for (i = 0; i < 5; i++) { /* turn up to 5 rooms swampy */ sroom = &lev->rooms[rn2(lev->nroom)]; if (sroom->hx < 0 || sroom->rtype != OROOM || has_upstairs(lev, sroom) || has_dnstairs(lev, sroom)) continue; /* satisfied; make a swamp */ sroom->rtype = SWAMP; for (sx = sroom->lx; sx <= sroom->hx; sx++) for (sy = sroom->ly; sy <= sroom->hy; sy++) if (!OBJ_AT_LEV(lev, sx, sy) && !MON_AT(lev, sx, sy) && !t_at(lev, sx, sy) && !nexttodoor(lev, sx, sy)) { if ((sx + sy) % 2) { lev->locations[sx][sy].typ = POOL; if (!eelct || !rn2(4)) { /* mkclass() won't do, as we might get kraken */ makemon(rn2(5) ? &mons[PM_GIANT_EEL] : rn2(2) ? &mons[PM_PIRANHA] : &mons[PM_ELECTRIC_EEL], lev, sx, sy, NO_MM_FLAGS); eelct++; } } else if (!rn2(4)) /* swamps tend to be moldy */ makemon(mkclass(&lev->z, S_FUNGUS, 0), lev, sx, sy, NO_MM_FLAGS); } lev->flags.has_swamp = 1; } }
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 */ } }
static void newmail() { /* produce a scroll of mail */ struct obj *obj; struct monst *md; extern char plname[]; extern struct obj *mksobj(); extern struct monst *makemon(); extern struct permonst pm_mail_daemon; obj = mksobj(SCR_MAIL); if(md = makemon(&pm_mail_daemon, u.ux, u.uy)) /* always succeeds */ mdrush(md,0); pline("\"Hello, %s! I have some mail for you.\"", plname); if(md) { if(dist(md->mx,md->my) > 2) pline("\"Catch!\""); more(); /* let him disappear again */ mdrush(md,1); mondead(md); } obj = addinv(obj); (void) identify(obj); /* set known and do prinv() */ }
struct monst * mk_roamer(const struct permonst *ptr, aligntyp alignment, struct level *lev, xchar x, xchar y, boolean peaceful, int mm_flags) { struct monst *roamer; boolean coaligned = (u.ualign.type == alignment); if (ptr != &mons[PM_ALIGNED_PRIEST] && ptr != &mons[PM_ANGEL]) return NULL; if (MON_AT(lev, x, y)) rloc(m_at(lev, x, y), FALSE); /* insurance */ if (!(roamer = makemon(ptr, lev, x, y, mm_flags))) return NULL; EPRI(roamer)->shralign = alignment; if (coaligned && !peaceful) EPRI(roamer)->renegade = TRUE; /* roamer->ispriest == FALSE naturally */ roamer->isminion = TRUE; /* borrowing this bit */ roamer->mtrapseen = ~0; /* traps are known */ msethostility(roamer, !peaceful, TRUE); /* TODO: handle in_mklev */ roamer->msleeping = 0; /* MORE TO COME */ return roamer; }
void mkswamp(void) { // Michiel Huisjes & Fred de Wilde struct mkroom *sroom; int sx, sy, i, eelct = 0; for (i = 0; i < 5; i++) { // 5 tries sroom = &rooms[rn2(nroom)]; if (sroom->hx < 0 || sroom->rtype || has_upstairs(sroom) || has_dnstairs(sroom)) continue; // satisfied; make a swamp sroom->rtype = SWAMP; for (sx = sroom->lx; sx <= sroom->hx; sx++) for (sy = sroom->ly; sy <= sroom->hy; sy++) if ((sx + sy) % 2 && !o_at(sx, sy) && !t_at(sx, sy) && !m_at(sx, sy) && !nexttodoor(sx, sy)) { levl[sx][sy].typ = POOL; levl[sx][sy].scrsym = POOL_SYM; if (!eelct || !rn2(4)) { (void) makemon(PM_EEL, sx, sy); eelct++; } } } }
/* create a new shopkeeper in the given room */ static int shkinit ( const struct shclass *shp, struct mkroom *sroom) { int sh, sx, sy; struct monst *shk; /* place the shopkeeper in the given room */ sh = sroom->fdoor; sx = doors[sh].x; sy = doors[sh].y; /* check that the shopkeeper placement is sane */ if(sroom->irregular) { int rmno = (sroom - rooms) + ROOMOFFSET; if (isok(sx-1,sy) && !levl[sx-1][sy].edge && (int) levl[sx-1][sy].roomno == rmno) sx--; else if (isok(sx+1,sy) && !levl[sx+1][sy].edge && (int) levl[sx+1][sy].roomno == rmno) sx++; else if (isok(sx,sy-1) && !levl[sx][sy-1].edge && (int) levl[sx][sy-1].roomno == rmno) sy--; else if (isok(sx,sy+1) && !levl[sx][sy+1].edge && (int) levl[sx][sy+1].roomno == rmno) sx++; else goto shk_failed; } else if(sx == sroom->lx-1) sx++; else if(sx == sroom->hx+1) sx--; else if(sy == sroom->ly-1) sy++; else if(sy == sroom->hy+1) sy--; else { shk_failed: return(-1); } if(MON_AT(sx, sy)) (void) rloc(m_at(sx, sy), false); /* insurance */ /* now initialize the shopkeeper monster structure */ if(!(shk = makemon(&mons[PM_SHOPKEEPER], sx, sy, NO_MM_FLAGS))) return(-1); shk->isshk = shk->mpeaceful = 1; set_malign(shk); shk->msleeping = 0; shk->mtrapseen = ~0; /* we know all the traps already */ ESHK(shk)->shoproom = (sroom - rooms) + ROOMOFFSET; sroom->resident = shk; ESHK(shk)->shoptype = sroom->rtype; assign_level(&(ESHK(shk)->shoplevel), &u.uz); ESHK(shk)->shd = doors[sh]; ESHK(shk)->shk.x = sx; ESHK(shk)->shk.y = sy; ESHK(shk)->robbed = 0L; ESHK(shk)->credit = 0L; ESHK(shk)->debit = 0L; ESHK(shk)->loan = 0L; ESHK(shk)->visitct = 0; ESHK(shk)->following = 0; ESHK(shk)->billct = 0; shk->mgold = 1000L + 30L*(long)rnd(100); /* initial capital */ if (shp->shknms == shkrings) (void) mongets(shk, TOUCHSTONE); nameshk(shk, shp->shknms); return(sh); }
void makedog() { struct monst *mtmp = makemon(&li_dog,u.ux,u.uy); if(!mtmp) return; /* dogs were genocided */ initedog(mtmp); }
void makerogueghost(struct level *lev) { struct monst *ghost; struct obj *ghostobj; struct mkroom *croom; int x,y; if (!lev->nroom) return; /* Should never happen */ croom = &lev->rooms[rn2(lev->nroom)]; x = somex(croom); y = somey(croom); if (!(ghost = makemon(&mons[PM_GHOST], lev, x, y, NO_MM_FLAGS))) return; ghost->msleeping = 1; christen_monst(ghost, roguename()); if (rn2(4)) { ghostobj = mksobj_at(FOOD_RATION, lev, x, y, FALSE, FALSE); ghostobj->quan = (long) rnd(7); ghostobj->owt = weight(ghostobj); } if (rn2(2)) { ghostobj = mksobj_at(MACE, lev, x, y, FALSE, FALSE); ghostobj->spe = rnd(3); if (rn2(4)) curse(ghostobj); } else { ghostobj = mksobj_at(TWO_HANDED_SWORD, lev, x, y, FALSE, FALSE); ghostobj->spe = rnd(5) - 2; if (rn2(4)) curse(ghostobj); } ghostobj = mksobj_at(BOW, lev, x, y, FALSE, FALSE); ghostobj->spe = 1; if (rn2(4)) curse(ghostobj); ghostobj = mksobj_at(ARROW, lev, x, y, FALSE, FALSE); ghostobj->spe = 0; ghostobj->quan = (long) rn1(10,25); ghostobj->owt = weight(ghostobj); if (rn2(4)) curse(ghostobj); if (rn2(2)) { ghostobj = mksobj_at(RING_MAIL, lev, x, y, FALSE, FALSE); ghostobj->spe = rn2(3); if (!rn2(3)) ghostobj->oerodeproof = TRUE; if (rn2(4)) curse(ghostobj); } else { ghostobj = mksobj_at(PLATE_MAIL, lev, x, y, FALSE, FALSE); ghostobj->spe = rnd(5) - 2; if (!rn2(3)) ghostobj->oerodeproof = TRUE; if (rn2(4)) curse(ghostobj); } if (rn2(2)) { ghostobj = mksobj_at(FAKE_AMULET_OF_YENDOR, lev, x, y, TRUE, FALSE); ghostobj->known = TRUE; } }
struct monst* mkmon_at(int let, int x, int y) { for (unsigned ct = 0; ct < CMNUM; ++ct) { const struct permonst* ptr = &c_Monsters[ct]; if (ptr->mlet == let) return makemon (ptr, x, y); } return 0; }
void mkzoo(int type) { struct mkroom *sroom; struct monst *mon; int sh, sx, sy, i; int goldlim = 500 * dlevel; int moct = 0; i = nroom; for (sroom = &rooms[rn2(nroom)];; sroom++) { if (sroom == &rooms[nroom]) sroom = &rooms[0]; if (!i-- || sroom->hx < 0) return; if (sroom->rtype) continue; if (type == MORGUE && sroom->rlit) continue; if (has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3))) continue; if (sroom->doorct == 1 || !rn2(5)) break; } sroom->rtype = type; sh = sroom->fdoor; for (sx = sroom->lx; sx <= sroom->hx; sx++) for (sy = sroom->ly; sy <= sroom->hy; sy++) { if ((sx == sroom->lx && doors[sh].x == sx - 1) || (sx == sroom->hx && doors[sh].x == sx + 1) || (sy == sroom->ly && doors[sh].y == sy - 1) || (sy == sroom->hy && doors[sh].y == sy + 1)) continue; mon = makemon((type == MORGUE) ? morguemon() : (type == BEEHIVE) ? PM_KILLER_BEE : (struct permonst *) 0, sx, sy); if (mon) mon->msleep = 1; switch (type) { case ZOO: i = sq(dist2(sx, sy, doors[sh].x, doors[sh].y)); if (i >= goldlim) i = 5 * dlevel; goldlim -= i; mkgold((long) (10 + rn2(i)), sx, sy); break; case MORGUE: // Usually there is one dead body in the morgue if (!moct && rn2(3)) { mksobj_at(CORPSE, sx, sy); moct++; } break; case BEEHIVE: if (!rn2(3)) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy); break; } } }
/* * This function is only called from newgame, so we know: * - pets aren't genocided so makemon will always work * - the petname has not been used yet * This is called very late in the newgame sequence, and so can safely clobber * the charstats RNGs. */ struct monst * makedog(struct newgame_options *ngo) { struct monst *mtmp; struct obj *otmp; const char *petname; int pettype; if (ngo->preferred_pet == 'n') return NULL; pettype = pet_type(ngo); if (pettype == PM_LITTLE_DOG) petname = ngo->dogname; else if (pettype == PM_PONY) petname = ngo->horsename; else petname = ngo->catname; /* default pet names */ if (!*petname && pettype == PM_LITTLE_DOG) { /* All of these names were for dogs. */ if (Role_if(PM_CAVEMAN)) petname = "Slasher"; /* The Warrior */ if (Role_if(PM_SAMURAI)) petname = "Hachi"; /* Shibuya Station */ if (Role_if(PM_BARBARIAN)) petname = "Idefix"; /* Obelix */ if (Role_if(PM_RANGER)) petname = "Sirius"; /* Orion's dog */ } /* ideally we'd use rng_charstats_role for this, but... */ mtmp = makemon(&mons[pettype], level, u.ux, u.uy, MM_EDOG); /* Horses already wear a saddle */ if (pettype == PM_PONY && ((otmp = mksobj(level, SADDLE, TRUE, FALSE, rng_charstats_role)))) { if (mpickobj(mtmp, otmp)) panic("merged saddle?"); mtmp->misc_worn_check |= W_MASK(os_saddle); otmp->dknown = otmp->bknown = otmp->rknown = 1; otmp->owornmask = W_MASK(os_saddle); otmp->leashmon = mtmp->m_id; update_mon_intrinsics(mtmp, otmp, TRUE, TRUE); } if (*petname) mtmp = christen_monst(mtmp, petname); initedog(mtmp); return mtmp; }
static void clonewiz(struct monst *mtmp) { struct monst *mtmp2; if ((mtmp2 = makemon(PM_WIZARD, mtmp->mx, mtmp->my))) { flags.no_of_wizards = 2; unpmon(mtmp2); mtmp2->mappearance = wizapp[rn2(sizeof(wizapp)-1)]; pmon(mtmp); } }
int dosearch(void) { xchar x, y; struct trap *trap; struct monst *mtmp; if (u.uswallow) pline("What are you looking for? The exit?"); else for (x = u.ux - 1; x < u.ux + 2; x++) for (y = u.uy - 1; y < u.uy + 2; y++) if (x != u.ux || y != u.uy) { if (levl[x][y].typ == SDOOR) { if (rn2(7)) continue; levl[x][y].typ = DOOR; levl[x][y].seen = 0; // force prl prl(x, y); nomul(0); } else if (levl[x][y].typ == SCORR) { if (rn2(7)) continue; levl[x][y].typ = CORR; levl[x][y].seen = 0; // force prl prl(x, y); nomul(0); } else { // Be careful not to find anything in an SCORR or SDOOR if ((mtmp = m_at(x, y)) != NULL) { if (mtmp->mimic) { seemimic(mtmp); pline("You find a mimic."); return 1; } } for (trap = ftrap; trap; trap = trap->ntrap) { if (trap->tx == x && trap->ty == y && !trap->tseen && !rn2(8)) { nomul(0); pline("You find a%s.", traps[trap->ttyp]); if (trap->ttyp == PIERC) { deltrap(trap); (void) makemon(PM_PIERCER, x, y); return 1; } trap->tseen = 1; if (!vism_at(x, y)) atl(x, y, '^'); } } } } return 1; }
struct monst * mkmon_at(char let, int x, int y) { int ct; struct permonst *ptr; for(ct = 0; ct < CMNUM; ct++) { ptr = &mons[ct]; if(ptr->mlet == let) return(makemon(ptr,x,y)); } return(NULL); }
static void ghost_from_bottle() { monst_t *mtmp; mtmp = makemon(PM_GHOST,you.ux,you.uy); if (!mtmp) { message("This bottle turns out to be empty."); return; } mnexto(mtmp); message("As you open the bottle, an enormous ghost emerges!"); message("You are frightened to death, and unable to move."); nomul(-3); }
// ok, the SDOOR/SCORR part works. however, none of the rest is tested // (traps, mimics, swallowed, etc) void do_search() // was dosearch { Int8 x,y; trap_t *trap; monst_t *mtmp; UChar floor_type, tmp_type; if (you.uswallow) { message("What are you looking for? The exit?"); return; } for (x = you.ux - 1 ; x <= you.ux + 1 ; x++) for (y = you.uy - 1 ; y <= you.uy + 1 ; y++) { if (x == you.ux && y == you.uy) continue; floor_type = get_cell_type(floor_info[x][y]); if (floor_type == SDOOR || floor_type == SCORR) { if (rund(7)) continue; tmp_type = (floor_type == SDOOR) ? DOOR : CORR; set_cell_type(floor_info[x][y], tmp_type); floor_info[x][y] &= ~SEEN_CELL; /* force prl */ prl(x,y); nomul(0); } else { /* Be careful not to find anything in an SCORR or SDOOR */ mtmp = mon_at(x,y); if (mtmp && (mtmp->bitflags & M_IS_MIMIC)) { see_mimic(mtmp); message("You find a mimic."); return; } for (trap = ftrap ; trap ; trap = trap->ntrap) if (trap->tx == x && trap->ty == y && !(get_trap_seen(trap->trap_info)) && !rund(8)) { nomul(0); tmp_type = get_trap_type(trap->trap_info); StrPrintF(ScratchBuffer, "You find a%s.", traps[tmp_type]); message(ScratchBuffer); if (tmp_type == PIERC) { deltrap(trap); makemon(PM_PIERCER, x, y); return; } trap->trap_info |= SEEN_TRAP; if (!vism_at(x,y)) print(x, y, '^'); } } } }
static void ghost_from_bottle() { extern struct permonst pm_ghost; struct monst *mtmp; if(!(mtmp = makemon(PM_GHOST,u.ux,u.uy))){ pline("This bottle turns out to be empty."); return; } mnexto(mtmp); pline("As you open the bottle, an enormous ghost emerges!"); pline("You are frightened to death, and unable to move."); nomul(-3); }
/*ARGSUSED*/ STATIC_OVL void newmail(struct mail_info *info) { struct monst *md; coord start, stop; boolean message_seen = FALSE; /* Try to find good starting and stopping places. */ if (!md_start(&start) || !md_stop(&stop,&start)) goto give_up; /* Make the daemon. Have it rush towards the hero. */ if (!(md = makemon(&mons[PM_MAIL_DAEMON], start.x, start.y, NO_MM_FLAGS))) goto give_up; if (!md_rush(md, stop.x, stop.y)) goto go_back; message_seen = TRUE; verbalize("%s, %s! %s.", Hello(md), plname, info->display_txt); if (info->message_typ) { struct obj *obj = mksobj(SCR_MAIL, FALSE, FALSE); if (info->message_typ == MSG_HINT) obj->spe = MAIL_HINT; if (distu(md->mx,md->my) > 2) verbalize("Catch!"); display_nhwindow(WIN_MESSAGE, FALSE); if (info->object_nam) { obj = oname(obj, info->object_nam); if (info->response_cmd) { /*(hide extension of the obj name)*/ int namelth = info->response_cmd - info->object_nam - 1; if ( namelth <= 0 || namelth >= (int) obj->onamelth ) warning("mail delivery screwed up"); else *(ONAME(obj) + namelth) = '\0'; /* Note: renaming object will discard the hidden command. */ } } obj = hold_another_object(obj, "Oops!", (const char *)0, (const char *)0); } /* zip back to starting location */ go_back: (void) md_rush(md, start.x, start.y); mongone(md); /* deliver some classes of messages even if no daemon ever shows up */ give_up: if (!message_seen && info->message_typ == MSG_OTHER) pline("Hark! \"%s.\"", info->display_txt); }
Short findit() /* returns number of things found */ { Short num; UChar zx,zy; trap_t *ttmp; monst_t *mtmp; UChar lx,hx,ly,hy; if (you.uswallow) return false; for (lx = you.ux; (num = get_cell_type(floor_info[lx-1][you.uy])) && num != CORR; lx--) ; for (hx = you.ux; (num = get_cell_type(floor_info[hx+1][you.uy])) && num != CORR; hx++) ; for (ly = you.uy; (num = get_cell_type(floor_info[you.ux][ly-1])) && num != CORR; ly--) ; for (hy = you.uy; (num = get_cell_type(floor_info[you.ux][hy+1])) && num != CORR; hy++) ; num = 0; for (zy = ly; zy <= hy; zy++) { for (zx = lx; zx <= hx; zx++) { if (get_cell_type(floor_info[zx][zy]) == SDOOR) { set_cell_type(floor_info[zx][zy], DOOR); print(zx, zy, DOOR_SYM); num++; } else if (get_cell_type(floor_info[zx][zy]) == SCORR) { set_cell_type(floor_info[zx][zy], CORR); print(zx, zy, CORR_SYM); num++; } else if ((ttmp = trap_at(zx, zy))) { if (get_trap_type(ttmp->trap_info) == PIERC) { makemon(PM_PIERCER, zx, zy); num++; deltrap(ttmp); } else if (!get_trap_seen(ttmp->trap_info)) { ttmp->trap_info |= SEEN_TRAP; if (!vism_at(zx, zy)) print(zx,zy,'^'); num++; } } else if ((mtmp = mon_at(zx,zy)) && (mtmp->bitflags & M_IS_MIMIC)) { see_mimic(mtmp); num++; } } } return num; }
/* make a swarm of undead around mm; uses the main RNG */ void mkundead(struct level *lev, coord *mm, boolean revive_corpses, int mm_flags) { int cnt = (level_difficulty(&lev->z) + 1) / 10 + rnd(5); const struct permonst *mdat; struct obj *otmp; coord cc; while (cnt--) { mdat = morguemon(&lev->z, rng_main); if (enexto(&cc, lev, mm->x, mm->y, mdat) && (!revive_corpses || !(otmp = sobj_at(CORPSE, lev, cc.x, cc.y)) || !revive(otmp))) makemon(mdat, lev, cc.x, cc.y, mm_flags); } lev->flags.graveyard = TRUE; /* reduced chance for undead corpse */ }
/* make a swarm of undead around mm */ void mkundead (coord *mm, bool revive_corpses, int mm_flags) { int cnt = (level_difficulty() + 1)/10 + rnd(5); struct permonst *mdat; struct obj *otmp; coord cc; while (cnt--) { mdat = morguemon(); if (enexto(&cc, mm->x, mm->y, mdat) && (!revive_corpses || !(otmp = sobj_at(CORPSE, cc.x, cc.y)) || !revive(otmp))) (void) makemon(mdat, cc.x, cc.y, mm_flags); } level.flags.graveyard = true; /* reduced chance for undead corpse */ }
int findit(void) { // returns number of things found int num; xchar zx, zy; struct trap *ttmp; struct monst *mtmp; xchar lx, hx, ly, hy; if (u.uswallow) return 0; for (lx = u.ux; (num = levl[lx - 1][u.uy].typ) && num != CORR; lx--); for (hx = u.ux; (num = levl[hx + 1][u.uy].typ) && num != CORR; hx++); for (ly = u.uy; (num = levl[u.ux][ly - 1].typ) && num != CORR; ly--); for (hy = u.uy; (num = levl[u.ux][hy + 1].typ) && num != CORR; hy++); num = 0; for (zy = ly; zy <= hy; zy++) for (zx = lx; zx <= hx; zx++) { if (levl[zx][zy].typ == SDOOR) { levl[zx][zy].typ = DOOR; atl(zx, zy, '+'); num++; } else if (levl[zx][zy].typ == SCORR) { levl[zx][zy].typ = CORR; atl(zx, zy, CORR_SYM); num++; } else if ((ttmp = t_at(zx, zy)) != NULL) { if (ttmp->ttyp == PIERC) { (void) makemon(PM_PIERCER, zx, zy); num++; deltrap(ttmp); } else if (!ttmp->tseen) { ttmp->tseen = 1; if (!vism_at(zx, zy)) atl(zx, zy, '^'); num++; } } else if ((mtmp = m_at(zx, zy)) != NULL) if (mtmp->mimic) { seemimic(mtmp); num++; } } return num; }
static void dowatersnakes() /* Fountain of snakes! */ { register int num = rn1(5,2); struct monst *mtmp; if (!(mons[PM_WATER_MOCCASIN].geno & (G_GENOD | G_EXTINCT))) { if (!Blind) pline("An endless stream of %s pours forth!", Hallucination ? makeplural(rndmonnam()) : "snakes"); else You("hear something hissing!"); while(num-- > 0) if((mtmp = makemon(&mons[PM_WATER_MOCCASIN],u.ux,u.uy)) && t_at(mtmp->mx, mtmp->my)) (void) mintrap(mtmp); } else pline("The fountain bubbles furiously for a moment, then calms."); }
/* were-creature (even you) summons a horde */ int were_summon(const struct permonst *ptr, boolean yours, int *visible, /* number of visible helpers created */ char *genbuf) { int i, typ, pm = monsndx(ptr); struct monst *mtmp; int total = 0; *visible = 0; if (Protection_from_shape_changers && !yours) return 0; for (i = rnd(5); i > 0; i--) { switch(pm) { case PM_WERERAT: case PM_HUMAN_WERERAT: typ = rn2(3) ? PM_SEWER_RAT : rn2(3) ? PM_GIANT_RAT : PM_RABID_RAT ; if (genbuf) strcpy(genbuf, "rat"); break; case PM_WEREJACKAL: case PM_HUMAN_WEREJACKAL: typ = PM_JACKAL; if (genbuf) strcpy(genbuf, "jackal"); break; case PM_WEREWOLF: case PM_HUMAN_WEREWOLF: typ = rn2(5) ? PM_WOLF : PM_WINTER_WOLF ; if (genbuf) strcpy(genbuf, "wolf"); break; default: continue; } mtmp = makemon(&mons[typ], level, u.ux, u.uy, NO_MM_FLAGS); if (mtmp) { total++; if (canseemon(mtmp)) *visible += 1; } if (yours && mtmp) tamedog(mtmp, NULL); } return total; }
static void dowaternymph() /* Water Nymph */ { register struct monst *mtmp; if(mons[PM_WATER_NYMPH].geno & (G_GENOD | G_EXTINCT)) return; if((mtmp = makemon(&mons[PM_WATER_NYMPH],u.ux,u.uy))) { if (!Blind) You("attract %s!", a_monnam(mtmp)); else You("hear a seductive voice."); mtmp->msleep = 0; if (t_at(mtmp->mx, mtmp->my)) (void) mintrap(mtmp); } else if (!Blind) pline("A large bubble rises to the surface and pops."); else You("hear a loud pop."); }
/* make an object of the appropriate type for a shop square */ static void mkshobj_at ( const struct shclass *shp, int sx, int sy) { struct monst *mtmp; int atype; struct permonst *ptr; if (rn2(100) < depth(&u.uz) && !MON_AT(sx, sy) && (ptr = mkclass(S_MIMIC,0)) && (mtmp = makemon(ptr,sx,sy,NO_MM_FLAGS)) != 0) { /* note: makemon will set the mimic symbol to a shop item */ if (rn2(10) >= depth(&u.uz)) { mtmp->m_ap_type = M_AP_OBJECT; mtmp->mappearance = STRANGE_OBJECT; } } else { atype = get_shop_item(shp - shtypes); if (atype < 0) (void) mksobj_at(-atype, sx, sy, true, true); else (void) mkobj_at(atype, sx, sy, true); } }
void newmail(void) { // produce a scroll of mail struct obj *obj; struct monst *md; obj = mksobj(SCR_MAIL); if (md = makemon(&pm_mail_daemon, u.ux, u.uy)) // always succeeds mdrush(md, 0); pline("\"Hello, %s! I have some mail for you.\"", plname); if (md) { if (dist(md->mx, md->my) > 2) pline("\"Catch!\""); more(); // let him disappear again mdrush(md, 1); mondead(md); } obj = addinv(obj); (void) identify(obj); // set known and do prinv() }
static void dowaterdemon() /* Water demon */ { register struct monst *mtmp; if(mons[PM_WATER_DEMON].geno & (G_GENOD | G_EXTINCT)) return; if((mtmp = makemon(&mons[PM_WATER_DEMON],u.ux,u.uy))) { if (!Blind) You("unleash %s!", a_monnam(mtmp)); else You("feel the presence of evil."); /* Give those on low levels a (slightly) better chance of survival */ if (rnd(100) > (80 + level_difficulty())) { pline("Grateful for %s release, %s grants you a wish!", his[pronoun_gender(mtmp)], he[pronoun_gender(mtmp)]); makewish(); mongone(mtmp); } else if (t_at(mtmp->mx, mtmp->my)) (void) mintrap(mtmp); } }
/* Make an object of the appropriate type for a shop square. Uses the level generation RNG. */ static void mkshobj_at(const struct shclass *shp, struct level *lev, int sx, int sy) { struct monst *mtmp; int atype; const struct permonst *ptr; enum rng rng = rng_for_level(&lev->z); if (rn2_on_rng(100, rng) < depth(&lev->z) && !MON_AT(lev, sx, sy) && (ptr = mkclass(&lev->z, S_MIMIC, 0, rng)) && (mtmp = makemon(ptr, lev, sx, sy, MM_ALLLEVRNG)) != 0) { /* note: makemon will set the mimic symbol to a shop item */ if (rn2_on_rng(10, rng) >= depth(&lev->z)) { mtmp->m_ap_type = M_AP_OBJECT; mtmp->mappearance = STRANGE_OBJECT; } } else { atype = get_shop_item(shp - shtypes, rng); if (atype < 0) mksobj_at(-atype, lev, sx, sy, TRUE, TRUE, rng); else mkobj_at(atype, lev, sx, sy, TRUE, rng); } }
/* * called with [x,y] = coordinates; * [0,0] means anyplace * [u.ux,u.uy] means: call mnexto (if !in_mklev) * * In case we make an Orc or killer bee, we make an entire horde (swarm); * note that in this case we return only one of them (the one at [x,y]). */ struct monst * makemon(struct permonst *ptr, int x, int y) { struct monst *mtmp; int tmp, ct; boolean anything = (!ptr); extern boolean in_mklev; if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0); if(ptr){ if(strchr(fut_geno, ptr->mlet)) return((struct monst *) 0); } else { ct = CMNUM - strlen(fut_geno); if(strchr(fut_geno, 'm')) ct++; /* make only 1 minotaur */ if(strchr(fut_geno, '@')) ct++; if(ct <= 0) return(0); /* no more monsters! */ tmp = rn2(ct*dlevel/24 + 7); if(tmp < dlevel - 4) tmp = rn2(ct*dlevel/24 + 12); if(tmp >= ct) tmp = rn1(ct - ct/2, ct/2); for(ct = 0; ct < CMNUM; ct++){ ptr = &mons[ct]; if(strchr(fut_geno, ptr->mlet)) continue; if(!tmp--) goto gotmon; } panic("makemon?"); } gotmon: mtmp = newmonst(ptr->pxlth); *mtmp = zeromonst; /* clear all entries in structure */ for(ct = 0; ct < ptr->pxlth; ct++) ((char *) &(mtmp->mextra[0]))[ct] = 0; mtmp->nmon = fmon; fmon = mtmp; mtmp->m_id = flags.ident++; mtmp->data = ptr; mtmp->mxlth = ptr->pxlth; if(ptr->mlet == 'D') mtmp->mhpmax = mtmp->mhp = 80; else if(!ptr->mlevel) mtmp->mhpmax = mtmp->mhp = rnd(4); else mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8); mtmp->mx = x; mtmp->my = y; mtmp->mcansee = 1; if(ptr->mlet == 'M'){ mtmp->mimic = 1; mtmp->mappearance = ']'; } if(!in_mklev) { if(x == u.ux && y == u.uy && ptr->mlet != ' ') mnexto(mtmp); if(x == 0 && y == 0) rloc(mtmp); } if(ptr->mlet == 's' || ptr->mlet == 'S') { mtmp->mhide = mtmp->mundetected = 1; if(in_mklev) if(mtmp->mx && mtmp->my) (void) mkobj_at(0, mtmp->mx, mtmp->my); } if(ptr->mlet == ':') { mtmp->cham = 1; (void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]); } if(ptr->mlet == 'I' || ptr->mlet == ';') mtmp->minvis = 1; if(ptr->mlet == 'L' || ptr->mlet == 'N' || (in_mklev && strchr("&w;", ptr->mlet) && rn2(5)) ) mtmp->msleep = 1; #ifndef NOWORM if(ptr->mlet == 'w' && getwn(mtmp)) initworm(mtmp); #endif /* NOWORM */ if(anything) if(ptr->mlet == 'O' || ptr->mlet == 'k') { coord mm; int cnt = rnd(10); mm.x = x; mm.y = y; while(cnt--) { mm = enexto(mm.x, mm.y); (void) makemon(ptr, mm.x, mm.y); } } return(mtmp); }