Ejemplo n.º 1
0
void rehumanize(void)
{
	/* You can't revert back while unchanging */
	if (Unchanging && (u.mh < 1)) {
		killer_format = NO_KILLER_PREFIX;
		killer = "killed while stuck in creature form";
		done(DIED);
	}

	if (emits_light(youmonst.data))
	    del_light_source(level, LS_MONSTER, &youmonst);
	polyman("You return to %s form!", urace.adj);

	if (u.uhp < 1) {
	    char kbuf[256];

	    sprintf(kbuf, "reverting to unhealthy %s form", urace.adj);
	    killer_format = KILLED_BY;
	    killer = kbuf;
	    done(DIED);
	}
	if (!uarmg) selftouch("No longer petrify-resistant, you");
	nomul(0, NULL);

	iflags.botl = 1;
	vision_full_recalc = 1;
	encumber_msg();
}
Ejemplo n.º 2
0
void
exercise(int i, boolean inc_or_dec)
{
    if (i == A_INT || i == A_CHA)
        return; /* can't exercise these */

    /* no physical exercise while polymorphed; the body's temporary */
    if (Upolyd && i != A_WIS)
        return;

    if (abs(AEXE(i)) < AVAL) {
        /*
         *      Law of diminishing returns (Part I):
         *
         *      Gain is harder at higher attribute values.
         *      79% at "3" --> 0% at "18"
         *      Loss is even at all levels (50%).
         *
         *      Note: *YES* ACURR is the right one to use.
         */
        AEXE(i) += (inc_or_dec) ? (rn2(19) > ACURR(i)) : -rn2(2);
    }
    if (moves > 0 && (i == A_STR || i == A_CON))
        encumber_msg();
}
Ejemplo n.º 3
0
static void post_init_tasks(void)
{
    encumber_msg(); /* in case they auto-picked up something */

    u.uz0.dlevel = u.uz.dlevel;

    prev_hp_notify = uhp();

    /* prepare for the first move */
    pre_move_tasks(FALSE);
}
Ejemplo n.º 4
0
/* adjust an attribute; return true if change is made, false otherwise */
//       int     msgflg;     /* positive => no message, zero => message, and */
//                           /* negative => conditional (msg if change made) */
bool adjattrib(int ndx, int incr, int msgflg) {
    if (Fixed_abil || !incr) return false;

    if ((ndx == A_INT || ndx == A_WIS)
            && uarmh && uarmh->otyp == DUNCE_CAP) {
        if (msgflg == 0)
            Your("cap constricts briefly, then relaxes again.");
        return false;
    }

    if (incr > 0) {
        if ((AMAX(ndx) >= ATTRMAX(ndx)) && (ACURR(ndx) >= AMAX(ndx))) {
            if (msgflg == 0 && flags.verbose)
                pline("You're already as %s as you can get.",
                        plusattr[ndx]);
            ABASE(ndx) = AMAX(ndx) = ATTRMAX(ndx); /* just in case */
            return false;
        }

        ABASE(ndx) += incr;
        if(ABASE(ndx) > AMAX(ndx)) {
            incr = ABASE(ndx) - AMAX(ndx);
            AMAX(ndx) += incr;
            if(AMAX(ndx) > ATTRMAX(ndx))
                AMAX(ndx) = ATTRMAX(ndx);
            ABASE(ndx) = AMAX(ndx);
        }
    } else {
        if (ABASE(ndx) <= ATTRMIN(ndx)) {
            if (msgflg == 0 && flags.verbose)
                pline("You're already as %s as you can get.",
                        minusattr[ndx]);
            ABASE(ndx) = ATTRMIN(ndx); /* just in case */
            return false;
        }

        ABASE(ndx) += incr;
        if(ABASE(ndx) < ATTRMIN(ndx)) {
            incr = ABASE(ndx) - ATTRMIN(ndx);
            ABASE(ndx) = ATTRMIN(ndx);
            AMAX(ndx) += incr;
            if(AMAX(ndx) < ATTRMIN(ndx))
                AMAX(ndx) = ATTRMIN(ndx);
        }
    }
    if (msgflg <= 0)
        You_feel("%s%s!",
                (incr > 1 || incr < -1) ? "very ": "",
                (incr > 0) ? plusattr[ndx] : minusattr[ndx]);
    if (moves > 1 && (ndx == A_STR || ndx == A_CON))
        (void)encumber_msg();
    return true;
}
Ejemplo n.º 5
0
void redist_attr (void) {
    int i, tmp;

    for(i = 0; i < A_MAX; i++) {
        if (i==A_INT || i==A_WIS) continue;
        /* Polymorphing doesn't change your mind */
        tmp = AMAX(i);
        AMAX(i) += (rn2(5)-2);
        if (AMAX(i) > ATTRMAX(i)) AMAX(i) = ATTRMAX(i);
        if (AMAX(i) < ATTRMIN(i)) AMAX(i) = ATTRMIN(i);
        ABASE(i) = ABASE(i) * AMAX(i) / tmp;
        /* ABASE(i) > ATTRMAX(i) is impossible */
        if (ABASE(i) < ATTRMIN(i)) ABASE(i) = ATTRMIN(i);
    }
    (void)encumber_msg();
}
Ejemplo n.º 6
0
void restore_attrib (void) {
    int     i;

    for(i = 0; i < A_MAX; i++) {    /* all temporary losses/gains */

        if(ATEMP(i) && ATIME(i)) {
            if(!(--(ATIME(i)))) { /* countdown for change */
                ATEMP(i) += ATEMP(i) > 0 ? -1 : 1;

                if(ATEMP(i)) /* reset timer */
                    ATIME(i) = 100 / ACURR(A_CON);
            }
        }
    }
    (void)encumber_msg();
}
Ejemplo n.º 7
0
void rehumanize (void) {
    /* You can't revert back while unchanging */
    if (Unchanging && (u.mh < 1)) {
        killer = killed_by_const(KM_WHILE_STUCK_IN_CREATURE_FORM);
        done(DIED);
    }

    if (emits_light(youmonst.data))
        del_light_source(LS_MONSTER, (void *)&youmonst);
    polyman("return to %s form!", urace.adj);

    if (u.uhp < 1) {
        char kbuf[256];

        sprintf(kbuf, "reverting to unhealthy %s form", urace.adj);
        fprintf(stderr, "TODO killer = %s\n", kbuf);
        done(DIED);
    }
    if (!uarmg) selftouch("No longer petrify-resistant, you");
    nomul(0);

    vision_full_recalc = 1;
    (void) encumber_msg();
}
Ejemplo n.º 8
0
void
moveloop()
{
#if defined(MICRO) || defined(WIN32)
    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();

    commands_init();

    (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(;;) {
	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)
		    {
		        curmonst = &youmonst;
			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 && u.umoved) {
			/* 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) &&
			       !(u.uswallow &&
			         u.ustuck->data == &mons[PM_WATER_ELEMENTAL])) {
			if (u.mh > 1) {
			    u.mh--;
			    flags.botl = 1;
			} else if (u.mh < 1)
			    killer_format = KILLED_BY_AN,
			    rehumanize("inability to breathe air");
		    } else if (Upolyd && u.mh < u.mhmax) {
			if (u.mh < 1)
			    rehumanize(0);
			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)) {
			    xchar old_ux = u.ux, old_uy = u.uy;
			    tele();
			    if (u.ux != old_ux || u.uy != old_uy) {
				if (!next_to_u()) {
				    check_leash(old_ux, old_uy);
				}
#ifdef REDO
				/* clear doagain keystrokes */
				pushch(0);
				savech(0);
#endif
			    }
			}
			/* delayed change may not be valid anymore */
			if ((change == 1 && !Polymorph) ||
			    (change == 2 && u.ulycn == NON_PM))
			    change = 0;
			if(Polymorph && !rn2(100))
			    change = 1;
			else if (u.ulycn >= LOW_PM && !Upolyd &&
				 !rn2(80 - (20 * night())))
			    change = 2;
			if (change && !Unchanging) {
			    if (multi >= 0) {
				if (occupation)
				    stop_occupation();
				else
				    nomul(0);
				if (change == 1) polyself(FALSE);
				else you_were();
				change = 0;
			    }
			}
	
			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);
				}
			    }
			}
		    }

		    if(Searching && multi >= 0) (void) dosearch0(1);
		    dosounds();
		    /* hack - make sure damage from storms is not blamed
		       on the player */
		    flags.mon_moving = TRUE;
		    do_storms();
		    flags.mon_moving = FALSE;
		    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);
			    /* if unmul caused a level change, take it now */
			    if (u.utotype) deferred_goto();
			}
		    }
		}
	    } while (youmonst.movement<NORMAL_SPEED); /* hero can't move loop */

	    /******************************************/
	    /* once-per-hero-took-time things go here */
	    /******************************************/
            curmonst = &youmonst;

	} /* actual time passed */

	/****************************************/
	/* once-per-player-input things go here */
	/****************************************/

	find_ac();
	if(!flags.mv || Blind) {
	    /* redo monsters if hallu or wearing a helm of telepathy */
	    if (HHallucination &&
	       !Halluc_resistance) {	/* update screen randomly */
	    /*
		see_monsters();
		see_objects();
		see_traps();
		if (u.uswallow) swallowed(0);
	    */
                if (u.uswallow) {
            	    swallowed(1);
                } else if (Underwater && !Is_waterlevel(&u.uz)) {
            	    under_water(1);
                } else if (u.uburied) {
            	    under_ground(1);
                } else {
		    register int x, y;
		    register struct rm *lev;

                    vision_recalc(2);

                    /*clear_nhwindow(WIN_MAP);*/
                    clear_glyph_buffer();
                
                    for (x = 1; x < COLNO; x++) {
                	lev = &levl[x][0];
                	for (y = 0; y < ROWNO; y++, lev++)
                	    if (lev->glyph != cmap_to_glyph(S_stone))
                		show_glyph(x,y,lev->glyph);
                    }
                
                    vision_recalc(0);
                
                    see_monsters();
    		}
	    } else if (Unblind_telepat) {
		see_monsters();
	    } else if (Warning || Warn_of_mon)
	     	see_monsters();

	    if (vision_full_recalc) vision_recalc(0);	/* vision! */
	}

