From e4630fb8264cb94f3862c7e6600cea109079af19 Mon Sep 17 00:00:00 2001 From: jwalz Date: Sat, 5 Jan 2002 21:05:48 +0000 Subject: [PATCH] *** empty log message *** --- src/allmain.c | 616 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 616 insertions(+) create mode 100644 src/allmain.c diff --git a/src/allmain.c b/src/allmain.c new file mode 100644 index 000000000..2bfdb772b --- /dev/null +++ b/src/allmain.c @@ -0,0 +1,616 @@ +/* SCCS Id: @(#)allmain.c 3.3 2000/05/05 */ +/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ +/* NetHack may be freely redistributed. See license for details. */ + +/* various code that was replicated in *main.c */ + +#include "hack.h" + +#ifndef NO_SIGNAL +#include +#endif + +#ifdef POSITIONBAR +STATIC_DCL void NDECL(do_positionbar); +#endif + +#ifdef OVL0 + +void +moveloop() +{ +#ifdef MICRO + char ch; + int abort_lev; +#endif + int moveamt = 0, wtcap = 0, change = 0; + boolean didmove = FALSE, monscanmove = FALSE; + + flags.moonphase = phase_of_the_moon(); + if(flags.moonphase == FULL_MOON) { + You("are lucky! Full moon tonight."); + change_luck(1); + } else if(flags.moonphase == NEW_MOON) { + pline("Be careful! New moon tonight."); + } + flags.friday13 = friday_13th(); + if (flags.friday13) { + pline("Watch out! Bad things can happen on Friday the 13th."); + change_luck(-1); + } + + initrack(); + + + /* Note: these initializers don't do anything except guarantee that + we're linked properly. + */ + decl_init(); + monst_init(); + monstr_init(); /* monster strengths */ + objects_init(); + +#ifdef WIZARD + if (wizard) add_debug_extended_commands(); +#endif + + (void) encumber_msg(); /* in case they auto-picked up something */ + + u.uz0.dlevel = u.uz.dlevel; + youmonst.movement = NORMAL_SPEED; /* give the hero some movement points */ + + for(;;) { +#ifdef CLIPPING + cliparound(u.ux, u.uy); +#endif + get_nh_event(); +#ifdef POSITIONBAR + do_positionbar(); +#endif + + didmove = flags.move; + if(didmove) { + /* actual time passed */ + youmonst.movement -= NORMAL_SPEED; + + do { /* hero can't move this turn loop */ + wtcap = encumber_msg(); + + flags.mon_moving = TRUE; + do { + monscanmove = movemon(); + if (youmonst.movement > NORMAL_SPEED) + break; /* it's now your turn */ + } while (monscanmove); + flags.mon_moving = FALSE; + + if (!monscanmove && youmonst.movement < NORMAL_SPEED) { + /* both you and the monsters are out of steam this round */ + /* set up for a new turn */ + struct monst *mtmp; + mcalcdistress(); /* adjust monsters' trap, blind, etc */ + + /* reallocate movement rations to monsters */ + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) + mtmp->movement += mcalcmove(mtmp); + + if(!rn2(u.uevent.udemigod ? 25 : + (depth(&u.uz) > depth(&stronghold_level)) ? 50 : 70)) + (void) makemon((struct permonst *)0, 0, 0, NO_MM_FLAGS); + + /* calculate how much time passed. */ +#ifdef STEED + if (u.usteed && flags.mv) { + /* your speed doesn't augment steed's speed */ + moveamt = mcalcmove(u.usteed); + } else +#endif + { + moveamt = youmonst.data->mmove; + + if (Very_fast) { /* speed boots or potion */ + /* average movement is 1.67 times normal */ + moveamt += NORMAL_SPEED / 2; + if (rn2(3) == 0) moveamt += NORMAL_SPEED / 2; + } else if (Fast) { + /* average movement is 1.33 times normal */ + if (rn2(3) != 0) moveamt += NORMAL_SPEED / 2; + } + } + + switch (wtcap) { + case UNENCUMBERED: break; + case SLT_ENCUMBER: moveamt -= (moveamt / 4); break; + case MOD_ENCUMBER: moveamt -= (moveamt / 2); break; + case HVY_ENCUMBER: moveamt -= ((moveamt * 3) / 4); break; + case EXT_ENCUMBER: moveamt -= ((moveamt * 7) / 8); break; + default: break; + } + + youmonst.movement += moveamt; + if (youmonst.movement < 0) youmonst.movement = 0; + settrack(); + + monstermoves++; + moves++; + + /********************************/ + /* once-per-turn things go here */ + /********************************/ + + if (flags.bypasses) clear_bypasses(); + if(Glib) glibr(); + nh_timeout(); + run_regions(); + + if (u.ublesscnt) u.ublesscnt--; + if(flags.time && !flags.run) + flags.botl = 1; + + /* One possible result of prayer is healing. Whether or + * not you get healed depends on your current hit points. + * If you are allowed to regenerate during the prayer, the + * end-of-prayer calculation messes up on this. + * Another possible result is rehumanization, which requires + * that encumbrance and movement rate be recalculated. + */ + if (u.uinvulnerable) { + /* for the moment at least, you're in tiptop shape */ + wtcap = UNENCUMBERED; + } else if (Upolyd && youmonst.data->mlet == S_EEL && !is_pool(u.ux,u.uy) && !Is_waterlevel(&u.uz)) { + if (u.mh > 1) { + u.mh--; + flags.botl = 1; + } else if (u.mh < 1) + rehumanize(); + } else if (Upolyd && u.mh < u.mhmax) { + if (u.mh < 1) + rehumanize(); + else if (Regeneration || + (wtcap < MOD_ENCUMBER && !(moves%20))) { + flags.botl = 1; + u.mh++; + } + } else if (u.uhp < u.uhpmax && + (wtcap < MOD_ENCUMBER || !u.umoved || Regeneration)) { + if (u.ulevel > 9 && !(moves % 3)) { + int heal, Con = (int) ACURR(A_CON); + + if (Con <= 12) { + heal = 1; + } else { + heal = rnd(Con); + if (heal > u.ulevel-9) heal = u.ulevel-9; + } + flags.botl = 1; + u.uhp += heal; + if(u.uhp > u.uhpmax) + u.uhp = u.uhpmax; + } else if (Regeneration || + (u.ulevel <= 9 && + !(moves % ((MAXULEV+12) / (u.ulevel+2) + 1)))) { + flags.botl = 1; + u.uhp++; + } + } + + /* moving around while encumbered is hard work */ + if (wtcap > MOD_ENCUMBER && u.umoved) { + if(!(wtcap < EXT_ENCUMBER ? moves%30 : moves%10)) { + if (Upolyd && u.mh > 1) { + u.mh--; + } else if (!Upolyd && u.uhp > 1) { + u.uhp--; + } else { + You("pass out from exertion!"); + exercise(A_CON, FALSE); + fall_asleep(-10, FALSE); + } + } + } + + if ((u.uen < u.uenmax) && + ((wtcap < MOD_ENCUMBER && + (!(moves%((MAXULEV + 8 - u.ulevel) * + (Role_if(PM_WIZARD) ? 3 : 4) / 6)))) + || Energy_regeneration)) { + u.uen += rn1((int)(ACURR(A_WIS) + ACURR(A_INT)) / 15 + 1,1); + if (u.uen > u.uenmax) u.uen = u.uenmax; + flags.botl = 1; + } + + if(!u.uinvulnerable) { + if(Teleportation && !rn2(85)) { +#ifdef REDO + xchar old_ux = u.ux, old_uy = u.uy; +#endif + tele(); +#ifdef REDO + if (u.ux != old_ux || u.uy != old_uy) { + /* clear doagain keystrokes */ + pushch(0); + savech(0); + } +#endif + } + if(Polymorph && !rn2(100)) + change = 1; + else if (u.ulycn >= LOW_PM && !rn2(80 - (20 * night()))) + change = 2; + if (change && !Unchanging) { + if (multi >= 0) { + if (occupation) + stop_occupation(); + else + nomul(0); + if (change == 1) polyself(); + else you_were(); + change = 0; + } + } + } + + if(Searching && multi >= 0) (void) dosearch0(1); + dosounds(); + do_storms(); + gethungry(); + age_spells(); + exerchk(); + invault(); + if (u.uhave.amulet) amulet(); + if (!rn2(40+(int)(ACURR(A_DEX)*3))) + u_wipe_engr(rnd(3)); + if (u.uevent.udemigod && !u.uinvulnerable) { + if (u.udg_cnt) u.udg_cnt--; + if (!u.udg_cnt) { + intervene(); + u.udg_cnt = rn1(200, 50); + } + } + restore_attrib(); + /* underwater and waterlevel vision are done here */ + if (Is_waterlevel(&u.uz)) + movebubbles(); + else if (Underwater) + under_water(0); + /* vision while buried done here */ + else if (u.uburied) under_ground(0); + + /* when immobile, count is in turns */ + if(multi < 0) { + if (++multi == 0) /* finished yet? */ + unmul((char *)0); + } + } + } while (youmonst.movement= 0 && occupation) { +#ifdef MICRO + abort_lev = 0; + if (kbhit()) { + if ((ch = Getchar()) == ABORT) + abort_lev++; +# ifdef REDO + else + pushch(ch); +# endif /* REDO */ + } + if (!abort_lev && (*occupation)() == 0) +#else + if ((*occupation)() == 0) +#endif + occupation = 0; + if( +#ifdef MICRO + abort_lev || +#endif + monster_nearby()) { + stop_occupation(); + reset_eat(); + } +#ifdef MICRO + if (!(++occtime % 7)) + display_nhwindow(WIN_MAP, FALSE); +#endif + continue; + } + + if ((u.uhave.amulet || Clairvoyant) && + !In_endgame(&u.uz) && !BClairvoyant && + !(moves % 15) && !rn2(2)) + do_vicinity_map(); + + if(u.utrap && u.utraptype == TT_LAVA) { + if(!is_lava(u.ux,u.uy)) + u.utrap = 0; + else if (!u.uinvulnerable) { + u.utrap -= 1<<8; + if(u.utrap < 1<<8) { + killer_format = KILLED_BY; + killer = "molten lava"; + You("sink below the surface and die."); + done(DISSOLVED); + } else if(didmove && !u.umoved) { + Norep("You sink deeper into the lava."); + u.utrap += rnd(4); + } + } + } + +#ifdef WIZARD + if (iflags.sanity_check) + sanity_check(); +#endif + + u.umoved = FALSE; + + if (multi > 0) { + lookaround(); + if (!multi) { + /* lookaround may clear multi */ + flags.move = 0; + if (flags.time) flags.botl = 1; + continue; + } + if (flags.mv) { + if(multi < COLNO && !--multi) + flags.travel = flags.mv = flags.run = 0; + domove(); + } else { + --multi; + rhack(save_cm); + } + } else if (multi == 0) { +#ifdef MAIL + ckmailstatus(); +#endif + rhack((char *)0); + } + if (u.utotype) /* change dungeon level */ + deferred_goto(); /* after rhack() */ + /* !flags.move here: multiple movement command stopped */ + else if (flags.time && (!flags.move || !flags.mv)) + flags.botl = 1; + + if (vision_full_recalc) vision_recalc(0); /* vision! */ + if (multi && multi%7 == 0) + display_nhwindow(WIN_MAP, FALSE); + } +} + +#endif /* OVL0 */ +#ifdef OVL1 + +void +stop_occupation() +{ + if(occupation) { + You("stop %s.", occtxt); + occupation = 0; + flags.botl = 1; /* in case u.uhs changed */ +/* fainting stops your occupation, there's no reason to sync. + sync_hunger(); +*/ +#ifdef REDO + nomul(0); + pushch(0); +#endif + } +} + +#endif /* OVL1 */ +#ifdef OVLB + +void +display_gamewindows() +{ + WIN_MESSAGE = create_nhwindow(NHW_MESSAGE); + WIN_STATUS = create_nhwindow(NHW_STATUS); + WIN_MAP = create_nhwindow(NHW_MAP); + WIN_INVEN = create_nhwindow(NHW_MENU); + +#ifdef MAC + /* + * This _is_ the right place for this - maybe we will + * have to split display_gamewindows into create_gamewindows + * and show_gamewindows to get rid of this ifdef... + */ + if ( ! strcmp ( windowprocs . name , "mac" ) ) { + SanePositions ( ) ; + } +#endif + + /* + * The mac port is not DEPENDENT on the order of these + * displays, but it looks a lot better this way... + */ + display_nhwindow(WIN_STATUS, FALSE); + display_nhwindow(WIN_MESSAGE, FALSE); + clear_glyph_buffer(); + display_nhwindow(WIN_MAP, FALSE); +} + +void +newgame() +{ + int i; + +#ifdef MFLOPPY + gameDiskPrompt(); +#endif + + flags.ident = 1; + + for (i = 0; i < NUMMONS; i++) + mvitals[i].mvflags = mons[i].geno & G_NOCORPSE; + + init_objects(); /* must be before u_init() */ + + flags.pantheon = -1; /* role_init() will reset this */ + role_init(); /* must be before init_dungeons(), u_init(), + * and init_artifacts() */ + + init_dungeons(); /* must be before u_init() to avoid rndmonst() + * creating odd monsters for initial tins and + * eggs */ + u_init(); + init_artifacts(); + +#ifndef NO_SIGNAL + (void) signal(SIGINT, (SIG_RET_TYPE) done1); +#endif +#ifdef NEWS + if(iflags.news) display_file(NEWS, FALSE); +#endif + load_qtlist(); /* load up the quest text info */ +/* quest_init();*/ /* Now part of role_init() */ + + mklev(); + u_on_upstairs(); + vision_reset(); /* set up internals for level (after mklev) */ + check_special_room(FALSE); + + flags.botlx = 1; + + /* Move the monster from under you or else + * makedog() will fail when it calls makemon(). + * - ucsfcgl!kneller + */ + if(MON_AT(u.ux, u.uy)) mnexto(m_at(u.ux, u.uy)); + (void) makedog(); + docrt(); + + if (flags.legacy) { + flush_screen(1); + com_pager(1); + } + +#ifdef INSURANCE + save_currentstate(); +#endif + program_state.something_worth_saving++; /* useful data now exists */ + + /* Success! */ + welcome(TRUE); + return; +} + +/* show "welcome [back] to nethack" message at program startup */ +void +welcome(new_game) +boolean new_game; /* false => restoring an old game */ +{ + char buf[BUFSZ]; + boolean currentgend = Upolyd ? u.mfemale : flags.female; + + /* + * The "welcome back" message always describes your innate form + * even when polymorphed or wearing a helm of opposite alignment. + * Alignment is shown unconditionally for new games; for restores + * it's only shown if it has changed from its original value. + * Sex is shown for new games except when it is redundant; for + * restores it's only shown if different from its original value. + */ + *buf = '\0'; + if (new_game || u.ualignbase[A_ORIGINAL] != u.ualignbase[A_CURRENT]) + Sprintf(eos(buf), " %s", align_str(u.ualignbase[A_ORIGINAL])); + if (!urole.name.f && + (new_game ? (urole.allow & ROLE_GENDMASK) == (ROLE_MALE|ROLE_FEMALE) : + currentgend != flags.initgend)) + Sprintf(eos(buf), " %s", genders[currentgend].adj); + + pline(new_game ? "%s %s, welcome to NetHack! You are a%s %s %s." + : "%s %s, the%s %s %s, welcome back to NetHack!", + Hello((struct monst *) 0), plname, buf, urace.adj, + (currentgend && urole.name.f) ? urole.name.f : urole.name.m); +} + +#ifdef POSITIONBAR +STATIC_DCL void +do_positionbar() +{ + static char pbar[COLNO]; + char *p; + + p = pbar; + /* up stairway */ + if (upstair.sx && + (glyph_to_cmap(level.locations[upstair.sx][upstair.sy].glyph) == + S_upstair || + glyph_to_cmap(level.locations[upstair.sx][upstair.sy].glyph) == + S_upladder)) { + *p++ = '<'; + *p++ = upstair.sx; + } + if (sstairs.sx && + (glyph_to_cmap(level.locations[sstairs.sx][sstairs.sy].glyph) == + S_upstair || + glyph_to_cmap(level.locations[sstairs.sx][sstairs.sy].glyph) == + S_upladder)) { + *p++ = '<'; + *p++ = sstairs.sx; + } + + /* down stairway */ + if (dnstair.sx && + (glyph_to_cmap(level.locations[dnstair.sx][dnstair.sy].glyph) == + S_dnstair || + glyph_to_cmap(level.locations[dnstair.sx][dnstair.sy].glyph) == + S_dnladder)) { + *p++ = '>'; + *p++ = dnstair.sx; + } + if (sstairs.sx && + (glyph_to_cmap(level.locations[sstairs.sx][sstairs.sy].glyph) == + S_dnstair || + glyph_to_cmap(level.locations[sstairs.sx][sstairs.sy].glyph) == + S_dnladder)) { + *p++ = '>'; + *p++ = sstairs.sx; + } + + /* hero location */ + if (u.ux) { + *p++ = '@'; + *p++ = u.ux; + } + /* fence post */ + *p = 0; + + update_positionbar(pbar); +} +#endif + +#endif /* OVLB */ + +/*allmain.c*/