static bool bhito(struct obj *obj, struct obj *otmp) /* object obj was hit by the effect of wand otmp */ /* returns TRUE if sth was done */ { int res = TRUE; if(obj == uball || obj == uchain) res = FALSE; else switch(otmp->otyp) { case WAN_POLYMORPH: /* preserve symbol and quantity, but turn rocks into gems */ mkobj_at((obj->otyp == ROCK || obj->otyp == ENORMOUS_ROCK) ? GEM_SYM : obj->olet, obj->ox, obj->oy) -> quan = obj->quan; delobj(obj); break; case WAN_STRIKING: if(obj->otyp == ENORMOUS_ROCK) fracture_rock(obj); else res = FALSE; break; case WAN_CANCELLATION: if(obj->spe && obj->olet != AMULET_SYM) { obj->spe = 0; } break; case WAN_TELEPORTATION: rloco(obj); break; case WAN_MAKE_INVISIBLE: obj->oinvis = 1; break; case WAN_UNDEAD_TURNING: res = revive(obj); break; case WAN_SLOW_MONSTER: /* no effect on objects */ case WAN_SPEED_MONSTER: #ifdef WAN_PROBING case WAN_PROBING: #endif /* WAN_PROBING */ res = FALSE; break; default: impossible("What an interesting wand (%u)", otmp->otyp); } return(res); }
/* drop (perhaps) a cadaver and remove monster */ void mondied(struct monst *mdef) { const struct permonst *pd = mdef->data; if (letter(pd->mlet) && rn2(3)) { (void) mkobj_at(pd->mlet, mdef->mx, mdef->my); if (cansee(mdef->mx, mdef->my)) { unpmon(mdef); atl(mdef->mx, mdef->my, fobj->olet); } stackobj(fobj); } mondead(mdef); }
static void makeniche(bool with_trap) { struct mkroom *aroom; struct rm *rm; int vct = 8; coord dd; int dy,xx,yy; struct trap *ttmp; if(doorindex < DOORMAX) while(vct--) { aroom = &rooms[rn2(nroom-1)]; if(aroom->rtype != 0) continue; /* not an ordinary room */ if(aroom->doorct == 1 && rn2(5)) continue; if(rn2(2)) { dy = 1; dd = finddpos(aroom->lx,aroom->hy+1,aroom->hx,aroom->hy+1); } else { dy = -1; dd = finddpos(aroom->lx,aroom->ly-1,aroom->hx,aroom->ly-1); } xx = dd.x; yy = dd.y; if((rm = &levl[xx][yy+dy])->typ) continue; if(with_trap || !rn2(4)) { rm->typ = SCORR; rm->scrsym = ' '; if(with_trap) { ttmp = maketrap(xx, yy+dy, TELEP_TRAP); ttmp->once = 1; make_engr_at(xx, yy-dy, "ad ae?ar um"); } dosdoor(xx, yy, aroom, SDOOR); } else { rm->typ = CORR; rm->scrsym = CORR_SYM; if(rn2(7)) dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR); else { mksobj_at(SCR_TELEPORTATION, xx, yy+dy); if(!rn2(3)) mkobj_at(0, xx, yy+dy); } } return; } }
/* 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); } }
/* 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); }
void fill_zoo (struct mkroom *sroom) { struct monst *mon; int sx,sy,i; int sh, tx, ty, goldlim, type = sroom->rtype; int rmno = (sroom - rooms) + ROOMOFFSET; coord mm; sh = sroom->fdoor; switch(type) { case COURT: if(level.flags.is_maze_lev) { for(tx = sroom->lx; tx <= sroom->hx; tx++) for(ty = sroom->ly; ty <= sroom->hy; ty++) if(IS_THRONE(levl[tx][ty].typ)) goto throne_placed; } i = 100; do { /* don't place throne on top of stairs */ (void) somexy(sroom, &mm); tx = mm.x; ty = mm.y; } while (occupied((signed char)tx, (signed char)ty) && --i > 0); throne_placed: /* TODO: try to ensure the enthroned monster is an M2_PRINCE */ break; case BEEHIVE: tx = sroom->lx + (sroom->hx - sroom->lx + 1)/2; ty = sroom->ly + (sroom->hy - sroom->ly + 1)/2; if(sroom->irregular) { /* center might not be valid, so put queen elsewhere */ if ((int) levl[tx][ty].roomno != rmno || levl[tx][ty].edge) { (void) somexy(sroom, &mm); tx = mm.x; ty = mm.y; } } break; case ZOO: case LEPREHALL: goldlim = 500 * level_difficulty(); break; } for(sx = sroom->lx; sx <= sroom->hx; sx++) for(sy = sroom->ly; sy <= sroom->hy; sy++) { if(sroom->irregular) { if ((int) levl[sx][sy].roomno != rmno || levl[sx][sy].edge || (sroom->doorct && distmin(sx, sy, doors[sh].x, doors[sh].y) <= 1)) continue; } else if(!SPACE_POS(levl[sx][sy].typ) || (sroom->doorct && ((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; /* don't place monster on explicitly placed throne */ if(type == COURT && IS_THRONE(levl[sx][sy].typ)) continue; mon = makemon( (type == COURT) ? courtmon() : (type == BARRACKS) ? squadmon() : (type == MORGUE) ? morguemon() : (type == BEEHIVE) ? (sx == tx && sy == ty ? &mons[PM_QUEEN_BEE] : &mons[PM_KILLER_BEE]) : (type == LEPREHALL) ? &mons[PM_LEPRECHAUN] : (type == COCKNEST) ? &mons[PM_COCKATRICE] : (type == ANTHOLE) ? antholemon() : (struct permonst *) 0, sx, sy, NO_MM_FLAGS); if(mon) { mon->msleeping = 1; if (type==COURT && mon->mpeaceful) { mon->mpeaceful = 0; set_malign(mon); } } switch(type) { case ZOO: case LEPREHALL: if(sroom->doorct) { int distval = dist2(sx,sy,doors[sh].x,doors[sh].y); i = sq(distval); } else i = goldlim; if(i >= goldlim) i = 5*level_difficulty(); goldlim -= i; (void) mkgold((long) rn1(i, 10), sx, sy); break; case MORGUE: if(!rn2(5)) (void) mk_tt_object(CORPSE, sx, sy); if(!rn2(10)) /* lots of treasure buried with dead */ (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy, true, false); if (!rn2(5)) make_grave(sx, sy, (char *)0); break; case BEEHIVE: if(!rn2(3)) (void) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy, true, false); break; case BARRACKS: if(!rn2(20)) /* the payroll and some loot */ (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy, true, false); break; case COCKNEST: if(!rn2(3)) { struct obj *sobj = mk_tt_object(STATUE, sx, sy); if (sobj) { for (i = rn2(5); i; i--) (void) add_to_container(sobj, mkobj(RANDOM_CLASS, false)); sobj->owt = weight(sobj); } } break; case ANTHOLE: if(!rn2(3)) (void) mkobj_at(FOOD_CLASS, sx, sy, false); break; } } switch (type) { case COURT: { struct obj *chest; levl[tx][ty].typ = THRONE; (void) somexy(sroom, &mm); (void) mkgold((long) rn1(50 * level_difficulty(),10), mm.x, mm.y); /* the royal coffers */ chest = mksobj_at(CHEST, mm.x, mm.y, true, false); chest->spe = 2; /* so it can be found later */ level.flags.has_court = 1; break; } case BARRACKS: level.flags.has_barracks = 1; break; case ZOO: level.flags.has_zoo = 1; break; case MORGUE: level.flags.has_morgue = 1; break; case SWAMP: level.flags.has_swamp = 1; break; case BEEHIVE: level.flags.has_beehive = 1; break; } }
static void join(int a, int b) { coord cc,tt; int tx, ty, xx, yy; struct rm *crm; struct mkroom *croom, *troom; int dx, dy, dix, diy, cct; croom = &rooms[a]; troom = &rooms[b]; /* find positions cc and tt for doors in croom and troom and direction for a corridor between them */ if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return; if(troom->lx > croom->hx) { dx = 1; dy = 0; xx = croom->hx+1; tx = troom->lx-1; cc = finddpos(xx,croom->ly,xx,croom->hy); tt = finddpos(tx,troom->ly,tx,troom->hy); } else if(troom->hy < croom->ly) { dy = -1; dx = 0; yy = croom->ly-1; cc = finddpos(croom->lx,yy,croom->hx,yy); ty = troom->hy+1; tt = finddpos(troom->lx,ty,troom->hx,ty); } else if(troom->hx < croom->lx) { dx = -1; dy = 0; xx = croom->lx-1; tx = troom->hx+1; cc = finddpos(xx,croom->ly,xx,croom->hy); tt = finddpos(tx,troom->ly,tx,troom->hy); } else { dy = 1; dx = 0; yy = croom->hy+1; ty = troom->ly-1; cc = finddpos(croom->lx,yy,croom->hx,yy); tt = finddpos(troom->lx,ty,troom->hx,ty); } xx = cc.x; yy = cc.y; tx = tt.x - dx; ty = tt.y - dy; if(nxcor && levl[xx+dx][yy+dy].typ) return; dodoor(xx,yy,croom); cct = 0; while(xx != tx || yy != ty) { xx += dx; yy += dy; /* loop: dig corridor at [xx,yy] and find new [xx,yy] */ if(cct++ > 500 || (nxcor && !rn2(35))) return; if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1) return; /* impossible */ crm = &levl[xx][yy]; if(!(crm->typ)) { if(rn2(100)) { crm->typ = CORR; crm->scrsym = CORR_SYM; if(nxcor && !rn2(50)) mkobj_at(ROCK_SYM, xx, yy); } else { crm->typ = SCORR; crm->scrsym = ' '; } } else if(crm->typ != CORR && crm->typ != SCORR) { /* strange ... */ return; } /* find next corridor position */ dix = abs(xx-tx); diy = abs(yy-ty); /* do we have to change direction ? */ if(dy && dix > diy) { int ddx = (xx > tx) ? -1 : 1; crm = &levl[xx+ddx][yy]; if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) { dx = ddx; dy = 0; continue; } } else if(dx && diy > dix) { int ddy = (yy > ty) ? -1 : 1; crm = &levl[xx][yy+ddy]; if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) { dy = ddy; dx = 0; continue; } } /* continue straight on? */ crm = &levl[xx+dx][yy+dy]; if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) continue; /* no, what must we do now?? */ if(dx) { dx = 0; dy = (ty < yy) ? -1 : 1; crm = &levl[xx+dx][yy+dy]; if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) continue; dy = -dy; continue; } else { dy = 0; dx = (tx < xx) ? -1 : 1; crm = &levl[xx+dx][yy+dy]; if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) continue; dx = -dx; continue; } } /* we succeeded in digging the corridor */ dodoor(tt.x, tt.y, troom); if(smeq[a] < smeq[b]) smeq[b] = smeq[a]; else smeq[a] = smeq[b]; }
void makelevel(void) { struct mkroom *croom, *troom; unsigned tryct; int x,y; nroom = 0; doorindex = 0; rooms[0].hx = -1; /* in case we are in a maze */ for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) levl[x][y] = zerorm; oinit(); /* assign level dependent obj probabilities */ if(dlevel >= rn1(3, 26)) { /* there might be several mazes */ makemaz(); return; } /* construct the rooms */ nroom = 0; secret = FALSE; makerooms(); /* construct stairs (up and down in different rooms if possible) */ croom = &rooms[rn2(nroom)]; xdnstair = somex(); ydnstair = somey(); levl[xdnstair][ydnstair].scrsym ='>'; levl[xdnstair][ydnstair].typ = STAIRS; if(nroom > 1) { troom = croom; croom = &rooms[rn2(nroom-1)]; if(croom >= troom) croom++; } xupstair = somex(); /* %% < and > might be in the same place */ yupstair = somey(); levl[xupstair][yupstair].scrsym ='<'; levl[xupstair][yupstair].typ = STAIRS; /* for each room: put things inside */ for(croom = rooms; croom->hx > 0; croom++) { /* put a sleeping monster inside */ /* Note: monster may be on the stairs. This cannot be avoided: maybe the player fell through a trapdoor while a monster was on the stairs. Conclusion: we have to check for monsters on the stairs anyway. */ if(!rn2(3)) makemon(NULL, somex(), somey()); /* put traps and mimics inside */ goldseen = FALSE; while(!rn2(8-(dlevel/6))) mktrap(0,0,croom); if(!goldseen && !rn2(3)) mkgold(0L,somex(),somey()); if(!rn2(3)) { mkobj_at(0, somex(), somey()); tryct = 0; while(!rn2(5)) { if(++tryct > 100){ printf("tryct overflow4\n"); break; } mkobj_at(0, somex(), somey()); } } } qsort((char *) rooms, nroom, sizeof(struct mkroom), comp); makecorridors(); make_niches(); /* make a secret treasure vault, not connected to the rest */ if(nroom <= (2*MAXNROFROOMS/3)) if(rn2(3)) { troom = &rooms[nroom]; secret = TRUE; if(makerooms()) { troom->rtype = VAULT; /* treasure vault */ for(x = troom->lx; x <= troom->hx; x++) for(y = troom->ly; y <= troom->hy; y++) mkgold((long)(rnd(dlevel*100) + 50), x, y); if(!rn2(3)) makevtele(); } } #ifndef QUEST #ifdef WIZARD if(wizard && getenv("SHOPTYPE")) mkshop(); else #endif /* WIZARD */ if(dlevel > 1 && dlevel < 20 && rn2(dlevel) < 3) mkshop(); else if(dlevel > 6 && !rn2(7)) mkzoo(ZOO); else if(dlevel > 9 && !rn2(5)) mkzoo(BEEHIVE); else if(dlevel > 11 && !rn2(6)) mkzoo(MORGUE); else if(dlevel > 18 && !rn2(6)) mkswamp(); #endif /* QUEST */ }
int doread() { struct obj *scroll; boolean confused = (Confusion != 0); boolean known = FALSE; scroll = getobj("?", "read"); if(!scroll) return(0); if(!scroll->dknown && Blind) { pline("Being blind, you cannot read the formula on the scroll."); return(0); } if(Blind) pline("As you pronounce the formula on it, the scroll disappears."); else pline("As you read the scroll, it disappears."); if(confused) pline("Being confused, you mispronounce the magic words ... "); switch(scroll->otyp) { #ifdef MAIL case SCR_MAIL: readmail(/* scroll */); break; #endif /* MAIL */ case SCR_ENCHANT_ARMOR: { struct obj *otmp = some_armor(); if(!otmp) { strange_feeling(scroll,"Your skin glows then fades."); return(1); } if(confused) { pline("Your %s glows silver for a moment.", objects[otmp->otyp].oc_name); otmp->rustfree = 1; break; } if(otmp->spe > 3 && rn2(otmp->spe)) { pline("Your %s glows violently green for a while, then evaporates.", objects[otmp->otyp].oc_name); useup(otmp); break; } pline("Your %s glows green for a moment.", objects[otmp->otyp].oc_name); otmp->cursed = 0; otmp->spe++; break; } case SCR_DESTROY_ARMOR: if(confused) { struct obj *otmp = some_armor(); if(!otmp) { strange_feeling(scroll,"Your bones itch."); return(1); } pline("Your %s glows purple for a moment.", objects[otmp->otyp].oc_name); otmp->rustfree = 0; break; } if(uarm) { pline("Your armor turns to dust and falls to the floor!"); useup(uarm); } else if(uarmh) { pline("Your helmet turns to dust and is blown away!"); useup(uarmh); } else if(uarmg) { pline("Your gloves vanish!"); useup(uarmg); selftouch("You"); } else { strange_feeling(scroll,"Your skin itches."); return(1); } break; case SCR_CONFUSE_MONSTER: if(confused) { pline("Your hands begin to glow purple."); Confusion += rnd(100); } else { pline("Your hands begin to glow blue."); u.umconf = 1; } break; case SCR_SCARE_MONSTER: { int ct = 0; struct monst *mtmp; for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(cansee(mtmp->mx,mtmp->my)) { if(confused) mtmp->mflee = mtmp->mfroz = mtmp->msleep = 0; else mtmp->mflee = 1; ct++; } if(!ct) { if(confused) pline("You hear sad wailing in the distance."); else pline("You hear maniacal laughter in the distance."); } break; } case SCR_BLANK_PAPER: if(confused) pline("You see strange patterns on this scroll."); else pline("This scroll seems to be blank."); break; case SCR_REMOVE_CURSE: { struct obj *obj; if(confused) pline("You feel like you need some help."); else pline("You feel like someone is helping you."); for(obj = invent; obj ; obj = obj->nobj) if(obj->owornmask) obj->cursed = confused; if(Punished && !confused) { Punished = 0; freeobj(uchain); unpobj(uchain); free(uchain); uball->spe = 0; uball->owornmask &= ~W_BALL; uchain = uball = (struct obj *) 0; } break; } case SCR_CREATE_MONSTER: { int cnt = 1; if(!rn2(73)) cnt += rnd(4); if(confused) cnt += 12; while(cnt--) (void) makemon(confused ? PM_ACID_BLOB : (struct permonst *) 0, u.ux, u.uy); break; } case SCR_ENCHANT_WEAPON: if(uwep && confused) { pline("Your %s glows silver for a moment.", objects[uwep->otyp].oc_name); uwep->rustfree = 1; } else if(!chwepon(scroll, 1)) /* tests for !uwep */ return(1); break; case SCR_DAMAGE_WEAPON: if(uwep && confused) { pline("Your %s glows purple for a moment.", objects[uwep->otyp].oc_name); uwep->rustfree = 0; } else if(!chwepon(scroll, -1)) /* tests for !uwep */ return(1); break; case SCR_TAMING: { int i,j; int bd = confused ? 5 : 1; struct monst *mtmp; for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++) if ((mtmp = m_at(u.ux+i, u.uy+j))) (void) tamedog(mtmp, NULL); break; } case SCR_GENOCIDE: { extern char genocided[], fut_geno[]; char buf[BUFSZ]; struct monst *mtmp, *mtmp2; pline("You have found a scroll of genocide!"); known = TRUE; if(confused) *buf = u.usym; else do { pline("What monster do you want to genocide (Type the letter)? "); getlin(buf); } while(strlen(buf) != 1 || !monstersym(*buf)); if(!strchr(fut_geno, *buf)) charcat(fut_geno, *buf); if(!strchr(genocided, *buf)) charcat(genocided, *buf); else { pline("Such monsters do not exist in this world."); break; } for(mtmp = fmon; mtmp; mtmp = mtmp2){ mtmp2 = mtmp->nmon; if(mtmp->data->mlet == *buf) mondead(mtmp); } pline("Wiped out all %c's.", *buf); if(*buf == u.usym) { killer = "scroll of genocide"; u.uhp = -1; } break; } case SCR_LIGHT: if(!Blind) known = TRUE; litroom(!confused); break; case SCR_TELEPORTATION: if(confused) level_tele(); else { #ifdef QUEST int oux = u.ux, ouy = u.uy; tele(); if(dist(oux, ouy) > 100) known = TRUE; #else /* QUEST */ int uroom = inroom(u.ux, u.uy); tele(); if(uroom != inroom(u.ux, u.uy)) known = TRUE; #endif /* QUEST */ } break; case SCR_GOLD_DETECTION: /* Unfortunately this code has become slightly less elegant, now that gold and traps no longer are of the same type. */ if(confused) { struct trap *ttmp; if(!ftrap) { strange_feeling(scroll, "Your toes stop itching."); return(1); } else { for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) if(ttmp->tx != u.ux || ttmp->ty != u.uy) goto outtrapmap; /* only under me - no separate display required */ pline("Your toes itch!"); break; outtrapmap: cls(); for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) at(ttmp->tx, ttmp->ty, '$'); prme(); pline("You feel very greedy!"); } } else { struct gold *gtmp; if(!fgold) { strange_feeling(scroll, "You feel materially poor."); return(1); } else { known = TRUE; for(gtmp = fgold; gtmp; gtmp = gtmp->ngold) if(gtmp->gx != u.ux || gtmp->gy != u.uy) goto outgoldmap; /* only under me - no separate display required */ pline("You notice some gold between your feet."); break; outgoldmap: cls(); for(gtmp = fgold; gtmp; gtmp = gtmp->ngold) at(gtmp->gx, gtmp->gy, '$'); prme(); pline("You feel very greedy, and sense gold!"); } } /* common sequel */ more(); docrt(); break; case SCR_FOOD_DETECTION: { int ct = 0, ctu = 0; struct obj *obj; char foodsym = confused ? POTION_SYM : FOOD_SYM; for(obj = fobj; obj; obj = obj->nobj) if(obj->olet == FOOD_SYM) { if(obj->ox == u.ux && obj->oy == u.uy) ctu++; else ct++; } if(!ct && !ctu) { strange_feeling(scroll,"Your nose twitches."); return(1); } else if(!ct) { known = TRUE; pline("You smell %s close nearby.", confused ? "something" : "food"); } else { known = TRUE; cls(); for(obj = fobj; obj; obj = obj->nobj) if(obj->olet == foodsym) at(obj->ox, obj->oy, FOOD_SYM); prme(); pline("Your nose tingles and you smell %s!", confused ? "something" : "food"); more(); docrt(); } break; } case SCR_IDENTIFY: /* known = TRUE; */ if(confused) pline("You identify this as an identify scroll."); else pline("This is an identify scroll."); useup(scroll); objects[SCR_IDENTIFY].oc_name_known = 1; if(!confused) while( !ggetobj("identify", identify, rn2(5) ? 1 : rn2(5)) && invent ); return(1); case SCR_MAGIC_MAPPING: { struct rm *lev; int num, zx, zy; known = TRUE; pline("On this scroll %s a map!", confused ? "was" : "is"); for(zy = 0; zy < ROWNO; zy++) for(zx = 0; zx < COLNO; zx++) { if(confused && rn2(7)) continue; lev = &(levl[zx][zy]); if((num = lev->typ) == 0) continue; if(num == SCORR) { lev->typ = CORR; lev->scrsym = CORR_SYM; } else if(num == SDOOR) { lev->typ = DOOR; lev->scrsym = '+'; /* do sth in doors ? */ } else if(lev->seen) continue; #ifndef QUEST if(num != ROOM) #endif /* QUEST */ { lev->seen = lev->new = 1; if(lev->scrsym == ' ' || !lev->scrsym) newsym(zx,zy); else on_scr(zx,zy); } } break; } case SCR_AMNESIA: { int zx, zy; known = TRUE; for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++) if(!confused || rn2(7)) if(!cansee(zx,zy)) levl[zx][zy].seen = 0; docrt(); pline("Thinking of Maud you forget everything else."); break; } case SCR_FIRE: { int num; struct monst *mtmp; known = TRUE; if(confused) { pline("The scroll catches fire and you burn your hands."); losehp(1, "scroll of fire"); } else { pline("The scroll erupts in a tower of flame!"); if(Fire_resistance) pline("You are uninjured."); else { num = rnd(6); u.uhpmax -= num; losehp(num, "scroll of fire"); } } num = (2*num + 1)/3; for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { if(dist(mtmp->mx,mtmp->my) < 3) { mtmp->mhp -= num; if(strchr("FY", mtmp->data->mlet)) mtmp->mhp -= 3*num; /* this might well kill 'F's */ if(mtmp->mhp < 1) { killed(mtmp); break; /* primitive */ } } } break; } case SCR_PUNISHMENT: known = TRUE; if(confused) { pline("You feel guilty."); break; } pline("You are being punished for your misbehaviour!"); if(Punished){ pline("Your iron ball gets heavier."); uball->owt += 15; break; } Punished = INTRINSIC; setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN); setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL); uball->spe = 1; /* special ball (see save) */ break; default: impossible("What weird language is this written in? (%u)", scroll->otyp); }
mkshop(){ register struct mkroom *sroom; register int sh,sx,sy,i = -1; register char let; int roomno; register struct monst *shk; #ifdef WIZARD /* first determine shoptype */ if(wizard){ extern char *getenv(); register char *ep = getenv("SHOPTYPE"); if(ep){ if(*ep == 'z' || *ep == 'Z'){ mkzoo(ZOO); return; } if(*ep == 'm' || *ep == 'M'){ mkzoo(MORGUE); return; } if(*ep == 'b' || *ep == 'B'){ mkzoo(BEEHIVE); return; } if(*ep == 's' || *ep == 'S'){ mkswamp(); return; } for(i=0; shtypes[i]; i++) if(*ep == shtypes[i]) break; goto gottype; } } gottype: #endif WIZARD for(sroom = &rooms[0], roomno = 0; ; sroom++, roomno++){ if(sroom->hx < 0) return; if(sroom - rooms >= nroom) { pline("rooms not closed by -1?"); return; } if(sroom->rtype) continue; if(!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom)) continue; if( #ifdef WIZARD (wizard && getenv("SHOPTYPE") && sroom->doorct != 0) || #endif WIZARD sroom->doorct == 1) break; } if(i < 0) { /* shoptype not yet determined */ register int j; for(j = rn2(100), i = 0; (j -= shprobs[i])>= 0; i++) if(!shtypes[i]) break; /* superfluous */ if(isbig(sroom) && i + SHOPBASE == WANDSHOP) i = GENERAL-SHOPBASE; } sroom->rtype = i + SHOPBASE; let = shtypes[i]; sh = sroom->fdoor; sx = doors[sh].x; sy = doors[sh].y; 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 { #ifdef WIZARD /* This is said to happen sometimes, but I've never seen it. */ if(wizard) { register int j = sroom->doorct; extern int doorindex; pline("Where is shopdoor?"); pline("Room at (%d,%d),(%d,%d).", sroom->lx, sroom->ly, sroom->hx, sroom->hy); pline("doormax=%d doorct=%d fdoor=%d", doorindex, sroom->doorct, sh); while(j--) { pline("door [%d,%d]", doors[sh].x, doors[sh].y); sh++; } more(); } #endif WIZARD return; } if(!(shk = makemon(PM_SHK,sx,sy))) return; shk->isshk = shk->mpeaceful = 1; shk->msleep = 0; shk->mtrapseen = ~0; /* we know all the traps already */ ESHK->shoproom = roomno; ESHK->shoplevel = dlevel; ESHK->shd = doors[sh]; ESHK->shk.x = sx; ESHK->shk.y = sy; ESHK->robbed = 0; ESHK->visitct = 0; ESHK->following = 0; shk->mgold = 1000 + 30*rnd(100); /* initial capital */ ESHK->billct = 0; findname(ESHK->shknam, let); for(sx = sroom->lx; sx <= sroom->hx; sx++) for(sy = sroom->ly; sy <= sroom->hy; sy++){ register struct monst *mtmp; 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; if(rn2(100) < dlevel && !m_at(sx,sy) && (mtmp = makemon(PM_MIMIC, sx, sy))){ mtmp->mimic = 1; mtmp->mappearance = (let && rn2(10) < dlevel) ? let : ']'; continue; } (void) mkobj_at(let, sx, sy); } }
void killed(struct monst *mtmp) { #define NEW_SCORING int tmp; int tmp2; int nk; int x; int y; struct permonst *mdat = mtmp->data; if(mtmp->cham != 0) { mdat = PM_CHAM; } if(Blind != 0) { pline("You destroy it!"); } else { if(mtmp->mtame != 0) { pline("You destroy %s!", amonnam(mtmp, "poor")); } else { pline("You destroy %s!", monnam(mtmp)); } } if(u.umconf != 0) { if(Blind == 0) { pline("Your hands stop clowing blue."); u.umconf = 0; } } /* Count killed monsters */ #define MAXMONNO 100 /* In case we cannot find it in mons */ nk = 1; /* Index in mons array (if not 'd', '@', ...) */ tmp = mdat - mons; if((tmp >= 0) && (tmp < (CMNUM + 2))) { extern char fut_geno[]; ++u.nr_killed[tmp]; nk = u.nr_killed[tmp]; if((nk > MAXMONNO) && (index(fut_geno, mdat->mlet) == 0)) { charcat(fut_geno, mdat->mlet); } } /* Punish bad behaviour */ if(mdat->mlet == '@') { Telepat = 0; u.uluck -= 2; } if((mtmp->mpeaceful != 0) || (mtmp->mtame != 0)) { --u.uluck; } if(mdat->mlet == 'u') { u.uluck -= 5; } /* Give experience points */ tmp = 1 + (mdat->mlevel * mdat->mlevel); if(mdat->ac < 3) { tmp += (2 * (7 - mdat->ac)); } if(index("AcsSDXaeRTVWU&In:P", mdat->mlet) != 0) { tmp += (2 * mdat->mlevel); } if(index("DeV&P", mdat->mlet) != 0) { tmp += (7 * mdat->mlevel); } if(mdat->mlevel > 6) { tmp += 50; } #ifdef NEW_SCORING /* * ------- Recent addition: make number of points decrease * when this is not the first of this kind */ int ul = u.ulevel; int ml = mdat->mlevel; /* Points are given based on present and future level */ if(ul < 14) { for(tmp2 = 0; (tmp2 == 0) || ((ul + tmp2) <= ml); ++tmp2) { if(tmp <= 0) { if(((u.uexp + 1) + ((tmp + (0)) / nk)) >= (10 * pow(2, (unsigned)(ul - 1)))) { ++ul; if(ul == 14) { break; } } } else { if(((u.uexp + 1) + ((tmp + (4 << (tmp2 - 1))) / nk)) >= (10 * pow(2, (unsigned)(ul - 1)))) { ++ul; if(ul == 14) { break; } } } } } tmp2 = (ml - ul) - 1; if(tmp2 < 0) { tmp = (tmp + (0)) / nk; } else { tmp = (tmp + (4 << tmp2)) / nk; } if(tmp == 0) { tmp = 1; } /* * Note: ul is not necessarily the future value of u.ulevel * ------- End of recent valuation change ------- */ #endif u.uexp += tmp; u.urexp += (4 * tmp); flags.botl = 1; while((u.ulevel < 14) && (u.uexp >= (10 * pow(2, u.ulevel - 1)))) { ++u.ulevel; pline("Welcome to level %d.", u.ulevel); tmp = rnd(30); if(tmp < 3) { tmp = rnd(10); } u.uhpmax += tmp; u.uhp += tmp; flags.botl = 1; } /* Dispose of monster and make cadaver */ x = mtmp->mx; y = mtmp->my; mondead(mtmp); tmp = mdat->mlet; if(tmp == 'm') { /* He killed a minotaur, give him a wand of digging */ /* Note: The dead minotaur will be on top of it! */ mksobj_at(WAND_SYM, WAN_DIGGING, x, y); /* * if(cansee(x, y) != 0) { * atl(x, y, fobj->olet); * } */ stackobj(fobj); } #ifndef NOWORM else if(tmp == 'w') { mksobj_at(WEAPON_SYM, WORM_TOOTH, x, y); stackobj(fobj); } #endif else { if((letter(tmp) == 0) || (rn2(3) == 0)) { tmp = 0; } if(levl[x][y].typ >= DOOR) { /* Might be a mimic in wall */ if((x != u.ux) || (y != u.uy)) { /* Might be here after swallowed */ if((index("NTVm&", mdat->mlet) != NULL) || (rn2(5) != 0)) { mkobj_at(tmp, x, y); if(cansee(x, y) != 0) { atl(x, y, fobj->olet); } stackobj(fobj); } } } } }
void makemaz() { int x,y; int zx,zy; coord mm; boolean al = (dlevel >= 30 && !flags.made_amulet); for(x = 2; x < COLNO-1; x++) for(y = 2; y < ROWNO-1; y++) levl[x][y].typ = (x%2 && y%2) ? 0 : HWALL; if(al) { struct monst *mtmp; zx = 2*(COLNO/4) - 1; zy = 2*(ROWNO/4) - 1; for(x = zx-2; x < zx+4; x++) for(y = zy-2; y <= zy+2; y++) { levl[x][y].typ = (y == zy-2 || y == zy+2 || x == zx-2 || x == zx+3) ? POOL : (y == zy-1 || y == zy+1 || x == zx-1 || x == zx+2) ? HWALL: ROOM; } (void) mkobj_at(AMULET_SYM, zx, zy); flags.made_amulet = 1; walkfrom(zx+4, zy); if ((mtmp = makemon(&hell_hound, zx, zy))) mtmp->msleep = 1; if ((mtmp = makemon(PM_WIZARD, zx+1, zy))) { mtmp->msleep = 1; flags.no_of_wizards = 1; } } else { mm = mazexy(); zx = mm.x; zy = mm.y; walkfrom(zx,zy); (void) mksobj_at(WAN_WISHING, zx, zy); (void) mkobj_at(ROCK_SYM, zx, zy); /* put a rock on top of it */ } for(x = 2; x < COLNO-1; x++) for(y = 2; y < ROWNO-1; y++) { switch(levl[x][y].typ) { case HWALL: levl[x][y].scrsym = '-'; break; case ROOM: levl[x][y].scrsym = '.'; break; } } for(x = rn1(8,11); x; x--) { mm = mazexy(); (void) mkobj_at(rn2(2) ? GEM_SYM : 0, mm.x, mm.y); } for(x = rn1(10,2); x; x--) { mm = mazexy(); (void) mkobj_at(ROCK_SYM, mm.x, mm.y); } mm = mazexy(); (void) makemon(PM_MINOTAUR, mm.x, mm.y); for(x = rn1(5,7); x; x--) { mm = mazexy(); (void) makemon((struct permonst *) 0, mm.x, mm.y); } for(x = rn1(6,7); x; x--) { mm = mazexy(); mkgold(0L,mm.x,mm.y); } for(x = rn1(6,7); x; x--) mktrap(0,1,(struct mkroom *) 0); mm = mazexy(); levl[(int)(xupstair = mm.x)][(int)(yupstair = mm.y)].scrsym = '<'; levl[(int)xupstair][(int)yupstair].typ = STAIRS; xdnstair = ydnstair = 0; }
// // 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 (const struct permonst* ptr, int x, int y) { if (x != 0 || y != 0) if (m_at(x, y)) return NULL; bool anything = false; if (!ptr) { anything = true; unsigned mi = rn2 (CMNUM*_u.dlevel/24+7); if (mi+4 < _u.dlevel) mi = rn2 (CMNUM*_u.dlevel/24+12); if (mi >= CMNUM) mi = rn1 (CMNUM-CMNUM/2, CMNUM/2); while (mi < CMNUM && is_monster_genocided (c_Monsters[mi].mlet)) ++mi; if (mi >= CMNUM) return NULL; // all monsters genocided ptr = &c_Monsters[mi]; } else if (is_monster_genocided (ptr->mlet)) return NULL; struct monst* mtmp = newmonst(ptr->pxlth); mtmp->nmon = _level->monsters; _level->monsters = mtmp; mtmp->m_id = _wflags.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 (!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) mkobj_at(0, mtmp->mx, mtmp->my); } 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; if (anything) if (ptr->mlet == 'O' || ptr->mlet == 'k') { struct coord mm; int cnt = rnd(10); mm.x = x; mm.y = y; while (cnt--) { mm = enexto(mm.x, mm.y); makemon(ptr, mm.x, mm.y); } } return mtmp; }
void fill_zoo(struct level *lev, struct mkroom *sroom, enum rng rng) { struct monst *mon; int sx, sy, i; int sh, tx, ty, goldlim, type = sroom->rtype; int rmno = (sroom - lev->rooms) + ROOMOFFSET; coord mm; tx = ty = goldlim = 0; sh = sroom->fdoor; switch (type) { case COURT: if (lev->flags.is_maze_lev) { for (tx = sroom->lx; tx <= sroom->hx; tx++) for (ty = sroom->ly; ty <= sroom->hy; ty++) if (IS_THRONE(lev->locations[tx][ty].typ)) goto throne_placed; } i = 100; do { /* don't place throne on top of stairs */ somexy(lev, sroom, &mm, rng); tx = mm.x; ty = mm.y; } while (occupied(lev, tx, ty) && --i > 0); throne_placed: /* TODO: try to ensure the enthroned monster is an M2_PRINCE */ break; case BEEHIVE: tx = sroom->lx + (sroom->hx - sroom->lx + 1) / 2; ty = sroom->ly + (sroom->hy - sroom->ly + 1) / 2; if (sroom->irregular) { /* center might not be valid, so put queen elsewhere */ if ((int)lev->locations[tx][ty].roomno != rmno || lev->locations[tx][ty].edge) { somexy(lev, sroom, &mm, rng); tx = mm.x; ty = mm.y; } } break; case ZOO: case LEPREHALL: goldlim = 500 * level_difficulty(&lev->z); break; } for (sx = sroom->lx; sx <= sroom->hx; sx++) for (sy = sroom->ly; sy <= sroom->hy; sy++) { if (sroom->irregular) { if ((int)lev->locations[sx][sy].roomno != rmno || lev->locations[sx][sy].edge || (sroom->doorct && distmin(sx, sy, lev->doors[sh].x, lev->doors[sh].y) <= 1)) continue; } else if (!SPACE_POS(lev->locations[sx][sy].typ) || (sroom->doorct && ((sx == sroom->lx && lev->doors[sh].x == sx - 1) || (sx == sroom->hx && lev->doors[sh].x == sx + 1) || (sy == sroom->ly && lev->doors[sh].y == sy - 1) || (sy == sroom->hy && lev->doors[sh].y == sy + 1)))) continue; /* don't place monster on explicitly placed throne */ if (type == COURT && IS_THRONE(lev->locations[sx][sy].typ)) continue; mon = makemon((type == COURT) ? courtmon(&lev->z, rng) : (type == BARRACKS) ? squadmon(&lev->z) : (type == MORGUE) ? morguemon(&lev->z, rng) : (type == BEEHIVE) ? (sx == tx && sy == ty ? &mons[PM_QUEEN_BEE] : &mons[PM_KILLER_BEE]) : (type == LEPREHALL) ? &mons[PM_LEPRECHAUN] : (type == COCKNEST) ? &mons[PM_COCKATRICE] : (type == ANTHOLE) ? antholemon(&lev->z) : NULL, lev, sx, sy, rng == rng_main ? NO_MM_FLAGS : MM_ALLLEVRNG); if (mon) { mon->msleeping = 1; if (type == COURT && mon->mpeaceful) msethostility(mon, TRUE, TRUE); } switch (type) { case ZOO: case LEPREHALL: if (sroom->doorct) { int distval = dist2(sx, sy, lev->doors[sh].x, lev->doors[sh].y); i = sq(distval); } else i = goldlim; if (i >= goldlim) i = 5 * level_difficulty(&lev->z); goldlim -= i; mkgold(10 + rn2_on_rng(i, rng), lev, sx, sy, rng); break; case MORGUE: if (!rn2_on_rng(5, rng)) mk_tt_object(lev, CORPSE, sx, sy); if (!rn2_on_rng(10, rng)) /* lots of treasure */ mksobj_at(rn2_on_rng(3, rng) ? LARGE_BOX : CHEST, lev, sx, sy, TRUE, FALSE, rng); if (!rn2_on_rng(5, rng)) make_grave(lev, sx, sy, NULL); break; case BEEHIVE: if (!rn2_on_rng(3, rng)) mksobj_at(LUMP_OF_ROYAL_JELLY, lev, sx, sy, TRUE, FALSE, rng); break; case BARRACKS: if (!rn2_on_rng(20, rng)) /* the payroll and some loot */ mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, lev, sx, sy, TRUE, FALSE, rng); break; case COCKNEST: if (!rn2_on_rng(3, rng)) { struct obj *sobj = mk_tt_object(lev, STATUE, sx, sy); if (sobj) { for (i = rn2_on_rng(5, rng); i; i--) add_to_container(sobj, mkobj(lev, RANDOM_CLASS, FALSE, rng)); sobj->owt = weight(sobj); } } break; case ANTHOLE: if (!rn2_on_rng(3, rng)) mkobj_at(FOOD_CLASS, lev, sx, sy, FALSE, rng); break; } } if (type == COURT) { struct obj *chest; lev->locations[tx][ty].typ = THRONE; somexy(lev, sroom, &mm, rng); mkgold(10 + rn2_on_rng(50 * level_difficulty(&lev->z), rng), lev, mm.x, mm.y, rng); /* the royal coffers */ chest = mksobj_at(CHEST, lev, mm.x, mm.y, TRUE, FALSE, rng); chest->spe = 2; /* so it can be found later */ } }
void mkshop() { struct mkroom *sroom; int sh; int sx; int sy; int i; char let; int roomno; struct monst *shk; sroom = &rooms[0]; roomno = 0; while(1) { if(sroom->hx < 0) { return; } if((sroom->lx <= xdnstair) && (xdnstair <= sroom->hx) && (sroom->ly <= ydnstair) && (ydnstair <= sroom->hy)) { ++sroom; ++roomno; continue; } if((sroom->lx <= xupstair) && (xupstair <= sroom->hx) && (sroom->ly <= yupstair) && (yupstair <= sroom->hy)) { ++sroom; ++roomno; continue; } #ifdef WIZARD if(wizard || (sroom->doorct == 1)) { break; } #else if(sroom->doorct == 1) { break; } #endif } #ifdef WIZARD int flag = 0; if(wizard) { char *ep = getenv("SHOPTYPE"); if(ep != NULL) { if((*ep == 'z') || (*ep == 'Z')) { mkzoo(); return; } for(i = 0; shtypes[i]; ++i) { if(*ep == shtypes[i]) { break; } } let = i; flag = 1; } } if(flag == 0) { let = 0; i = rn2(100) - shprobs[(int)let]; while(i > 0) { if(shprobs[(int)let] == 0) { break; /* Superfluous */ } ++let; i -= shprobs[(int)let]; } } #else let = 0; i = rn2(100) - shprobs[(int)let]; while(i > 0) { if(shprobs[(int)let] == 0) { break; /* Superfluous */ } ++let; i -= shprobs[(int)let]; } #endif sroom->rtype = 8 + let; let = shtypes[(int)let]; sh = sroom->fdoor; sx = doors[sh].x; sy = doors[sh].y; 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 { printf("Where is shopdoor?"); return; } shk = makemon(PM_SHK, sx, sy); if(shk == NULL) { return; } shk->mpeaceful = 1; shk->isshk = shk->mpeaceful; shk->msleep = 0; shk->mtrapseen = ~0; /* We know all the traps already */ ESHK->shoproom = roomno; ESHK->shd = doors[sh]; ESHK->shk.x = sx; ESHK->shk.y = sy; ESHK->robbed = 0; ESHK->visitct = 0; shk->mgold = 1000 + (30 * rnd(100)); /* Initial capital */ ESHK->billct = 0; findname(ESHK->shknam, let); for(sx = sroom->lx; sx <= sroom->hx; ++sx) { for(sy = sroom->ly; sy <= sroom->hy; ++sy) { struct monst *mtmp; 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; } if((rn2(100) < dlevel) && !m_at(sx, sy)) { mtmp = makemon(PM_MIMIC, sx, sy); if(mtmp != NULL) { if(let && (rn2(10) < dlevel)) { mtmp->mimic = let; } else { mtmp->mimic = ']'; } continue; } } mkobj_at(let, sx, sy); } } #ifdef WIZARD if(wizard) { if(let) { printf("I made a %c-shop.", let); } else { printf("I made a g-shop."); } } #endif ++sroom; ++roomno; }