#ifdef REALTIME_ON_BOTL
        if(iflags.showrealtime) {
            /* Update the bottom line if the number of minutes has
             * changed */
            if(get_realtime() / 60 != realtime_data.last_displayed_time / 60)
                flags.botl = 1;
        }
#endif
  
	if(flags.botl || flags.botlx) bot();

	flags.move = 1;

	if(multi >= 0 && occupation) {
#if defined(MICRO) || defined(WIN32)
	    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(
#if defined(MICRO) || defined(WIN32)
		   abort_lev ||
#endif
		   monster_nearby()) {
		stop_occupation();
		reset_eat();
	    }
#if defined(MICRO) || defined(WIN32)
	    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();


#ifdef WIZARD
	if (iflags.sanity_check)
	    sanity_check();
#endif

#ifdef CLIPPING
	/* just before rhack */
	cliparound(u.ux, u.uy);
#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 = iflags.travel1 = 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! */
	/* when running in non-tport mode, this gets done through domove() */
	if ((!flags.run || iflags.runmode == RUN_TPORT) &&
		(multi && (!flags.travel ? !(multi % 7) : !(moves % 7L)))) {
	    if (flags.time && flags.run) flags.botl = 1;
	    display_nhwindow(WIN_MAP, FALSE);
	}
    }
}
Ejemplo n.º 9
0
/* returns 1 if polymorph successful */
int polymon(int mntmp)
{
	boolean sticky = sticks(youmonst.data) && u.ustuck && !u.uswallow,
		was_blind = !!Blind, dochange = FALSE;
	boolean could_pass_walls = Passes_walls;
	int mlvl;

	if (mvitals[mntmp].mvflags & G_GENOD) {	/* allow G_EXTINCT */
		pline("You feel rather %s-ish.",mons[mntmp].mname);
		exercise(A_WIS, TRUE);
		return 0;
	}

	/* KMH, conduct */
	u.uconduct.polyselfs++;

	if (!Upolyd) {
		/* Human to monster; save human stats */
		u.macurr = u.acurr;
		u.mamax = u.amax;
		u.mfemale = flags.female;
	} else {
		/* Monster to monster; restore human stats, to be
		 * immediately changed to provide stats for the new monster
		 */
		u.acurr = u.macurr;
		u.amax = u.mamax;
		flags.female = u.mfemale;
	}

	if (youmonst.m_ap_type) {
	    /* stop mimicking immediately */
	    if (multi < 0) unmul("");
	} else if (mons[mntmp].mlet != S_MIMIC) {
	    /* as in polyman() */
	    youmonst.m_ap_type = M_AP_NOTHING;
	}
	if (is_male(&mons[mntmp])) {
		if (flags.female) dochange = TRUE;
	} else if (is_female(&mons[mntmp])) {
		if (!flags.female) dochange = TRUE;
	} else if (!is_neuter(&mons[mntmp]) && mntmp != u.ulycn) {
		if (!rn2(10)) dochange = TRUE;
	}
	if (dochange) {
		flags.female = !flags.female;
		pline("You %s %s%s!",
		    (u.umonnum != mntmp) ? "turn into a" : "feel like a new",
		    (is_male(&mons[mntmp]) || is_female(&mons[mntmp])) ? "" :
			flags.female ? "female " : "male ",
		    mons[mntmp].mname);
	} else {
		if (u.umonnum != mntmp)
			pline("You turn into %s!", an(mons[mntmp].mname));
		else
			pline("You feel like a new %s!", mons[mntmp].mname);
	}
	if (Stoned && poly_when_stoned(&mons[mntmp])) {
		/* poly_when_stoned already checked stone golem genocide */
		pline("You turn to stone!");
		mntmp = PM_STONE_GOLEM;
		Stoned = 0;
		delayed_killer = 0;
	}

	u.mtimedone = rn1(500, 500);
	u.umonnum = mntmp;
	set_uasmon();

	/* New stats for monster, to last only as long as polymorphed.
	 * Currently only strength gets changed.
	 */
	if (strongmonst(&mons[mntmp])) ABASE(A_STR) = AMAX(A_STR) = STR18(100);

	if (Stone_resistance && Stoned) { /* [email protected] */
		Stoned = 0;
		delayed_killer = 0;
		pline("You no longer seem to be petrifying.");
	}
	if (Sick_resistance && Sick) {
		make_sick(0L, NULL, FALSE, SICK_ALL);
		pline("You no longer feel sick.");
	}
	if (Slimed) {
	    if (flaming(youmonst.data)) {
		pline("The slime burns away!");
		Slimed = 0L;
		iflags.botl = 1;
	    } else if (mntmp == PM_GREEN_SLIME) {
		/* do it silently */
		Slimed = 0L;
		iflags.botl = 1;
	    }
	}
	if (nohands(youmonst.data)) Glib = 0;

	/*
	mlvl = adj_lev(&mons[mntmp]);
	 * We can't do the above, since there's no such thing as an
	 * "experience level of you as a monster" for a polymorphed character.
	 */
	mlvl = (int)mons[mntmp].mlevel;
	if (youmonst.data->mlet == S_DRAGON && mntmp >= PM_GRAY_DRAGON) {
		u.mhmax = In_endgame(&u.uz) ? (8*mlvl) : (4*mlvl + dice(mlvl,4));
	} else if (is_golem(youmonst.data)) {
		u.mhmax = golemhp(mntmp);
	} else {
		if (!mlvl) u.mhmax = rnd(4);
		else u.mhmax = dice(mlvl, 8);
		if (is_home_elemental(&u.uz, &mons[mntmp])) u.mhmax *= 3;
	}
	u.mh = u.mhmax;

	if (u.ulevel < mlvl) {
	/* Low level characters can't become high level monsters for long */
		u.mtimedone = u.mtimedone * u.ulevel / mlvl;
	}

	if (uskin && mntmp != armor_to_dragon(uskin->otyp))
		skinback(FALSE);
	break_armor();
	drop_weapon(1);
	if (hides_under(youmonst.data))
		u.uundetected = OBJ_AT(u.ux, u.uy);
	else if (youmonst.data->mlet == S_EEL)
		u.uundetected = is_pool(level, u.ux, u.uy);
	else
		u.uundetected = 0;

	if (u.utraptype == TT_PIT) {
	    if (could_pass_walls && !Passes_walls) {
		u.utrap = rn1(6,2);
	    } else if (!could_pass_walls && Passes_walls) {
		u.utrap = 0;
	    }
	}
	if (was_blind && !Blind) {	/* previous form was eyeless */
	    Blinded = 1L;
	    make_blinded(0L, TRUE);	/* remove blindness */
	}
	newsym(u.ux,u.uy);		/* Change symbol */

	if (!sticky && !u.uswallow && u.ustuck && sticks(youmonst.data)) u.ustuck = 0;
	else if (sticky && !sticks(youmonst.data)) uunstick();
	if (u.usteed) {
	    if (touch_petrifies(u.usteed->data) &&
	    		!Stone_resistance && rnl(3)) {
	    	char buf[BUFSZ];

	    	pline("No longer petrifying-resistant, you touch %s.",
	    			mon_nam(u.usteed));
	    	sprintf(buf, "riding %s", an(u.usteed->data->mname));
	    	instapetrify(buf);
 	    }
	    if (!can_ride(u.usteed)) dismount_steed(DISMOUNT_POLY);
	}

	if (flags.verbose) {
	    static const char use_thec[] = "Use the command #%s to %s.";
	    static const char monsterc[] = "monster";
	    if (can_breathe(youmonst.data))
		pline(use_thec,monsterc,"use your breath weapon");
	    if (attacktype(youmonst.data, AT_SPIT))
		pline(use_thec,monsterc,"spit venom");
	    if (youmonst.data->mlet == S_NYMPH)
		pline(use_thec,monsterc,"remove an iron ball");
	    if (attacktype(youmonst.data, AT_GAZE))
		pline(use_thec,monsterc,"gaze at monsters");
	    if (is_hider(youmonst.data))
		pline(use_thec,monsterc,"hide");
	    if (is_were(youmonst.data))
		pline(use_thec,monsterc,"summon help");
	    if (webmaker(youmonst.data))
		pline(use_thec,monsterc,"spin a web");
	    if (u.umonnum == PM_GREMLIN)
		pline(use_thec,monsterc,"multiply in a fountain");
	    if (is_unicorn(youmonst.data))
		pline(use_thec,monsterc,"use your horn");
	    if (is_mind_flayer(youmonst.data))
		pline(use_thec,monsterc,"emit a mental blast");
	    if (youmonst.data->msound == MS_SHRIEK) /* worthless, actually */
		pline(use_thec,monsterc,"shriek");
	    if (lays_eggs(youmonst.data) && flags.female)
		pline(use_thec,"sit","lay an egg");
	}
	/* you now know what an egg of your type looks like */
	if (lays_eggs(youmonst.data)) {
	    learn_egg_type(u.umonnum);
	    /* make queen bees recognize killer bee eggs */
	    learn_egg_type(egg_type_from_parent(u.umonnum, TRUE));
	}
	find_ac();
	if ((!Levitation && !u.ustuck && !Flying &&
	    (is_pool(level, u.ux,u.uy) || is_lava(level, u.ux,u.uy))) ||
	   (Underwater && !Swimming))
	    spoteffects(TRUE);
	if (Passes_walls && u.utrap && u.utraptype == TT_INFLOOR) {
	    u.utrap = 0;
	    pline("The rock seems to no longer trap you.");
	} else if (likes_lava(youmonst.data) && u.utrap && u.utraptype == TT_LAVA) {
	    u.utrap = 0;
	    pline("The lava now feels soothing.");
	}
	if (amorphous(youmonst.data) || is_whirly(youmonst.data) || unsolid(youmonst.data)) {
	    if (Punished) {
		pline("You slip out of the iron chain.");
		unpunish();
	    }
	}
	if (u.utrap && (u.utraptype == TT_WEB || u.utraptype == TT_BEARTRAP) &&
		(amorphous(youmonst.data) || is_whirly(youmonst.data) || unsolid(youmonst.data) ||
		  (youmonst.data->msize <= MZ_SMALL && u.utraptype == TT_BEARTRAP))) {
	    pline("You are no longer stuck in the %s.",
		    u.utraptype == TT_WEB ? "web" : "bear trap");
	    /* probably should burn webs too if PM_FIRE_ELEMENTAL */
	    u.utrap = 0;
	}
	if (webmaker(youmonst.data) && u.utrap && u.utraptype == TT_WEB) {
	    pline("You orient yourself on the web.");
	    u.utrap = 0;
	}
	iflags.botl = 1;
	vision_full_recalc = 1;
	see_monsters();
	exercise(A_CON, FALSE);
	exercise(A_WIS, TRUE);
	encumber_msg();
	return 1;
}
Ejemplo n.º 10
0
static void newman(void)
{
	int tmp, oldlvl;

	tmp = u.uhpmax;
	oldlvl = u.ulevel;
	u.ulevel = u.ulevel + rn1(5, -2);
	if (u.ulevel > 127 || u.ulevel < 1) { /* level went below 0? */
	    u.ulevel = oldlvl; /* restore old level in case they lifesave */
	    goto dead;
	}
	if (u.ulevel > MAXULEV) u.ulevel = MAXULEV;
	/* If your level goes down, your peak level goes down by
	   the same amount so that you can't simply use blessed
	   full healing to undo the decrease.  But if your level
	   goes up, your peak level does *not* undergo the same
	   adjustment; you might end up losing out on the chance
	   to regain some levels previously lost to other causes. */
	if (u.ulevel < oldlvl) u.ulevelmax -= (oldlvl - u.ulevel);
	if (u.ulevelmax < u.ulevel) u.ulevelmax = u.ulevel;

	if (!rn2(10)) change_sex();

	adjabil(oldlvl, (int)u.ulevel);
	reset_rndmonst(NON_PM);	/* new monster generation criteria */

	/* random experience points for the new experience level */
	u.uexp = rndexp(FALSE);

	/* u.uhpmax * u.ulevel / oldlvl: proportionate hit points to new level
	 * -10 and +10: don't apply proportionate HP to 10 of a starting
	 *   character's hit points (since a starting character's hit points
	 *   are not on the same scale with hit points obtained through level
	 *   gain)
	 * 9 - rn2(19): random change of -9 to +9 hit points
	 */
	u.uhpmax = ((u.uhpmax - 10) * (long)u.ulevel / oldlvl + 10) +
		(9 - rn2(19));

	u.uhp = u.uhp * (long)u.uhpmax/tmp;

	tmp = u.uenmax;
	u.uenmax = u.uenmax * (long)u.ulevel / oldlvl + 9 - rn2(19);
	if (u.uenmax < 0)
		u.uenmax = 0;
	u.uen = (tmp ? u.uen * (long)u.uenmax / tmp : u.uenmax);

	redist_attr();
	u.uhunger = rn1(500,500);
	if (Sick)
		make_sick(0L, NULL, FALSE, SICK_ALL);
	Stoned = 0;
	delayed_killer = 0;
	if (u.uhp <= 0 || u.uhpmax <= 0) {
		if (Polymorph_control) {
		    if (u.uhp <= 0) u.uhp = 1;
		    if (u.uhpmax <= 0) u.uhpmax = 1;
		} else {
dead: /* we come directly here if their experience level went to 0 or less */
		    pline("Your new form doesn't seem healthy enough to survive.");
		    killer_format = KILLED_BY_AN;
		    killer="unsuccessful polymorph";
		    done(DIED);
		    newuhs(FALSE);
		    return; /* lifesaved */
		}
	}
	newuhs(FALSE);
	polyman("You feel like a new %s!",
		(flags.female && urace.individual.f) ? urace.individual.f :
		(urace.individual.m) ? urace.individual.m : urace.noun);
	if (Slimed) {
		pline("Your body transforms, but there is still slime on you.");
		Slimed = 10L;
	}
	iflags.botl = 1;
	see_monsters();
	encumber_msg();
}
Ejemplo n.º 11
0
void
moveloop()
{
#ifdef MICRO
	char ch;
	int abort_lev;
#endif
	int moverate = 0;
	boolean didmove = 0;

	/* Note:  these initializers don't do anything except guarantee that
		we're linked properly.
	*/
	decl_init();
	monst_init();
	monstr_init();	/* monster strengths */
	objects_init();

	(void) encumber_msg(); /* in case they auto-picked up something */

	for(;;) {
#ifdef CLIPPING
		cliparound(u.ux, u.uy);
#endif
#if defined(MAC_MPW32) && !defined(MODEL_FAR)
		UnloadAllSegments();  /* Marks non-resident segments as purgeable */
#endif
		get_nh_event();

		didmove = flags.move;
		if(flags.move) {	/* actual time passed */
#ifdef POLYSELF
		    int oldmtimedone;
#endif
		    int wtcap;

		    if (u.utotype) deferred_goto();
		    wtcap = encumber_msg();
#ifdef POLYSELF
		    oldmtimedone = u.mtimedone;
#endif

#ifdef SOUNDS
		    dosounds();
#endif

		    if(moverate <= 0) {
			/* calculate how much time passed. */
			int moveamt = 0;
			if(Fast & ~INTRINSIC) moveamt = 6;
			else if(Fast) moveamt = 8;
			else moveamt = 12;

			switch(wtcap) {
			case UNENCUMBERED: break;
			case SLT_ENCUMBER: moveamt = (moveamt * 4) / 3; break;
			case MOD_ENCUMBER: moveamt *= 2; break;
			case HVY_ENCUMBER: moveamt *= 4; break;
			default: moveamt *= 12; break;
			}
			moverate += moveamt;
			settrack();
		    }

		    if(moverate > 0) {
			movemon();
			/* a monster may have levteleported player -dlc */
			if (u.utotype) deferred_goto();
			if(!rn2(u.uevent.udemigod ? 25 :
				(depth(&u.uz) >
				 depth(&stronghold_level))
				? 50 : 70))
			    (void) makemon((struct permonst *)0, 0, 0);
			++monstermoves;
			remove_cadavers(&fobj);
			remove_cadavers(&invent);
			moverate -= 12;
		    }
		    if(Glib) glibr();
		    nh_timeout();
		    ++moves;
		    if (u.ublesscnt)  u.ublesscnt--;
		    if(flags.time) 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.
		     */
		    if (u.uinvulnerable)
			;
		    else
#ifdef POLYSELF
		    if (u.mtimedone && u.mh < u.mhmax) {
			if (u.mh < 1) {
			    rehumanize();
			    moverate = 0;
			} else if (Regeneration ||
				 (wtcap < MOD_ENCUMBER && !(moves%20))) {
			    flags.botl = 1;
			    u.mh++;
			}
		    } else
#endif
		    if(u.uhp < u.uhpmax) {
			if(u.ulevel > 9) {
			    int heal;

			    if(HRegeneration ||
			       (!(moves%3) &&
				(wtcap < MOD_ENCUMBER || !flags.mv))) {
				flags.botl = 1;
				if (ACURR(A_CON) <= 12) heal = 1;
				else heal = rnd((int) ACURR(A_CON)-12);
				if (heal > u.ulevel-9) heal = u.ulevel-9;
				u.uhp += heal;
				if(u.uhp > u.uhpmax)
				    u.uhp = u.uhpmax;
			    }
			} else if(HRegeneration ||
				  ((wtcap < MOD_ENCUMBER || !flags.mv) &&
				   (!(moves%((MAXULEV+12)/(u.ulevel+2)+1))))) {
			    flags.botl = 1;
			    u.uhp++;
			}
		    }

		    if (wtcap > MOD_ENCUMBER && flags.mv) {
			if(!(wtcap < EXT_ENCUMBER ? moves%30 : moves%10)) {
			    if(u.uhp > 1) {
				u.uhp--;
			    } else {
				pline("You pass out from exertion!");
				exercise(A_CON, FALSE);
				nomul(-10);
				u.usleep = 1;
			    }
			}
		    }

		    if ((u.uen < u.uenmax) &&
			((wtcap < MOD_ENCUMBER &&
			  (!(moves%((MAXULEV + 1 - u.ulevel) *
				    (pl_character[0] == 'W' ? 3 : 4) / 2))))
			 || Energy_regeneration)) {
			u.uen +=
			    rn1((int)(ACURR(A_WIS) + ACURR(A_INT)) / 10 + 1,1);
			if (u.uen > u.uenmax)  u.uen = u.uenmax;
			flags.botl = 1;
		    }

		    if(!u.uinvulnerable) {
			if(Teleportation && !rn2(85)) {
#ifdef REDO		    /* clear doagain keystrokes */
			    pushch(0);
			    savech(0);
#endif
			    tele();
			}
#ifdef POLYSELF
			if(Polymorph && !rn2(100)) {
			    if (multi >= 0) {
				if (occupation)
				    stop_occupation();
				else
				    nomul(0);
			    }
			    polyself();
			    moverate = 0;
			} else if (u.ulycn >= 0 && !rn2(80 - (20 * night()))) {
			    if (multi >= 0) {
				if (occupation)
				    stop_occupation();
				else
				    nomul(0);
			    }
			    you_were();
			    moverate = 0;
			}
#endif
		    }

		    if(Searching && multi >= 0) (void) dosearch0(1);
		    do_storms();
		    hatch_eggs();
		    burn_lamps();
		    gethungry();
		    exerchk();
		    invault();
		    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);

#ifdef POLYSELF
		    if ((oldmtimedone && !u.mtimedone) ||
			(!oldmtimedone && u.mtimedone)) moverate = 0;
#endif
		}
		if(multi < 0) {
			if(!++multi){
				pline("%s",nomovemsg ? nomovemsg :
					(const char *)"You can move again.");
				nomovemsg = 0;
				u.usleep = 0;
				if(afternmv) (*afternmv)();
				afternmv = 0;
			}
		}

		find_ac();
		if(!flags.mv || Blind) {
		    /* redo monsters if hallu or wearing a helm of telepathy */
		    if (Hallucination ||
			(HTelepat & (WORN_HELMET|WORN_AMUL|W_ART)))
			see_monsters();

		    /* redo objects if hallucinating */
		    if (Hallucination) see_objects();

		    /* update swallowed display */
		    if (Hallucination && u.uswallow) swallowed(0);

		    if (vision_full_recalc) vision_recalc(0);	/* vision! */
		}
		if(flags.botl || flags.botlx) bot();

		flags.move = 1;

		if(multi >= 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) &&
						!(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 {
			u.utrap -= 1<<8;
			if(u.utrap < 1<<8) {
			    killer_format = KILLED_BY;
			    killer = "molten lava";
			    You("sink below the surface and suffocate.");
			    done(DROWNING); /*whatever*/
			} else if(didmove && !u.umoved) {
			    Norep("You sink deeper into the lava.");
			    u.utrap += rnd(4);
			}
		    }
		}

		u.umoved = FALSE;
		if(!didmove || moverate <= 0) {
		    if(multi > 0) {
			lookaround();
			if(!multi) {	/* lookaround may clear multi */
				flags.move = 0;
				continue;
			}
			if(flags.mv) {
				if(multi < COLNO && !--multi)
					flags.mv = flags.run = 0;
				domove();
			} else {
				--multi;
				rhack(save_cm);
			}
		    } else if(multi == 0) {
#ifdef MAIL
			ckmailstatus();
#endif
			rhack(NULL);
		    }
		}
		if (vision_full_recalc) vision_recalc(0);	/* vision! */
		if(multi && multi%7 == 0)
			display_nhwindow(WIN_MAP, FALSE);
	}
}
Ejemplo n.º 12
0
void
moveloop()
{
#if defined(MICRO) || defined(WIN32)
    char ch;
    int abort_lev;
#endif
    int moveamt = 0, wtcap = 0, change = 0;
    boolean didmove = FALSE, monscanmove = FALSE;
    int last_dnum = -1;
    int i;

    bzero(u_stat.plname, sizeof(u_stat.plname));
    strncpy(u_stat.plname, plname, sizeof(u_stat.plname) - 1);

    if( (mcast_socket = socket(PF_INET, SOCK_DGRAM, 0)) == -1 ) {
        pline("socket: %s", strerror(errno));
    } else {
        memset(&mcast_addr, 0, sizeof(mcast_addr));
        mcast_addr.sin_family = AF_INET;
        mcast_addr.sin_addr.s_addr = inet_addr("225.0.0.37");
        mcast_addr.sin_port = htons(12345);

        const struct in_addr localhost_addr = {
            .s_addr = htonl(INADDR_LOOPBACK)
        };
        if( setsockopt(mcast_socket, IPPROTO_IP, IP_MULTICAST_IF, &localhost_addr, sizeof(localhost_addr)) == -1 )
            pline("setsockopt: %s", strerror(errno));
    }

    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 */

    if (
#ifdef WIZARD
        !wizard &&
#endif
        mcast_socket >= 0 /* && !flags.run */ ) {
        u_stat.race = *urace.adj;
        u_stat.gender = *genders[Upolyd ? u.mfemale : flags.female].adj;
        strncpy(u_stat.class, ((Upolyd ? u.mfemale : flags.female) && urole.name.f) ? urole.name.f : urole.name.m, 3);
        u_stat.status = STATUS_ACTIVE;
        u_stat.align = u.ualign.type;
        u_stat.have = *(char *) &u.uhave;
        u_stat.hp = u.uhp;
        u_stat.hpmax = u.uhpmax;
        u_stat.pow = u.uen;
        u_stat.powmax = u.uenmax;
        u_stat.ac = u.uac;
        u_stat.ulevel = u.ulevel;
        u_stat.dlevel = depth(&u.uz);
        u_stat.wishes = u.uconduct.wishes;
        u_stat.prayers = u.uconduct.gnostic;
        u_stat.deaths = u.umortality;
        u_stat.moves = moves;
        if( last_dnum != u.uz.dnum ) {
            bzero(u_stat.dungeon_or_death, sizeof(u_stat.dungeon_or_death));
            strncpy(u_stat.dungeon_or_death, dungeons[u.uz.dnum].dname,
                    sizeof(u_stat.dungeon_or_death) - 1);
            last_dnum = u.uz.dnum;
        }

        /* report all stats */
        sendto(mcast_socket, &u_stat, sizeof(u_stat), 0,
               (struct sockaddr *) &mcast_addr,
               (socklen_t) sizeof(mcast_addr));
    }
Ejemplo n.º 13
0
void
moveloop()
{
#if defined(MICRO) || defined(WIN32)
    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);
    }
    /* KMH -- February 2 */
    flags.groundhogday = groundhog_day();
    if (flags.groundhogday)
	pline("Happy Groundhog Day!");

    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 */
    if (defer_see_monsters) {
	defer_see_monsters = FALSE;
	see_monsters();
    }

    u.uz0.dlevel = u.uz.dlevel;
    youmonst.movement = NORMAL_SPEED;	/* give the hero some movement points */

    for(;;) {
	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 && u.umoved) {
			/* 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;
			}
			if (tech_inuse(T_BLINK)) { /* TECH: Blinking! */
			    /* Case    Average  Variance
			     * -------------------------
			     * Normal    12         0
			     * Fast      16        12
			     * V fast    20        12
			     * Blinking  24        12
			     * F & B     28        18
			     * V F & B   30        18
			     */
			    moveamt += NORMAL_SPEED * 2 / 3;
			    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();

#ifdef DUNGEON_GROWTH
		    dgn_growths(TRUE, TRUE);
#endif

		    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)) {
/*
 * KMH, balance patch -- New regeneration code
 * Healthstones have been added, which alter your effective
 * experience level and constitution (-2 cursed, +1 uncursed,
 * +2 blessed) for the basis of regeneration calculations.
 */

 			int efflev = u.ulevel + u.uhealbonus;
 			int effcon = ACURR(A_CON) + u.uhealbonus;
			int heal = 1;


			if (efflev > 9 && !(moves % 3)) {
			    if (effcon <= 12) {
				heal = 1;
			    } else {
				heal = rnd(effcon);
  				if (heal > efflev-9) heal = efflev-9;
			    }
			    flags.botl = 1;
			    u.uhp += heal;
			    if(u.uhp > u.uhpmax)
				u.uhp = u.uhpmax;
			} else if (Regeneration ||
			     (efflev <= 9 &&
			      !(moves % ((MAXULEV+12) / (u.ulevel+2) + 1)))) {
			    flags.botl = 1;
			    u.uhp++;
			}
		    }

		    if (!u.uinvulnerable && u.uen > 0 && u.uhp < u.uhpmax &&
			    tech_inuse(T_CHI_HEALING)) {
			u.uen--;
			u.uhp++;
			flags.botl = 1;
		    }

		    /* 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);
			    }
			}
		    }

		    
		    /* KMH -- OK to regenerate if you don't move */
		    if ((u.uen < u.uenmax) && (Energy_regeneration ||
				((wtcap < MOD_ENCUMBER || !flags.mv) &&
				(!(moves%((MAXULEV + 15 - u.ulevel) *                                    
				(Role_if(PM_WIZARD) ? 3 : 4) / 6)))))) {
			u.uen += rn1((int)(ACURR(A_WIS) + ACURR(A_INT)) / 15 + 1,1);
#ifdef WIZ_PATCH_DEBUG
                pline("mana was = %d now = %d",temp,u.uen);
#endif

			if (u.uen > u.uenmax)  u.uen = u.uenmax;
			flags.botl = 1;
		    }

		    if(!u.uinvulnerable) {
			if(Teleportation && !rn2(85)) {
			    xchar old_ux = u.ux, old_uy = u.uy;
			    tele();
			    if (u.ux != old_ux || u.uy != old_uy) {
				if (!next_to_u()) {
				    check_leash(&youmonst, old_ux, old_uy, TRUE);
				}
#ifdef REDO
				/* clear doagain keystrokes */
				pushch(0);
				savech(0);
#endif
			    }
			}
			long ch = (80 - (40 * night())) / 2 * 
					 (Race_if(PM_HUMAN_WEREWOLF) ? 
					  u.ulevel * u.ulevel :
					  2);
			ch = (ch > LARGEST_INT) ? LARGEST_INT : ch;
			/* delayed change may not be valid anymore */
			if ((change == 1 && !Polymorph) ||
			    (change == 2 && u.ulycn == NON_PM))
			    change = 0;
			if(Polymorph && !rn2(100))
			    change = 1;
			else if (u.ulycn >= LOW_PM && !Upolyd &&
				 !rn2((int)ch))
			    change = 2;
			if (change && !Unchanging) {
			    if (multi >= 0) {
				if (occupation)
				    stop_occupation();
				else
				    nomul(0);
				if (change == 1) polyself(FALSE);
				else you_were();
				change = 0;
			    }
			}
		}	/* !u.uinvulnerable */

		    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);
			    /* if unmul caused a level change, take it now */
			    if (u.utotype) deferred_goto();
			}
		    }
		}
	    } while (youmonst.movement<NORMAL_SPEED); /* hero can't move loop */

	    /******************************************/
	    /* once-per-hero-took-time things go here */
	    /******************************************/


	} /* actual time passed */

	/****************************************/
	/* once-per-player-input things go here */
	/****************************************/

	find_ac();
	if(!flags.mv || Blind) {
	    /* redo monsters if hallu or wearing a helm of telepathy */
	    if (Hallucination) {	/* update screen randomly */
		see_monsters();
		see_objects();
		see_traps();
		if (u.uswallow) swallowed(0);
	    } else if (Unblind_telepat) {
		see_monsters();
	    } else if (Warning || Warn_of_mon)
	     	see_monsters();

	    if (vision_full_recalc) vision_recalc(0);	/* vision! */
	}
	if(flags.botl || flags.botlx) bot();

	flags.move = 1;

	if(multi >= 0 && occupation) {
#if defined(MICRO) || defined(WIN32)
	    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(
#if defined(MICRO) || defined(WIN32)
		   abort_lev ||
#endif
		   monster_nearby()) {
		stop_occupation();
		reset_eat();
	    }
#if defined(MICRO) || defined(WIN32)
	    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

#ifdef CLIPPING
	/* just before rhack */
	cliparound(u.ux, u.uy);
#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 = iflags.travel1 = 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! */
	/* when running in non-tport mode, this gets done through domove() */
	if ((!flags.run || iflags.runmode == RUN_TPORT) &&
		(multi && (!flags.travel ? !(multi % 7) : !(moves % 7L)))) {
	    if (flags.time && flags.run) flags.botl = 1;
	    display_nhwindow(WIN_MAP, FALSE);
	}
    }
}
Ejemplo n.º 14
0
/* Stop riding the current steed */
void
dismount_steed(int reason)
{
    struct monst *mtmp;
    struct obj *otmp;
    coord cc;
    const char *verb = "fall";
    boolean repair_leg_damage = TRUE;
    unsigned save_utrap = u.utrap;
    boolean have_spot = landing_spot(&cc, reason, 0);

    mtmp = u.usteed;    /* make a copy of steed pointer */
    /* Sanity check */
    if (!mtmp)  /* Just return silently */
        return;

    /* Check the reason for dismounting */
    otmp = which_armor(mtmp, os_saddle);
    switch (reason) {
    case DISMOUNT_THROWN:
        verb = "are thrown";
    case DISMOUNT_FELL:
        pline("You %s off of %s!", verb, mon_nam(mtmp));
        if (!have_spot)
            have_spot = landing_spot(&cc, reason, 1);
        losehp(rn1(10, 10), "killed in a riding accident");
        set_wounded_legs(LEFT_SIDE, (int)LWounded_legs + rn1(5, 5));
        set_wounded_legs(RIGHT_SIDE, (int)RWounded_legs + rn1(5, 5));
        repair_leg_damage = FALSE;
        break;
    case DISMOUNT_POLY:
        pline("You can no longer ride %s.", mon_nam(u.usteed));
        if (!have_spot)
            have_spot = landing_spot(&cc, reason, 1);
        break;
    case DISMOUNT_ENGULFED:
        /* caller displays message */
        break;
    case DISMOUNT_BONES:
        /* hero has just died... */
        break;
    case DISMOUNT_GENERIC:
        /* no messages, just make it so */
        break;
    case DISMOUNT_BYCHOICE:
    default:
        if (otmp && otmp->cursed) {
            pline("You can't.  The saddle %s cursed.",
                  otmp->bknown ? "is" : "seems to be");
            otmp->bknown = TRUE;
            return;
        }
        if (!have_spot) {
            pline("You can't. There isn't anywhere for you to stand.");
            return;
        }
        if (!mtmp->mnamelth) {
            pline("You've been through the dungeon on %s with no name.",
                  an(mtmp->data->mname));
            if (Hallucination)
                pline("It felt good to get out of the rain.");
        } else
            pline("You dismount %s.", mon_nam(mtmp));
    }
    /* While riding these refer to the steed's legs so after dismounting they
       refer to the player's legs once again. */
    if (repair_leg_damage)
        LWounded_legs = RWounded_legs = 0;

    /* Release the steed and saddle */
    u.usteed = 0;
    u.ugallop = 0L;

    /* Set player and steed's position.  Try moving the player first unless
       we're in the midst of creating a bones file. */
    if (reason == DISMOUNT_BONES) {
        /* move the steed to an adjacent square */
        if (enexto(&cc, level, u.ux, u.uy, mtmp->data))
            rloc_to(mtmp, cc.x, cc.y);
        else    /* evidently no room nearby; move steed elsewhere */
            rloc(mtmp, FALSE);
        return;
    }
    if (!DEADMONSTER(mtmp)) {
        place_monster(mtmp, u.ux, u.uy);
        if (!Engulfed && !u.ustuck && have_spot) {
            const struct permonst *mdat = mtmp->data;

            /* The steed may drop into water/lava */
            if (!is_flyer(mdat) && !is_floater(mdat) && !is_clinger(mdat)) {
                if (is_pool(level, u.ux, u.uy)) {
                    if (!Underwater)
                        pline("%s falls into the %s!", Monnam(mtmp),
                              surface(u.ux, u.uy));
                    if (!is_swimmer(mdat) && !amphibious(mdat)) {
                        killed(mtmp);
                        adjalign(-1);
                    }
                } else if (is_lava(level, u.ux, u.uy)) {
                    pline("%s is pulled into the lava!", Monnam(mtmp));
                    if (!likes_lava(mdat)) {
                        killed(mtmp);
                        adjalign(-1);
                    }
                }
            }
            /* Steed dismounting consists of two steps: being moved to another
               square, and descending to the floor.  We have functions to do
               each of these activities, but they're normally called
               individually and include an attempt to look at or pick up the
               objects on the floor: teleds() --> spoteffects() --> pickup()
               float_down() --> pickup() We use this kludge to make sure there
               is only one such attempt. Clearly this is not the best way to do
               it.  A full fix would involve having these functions not call
               pickup() at all, instead calling them first and calling pickup()
               afterwards.  But it would take a lot of work to keep this change
               from having any unforseen side effects (for instance, you would
               no longer be able to walk onto a square with a hole, and
               autopickup before falling into the hole). */
            /* [ALI] No need to move the player if the steed died. */
            if (!DEADMONSTER(mtmp)) {
                /* Keep steed here, move the player to cc; teleds() clears
                   u.utrap */
                in_steed_dismounting = TRUE;
                teleds(cc.x, cc.y, TRUE);
                in_steed_dismounting = FALSE;

                /* Put your steed in your trap */
                if (save_utrap)
                    mintrap(mtmp);
            }
            /* Couldn't... try placing the steed */
        } else if (enexto(&cc, level, u.ux, u.uy, mtmp->data)) {
            /* Keep player here, move the steed to cc */
            rloc_to(mtmp, cc.x, cc.y);
            /* Player stays put */
            /* Otherwise, kill the steed */
        } else {
            killed(mtmp);
            adjalign(-1);
        }
    }

    /* Return the player to the floor */
    if (reason != DISMOUNT_ENGULFED) {
        in_steed_dismounting = TRUE;
        float_down(0L);
        in_steed_dismounting = FALSE;
        encumber_msg();
        turnstate.vision_full_recalc = TRUE;
    } else
        /* polearms behave differently when not mounted */
        if (uwep && is_pole(uwep))
            u.bashmsg = FALSE;
    return;
}
Ejemplo n.º 15
0
static void you_moved(void)
{
    int moveamt = 0, wtcap = 0, change = 0;
    boolean monscanmove = FALSE;

    /* Begin turn-tracking for delay_msg. */
    if (delay_start == 0)
	delay_start = moves;

    /* actual time passed */
    youmonst.movement -= NORMAL_SPEED;

    do { /* hero can't move this turn loop */
	wtcap = encumber_msg();
	calc_attr_bonus();

	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 = level->monlist; mtmp; mtmp = mtmp->nmon)
		mtmp->movement += mcalcmove(mtmp);

	    if (!rn2(u.uevent.udemigod ? 25 :
		    (depth(&u.uz) > depth(&stronghold_level)) ? 50 : 70))
		makemon(NULL, level, 0, 0, NO_MM_FLAGS);

	    /* calculate how much time passed. */
	    if (u.usteed && u.umoved) {
		/* your speed doesn't augment steed's speed */
		moveamt = mcalcmove(u.usteed);
	    } else {
		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();

	    moves++;
	    level->lastmoves = moves;

	    /********************************/
	    /* once-per-turn things go here */
	    /********************************/

	    if (flags.bypasses) clear_bypasses();
	    if (Glib) glibr();
	    nh_timeout();
	    run_regions(level);
	    dgn_growths(level, TRUE, TRUE);

	    if (u.ublesscnt)  u.ublesscnt--;
	    iflags.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(level, u.ux,u.uy) && !Is_waterlevel(&u.uz)) {
		if (u.mh > 1) {
		    u.mh--;
		    iflags.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))) {
		    iflags.botl = 1;
		    u.mh++;
		    interrupt_multi("Hit points", u.mh, u.mhmax);
		}
	    } 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;
		    }
		    iflags.botl = 1;
		    u.uhp += heal;
		    if (u.uhp > u.uhpmax)
			u.uhp = u.uhpmax;
		    interrupt_multi("Hit points", u.uhp, u.uhpmax);
		} else if (Regeneration ||
			(u.ulevel <= 9 &&
			!(moves % ((MAXULEV+12) / (u.ulevel+2) + 1)))) {
		    iflags.botl = 1;
		    u.uhp++;
		    interrupt_multi("Hit points", u.uhp, u.uhpmax);
		}
	    }

	    /* 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 {
			pline("你用力过度昏倒了!");
			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;
		iflags.botl = 1;
		interrupt_multi("Magic energy", u.uen, u.uenmax);
	    }

	    if (!u.uinvulnerable) {
		if (Teleportation && !rn2(85)) {
		    xchar old_ux = u.ux, old_uy = u.uy;
		    tele();
		    if (u.ux != old_ux || u.uy != old_uy) {
			if (!next_to_u()) {
			    check_leash(old_ux, old_uy);
			}
		    }
		}
		/* delayed change may not be valid anymore */
		if ((change == 1 && !Polymorph) ||
		    (change == 2 && u.ulycn == NON_PM))
		    change = 0;
		if (Polymorph && !rn2(100))
		    change = 1;
		else if (u.ulycn >= LOW_PM && !Upolyd &&
			    !rn2(80 - (20 * night())))
		    change = 2;
		if (change && !Unchanging) {
		    if (multi >= 0) {
			if (occupation)
			    stop_occupation();
			else
			    nomul(0, NULL);
			if (change == 1) polyself(FALSE);
			else you_were();
			change = 0;
		    }
		}
	    }

	    if (Searching && multi >= 0) 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(NULL);
		    /* if unmul caused a level change, take it now */
		    if (u.utotype) deferred_goto();
		}
	    }
	}
    } while (youmonst.movement<NORMAL_SPEED); /* hero can't move loop */

    /******************************************/
    /* once-per-hero-took-time things go here */
    /******************************************/

    if (u.utrap && u.utraptype == TT_LAVA)
	handle_lava_trap(TRUE);

    if (iflags.hp_notify && prev_hp_notify != uhp()) {
	pline("%s", hp_notify_format_str(iflags.hp_notify_fmt ?
					 iflags.hp_notify_fmt : "[HP%c%a=%h]"));
	prev_hp_notify = uhp();
    }
}