int doup() { if(u.ux != xupstair || u.uy != yupstair) { pline("You can't go up here."); return(0); } if(u.ustuck) { pline("You are being held, and cannot go up."); return(1); } if(!Levitation && inv_weight() + 5 > 0) { pline("Your load is too heavy to climb the stairs."); return(1); } goto_level(dlevel-1, TRUE); return(1); }
void nh_timeout() { register struct prop *upp; int sleeptime; int m_idx; int baseluck = (flags.moonphase == FULL_MOON) ? 1 : 0; if (flags.friday13) baseluck -= 1; if (u.uluck != baseluck && moves % (u.uhave.amulet || u.ugangr ? 300 : 600) == 0) { /* Cursed luckstones stop bad luck from timing out; blessed luckstones * stop good luck from timing out; normal luckstones stop both; * neither is stopped if you don't have a luckstone. * Luck is based at 0 usually, +1 if a full moon and -1 on Friday 13th */ register int time_luck = stone_luck(FALSE); boolean nostone = !carrying(LUCKSTONE) && !stone_luck(TRUE); if(u.uluck > baseluck && (nostone || time_luck < 0)) u.uluck--; else if(u.uluck < baseluck && (nostone || time_luck > 0)) u.uluck++; } if(u.uinvulnerable) return; /* things past this point could kill you */ if(Stoned) stoned_dialogue(); if(Slimed) slime_dialogue(); if(Vomiting) vomiting_dialogue(); if(Strangled) choke_dialogue(); if(u.mtimedone && !--u.mtimedone) { if (Unchanging) u.mtimedone = rnd(100*youmonst.data->mlevel + 1); else rehumanize(); } if(u.ucreamed) u.ucreamed--; /* Dissipate spell-based protection. */ if (u.usptime) { if (--u.usptime == 0 && u.uspellprot) { u.usptime = u.uspmtime; u.uspellprot--; find_ac(); if (!Blind) Norep("The %s haze around you %s.", hcolor(NH_GOLDEN), u.uspellprot ? "becomes less dense" : "disappears"); } } #ifdef STEED if (u.ugallop) { if (--u.ugallop == 0L && u.usteed) pline("%s stops galloping.", Monnam(u.usteed)); } #endif for(upp = u.uprops; upp < u.uprops+SIZE(u.uprops); upp++) if((upp->intrinsic & TIMEOUT) && !(--upp->intrinsic & TIMEOUT)) { switch(upp - u.uprops){ case STONED: if (delayed_killer && !killer) { killer = delayed_killer; delayed_killer = 0; } if (!killer) { /* leaving killer_format would make it "petrified by petrification" */ killer_format = NO_KILLER_PREFIX; killer = "killed by petrification"; } done(STONING); break; case SLIMED: if (delayed_killer && !killer) { killer = delayed_killer; delayed_killer = 0; } if (!killer) { killer_format = NO_KILLER_PREFIX; killer = "turned into green slime"; } done(TURNED_SLIME); break; case VOMITING: make_vomiting(0L, TRUE); break; case SICK: You("die from your illness."); killer_format = KILLED_BY_AN; killer = u.usick_cause; if ((m_idx = name_to_mon(killer)) >= LOW_PM) { if (type_is_pname(&mons[m_idx])) { killer_format = KILLED_BY; } else if (mons[m_idx].geno & G_UNIQ) { killer = the(killer); Strcpy(u.usick_cause, killer); killer_format = KILLED_BY; } } u.usick_type = 0; done(POISONING); break; case FAST: if (!Very_fast) You_feel("yourself slowing down%s.", Fast ? " a bit" : ""); break; case CONFUSION: HConfusion = 1; /* So make_confused works properly */ make_confused(0L, TRUE); stop_occupation(); break; case STUNNED: HStun = 1; make_stunned(0L, TRUE); stop_occupation(); break; case BLINDED: Blinded = 1; make_blinded(0L, TRUE); stop_occupation(); break; case INVIS: newsym(u.ux,u.uy); if (!Invis && !BInvis && !Blind) { You(!See_invisible ? "are no longer invisible." : "can no longer see through yourself."); stop_occupation(); } break; case SEE_INVIS: set_mimic_blocking(); /* do special mimic handling */ see_monsters(); /* make invis mons appear */ newsym(u.ux,u.uy); /* make self appear */ stop_occupation(); break; case WOUNDED_LEGS: heal_legs(); stop_occupation(); break; case HALLUC: HHallucination = 1; (void) make_hallucinated(0L, TRUE, 0L); stop_occupation(); break; case SLEEPING: if (unconscious() || Sleep_resistance) HSleeping += rnd(100); else if (Sleeping) { You("fall asleep."); sleeptime = rnd(20); fall_asleep(-sleeptime, TRUE); HSleeping += sleeptime + rnd(100); } break; case LEVITATION: (void) float_down(I_SPECIAL|TIMEOUT, 0L); break; case STRANGLED: killer_format = KILLED_BY; killer = (u.uburied) ? "suffocation" : "strangulation"; done(DIED); break; case FUMBLING: /* call this only when a move took place. */ /* otherwise handle fumbling msgs locally. */ if (u.umoved && !Levitation) { slip_or_trip(); nomul(-2, "fumbling"); nomovemsg = ""; /* The more you are carrying the more likely you * are to make noise when you fumble. Adjustments * to this number must be thoroughly play tested. */ if ((inv_weight() > -500)) { You("make a lot of noise!"); wake_nearby(); } } /* from outside means slippery ice; don't reset counter if that's the only fumble reason */ HFumbling &= ~FROMOUTSIDE; if (Fumbling) HFumbling += rnd(20); break; case DETECT_MONSTERS: see_monsters(); break; case PREGNANT: { char buf[BUFSZ]; if (!flags.female) { strcpy(buf, body_part(STOMACH)); if (!strcmp(buf, "stomach")) strcpy(buf, "belly"); pline("Something bursts out of your %s!"); killer_format = KILLED_BY; killer = "male childbirth"; done(DIED); } mksobj_at(PLACENTA, u.ux, u.uy, FALSE, FALSE); pline("BABIES!"); /* TODO */ stop_occupation(); break; } } } run_timers(); }
void goto_level(int newlevel, boolean at_stairs) { int fd; boolean up = (newlevel < dlevel); if(newlevel <= 0) done("escaped"); /* in fact < 0 is impossible */ if(newlevel > MAXLEVEL) newlevel = MAXLEVEL; /* strange ... */ if(newlevel == dlevel) return; /* this can happen */ glo(dlevel); fd = creat(lock, FMASK); if(fd < 0) { /* * This is not quite impossible: e.g., we may have * exceeded our quota. If that is the case then we * cannot leave this level, and cannot save either. * Another possibility is that the directory was not * writable. */ pline("A mysterious force prevents you from going %s.", up ? "up" : "down"); return; } if(Punished) unplacebc(); u.utrap = 0; /* needed in level_tele */ u.ustuck = 0; /* idem */ keepdogs(); seeoff(1); if(u.uswallow) /* idem */ u.uswldtim = u.uswallow = 0; flags.nscrinh = 1; u.ux = FAR; /* hack */ (void) inshop(); /* probably was a trapdoor */ savelev(fd,dlevel); (void) close(fd); dlevel = newlevel; if(maxdlevel < dlevel) maxdlevel = dlevel; glo(dlevel); if(!level_exists[(int)dlevel]) mklev(); else { extern int hackpid; if((fd = open(lock, O_RDONLY)) < 0) { pline("Cannot open %s .", lock); pline("Probably someone removed it."); done("tricked"); } getlev(fd, hackpid, dlevel); (void) close(fd); } if(at_stairs) { if(up) { u.ux = xdnstair; u.uy = ydnstair; if(!u.ux) { /* entering a maze from below? */ u.ux = xupstair; /* this will confuse the player! */ u.uy = yupstair; } if(Punished && !Levitation){ pline("With great effort you climb the stairs."); placebc(1); } } else { u.ux = xupstair; u.uy = yupstair; if(inv_weight() + 5 > 0 || Punished){ pline("You fall down the stairs."); /* %% */ losehp(rnd(3), "fall"); if(Punished) { if(uwep != uball && rn2(3)){ pline("... and are hit by the iron ball."); losehp(rnd(20), "iron ball"); } placebc(1); } selftouch("Falling, you"); } } { struct monst *mtmp = m_at(u.ux, u.uy); if(mtmp) mnexto(mtmp); } } else { /* trapdoor or level_tele */ do { u.ux = rnd(COLNO-1); u.uy = rn2(ROWNO); } while(levl[(int)u.ux][(int)u.uy].typ != ROOM || m_at(u.ux,u.uy)); if(Punished){ if(uwep != uball && !up /* %% */ && rn2(5)){ pline("The iron ball falls on your head."); losehp(rnd(25), "iron ball"); } placebc(1); } selftouch("Falling, you"); } (void) inshop(); initrack(); losedogs(); { struct monst *mtmp; if ((mtmp = m_at(u.ux, u.uy))) mnexto(mtmp); /* riv05!a3 */ } flags.nscrinh = 0; setsee(); seeobjs(); /* make old cadavers disappear - riv05!a3 */ docrt(); pickup(1); read_engr_at(u.ux,u.uy); }
/* u.dx and u.dy must be set */ bool attack(struct monst *mtmp) { schar tmp; boolean malive = TRUE; struct permonst *mdat; mdat = mtmp->data; u_wipe_engr(3); /* andrew@orca: prevent unlimited pick-axe attacks */ if (mdat->mlet == 'L' && !mtmp->mfroz && !mtmp->msleep && !mtmp->mconf && mtmp->mcansee && !rn2(7) && (m_move(mtmp, 0) == 2 /* he died */ || /* he moved: */ mtmp->mx != u.ux + u.dx || mtmp->my != u.uy + u.dy)) return (FALSE); if (mtmp->mimic) { if (!u.ustuck && !mtmp->mflee) u.ustuck = mtmp; switch (levl[u.ux + u.dx][u.uy + u.dy].scrsym) { case '+': pline("The door actually was a Mimic."); break; case '$': pline("The chest was a Mimic!"); break; default: pline("Wait! That's a Mimic!"); } wakeup(mtmp); /* clears mtmp->mimic */ return (TRUE); } wakeup(mtmp); if (mtmp->mhide && mtmp->mundetected) { struct obj *obj; mtmp->mundetected = 0; if ((obj = o_at(mtmp->mx, mtmp->my)) && !Blind) pline("Wait! There's a %s hiding under %s!", mdat->mname, doname(obj)); return (TRUE); } tmp = u.uluck + u.ulevel + mdat->ac + abon(); if (uwep) { if (uwep->olet == WEAPON_SYM || uwep->otyp == PICK_AXE) tmp += uwep->spe; if (uwep->otyp == TWO_HANDED_SWORD) tmp -= 1; else if (uwep->otyp == DAGGER) tmp += 2; else if (uwep->otyp == CRYSKNIFE) tmp += 3; else if (uwep->otyp == SPEAR && strchr("XDne", mdat->mlet)) tmp += 2; } if (mtmp->msleep) { mtmp->msleep = 0; tmp += 2; } if (mtmp->mfroz) { tmp += 4; if (!rn2(10)) mtmp->mfroz = 0; } if (mtmp->mflee) tmp += 2; if (u.utrap) tmp -= 3; /* with a lot of luggage, your agility diminishes */ tmp -= (inv_weight() + 40) / 20; if (tmp <= rnd(20) && !u.uswallow) { if (Blind) pline("You miss it."); else pline("You miss %s.", monnam(mtmp)); } else { /* we hit the monster; be careful: it might die! */ if ((malive = hmon(mtmp, uwep, 0)) == TRUE) { /* monster still alive */ if (!rn2(25) && mtmp->mhp < mtmp->mhpmax / 2) { mtmp->mflee = 1; if (!rn2(3)) mtmp->mfleetim = rnd(100); if (u.ustuck == mtmp && !u.uswallow) u.ustuck = 0; } #ifndef NOWORM if (mtmp->wormno) cutworm(mtmp, u.ux + u.dx, u.uy + u.dy, uwep ? uwep->otyp : 0); #endif /* NOWORM */ } if (mdat->mlet == 'a') { if (rn2(2)) { pline("You are splashed by the blob's acid!"); losehp_m(rnd(6), mtmp); if (!rn2(30)) corrode_armor(); } if (!rn2(6)) corrode_weapon(); } } if (malive && mdat->mlet == 'E' && canseemon(mtmp) && !mtmp->mcan && rn2(3)) { if (mtmp->mcansee) { pline("You are frozen by the floating eye's gaze!"); nomul((u.ulevel > 6 || rn2(4)) ? rn1(20, -21) : -200); } else { pline("The blinded floating eye cannot defend itself."); if (!rn2(500)) if ((int)u.uluck > LUCKMIN) u.uluck--; } } return (TRUE); }
void u_init(void) { int i; char exper = 'y', pc; if (flags.female) /* should have been set in HACKOPTIONS */ strlcpy(roles[4], "Cave-woman", sizeof(roles[4])); for (i = 0; i < NR_OF_ROLES; i++) rolesyms[i] = roles[i][0]; rolesyms[i] = 0; if ((pc = pl_character[0]) != '\0') { if ('a' <= pc && pc <= 'z') pc += 'A' - 'a'; if ((i = role_index(pc)) >= 0) goto got_suffix; /* implies experienced */ printf("\nUnknown role: %c\n", pc); pl_character[0] = pc = 0; } printf("\nAre you an experienced player? [ny] "); while (!strchr("ynYN \n\004", (exper = readchar()))) bell(); if (exper == '\004') /* Give him an opportunity to get out */ end_of_input(); printf("%c\n", exper); /* echo */ if (strchr("Nn \n", exper)) { exper = 0; goto beginner; } printf("\nTell me what kind of character you are:\n"); printf("Are you"); for (i = 0; i < NR_OF_ROLES; i++) { printf(" a %s", roles[i]); if (i == 2) /* %% */ printf(",\n\t"); else if (i < NR_OF_ROLES - 2) printf(","); else if (i == NR_OF_ROLES - 2) printf(" or"); } printf("? [%s] ", rolesyms); while ((pc = readchar()) != '\0') { if ('a' <= pc && pc <= 'z') pc += 'A' - 'a'; if ((i = role_index(pc)) >= 0) { printf("%c\n", pc); /* echo */ fflush(stdout); /* should be seen */ break; } if (pc == '\n') break; if (pc == '\004') /* Give him the opportunity to get out */ end_of_input(); bell(); } if (pc == '\n') pc = 0; beginner: if (!pc) { printf("\nI'll choose a character for you.\n"); i = rn2(NR_OF_ROLES); pc = rolesyms[i]; printf("This game you will be a%s %s.\n", exper ? "n experienced" : "", roles[i]); getret(); /* give him some feedback in case mklev takes much time */ putchar('\n'); fflush(stdout); } if (exper) roles[i][0] = pc; got_suffix: strncpy(pl_character, roles[i], PL_CSIZ - 1); pl_character[PL_CSIZ - 1] = 0; flags.beginner = 1; u = zerou; u.usym = '@'; u.ulevel = 1; init_uhunger(); #ifdef QUEST u.uhorizon = 6; #endif /* QUEST */ uarm = uarm2 = uarmh = uarms = uarmg = uwep = uball = uchain = uleft = uright = 0; switch (pc) { case 'c': case 'C': Cave_man[2].trquan = 12 + rnd(9) * rnd(9); u.uhp = u.uhpmax = 16; u.ustr = u.ustrmax = 18; ini_inv(Cave_man); break; case 't': case 'T': Tourist[3].trquan = 20 + rnd(20); u.ugold = u.ugold0 = rnd(1000); u.uhp = u.uhpmax = 10; u.ustr = u.ustrmax = 8; ini_inv(Tourist); if (!rn2(25)) ini_inv(Tinopener); break; case 'w': case 'W': for (i = 1; i <= 4; i++) if (!rn2(5)) Wizard[i].trquan += rn2(3) - 1; u.uhp = u.uhpmax = 15; u.ustr = u.ustrmax = 16; ini_inv(Wizard); break; case 's': case 'S': Fast = INTRINSIC; Stealth = INTRINSIC; u.uhp = u.uhpmax = 12; u.ustr = u.ustrmax = 10; ini_inv(Speleologist); if (!rn2(10)) ini_inv(Tinopener); break; case 'k': case 'K': u.uhp = u.uhpmax = 12; u.ustr = u.ustrmax = 10; ini_inv(Knight); break; case 'f': case 'F': u.uhp = u.uhpmax = 14; u.ustr = u.ustrmax = 17; ini_inv(Fighter); break; default: /* impossible */ u.uhp = u.uhpmax = 12; u.ustr = u.ustrmax = 16; } find_ac(); if (!rn2(20)) { int d1 = rn2(7) - 2; /* biased variation */ u.ustr += d1; u.ustrmax += d1; } #ifdef WIZARD if (wizard) wiz_inv(); #endif /* WIZARD */ /* make sure he can carry all he has - especially for T's */ while (inv_weight() > 0 && u.ustr < 118) u.ustr++, u.ustrmax++; }
void statuswin::parse_statusline(std::string str) { int hp, hpmax, nconds; long val; std::string txt; int cap = near_capacity(); size_t pos; char buf[64]; /* get player name + title */ pos = str.find("St:", 0); if (pos != std::string::npos) tokenarray[0][0]->caption = str.substr(0, pos); /* strength needs special treatment */ if (ACURR(A_STR) > 18) { if (ACURR(A_STR) > STR18(100)) sprintf(buf,"St:%2d", ACURR(A_STR)-100); else if (ACURR(A_STR) < STR18(100)) sprintf(buf, "St:18/%02d", ACURR(A_STR)-18); else sprintf(buf,"St:18/**"); } else sprintf(buf, "St:%-1d", ACURR(A_STR)); tokenarray[0][1]->caption = buf; /* the other stats */ sprintf(buf, "Dx:%-1d", ACURR(A_DEX)); tokenarray[0][2]->caption = buf; sprintf(buf, "Co:%-1d", ACURR(A_CON)); tokenarray[0][3]->caption = buf; sprintf(buf, "In:%-1d", ACURR(A_INT)); tokenarray[1][1]->caption = buf; sprintf(buf, "Wi:%-1d", ACURR(A_WIS)); tokenarray[1][2]->caption = buf; sprintf(buf, "Ch:%-1d", ACURR(A_CHA)); tokenarray[1][3]->caption = buf; /* alignment */ tokenarray[4][0]->visible = 1; tokenarray[4][0]->caption = (u.ualign.type == A_CHAOTIC) ? "Chaotic" : (u.ualign.type == A_NEUTRAL) ? "Neutral" : "Lawful"; /* score */ #ifdef SCORE_ON_BOTL if (flags.showscore) { sprintf(buf, "S:%ld", botl_score()); tokenarray[3][4]->caption = buf; } else tokenarray[3][4]->caption.clear(); #endif /* money */ #ifndef GOLDOBJ val = u.ugold; #else val = money_cnt(invent); #endif if (val >= 100000) { sprintf(buf, "%c:%-2ldk", oc_syms[COIN_CLASS], val / 1000); tokenarray[3][2]->caption = buf; } else { sprintf(buf, "%c:%-2ld", oc_syms[COIN_CLASS], val); tokenarray[3][2]->caption = buf; } /* Experience */ if (Upolyd) { sprintf(buf, "HD:%d", mons[u.umonnum].mlevel); tokenarray[3][0]->caption = buf; } #ifdef EXP_ON_BOTL else if(flags.showexp) { Sprintf(buf, "Xp:%u/%-1ld", u.ulevel,u.uexp); tokenarray[3][0]->caption = buf; /* if the exp gets too long, suppress displaying the alignment */ if (tokenarray[3][0]->caption.length() > 10) tokenarray[4][0]->visible = 0; } #endif else { Sprintf(buf, "Exp:%u", u.ulevel); tokenarray[3][0]->caption = buf; } /* HP, energy, armor */ hp = Upolyd ? u.mh : u.uhp; hpmax = Upolyd ? u.mhmax : u.uhpmax; sprintf(buf, "HP:%d(%d)", hp, hpmax); tokenarray[2][1]->caption = buf; if (hp >= ((hpmax * 90) / 100)) tokenarray[2][1]->textcolor = warn_colors[V_WARN_NONE]; else if (hp >= ((hpmax * 70) / 100)) tokenarray[2][1]->textcolor = warn_colors[V_WARN_NORMAL]; else if (hp >= ((hpmax * 50) / 100)) tokenarray[2][1]->textcolor = warn_colors[V_WARN_MORE]; else if (hp >= ((hpmax * 25) / 100)) tokenarray[2][1]->textcolor = warn_colors[V_WARN_ALERT]; else tokenarray[2][1]->textcolor = warn_colors[V_WARN_CRITICAL]; sprintf(buf, "Pw:%d(%d)", u.uen, u.uenmax); tokenarray[2][2]->caption = buf; sprintf(buf, "AC:%-2d", u.uac); tokenarray[2][3]->caption = buf; /* time */ if(flags.time) { sprintf(buf, "T:%ld", moves); tokenarray[3][3]->caption = buf; } else tokenarray[3][3]->caption.clear(); /* depth again (numeric) */ sprintf(buf, "Dlvl:%-2d ", depth(&u.uz)); tokenarray[3][1]->caption = buf; /* conditions (hunger, confusion, etc) */ nconds = 0; if (u.uhs > 1) /* hunger */ add_cond(hu_stat[u.uhs], nconds++, u.uhs-1); else if (u.uhs < 1) /* satiated */ add_cond(hu_stat[u.uhs], nconds++, 0); if(Confusion) add_cond("Conf", nconds++, V_WARN_MORE); if(Sick) { if (u.usick_type & SICK_VOMITABLE) add_cond("FoodPois", nconds++, V_WARN_ALERT); if (u.usick_type & SICK_NONVOMITABLE) add_cond("Ill", nconds++, V_WARN_ALERT); } if(Blind) add_cond("Blind", nconds++, V_WARN_MORE); if(Stunned) add_cond("Stun", nconds++, V_WARN_MORE); if(Hallucination) add_cond("Hallu", nconds++, V_WARN_MORE); if(Slimed) add_cond("Slime", nconds++, V_WARN_ALERT); if(cap > UNENCUMBERED) add_cond(enc_stat[cap], nconds++, cap); /* reset the empty positions */ for ( ;nconds < 8; nconds++) add_cond("", nconds, 0); #ifdef SHOW_WEIGHT if (flags.showweight && !tokenarray[0][4]->caption[0]) { std::stringstream stream; stream << "Wt:" << static_cast<long>((inv_weight()+weight_cap())) << "/" << static_cast<long>(weight_cap()) ; tokenarray[0][4]->caption = stream.str(); } #endif }