// 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, '^'); } } } }
void get_default_username(Char *buf, Short max_len) { Char *tmp, *first_wspace; VoidHand h; tmp = md_malloc(sizeof(Char) * (dlkMaxUserNameLength + 1)); DlkGetSyncInfo(NULL, NULL, NULL, tmp, NULL, NULL); /* if it's too long, use the first name only */ // if (StrLen(tmp) > max_len-1) { if (StrLen(tmp) > 8) { first_wspace = StrChr(tmp, spaceChr); if (first_wspace) *(first_wspace) = '\0'; else tmp[max_len-1] = '\0'; } if (StrLen(tmp)) StrNCopy(buf, tmp, max_len); else { Short t = rund(3); switch(t) { case 0: StrPrintF(buf, "Noman"); break; case 1: StrPrintF(buf, "Outis"); break; // "no man" in greek, says the web default: StrPrintF(buf, "Metis"); break; // "no one"/"cunning" pun in greek } } h = MemPtrRecoverHandle(tmp); if (h) MemHandleFree(h); }
void oelevator(int dir) { if (dir==1) { if (level == 0) { lprcat(",\nunfortunately, it is out of order."); return; } playerx = rnd(MAXX-2); playery = rnd(MAXY-2); nap(2000); newcavelevel(rund(level)); } else { if (level==DBOTTOM || level==VBOTTOM) { nap(2000); lprcat("\nand it leads straight to HELL!"); beep(); lflush(); nap(3000); died(287); } playerx = rnd(MAXX-2); playery = rnd(MAXY-2); nap(2000); newcavelevel(level + rnd(DBOTTOM - level)); } positionplayer(); draws(0,MAXX,0,MAXY); bot_linex(); }
static void vtele() { room_t *croom; extern room_t rooms[MAX_ROOMS]; // in make_level.c .... SIGH... for (croom = &rooms[0] ; croom->hx >= 0 ; croom++) if (croom->rtype == VAULT) { Short x,y; x = rund(2) ? croom->lx : croom->hx; y = rund(2) ? croom->ly : croom->hy; if (teleok(x,y)) { teleds(x,y); map_mode_teleport = TELE_MAP; return; } } tele(); }
void drown() // not tested AT ALL yet { tri_val_t result; message("You fall into a pool!"); message("You can't swim!"); if (rund(3) < you.uluck+2) { /* most scrolls become unreadable */ obj_t *obj; for (obj = invent ; obj ; obj = obj->nobj) if (obj->olet == SCROLL_SYM && rund(12) > you.uluck) obj->otype = SCR_BLANK_PAPER; /* we should perhaps merge these scrolls ? */ // if you say so. message("You attempt a teleport spell."); // utcsri!carroll map_mode_teleport = TELE_DROWN; result = dotele(); // XXX Does not work right if you have Teleport_control! if (result != GO_ON) if (get_cell_type(floor_info[(Short) you.ux][(Short) you.uy]) != POOL) return; // else keep going to drown_finish. // for the case of GO_ON, we will check cell type in tele_finish, // which will call drown_finish if necessary. } drown_finish(); }
// Caller must have already prompted user and got 'newlevel' if applicable. void level_tele(Short newlevel, Boolean controlled) { if (controlled) { // caller should already have used the engrave form to get a Number. } else { newlevel = 5 + rund(20); /* 5 - 24 */ if (dlevel == newlevel) { if (!xdnstair) newlevel--; else newlevel++; } } if (newlevel >= 30) { if (newlevel > MAXLEVEL) newlevel = MAXLEVEL; message("You arrive at the center of the earth ..."); message("Unfortunately it is here that hell is located."); if (Fire_resistance) { message("But the fire doesn't seem to harm you."); } else { message("You burn to a crisp."); dlevel = maxdlevel = newlevel; killer = "visit to the hell"; done("burned"); return; } } if (newlevel < 0) { newlevel = 0; message("You are now high above the clouds ..."); if (Levitation) { message("You float gently down to earth."); done("escaped"); return; } message("Unfortunately, you don't know how to fly."); message("You fall down a few thousand feet and break your neck."); dlevel = 0; killer = "fall"; done("died"); return; } goto_level(newlevel, false); /* calls done("escaped") if newlevel==0 */ }
/* function to read a book */ void readbook(int arg) { int i,tmp; if (arg<=3) i = rund(((tmp=splev[arg])!=0)?tmp:1); else { if (arg >= 21) arg = 20; /* # entries in splev = 21 */ i = rnd( ((tmp=splev[arg]-9)!=0) ?tmp:1 ) + 9; } spelknow[i]=1; lprintf("\nSpell \"%s\": %s\n%s.", spelcode[i],spelname[i],speldescript[i]); if (rnd(10)==4) { lprcat("\nYou feel clever!"); c[INTELLIGENCE]++; bottomline(); } }
void tele_finish(Short x, Short y, Boolean controlled) { Short nux,nuy; Boolean done = false; if (controlled) { if (teleok(x, y)) { teleds(x, y); done = true; //return; } message("Sorry ..."); } if (!done) { do { nux = rnd(DCOLS-1); nuy = rund(DROWS); } while (!teleok(nux, nuy)); teleds(nux, nuy); } // clean up after drowning victims if (map_mode_teleport == TELE_DROWN) { if (get_cell_type(floor_info[(Short) you.ux][(Short) you.uy]) == POOL) drown_finish(); // else, after surviving, do we tick or not? XXXX think about this. } // else, if scroll or command, tick; if random timer, don't tick. // wait hm. // random timer - never tick. // command - tick iff controlled // scroll - tick iff controlled // drown - ??? // trap - ??? else if (controlled && map_mode_teleport != TELE_RNDTIMER) { extern Boolean took_time; void end_turn_start_turn(); // in main.c took_time = true; end_turn_start_turn(); // XXXX } // finally, reset. map_mode_teleport = TELE_MAP; }
/* * shk_move: return 1: he moved 0: he didnt -1: let m_move do it * (what about "return 2" ??? */ Short shk_move(monst_t *shkp) { monst_t *mtmp; permonst_t *mdat = shkp->data; UChar gx,gy,omx,omy,nx,ny,nix,niy; Int8 appr,i; Short udist; Short z; Int8 shkroom,chi,chcnt,cnt; Boolean uondoor=false, satdoor, avoid=false, badinv; coord poss[9]; Short info[9]; obj_t *ib = NULL; omx = shkp->mx; omy = shkp->my; if ((udist = dist(omx,omy)) < 3) { if (ANGRY(shkp)) { hit_you(shkp, dice(mdat->damn, mdat->damd)+1); return 0; } if (ESHK(shkp)->following) { if (StrNCompare(ESHK(shkp)->customer, plname, PL_NSIZ)) { StrPrintF(ScratchBuffer, "Hello %s! I was looking for %s.", plname, ESHK(shkp)->customer); message(ScratchBuffer); ESHK(shkp)->following = false; return 0; } if (!ESHK(shkp)->robbed) { /* impossible? */ ESHK(shkp)->following = false; return 0; } if (moves > followmsg+4) { StrPrintF(ScratchBuffer, "Hello %s! Didn't you forget to pay?", plname); message(ScratchBuffer); followmsg = moves; } if (udist < 2) return 0; } } shkroom = inroom(omx,omy); appr = 1; gx = ESHK(shkp)->shk.x; gy = ESHK(shkp)->shk.y; satdoor = (gx == omx && gy == omy); if (ESHK(shkp)->following || ((z = holetime()) >= 0 && z*z <= udist)){ gx = you.ux; gy = you.uy; if (shkroom < 0 || shkroom != inroom(you.ux,you.uy)) if (udist > 4) return -1; /* leave it to m_move */ } else if (ANGRY(shkp)) { Long saveBlind = Blind; Blind = 0; if ((shkp->mcansee_and_blinded & M_CAN_SEE) && !Invis && cansee(omx,omy)) { gx = you.ux; gy = you.uy; } Blind = saveBlind; avoid = false; } else { #define GDIST(x,y) ((x-gx)*(x-gx)+(y-gy)*(y-gy)) if (Invis) avoid = false; else { uondoor = (you.ux == ESHK(shkp)->shd.x && you.uy == ESHK(shkp)->shd.y); if (uondoor) { if (ESHK(shkp)->billct) { StrPrintF(ScratchBuffer, "Hello %s! Will you please pay before leaving?", plname); message(ScratchBuffer); } badinv = (carrying(PICK_AXE) || carrying(ICE_BOX)); if (satdoor && badinv) return 0; avoid = !badinv; } else { avoid = (you.uinshop && dist(gx,gy) > 8); badinv = false; } if (((!ESHK(shkp)->robbed && !ESHK(shkp)->billct) || avoid) && GDIST(omx,omy) < 3) { if (!badinv && !online(omx,omy)) return 0; if (satdoor) appr = gx = gy = 0; } } } if (omx == gx && omy == gy) return 0; if (shkp->bitflags & M_IS_CONFUSED) { avoid = false; appr = 0; } nix = omx; niy = omy; cnt = mfindpos(shkp,poss,info,ALLOW_SSM); if (avoid && uondoor) { /* perhaps we cannot avoid him */ for (i=0; i<cnt; i++) if (!(info[i] & NOTONL)) goto notonl_ok; avoid = false; notonl_ok: ; } chi = -1; chcnt = 0; for (i = 0 ; i < cnt ; i++) { nx = poss[i].x; ny = poss[i].y; if (get_cell_type(floor_info[nx][ny]) == ROOM || shkroom != ESHK(shkp)->shoproom || ESHK(shkp)->following) { #ifdef STUPID /* cater for stupid compilers */ Short zz; #endif STUPID if (uondoor && (ib = sobj_at(ICE_BOX, nx, ny))) { nix = nx; niy = ny; chi = i; break; } if (avoid && (info[i] & NOTONL)) continue; if ((!appr && !rund(++chcnt)) || #ifdef STUPID (appr && (zz = GDIST(nix,niy)) && zz > GDIST(nx,ny)) #else (appr && GDIST(nx,ny) < GDIST(nix,niy)) #endif STUPID ) { nix = nx; niy = ny; chi = i; } } } if (nix != omx || niy != omy) { if (info[chi] & ALLOW_M){ mtmp = mon_at(nix,niy); if (hitmm(shkp,mtmp) == 1 && rund(3) && hitmm(mtmp,shkp) == 2) return 2; return 0; } else if (info[chi] & ALLOW_U){ hit_you(shkp, dice(mdat->damn, mdat->damd)+1); return 0; } shkp->mx = nix; shkp->my = niy; pmon(shkp); if (ib) { unlink_obj(ib);//freeobj mpickobj(shkp, ib); } return 1; } return 0; }
// What does the return value indicate?? Boolean dopay() { Long ltmp; bill_t *bp; monst_t *shkp; Short pass, tmp; multi = 0; inshop(); for (shkp = fmon ; shkp ; shkp = shkp->nmon) if ((shkp->bitflags & M_IS_SHOPKEEPER) && dist(shkp->mx,shkp->my) < 3) break; if (!shkp && you.uinshop && inroom(shopkeeper->mx,shopkeeper->my) == ESHK(shopkeeper)->shoproom) shkp = shopkeeper; if (!shkp) { message("There is nobody here to receive your payment."); return false; } ltmp = ESHK(shkp)->robbed; if (shkp != shopkeeper && NOTANGRY(shkp)) { if (!ltmp) { StrPrintF(ScratchBuffer, "You do not owe %s anything.", monnam(shkp)); message(ScratchBuffer); } else if (!you.ugold) { message("You have no money."); } else { Long ugold = you.ugold; if (you.ugold > ltmp) { StrPrintF(ScratchBuffer, "You give %s the %ld gold pieces he asked for.", monnam(shkp), ltmp); message(ScratchBuffer); pay(ltmp, shkp); } else { StrPrintF(ScratchBuffer, "You give %s all your gold.", monnam(shkp)); message(ScratchBuffer); pay(you.ugold, shkp); } if (ugold < ltmp/2) { message("Unfortunately, he doesn't look satisfied."); } else { ESHK(shkp)->robbed = 0; ESHK(shkp)->following = false; if (ESHK(shkp)->shoplevel != dlevel) { /* For convenience's sake, let him disappear */ shkp->minvent = NULL; /* %% */ // xxx leak? shkp->mgold = 0; mondead(shkp); } } } return true; } if (!ESHK(shkp)->billct) { StrPrintF(ScratchBuffer, "You do not owe %s anything.", monnam(shkp)); message(ScratchBuffer); if (!you.ugold) { message("Moreover, you have no money."); return true; } if (ESHK(shkp)->robbed) { message("But since his shop has been robbed recently,"); StrPrintF(ScratchBuffer, "you%srepay %s's expenses.", (you.ugold < ESHK(shkp)->robbed) ? " partially " : " ", monnam(shkp)); message(ScratchBuffer); pay(min(you.ugold, ESHK(shkp)->robbed), shkp); ESHK(shkp)->robbed = 0; return true; } if (ANGRY(shkp)) { StrPrintF(ScratchBuffer, "But in order to appease %s,", amonnam(shkp, "angry")); message(ScratchBuffer); if (you.ugold >= 1000) { ltmp = 1000; message(" you give him 1000 gold pieces."); } else { ltmp = you.ugold; message(" you give him all your money."); } pay(ltmp, shkp); if (StrNCompare(ESHK(shkp)->customer, plname, PL_NSIZ) || rund(3)){ StrPrintF(ScratchBuffer, "%s calms down.", Monnam(shkp)); message(ScratchBuffer); shkp->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1; } else { StrPrintF(ScratchBuffer, "%s is as angry as ever.", Monnam(shkp)); message(ScratchBuffer); } } return true; } if (shkp != shopkeeper) { message("BUG: dopay: not to shopkeeper?"); if (shopkeeper) setpaid(); return false; } for (pass = 0 ; pass <= 1 ; pass++) { tmp = 0; while (tmp < ESHK(shopkeeper)->billct) { bp = &bill[tmp]; if (!pass && !bp->useup) { tmp++; continue; } if (!dopayobj(bp)) return true; bill[tmp] = bill[--ESHK(shopkeeper)->billct]; } } StrPrintF(ScratchBuffer, "Thank you for shopping in %s's %s store!", shkname(shopkeeper), shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]); shopkeeper->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1; return true; }
UInt inshop() { Short roomno = inroom(you.ux,you.uy); /* Did we just leave a shop? */ if (you.uinshop && (you.uinshop != roomno + 1 || shlevel != dlevel || !shopkeeper)) { if (shopkeeper) { if (ESHK(shopkeeper)->billct) { if (inroom(shopkeeper->mx, shopkeeper->my) == you.uinshop - 1) /* ab@unido */ message("Somehow you escaped the shop without paying!"); addupbill(); StrPrintF(ScratchBuffer,"You stole for a total worth of %ld zorkmids.", total); message(ScratchBuffer); ESHK(shopkeeper)->robbed += total; setpaid(); if ((rooms[ESHK(shopkeeper)->shoproom].rtype == GENERAL) == (rund(3) == 0)) ESHK(shopkeeper)->following = true; } shopkeeper = NULL; shlevel = 0; } you.uinshop = 0; } /* Did we just enter a zoo of some kind? */ if (roomno >= 0) { Short rt = rooms[roomno].rtype; monst_t *mtmp; if (rt == ZOO) { message("Welcome to David's treasure zoo!"); } else if (rt == SWAMP) { message("It looks rather muddy down here."); } else if (rt == MORGUE) { if (midnight()) message("Go away! Go away!"); else message("You get an uncanny feeling ..."); } else rt = 0; if (rt != 0) { rooms[roomno].rtype = 0; for (mtmp = fmon ; mtmp ; mtmp = mtmp->nmon) if (rt != ZOO || !rund(3)) mtmp->bitflags &= ~M_IS_ASLEEP; } } /* Did we just enter a shop? */ if (roomno >= 0 && rooms[roomno].rtype >= 8) { if (shlevel != dlevel || !shopkeeper || ESHK(shopkeeper)->shoproom != roomno) findshk(roomno); if (!shopkeeper) { rooms[roomno].rtype = 0; you.uinshop = 0; } else if (!you.uinshop) { if (!ESHK(shopkeeper)->visitct || StrNCompare(ESHK(shopkeeper)->customer, plname, PL_NSIZ)) { /* He seems to be new here */ ESHK(shopkeeper)->visitct = 0; ESHK(shopkeeper)->following = false; StrNCopy(ESHK(shopkeeper)->customer, plname, PL_NSIZ); shopkeeper->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1; } if (!ESHK(shopkeeper)->following) { Boolean box, pick; StrPrintF(ScratchBuffer, "Hello %s! Welcome%sto %s's %s shop!", plname, ESHK(shopkeeper)->visitct++ ? " again " : " ", shkname(shopkeeper), shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8] ); message(ScratchBuffer); box = carrying(ICE_BOX); pick = carrying(PICK_AXE); if (box || pick) { if (do_chug(shopkeeper)) { you.uinshop = 0; /* he died moving */ return 0; } StrPrintF(ScratchBuffer, "Will you please leave your %s outside?", (box && pick) ? "box and pick-axe" : box ? "box" : "pick-axe"); message(ScratchBuffer); } } you.uinshop = roomno + 1; // (0 is "not in shop") } } return you.uinshop; }
// Note: this is a litte different, it will return true // iff the action is COMPLETE, and false if there was no action OR // the action is needing to finish up (after leaving SenseForm). // So if (do_drink) the caller should exit invform _and_ tick, // otherwise the caller should just exit invform. // (exiting the invform occurs _before_ calling do_drink..) // .. Ok, I've modified this again so that it lets the caller distinguish // between "it worked" and "it worked and I popped up EngraveForm". tri_val_t do_drink(obj_t *otmp) { obj_t *objs; // monst_t *mtmp; Boolean unkn = false, nothing = false, b; Short tmp; if (!otmp) return NO_OP; tmp = oc_descr_offset[otmp->otype]; if (tmp >= 0 && (0 == StrNCompare("smoky", oc_descrs+tmp, 5)) && !rund(13)) { ghost_from_bottle(); useup(otmp); return DONE; } switch(otmp->otype) { case POT_RESTORE_STRENGTH: unkn = true; message("Wow! This makes you feel great!"); if (you.ustr < you.ustrmax) { you.ustr = you.ustrmax; flags.botl |= BOTL_STR; } break; case POT_BOOZE: unkn = true; message("Ooph! This tastes like liquid fire!"); Confusion += dice(3,8); /* the whiskey makes us feel better */ if (you.uhp < you.uhpmax) losehp(-1, "bottle of whiskey"); if (!rund(4)) { tri_val_t t; // Short coma; message("You pass out."); multi = -rnd(15); spin_multi("You awake with a headache."); // coma = rnd(15); // // do { tick(); } while (--coma > 0); // message("You awake with a headache."); // // nomovemsg = "You awake with a headache."; t = finish_do_drink(otmp, nothing, unkn); //.... I guess.... return (t==DONE ? NO_OP : t); // so that we don't take any _more_ turns } break; case POT_INVISIBILITY: if (Invis || See_invisible) nothing = true; else { if (!Blind) message("Gee! All of a sudden, you can't see yourself."); else { message("You feel rather airy."); unkn = true; } newsym(you.ux,you.uy); } Invis += rund(15)+31; break; case POT_FRUIT_JUICE: message("This tastes like fruit juice."); lesshungry(20); break; case POT_HEALING: message("You begin to feel better."); you.uhp += rnd(10); if (you.uhp > you.uhpmax) you.uhp = ++you.uhpmax; if (Blind) Blind = 1; /* you'll see again on the next move */ if (Sick) Sick = 0; flags.botl |= BOTL_HP; break; case POT_PARALYSIS: if (Levitation) message("You are motionlessly suspended."); else message("Your feet are frozen to the floor!"); nomul(-(rund(10)+25)); break; case POT_MONSTER_DETECTION: if (!fmon) { b = strange_feeling(otmp, "You feel threatened."); return ((b) ? GO_ON : DONE); } else { sense_what = SENSE_MONSTERS; sense_by_what = otmp; sense_init_screen(); FrmPopupForm(SenseForm); return GO_ON; // to postpone the tick! } break; case POT_OBJECT_DETECTION: if (!fobj) { b = strange_feeling(otmp, "You feel a pull downward."); return ((b) ? GO_ON : DONE); } else { for (objs = fobj; objs; objs = objs->nobj) if (objs->ox != you.ux || objs->oy != you.uy) { sense_what = SENSE_OBJECTS; sense_by_what = otmp; sense_init_screen(); FrmPopupForm(SenseForm); return GO_ON; // to postpone the tick! } message("You sense the presence of objects close nearby."); break; } break; case POT_SICKNESS: message("Yech! This stuff tastes like poison."); if (Poison_resistance) message("(But in fact it was biologically contaminated orange juice.)"); losestr(rund(4)+3); losehp(rnd(10), "contaminated potion"); flags.botl |= BOTL_STR; break; case POT_CONFUSION: if (!Confusion) message("Huh, What? Where am I?"); else nothing = true; Confusion += rund(7)+16; break; case POT_GAIN_STRENGTH: message("Wow do you feel strong!"); if (you.ustr >= 118) break; /* > 118 is impossible */ if (you.ustr > 17) you.ustr += rnd(118-you.ustr); else you.ustr++; if (you.ustr > you.ustrmax) you.ustrmax = you.ustr; flags.botl |= BOTL_STR; break; case POT_SPEED: if (Wounded_legs) { heal_legs(); unkn = true; break; } if (!(Fast & ~INTRINSIC)) message("You are suddenly moving much faster."); else { message("Your legs get new energy."); unkn = true; } Fast += rund(10)+100; break; case POT_BLINDNESS: if (!Blind) message("A cloud of darkness falls upon you."); else nothing = true; Blind += rund(100)+250; seeoff(false); break; case POT_GAIN_LEVEL: pluslvl(); break; case POT_EXTRA_HEALING: message("You feel much better."); you.uhp += dice(2,20)+1; if (you.uhp > you.uhpmax) you.uhp = (you.uhpmax += 2); if (Blind) Blind = 1; if (Sick) Sick = 0; flags.botl |= BOTL_HP; break; case POT_LEVITATION: if (!Levitation) float_up(); else nothing = true; Levitation += rnd(100); // you.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down; // UNNEEDED, // it has been replaced by tweaking timeout.c to call float_down directly! break; default: StrPrintF(ScratchBuffer, "What a funny potion! (%u)", otmp->otype); message(ScratchBuffer); return NO_OP; } return finish_do_drink(otmp, nothing, unkn); }
// NOTE: To hit "you" with a potion p, call "potionhit(NULL, p)". no "youmonst" void potionhit(monst_t *mon, obj_t *obj) { Char *botlnam = bottlenames[rund(MAX_BOTTLES)]; Boolean uclose; // , isyou = (mon==NULL); if (!mon) { uclose = true; StrPrintF(ScratchBuffer, "The %s crashes on your head and breaks into shivers.", botlnam); message(ScratchBuffer); losehp(rnd(2), "thrown potion"); } else { uclose = (dist(mon->mx,mon->my) < 3); /* perhaps 'E' and 'a' have no head? */ StrPrintF(ScratchBuffer, "The %s crashes on %s's head and breaks into shivers.", botlnam, monnam(mon)); message(ScratchBuffer); if (rund(5) && mon->mhp > 1) mon->mhp--; } StrPrintF(ScratchBuffer, "The %s evaporates.", xname(obj)); message(ScratchBuffer); if (mon && !rund(3)) { switch(obj->otype) { case POT_RESTORE_STRENGTH: case POT_GAIN_STRENGTH: case POT_HEALING: case POT_EXTRA_HEALING: if (mon->mhp < mon->mhpmax) { mon->mhp = mon->mhpmax; StrPrintF(ScratchBuffer, "%s looks sound and hale again!", Monnam(mon)); message(ScratchBuffer); } break; case POT_SICKNESS: if (mon->mhpmax > 3) mon->mhpmax /= 2; if (mon->mhp > 2) mon->mhp /= 2; break; case POT_CONFUSION: case POT_BOOZE: mon->bitflags |= M_IS_CONFUSED; // mon->mconf = 1; break; case POT_INVISIBILITY: unpmon(mon); mon->bitflags |= M_IS_INVISIBLE; // mon->minvis = 1; pmon(mon); break; case POT_PARALYSIS: mon->bitflags |= M_IS_FROZEN; // mon->mfroz = 1; break; case POT_SPEED: mon->mspeed = MFAST; break; case POT_BLINDNESS: mon->mcansee_and_blinded |= 64 + rund(64); // "|="? "=" to turn off SEE? break; /* case POT_GAIN_LEVEL: case POT_LEVITATION: case POT_FRUIT_JUICE: case POT_MONSTER_DETECTION: case POT_OBJECT_DETECTION: break; */ default: break; } } if (uclose && rund(5)) potionbreathe(obj); free_obj(obj, NULL); }
void do_trap(trap_t *trap) // was dotrap { Short ttype = get_trap_type(trap->trap_info); nomul(0); if (get_trap_seen(trap->trap_info) && !rund(5) && ttype != PIT) { StrPrintF(ScratchBuffer, "You escape a%s.", traps[ttype]); message(ScratchBuffer); } else { trap->trap_info |= SEEN_TRAP; switch(ttype) { case SLP_GAS_TRAP: message("A cloud of gas puts you to sleep!"); nomul(-rnd(25)); break; case BEAR_TRAP: if (Levitation) { message("You float over a bear trap."); break; } you.utrap = 4 + rund(4); you.utraptype = TT_BEARTRAP; message("A bear trap closes on your foot!"); break; case PIERC: deltrap(trap); if (makemon(PM_PIERCER, you.ux, you.uy)) { message("A piercer suddenly drops from the ceiling!"); if (uarmh) message("Its blow glances off your helmet."); else thing_hit_you(3, dice(4,6), "falling piercer"); } break; case ARROW_TRAP: message("An arrow shoots out at you!"); if (!thing_hit_you(8, rnd(6), "arrow")){ mksobj_at(ARROW, you.ux, you.uy); fobj->quantity = 1; } break; case TRAPDOOR: if (!xdnstair) { message("A trap door in the ceiling opens and a rock falls on your head!"); if (uarmh) message("Fortunately, you are wearing a helmet!"); losehp((uarmh ? 2 : dice(2,10)), "falling rock"); mksobj_at(ROCK, you.ux, you.uy); fobj->quantity = 1; stackobj(fobj); if (Invisible) newsym(you.ux, you.uy); } else { Short newlevel = dlevel + 1; while (!rund(4) && newlevel < 29) newlevel++; message("A trap door opens up under you!"); if (Levitation || you.ustuck) { message("For some reason you don't fall in."); break; } goto_level(newlevel, false); } break; case DART_TRAP: message("A little dart shoots out at you!"); if (thing_hit_you(7, rnd(3), "little dart")) { if (!rund(6)) poisoned("dart", "poison dart"); } else { mksobj_at(DART, you.ux, you.uy); fobj->quantity = 1; } break; case TELEP_TRAP: map_mode_teleport = TELE_TRAP; if (get_trap_once(trap->trap_info)) { deltrap(trap); newsym(you.ux,you.uy); vtele(); } else { newsym(you.ux,you.uy); tele(); } break; case PIT: if (Levitation) { message("A pit opens up under you!"); message("You don't fall in!"); break; } message("You fall into a pit!"); you.utrap = rund(6) + 2; you.utraptype = TT_PIT; losehp(rnd(6),"fall into a pit"); selftouch("Falling, you"); break; default: StrPrintF(ScratchBuffer, "BUG: You hit a trap with info=%u", trap->trap_info); message(ScratchBuffer); } } }
/* * ****** * OALTAR * ****** * */ void oaltar() { long k; int p; start: lprcat("\nDo you (p) pray (d) desecrate"); iopts(); while (1) { while (1) switch(getcharacter()) { case 'p': lprcat(" pray.\nDo you (m) give money or (j) just pray? "); while (1) switch(getcharacter()) { case 'j': p = rund(100); if (p < 12) createmonster(makemonst(level+2)); else if (p < 17) enchweapon(ENCH_ALTAR); else if (p < 22) enchantarmor(ENCH_ALTAR); else if (p < 27) ohear(); else lprcat("\nNothing happens."); return; case 'm': cursor(1,24); cltoeoln(); cursor(1,23); cltoeoln(); lprcat("how much do you donate? "); if ((k = readnum(c[GOLD])) < 0) goto start; if (c[GOLD] < k) { lprcat("You don't have that much!"); nap(1001); goto start; } if (k < (c[GOLD]/10) && rnd(60)<30 && !wizard) { lprcat("Cheapskate! The Gods are insulted by such a " "tiny offering!"); forget(); createmonster(DEMONPRINCE); c[AGGRAVATE] += 1500; return; } c[GOLD] -= k; if (k < (c[GOLD]+k)/10 || k < rnd(50) && !wizard) { createmonster(makemonst(level+2)); c[AGGRAVATE] += 500; bottomline(); return; } p = rund(16); if (p < 4) lprcat("Thank you."); else if (p < 6) { enchantarmor(ENCH_ALTAR); enchantarmor(ENCH_ALTAR); } else if (p < 8) { enchweapon(ENCH_ALTAR); enchweapon(ENCH_ALTAR); } else ohear(); bottomline(); return; } /* end while switch : case j or m */ case 'd': lprcat(" desecrate"); if (rnd(100)<60) { createmonster(makemonst(level+3)+8); c[AGGRAVATE] += 2500; } else if(rnd(100)<5) raiselevel(); else if (rnd(101)<30) { lprcat("\nThe altar crumbles into a pile of dust before your eyes."); forget(); /*remember to destroy the altar*/ } else lprcat("\nNothing happens."); return; case 'i': case ESC: ignore(); if (rnd(100)<30) { createmonster(makemonst(level+2)); c[AGGRAVATE] += rnd(450); } else lprcat("\nNothing happens."); return; } /* end while switch: pray, des, ignore */ } /* NOTREACHED */ } /* end oaltar */
/* function to drink a potion */ void quaffpotion(int pot) { int i,j; int k; if (pot<0 || pot>=MAXPOTION) return; /* check for within bounds */ /* first character of potion name starts off as \0. */ /* drinking a certain type of potion changes that to a space */ /* ...and from then on it is printable. */ /* if (potionname[pot][0] == '\0') */ /* potionname[pot][0] = ' '; */ if (potionknown[pot] == 0) potionknown[pot] = 1; lprintf("\nYou drink a potion of %s.", &potionname[pot][1]); switch(pot) { case PSLEEP: lprcat(" You fall asleep..."); lflush(); i=rnd(11)-(c[CONSTITUTION]>>2)+2; while(--i>0) { parse2(); nap(1000); } cursors(); lprcat("\n.. you wake up."); return; case PHEALING: lprcat(" You feel better."); if (c[HP] == c[HPMAX]) raisemhp(1); else if ((c[HP] += rnd(20)+20+c[LEVEL]) > c[HPMAX]) c[HP]=c[HPMAX]; break; case PRAISELEVEL: lprcat(" You feel much more skillful!"); raiselevel(); raisemhp(1); return; case PINCABILITY: lprcat(" You feel strange for a moment."); c[rund(6)]++; break; case PWISDOM: lprcat(" You feel more self-confident!"); c[WISDOM] += rnd(2); break; case PSTRENGTH: lprcat(" Wow! You feel great!"); if (c[STRENGTH]<12) c[STRENGTH]=12; else c[STRENGTH]++; break; case PCHARISMA: lprcat(" You feel charismatic!"); c[CHARISMA]++; break; case PDIZZINESS: lprcat(" You become dizzy!"); if (--c[STRENGTH] < 3) c[STRENGTH]=3; break; case PLEARNING: lprcat(" You feel clever!"); c[INTELLIGENCE]++; break; case PGOLDDET: lprcat(" You feel greedy..."); lflush(); nap(2000); for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) if ((item[j][i]==OGOLDPILE) || (item[j][i]==OMAXGOLD)) { know[j][i]=1; show1cell(j,i); } showplayer(); return; case PMONSTDET: for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) if (mitem[j][i].mon) { know[j][i]=1; show1cell(j,i); } return; case PFORGETFUL: lprcat(" You stagger for a moment..."); lflush(); for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) know[j][i]=0; nap(2000); draws(0,MAXX,0,MAXY); return; case PWATER: return; case PBLINDNESS: lprcat(" You can't see anything!"); c[BLINDCOUNT]+=500; /* dang, that's a long time. */ /* erase the character, too! */ cursor(playerx+1,playery+1); lprc(' '); cursor(playerx+1,playery+1); return; case PCONFUSION: lprcat(" You feel confused."); c[CONFUSE]+= 20+rnd(9); return; case PHEROISM: lprcat(" WOW! You feel fantastic!"); if (c[HERO]==0) for (i=0; i<6; i++) c[i] += 11; c[HERO] += 250; break; case PSTURDINESS: lprcat(" You feel healthier!"); c[CONSTITUTION]++; break; case PGIANTSTR: lprcat(" You now have incredible bulging muscles!"); if (c[GIANTSTR]==0) c[STREXTRA] += 21; c[GIANTSTR] += 700; break; case PFIRERESIST: lprcat(" You feel a chill run up your spine!"); c[FIRERESISTANCE] += 1000; break; case PTREASURE: lprcat(" You feel greedy..."); lflush(); nap(2000); for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) { k=item[j][i]; if ((k==ODIAMOND) || (k==ORUBY) || (k==OEMERALD) || (k==OMAXGOLD) || (k==OSAPPHIRE) || (k==OLARNEYE) || (k==OGOLDPILE)) { know[j][i]=1; show1cell(j,i); } } showplayer(); return; case PINSTHEAL: c[HP] = c[HPMAX]; removecurse(); break; case PCUREDIANTH: lprcat(" You don't seem to be affected."); return; case PPOISON: lprcat(" You feel a sickness engulf you!"); c[HALFDAM] += 200 + rnd(200); return; case PSEEINVIS: lprcat(" You feel your vision sharpen."); c[SEEINVISIBLE] += rnd(1000)+400; monstnamelist[INVISIBLESTALKER] = 'I'; return; }; /* show new stats */ bottomline(); return; }
Short mon_in_trap(monst_t *mtmp) // was mintrap { trap_t *trap = trap_at(mtmp->mx, mtmp->my); Boolean wasintrap = (mtmp->bitflags & M_IS_TRAPPED); if (!trap) { mtmp->bitflags &= ~M_IS_TRAPPED; /* perhaps teleported? */ } else if (wasintrap) { if (!rund(40)) mtmp->bitflags &= ~M_IS_TRAPPED; } else { Short tt = get_trap_type(trap->trap_info); Short in_sight = cansee(mtmp->mx, mtmp->my); if (mtmp->mtraps_seen & (1 << tt)) { /* he has been in such a trap - perhaps he escapes */ if (rund(4)) return 0; } mtmp->mtraps_seen |= (1 << tt); switch (tt) { case BEAR_TRAP: if (StrChr(mlarge, mtmp->data->mlet)) { if (in_sight) { StrPrintF(ScratchBuffer,"%s is caught in a bear trap!",Monnam(mtmp)); message(ScratchBuffer); } else if (mtmp->data->mlet == 'o') message("You hear the roaring of an angry bear!"); mtmp->bitflags |= M_IS_TRAPPED; } break; case PIT: /* there should be a mtmp/data -> floating */ if (!StrChr("EywBfk'& ", mtmp->data->mlet)) { /* ab */ mtmp->bitflags |= M_IS_TRAPPED; if (in_sight) { StrPrintF(ScratchBuffer, "%s falls in a pit!", Monnam(mtmp)); message(ScratchBuffer); } } break; case SLP_GAS_TRAP: if (!(mtmp->bitflags & (M_IS_ASLEEP | M_IS_FROZEN))) { mtmp->bitflags |= M_IS_ASLEEP; if (in_sight) { StrPrintF(ScratchBuffer, "%s suddenly falls asleep!", Monnam(mtmp)); message(ScratchBuffer); } } break; case TELEP_TRAP: rloc(mtmp); if (in_sight && !cansee(mtmp->mx,mtmp->my)) { StrPrintF(ScratchBuffer, "%s suddenly disappears!", Monnam(mtmp)); message(ScratchBuffer); } break; case ARROW_TRAP: if (in_sight) { StrPrintF(ScratchBuffer, "%s is hit by an arrow!", Monnam(mtmp)); message(ScratchBuffer); } mtmp->mhp -= 3; break; case DART_TRAP: if (in_sight) { StrPrintF(ScratchBuffer, "%s is hit by a dart!", Monnam(mtmp)); message(ScratchBuffer); } mtmp->mhp -= 2; /* not mondied here !! */ break; case TRAPDOOR: if (!xdnstair) { mtmp->mhp -= 10; if (in_sight) { StrPrintF(ScratchBuffer, "A trap door in the ceiling opens and a rock hits %s!", monnam(mtmp)); message(ScratchBuffer); } break; } if (mtmp->data->mlet != 'w') { fall_down(mtmp); if (in_sight) { StrPrintF(ScratchBuffer, "Suddenly, %s disappears out of sight.", monnam(mtmp)); message(ScratchBuffer); } return 2; /* no longer on this level */ } break; case PIERC: break; default: message("BUG: Some monster encountered a strange trap."); } } return ((mtmp->bitflags & M_IS_TRAPPED) != 0); }