1 /* NetHack 3.6 allmain.c $NHDT-Date: 1446975459 2015/11/08 09:37:39 $ $NHDT-Branch: master $:$NHDT-Revision: 1.66 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
10 /* various code that was replicated in *main.c */
19 STATIC_DCL void NDECL(do_positionbar);
26 #if defined(MICRO) || defined(WIN32)
30 int moveamt = 0, wtcap = 0, change = 0;
31 boolean monscanmove = FALSE;
33 /* Note: these initializers don't do anything except guarantee that
34 we're linked properly.
38 monstr_init(); /* monster strengths */
42 add_debug_extended_commands();
44 /* if a save file created in normal mode is now being restored in
45 explore mode, treat it as normal restore followed by 'X' command
46 to use up the save file and require confirmation for explore mode */
47 if (resuming && iflags.deferred_X)
48 (void) enter_explore_mode();
50 /* side-effects from the real world */
51 flags.moonphase = phase_of_the_moon();
52 if (flags.moonphase == FULL_MOON) {
54 You("are lucky! Full moon tonight.");
56 pline("
\83\89\83b
\83L
\81[
\81I
\8d¡
\94Ó
\82Í
\96\9e\8c\8e\82¾
\81D");
58 } else if (flags.moonphase == NEW_MOON) {
60 pline("Be careful! New moon tonight.");
62 pline("
\92\8d\88Ó
\82µ
\82ë
\81I
\8d¡
\94Ó
\82Í
\90V
\8c\8e\82¾
\81D");
64 flags.friday13 = friday_13th();
67 pline("Watch out! Bad things can happen on Friday the 13th.");
69 pline("
\97p
\90S
\82µ
\82ë
\81I
\82P
\82R
\93ú
\82Ì
\8bà
\97j
\93ú
\82É
\82Í
\82æ
\82
\82È
\82¢
\82±
\82Æ
\82ª
\82 \82é
\81D") ;
73 if (!resuming) { /* new game */
74 context.rndencode = rnd(9000);
75 set_wear((struct obj *) 0); /* for side-effects of starting gear */
76 (void) pickup(1); /* autopickup at initial location */
77 } else { /* restore old game */
79 update_inventory(); /* for perm_invent */
81 read_engr_at(u.ux, u.uy); /* subset of pickup() */
84 update_inventory(); /* for perm_invent */
87 (void) encumber_msg(); /* in case they auto-picked up something */
88 if (defer_see_monsters) {
89 defer_see_monsters = FALSE;
94 u.uz0.dlevel = u.uz.dlevel;
95 youmonst.movement = NORMAL_SPEED; /* give the hero some movement points */
98 program_state.in_moveloop = 1;
101 if (program_state.done_hup)
110 /* actual time passed */
111 youmonst.movement -= NORMAL_SPEED;
113 do { /* hero can't move this turn loop */
114 wtcap = encumber_msg();
116 context.mon_moving = TRUE;
118 monscanmove = movemon();
119 if (youmonst.movement >= NORMAL_SPEED)
120 break; /* it's now your turn */
121 } while (monscanmove);
122 context.mon_moving = FALSE;
124 if (!monscanmove && youmonst.movement < NORMAL_SPEED) {
125 /* both you and the monsters are out of steam this round
127 /* set up for a new turn */
129 mcalcdistress(); /* adjust monsters' trap, blind, etc */
131 /* reallocate movement rations to monsters */
132 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
133 mtmp->movement += mcalcmove(mtmp);
135 if (!rn2(u.uevent.udemigod
137 : (depth(&u.uz) > depth(&stronghold_level))
140 (void) makemon((struct permonst *) 0, 0, 0,
143 /* calculate how much time passed. */
144 if (u.usteed && u.umoved) {
145 /* your speed doesn't augment steed's speed */
146 moveamt = mcalcmove(u.usteed);
148 moveamt = youmonst.data->mmove;
150 if (Very_fast) { /* speed boots or potion */
151 /* average movement is 1.67 times normal */
152 moveamt += NORMAL_SPEED / 2;
154 moveamt += NORMAL_SPEED / 2;
156 /* average movement is 1.33 times normal */
158 moveamt += NORMAL_SPEED / 2;
166 moveamt -= (moveamt / 4);
169 moveamt -= (moveamt / 2);
172 moveamt -= ((moveamt * 3) / 4);
175 moveamt -= ((moveamt * 7) / 8);
181 youmonst.movement += moveamt;
182 if (youmonst.movement < 0)
183 youmonst.movement = 0;
189 /********************************/
190 /* once-per-turn things go here */
191 /********************************/
200 if (flags.time && !context.run)
203 /* One possible result of prayer is healing. Whether or
204 * not you get healed depends on your current hit points.
205 * If you are allowed to regenerate during the prayer, the
206 * end-of-prayer calculation messes up on this.
207 * Another possible result is rehumanization, which
209 * that encumbrance and movement rate be recalculated.
211 if (u.uinvulnerable) {
212 /* for the moment at least, you're in tiptop shape */
213 wtcap = UNENCUMBERED;
214 } else if (Upolyd && youmonst.data->mlet == S_EEL
215 && !is_pool(u.ux, u.uy)
216 && !Is_waterlevel(&u.uz)) {
217 /* eel out of water loses hp, same as for monsters;
218 as hp gets lower, rate of further loss slows down
220 if (u.mh > 1 && rn2(u.mh) > rn2(8)
221 && (!Half_physical_damage || !(moves % 2L))) {
226 } else if (Upolyd && u.mh < u.mhmax) {
229 else if (Regeneration
230 || (wtcap < MOD_ENCUMBER && !(moves % 20))) {
234 } else if (u.uhp < u.uhpmax
235 && (wtcap < MOD_ENCUMBER || !u.umoved
237 if (u.ulevel > 9 && !(moves % 3)) {
238 int heal, Con = (int) ACURR(A_CON);
244 if (heal > u.ulevel - 9)
249 if (u.uhp > u.uhpmax)
251 } else if (Regeneration
254 % ((MAXULEV + 12) / (u.ulevel + 2)
261 /* moving around while encumbered is hard work */
262 if (wtcap > MOD_ENCUMBER && u.umoved) {
263 if (!(wtcap < EXT_ENCUMBER ? moves % 30
265 if (Upolyd && u.mh > 1) {
267 } else if (!Upolyd && u.uhp > 1) {
271 You("pass out from exertion!");
273 pline("
\94æ
\98J
\82Å
\88Ó
\8e¯
\82ð
\8e¸
\82Á
\82½
\81I");
274 exercise(A_CON, FALSE);
275 fall_asleep(-10, FALSE);
280 if ((u.uen < u.uenmax)
281 && ((wtcap < MOD_ENCUMBER
282 && (!(moves % ((MAXULEV + 8 - u.ulevel)
283 * (Role_if(PM_WIZARD) ? 3 : 4)
284 / 6)))) || Energy_regeneration)) {
286 (int) (ACURR(A_WIS) + ACURR(A_INT)) / 15 + 1, 1);
287 if (u.uen > u.uenmax)
292 if (!u.uinvulnerable) {
293 if (Teleportation && !rn2(85)) {
294 xchar old_ux = u.ux, old_uy = u.uy;
296 if (u.ux != old_ux || u.uy != old_uy) {
298 check_leash(old_ux, old_uy);
300 /* clear doagain keystrokes */
305 /* delayed change may not be valid anymore */
306 if ((change == 1 && !Polymorph)
307 || (change == 2 && u.ulycn == NON_PM))
309 if (Polymorph && !rn2(100))
311 else if (u.ulycn >= LOW_PM && !Upolyd
312 && !rn2(80 - (20 * night())))
314 if (change && !Unchanging) {
329 if (Searching && multi >= 0)
339 if (!rn2(40 + (int) (ACURR(A_DEX) * 3)))
341 if (u.uevent.udemigod && !u.uinvulnerable) {
346 u.udg_cnt = rn1(200, 50);
350 /* underwater and waterlevel vision are done here */
351 if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz))
353 else if (Is_firelevel(&u.uz))
357 /* vision while buried done here */
361 /* when immobile, count is in turns */
363 if (++multi == 0) { /* finished yet? */
365 /* if unmul caused a level change, take it now */
371 } while (youmonst.movement
372 < NORMAL_SPEED); /* hero can't move loop */
374 /******************************************/
375 /* once-per-hero-took-time things go here */
376 /******************************************/
378 if (context.bypasses)
380 if ((u.uhave.amulet || Clairvoyant) && !In_endgame(&u.uz)
381 && !BClairvoyant && !(moves % 15) && !rn2(2))
383 if (u.utrap && u.utraptype == TT_LAVA)
385 /* when/if hero escapes from lava, he can't just stay there */
387 (void) pooleffects(FALSE);
389 } /* actual time passed */
391 /****************************************/
392 /* once-per-player-input things go here */
393 /****************************************/
397 if (!context.mv || Blind) {
398 /* redo monsters if hallu or wearing a helm of telepathy */
399 if (Hallucination) { /* update screen randomly */
405 } else if (Unblind_telepat) {
407 } else if (Warning || Warn_of_mon)
410 if (vision_full_recalc)
411 vision_recalc(0); /* vision! */
413 if (context.botl || context.botlx) {
420 if (multi >= 0 && occupation) {
421 #if defined(MICRO) || defined(WIN32)
424 if ((ch = pgetchar()) == ABORT)
429 if (!abort_lev && (*occupation)() == 0)
431 if ((*occupation)() == 0)
435 #if defined(MICRO) || defined(WIN32)
442 #if defined(MICRO) || defined(WIN32)
443 if (!(++occtime % 7))
444 display_nhwindow(WIN_MAP, FALSE);
449 if (iflags.sanity_check)
453 /* just before rhack */
454 cliparound(u.ux, u.uy);
462 /* lookaround may clear multi */
469 if (multi < COLNO && !--multi)
470 context.travel = context.travel1 = context.mv =
477 } else if (multi == 0) {
483 if (u.utotype) /* change dungeon level */
484 deferred_goto(); /* after rhack() */
485 /* !context.move here: multiple movement command stopped */
486 else if (flags.time && (!context.move || !context.mv))
489 if (vision_full_recalc)
490 vision_recalc(0); /* vision! */
491 /* when running in non-tport mode, this gets done through domove() */
492 if ((!context.run || flags.runmode == RUN_TPORT)
493 && (multi && (!context.travel ? !(multi % 7) : !(moves % 7L)))) {
494 if (flags.time && context.run)
496 display_nhwindow(WIN_MAP, FALSE);
505 if (!maybe_finished_meal(TRUE))
507 You("stop %s.", occtxt);
509 You("%s
\82Ì
\82ð
\92\86\92f
\82µ
\82½
\81D", occtxt);
511 context.botl = 1; /* in case u.uhs changed */
518 display_gamewindows()
520 WIN_MESSAGE = create_nhwindow(NHW_MESSAGE);
521 #ifdef STATUS_VIA_WINDOWPORT
522 status_initialize(0);
524 WIN_STATUS = create_nhwindow(NHW_STATUS);
526 WIN_MAP = create_nhwindow(NHW_MAP);
527 WIN_INVEN = create_nhwindow(NHW_MENU);
530 /* This _is_ the right place for this - maybe we will
531 * have to split display_gamewindows into create_gamewindows
532 * and show_gamewindows to get rid of this ifdef...
534 if (!strcmp(windowprocs.name, "mac"))
539 * The mac port is not DEPENDENT on the order of these
540 * displays, but it looks a lot better this way...
542 #ifndef STATUS_VIA_WINDOWPORT
543 display_nhwindow(WIN_STATUS, FALSE);
545 display_nhwindow(WIN_MESSAGE, FALSE);
546 clear_glyph_buffer();
547 display_nhwindow(WIN_MAP, FALSE);
561 context.stethoscope_move = -1L;
562 context.warnlevel = 1;
563 context.next_attrib_check = 600L; /* arbitrary first setting */
564 context.tribute.enabled = TRUE; /* turn on 3.6 tributes */
565 context.tribute.tributesz = sizeof(struct tribute_info);
567 for (i = 0; i < NUMMONS; i++)
568 mvitals[i].mvflags = mons[i].geno & G_NOCORPSE;
570 init_objects(); /* must be before u_init() */
572 flags.pantheon = -1; /* role_init() will reset this */
573 role_init(); /* must be before init_dungeons(), u_init(),
574 * and init_artifacts() */
576 init_dungeons(); /* must be before u_init() to avoid rndmonst()
577 * creating odd monsters for any tins and eggs
578 * in hero's initial inventory */
579 init_artifacts(); /* before u_init() in case $WIZKIT specifies
584 (void) signal(SIGINT, (SIG_RET_TYPE) done1);
588 display_file(NEWS, FALSE);
590 load_qtlist(); /* load up the quest text info */
591 /* quest_init(); -- Now part of role_init() */
596 obj_delivery(FALSE); /* finish wizkit */
597 vision_reset(); /* set up internals for level (after mklev) */
598 check_special_room(FALSE);
600 if (MON_AT(u.ux, u.uy))
601 mnexto(m_at(u.ux, u.uy));
610 urealtime.realtime = 0L;
611 urealtime.start_timing = getnow();
615 program_state.something_worth_saving++; /* useful data now exists */
622 /* show "welcome [back] to nethack" message at program startup */
625 boolean new_game; /* false => restoring an old game */
628 boolean currentgend = Upolyd ? u.mfemale : flags.female;
631 * The "welcome back" message always describes your innate form
632 * even when polymorphed or wearing a helm of opposite alignment.
633 * Alignment is shown unconditionally for new games; for restores
634 * it's only shown if it has changed from its original value.
635 * Sex is shown for new games except when it is redundant; for
636 * restores it's only shown if different from its original value.
639 if (new_game || u.ualignbase[A_ORIGINAL] != u.ualignbase[A_CURRENT])
641 Sprintf(eos(buf), " %s", align_str(u.ualignbase[A_ORIGINAL]));
643 Sprintf(eos(buf), "%s", align_str(u.ualignbase[A_ORIGINAL]));
646 ? (urole.allow & ROLE_GENDMASK) == (ROLE_MALE | ROLE_FEMALE)
647 : currentgend != flags.initgend))
649 Sprintf(eos(buf), " %s", genders[currentgend].adj);
651 Sprintf(eos(buf), "
\82Ì%s", genders[currentgend].adj);
654 pline(new_game ? "%s %s, welcome to NetHack! You are a%s %s %s."
655 : "%s %s, the%s %s %s, welcome back to NetHack!",
656 Hello((struct monst *) 0), plname, buf, urace.adj,
657 (currentgend && urole.name.f) ? urole.name.f : urole.name.m);
660 pline("%s
\81CNetHack
\82Ì
\90¢
\8aE
\82Ö
\81I
\82±
\82Ì
\83Q
\81[
\83\80\82Å
\82Í
\82 \82È
\82½
\82Í%s%s(%s)
\82¾
\81D",
661 Hello((struct monst *) 0), urace.adj,
662 (currentgend && urole.name.f) ? urole.name.f : urole.name.m,
665 pline("%s
\81CNetHack
\82Ì
\90¢
\8aE
\82Ö
\81I
\82 \82È
\82½
\82Í%s%s
\82¾
\81I",
666 Hello((struct monst *) 0), urace.adj,
667 (currentgend && urole.name.f) ? urole.name.f : urole.name.m);
676 static char pbar[COLNO];
682 && (glyph_to_cmap(level.locations[upstair.sx][upstair.sy].glyph)
684 || glyph_to_cmap(level.locations[upstair.sx][upstair.sy].glyph)
690 && (glyph_to_cmap(level.locations[sstairs.sx][sstairs.sy].glyph)
692 || glyph_to_cmap(level.locations[sstairs.sx][sstairs.sy].glyph)
700 && (glyph_to_cmap(level.locations[dnstair.sx][dnstair.sy].glyph)
702 || glyph_to_cmap(level.locations[dnstair.sx][dnstair.sy].glyph)
708 && (glyph_to_cmap(level.locations[sstairs.sx][sstairs.sy].glyph)
710 || glyph_to_cmap(level.locations[sstairs.sx][sstairs.sy].glyph)
724 update_positionbar(pbar);