diff -Nurd nethack-3.4.3-pristine/include/extern.h nethack-3.4.3/include/extern.h --- nethack-3.4.3-pristine/include/extern.h 2005-03-09 14:36:45.130487535 +0100 +++ nethack-3.4.3/include/extern.h 2005-03-09 14:36:57.382855368 +0100 @@ -697,6 +697,7 @@ E void FDECL(nomul, (int)); E void FDECL(unmul, (const char *)); E void FDECL(losehp, (int,const char *,BOOLEAN_P)); +E void NDECL(time_check); E int NDECL(weight_cap); E int NDECL(inv_weight); E int NDECL(near_capacity); @@ -1523,6 +1524,7 @@ E void NDECL(set_uasmon); E void NDECL(change_sex); E void FDECL(polyself, (BOOLEAN_P)); +E int FDECL(self_genocided, (int)); E int FDECL(polymon, (int)); E void NDECL(rehumanize); E int NDECL(dobreathe); diff -Nurd nethack-3.4.3-pristine/include/you.h nethack-3.4.3/include/you.h --- nethack-3.4.3-pristine/include/you.h 2005-03-09 14:36:45.166482740 +0100 +++ nethack-3.4.3/include/you.h 2005-03-09 14:36:57.386854835 +0100 @@ -51,6 +51,7 @@ #endif Bitfield(udemigod,1); /* killed the wiz */ Bitfield(ascended,1); /* has offered the Amulet */ + Bitfield(valley_entered,1); /* entered Hell */ }; /* KMH, conduct -- @@ -69,6 +70,16 @@ long polyselfs; /* transformed yourself */ long wishes; /* used a wish */ long wisharti; /* wished for an artifact */ + long sex; /* consorted with a foocubi */ + long conflict; /* caused conflict */ + long imbibe; /* drank anything */ +#ifdef ELBERETH + long elbereth; /* wrote Elbereth */ +#endif + /* Different logic: */ + long humhell; /* been in Hell as yourself: 1:no, 2:no+self-genocide */ + long armour; /* the last turn you _removed_ a piece of armour */ + long sight; /* the last turn you could see in a non-invocation spot */ /* genocides already listed at end of game */ }; @@ -360,7 +371,8 @@ xchar skill_record[P_SKILL_LIMIT]; /* skill advancements */ struct skills weapon_skills[P_NUM_SKILLS]; boolean twoweap; /* KMH -- Using two-weapon combat */ - + time_t uage; /* time wasted */ + time_t timecheck; /* last time check */ }; /* end of `struct you' */ #define Upolyd (u.umonnum != u.umonster) diff -Nurd nethack-3.4.3-pristine/src/allmain.c nethack-3.4.3/src/allmain.c --- nethack-3.4.3-pristine/src/allmain.c 2005-03-09 14:36:45.168482474 +0100 +++ nethack-3.4.3/src/allmain.c 2005-03-09 14:36:57.389854435 +0100 @@ -301,6 +301,8 @@ /* once-per-player-input things go here */ /****************************************/ + time_check(); + find_ac(); if(!flags.mv || Blind) { /* redo monsters if hallu or wearing a helm of telepathy */ diff -Nurd nethack-3.4.3-pristine/src/artifact.c nethack-3.4.3/src/artifact.c --- nethack-3.4.3-pristine/src/artifact.c 2005-03-09 14:36:45.171482074 +0100 +++ nethack-3.4.3/src/artifact.c 2005-03-09 14:36:57.396853503 +0100 @@ -1378,7 +1378,11 @@ } switch(oart->inv_prop) { case CONFLICT: - if(on) You_feel("like a rabble-rouser."); + if(on) + { + You_feel("like a rabble-rouser."); + u.uconduct.conflict++; + } else You_feel("the tension decrease around you."); break; case LEVITATION: diff -Nurd nethack-3.4.3-pristine/src/cmd.c nethack-3.4.3/src/cmd.c --- nethack-3.4.3-pristine/src/cmd.c 2005-03-09 14:36:45.176481409 +0100 +++ nethack-3.4.3/src/cmd.c 2005-03-09 14:36:57.405852304 +0100 @@ -1042,6 +1042,7 @@ if (Lifesaved) enl_msg("Your life ", "will be", "would have been", " saved"); if (u.twoweap) you_are("wielding two weapons at once"); + if (self_genocided(0) && final<2) you_are("dead inside"); /*** Miscellany ***/ if (Luck) { @@ -1250,11 +1251,33 @@ return 0; } +char * +short_time(char *buf, time_t t) +{ + char *obuf; + int y; + + if (t<0) + return strcpy(buf, "a negative amount"); + if (!t) + return strcpy(buf, "not even a second"); + obuf=buf; +#define UNIT(T,x) if (t>=(T)) {buf+=sprintf(buf,"%d%s ",y=t/(T),x);t-=y*(T);} + UNIT(365*24*3600, "y"); + UNIT( 24*3600, "d"); + UNIT( 3600, "h"); + UNIT( 60, "m"); + UNIT( 1, "s"); +#undef UNIT + *--buf=0; + return obuf; +} + void show_conduct(final) int final; { - char buf[BUFSZ]; + char buf[BUFSZ],buf2[BUFSZ]; int ngenocided; /* Create the conduct window */ @@ -1335,6 +1358,47 @@ enl_msg(You_, "have not wished", "did not wish", " for any artifacts"); } + + if (!u.uconduct.sex) + you_have_been("celibate"); + + switch(u.uconduct.humhell) + { + case 1: + Sprintf(buf, "defiled %s brain with the depravity of hell", + an(urace.noun)); + you_have_never(buf); + break; + case 2: + Sprintf(buf, "the last %s to ever enter Hell", urace.noun); + you_have_been(buf); + } + + if (!u.uconduct.conflict && (final||objects[RIN_CONFLICT].oc_name_known)) + you_have_never("caused conflict"); + + if (!u.uconduct.imbibe) + you_have_never("drank anything"); + + if (!u.uconduct.elbereth) + you_have_never("invoked the word of protection"); + /* 1KB: personally, I believe it should say "used the cheat code", + but somehow I don't think the patch would get accepted */ + + if (u.uconduct.armour<10 && !uarm && !uarmc && !uarmh && !uarmg + && !uarms && !uarmf +#ifdef TOURIST + && !uarmu +#endif + ) + you_have_never("used armour"); + /* "used" not "worn", as we give a bit of leeway */ + + if (Blind && u.uconduct.sight<10) + you_have_been("true to the spirit of Zen"); + + Sprintf(buf, "wasted %s of time%s", short_time(buf2, u.uage), final?"":" so far"); + you_have_X(buf); /* Pop up the window and wait for a key */ display_nhwindow(en_win, TRUE); diff -Nurd nethack-3.4.3-pristine/src/do.c nethack-3.4.3/src/do.c --- nethack-3.4.3-pristine/src/do.c 2005-03-09 14:36:45.182480610 +0100 +++ nethack-3.4.3/src/do.c 2005-03-09 14:36:57.412851371 +0100 @@ -1116,6 +1116,16 @@ vision_reset(); /* clear old level's line-of-sight */ vision_full_recalc = 0; /* don't let that reenable vision yet */ flush_screen(-1); /* ensure all map flushes are postponed */ + + if (!u.uevent.valley_entered) { + if (Upolyd) { + if (self_genocided(1)) + u.uconduct.humhell=2; /* you're the last of your race */ + else + u.uconduct.humhell=1; + } + u.uevent.valley_entered=1; + } if (portal && !In_endgame(&u.uz)) { /* find the portal on the new level */ diff -Nurd nethack-3.4.3-pristine/src/do_wear.c nethack-3.4.3/src/do_wear.c --- nethack-3.4.3-pristine/src/do_wear.c 2005-03-09 14:36:45.185480210 +0100 +++ nethack-3.4.3/src/do_wear.c 2005-03-09 14:36:57.420850306 +0100 @@ -693,6 +693,10 @@ if ((oldprop & W_RING) != W_RING) oldprop &= ~W_RING; switch(obj->otyp){ + case RIN_CONFLICT: + u.uconduct.conflict++; + /* 1KB: enlightenment will say "You cause conflict.", so we need + to mark the conduct even if it no monster was ever affected */ case RIN_TELEPORTATION: case RIN_REGENERATION: case RIN_SEARCHING: @@ -703,7 +707,6 @@ case RIN_FIRE_RESISTANCE: case RIN_COLD_RESISTANCE: case RIN_SHOCK_RESISTANCE: - case RIN_CONFLICT: case RIN_TELEPORT_CONTROL: case RIN_POLYMORPH: case RIN_POLYMORPH_CONTROL: @@ -934,6 +937,7 @@ if (Blind_telepat || Infravision) see_monsters(); vision_full_recalc = 1; /* recalc vision limits */ flags.botl = 1; + u.uconduct.sight=moves; } } @@ -969,6 +973,7 @@ if (Blind_telepat || Infravision) see_monsters(); vision_full_recalc = 1; /* recalc vision limits */ flags.botl = 1; + u.uconduct.sight=moves; } } diff -Nurd nethack-3.4.3-pristine/src/eat.c nethack-3.4.3/src/eat.c --- nethack-3.4.3-pristine/src/eat.c 2005-03-09 14:36:45.193479145 +0100 +++ nethack-3.4.3/src/eat.c 2005-03-09 14:40:10.197102638 +0100 @@ -1520,6 +1520,9 @@ makeknown(typ); } break; + case RIN_CONFLICT: + u.uconduct.conflict++; + break; } break; case RIN_ADORNMENT: diff -Nurd nethack-3.4.3-pristine/src/engrave.c nethack-3.4.3/src/engrave.c --- nethack-3.4.3-pristine/src/engrave.c 2005-03-09 14:36:45.195478878 +0100 +++ nethack-3.4.3/src/engrave.c 2005-03-09 14:36:57.425849640 +0100 @@ -369,8 +369,14 @@ ep->engr_y = y; ep->engr_txt = (char *)(ep + 1); Strcpy(ep->engr_txt, s); +#ifdef ELBERETH /* engraving Elbereth shows wisdom */ - if (!in_mklev && !strcmp(s, "Elbereth")) exercise(A_WIS, TRUE); + if (!in_mklev && !strcmp(s, "Elbereth")) + { + exercise(A_WIS, TRUE); + u.uconduct.elbereth++; + } +#endif ep->engr_time = e_time; ep->engr_type = e_type > 0 ? e_type : rnd(N_ENGRAVE-1); ep->engr_lth = strlen(s) + 1; diff -Nurd nethack-3.4.3-pristine/src/fountain.c nethack-3.4.3/src/fountain.c --- nethack-3.4.3-pristine/src/fountain.c 2005-03-09 14:36:45.199478346 +0100 +++ nethack-3.4.3/src/fountain.c 2005-03-09 14:36:57.429849107 +0100 @@ -203,6 +203,7 @@ return; } + u.uconduct.imbibe++; if (mgkftn && u.uluck >= 0 && fate >= 10) { int i, ii, littleluck = (u.uluck < 4); @@ -516,6 +517,7 @@ floating_above("sink"); return; } + u.uconduct.imbibe++; switch(rn2(20)) { case 0: You("take a sip of very cold water."); break; diff -Nurd nethack-3.4.3-pristine/src/hack.c nethack-3.4.3/src/hack.c --- nethack-3.4.3-pristine/src/hack.c 2005-03-09 14:36:45.200478212 +0100 +++ nethack-3.4.3/src/hack.c 2005-03-09 14:36:57.437848041 +0100 @@ -1411,6 +1411,9 @@ nomul(-2); nomovemsg = ""; } + + if (!Blind) + u.uconduct.sight=moves; if (flags.run && iflags.runmode != RUN_TPORT) { /* display every step or every 7th step depending upon mode */ @@ -2154,6 +2157,31 @@ } } +/* 1KB: call this whenever the player gave any input */ +/* As of the moment of writing, this function gets called from only a couple + places, making it very inaccurate. We really should put in win/ everywhere + where keyboard/mouse input is received. */ +void +time_check() +{ + time_t now, elapsed; + +#if defined(BSD) && !defined(POSIX_TYPES) + (void) time((long *)&now); +#else + (void) time(&now); +#endif + elapsed=now-u.timecheck; + u.timecheck=now; + if (elapsed<0) /* the clock was adjusted */ + return; + if (elapsed>10*365*24*3600) /* start or something fishy */ + return; + if (elapsed>30) /* beer/bathroom/work/rgrn or otherwise idle */ + elapsed=30; + u.uage+=elapsed; +} + int weight_cap() { diff -Nurd nethack-3.4.3-pristine/src/mhitu.c nethack-3.4.3/src/mhitu.c --- nethack-3.4.3-pristine/src/mhitu.c 2005-03-09 14:36:45.211476748 +0100 +++ nethack-3.4.3/src/mhitu.c 2005-03-09 14:36:57.446846842 +0100 @@ -2275,6 +2275,7 @@ } if (u.ualign.type == A_CHAOTIC) adjalign(1); + u.uconduct.sex++; /* by this point you have discovered mon's identity, blind or not... */ pline("Time stands still while you and %s lie in each other's arms...", diff -Nurd nethack-3.4.3-pristine/src/pline.c nethack-3.4.3/src/pline.c --- nethack-3.4.3-pristine/src/pline.c 2005-03-09 14:36:45.237473285 +0100 +++ nethack-3.4.3/src/pline.c 2005-03-09 14:36:57.450846309 +0100 @@ -66,6 +66,8 @@ if (vision_full_recalc) vision_recalc(0); if (u.ux) flush_screen(1); /* %% */ putstr(WIN_MESSAGE, 0, line); + + time_check(); /* actually, we should do this once the hero dismisses the command */ } /*VARARGS1*/ diff -Nurd nethack-3.4.3-pristine/src/polyself.c nethack-3.4.3/src/polyself.c --- nethack-3.4.3-pristine/src/polyself.c 2005-03-09 14:36:45.238473152 +0100 +++ nethack-3.4.3/src/polyself.c 2005-03-09 14:36:57.456845510 +0100 @@ -27,6 +27,20 @@ set_mon_data(&youmonst, &mons[u.umonnum], 0); } +/* check if the player has genocided h{im,er}self */ +int self_genocided(int justrace) +{ + if ((mvitals[urole.malenum].mvflags & G_GENOD) || + (urole.femalenum != NON_PM && + (mvitals[urole.femalenum].mvflags & G_GENOD))) + return 1; + if ((mvitals[urace.malenum].mvflags & G_GENOD) || + (urace.femalenum != NON_PM && + (mvitals[urace.femalenum].mvflags & G_GENOD))) + return 1; + return 0; +} + /* make a (new) human out of the player */ STATIC_OVL void polyman(fmt, arg) @@ -61,12 +75,8 @@ You(fmt, arg); /* check whether player foolishly genocided self while poly'd */ - if ((mvitals[urole.malenum].mvflags & G_GENOD) || - (urole.femalenum != NON_PM && - (mvitals[urole.femalenum].mvflags & G_GENOD)) || - (mvitals[urace.malenum].mvflags & G_GENOD) || - (urace.femalenum != NON_PM && - (mvitals[urace.femalenum].mvflags & G_GENOD))) { + if (self_genocided(0)) + { /* intervening activity might have clobbered genocide info */ killer = delayed_killer; if (!killer || !strstri(killer, "genocid")) { @@ -75,6 +85,8 @@ } done(GENOCIDED); } + if (u.uevent.valley_entered) + u.uconduct.humhell=0; if (u.twoweap && !could_twoweap(youmonst.data)) untwoweapon(); diff -Nurd nethack-3.4.3-pristine/src/potion.c nethack-3.4.3/src/potion.c --- nethack-3.4.3-pristine/src/potion.c 2005-03-09 14:36:45.239473019 +0100 +++ nethack-3.4.3/src/potion.c 2005-03-09 14:36:57.463844577 +0100 @@ -235,6 +235,8 @@ flags.botl = 1; vision_full_recalc = 1; /* blindness just got toggled */ if (Blind_telepat || Infravision) see_monsters(); + if (!invocation_pos(u.ux, u.uy)) + u.uconduct.sight=moves; } } @@ -390,6 +392,7 @@ otmp->in_use = TRUE; nothing = unkn = 0; + u.uconduct.imbibe++; if((retval = peffects(otmp)) >= 0) return(retval); if(nothing) { diff -Nurd nethack-3.4.3-pristine/src/worn.c nethack-3.4.3/src/worn.c --- nethack-3.4.3-pristine/src/worn.c 2005-03-09 14:36:45.277467958 +0100 +++ nethack-3.4.3/src/worn.c 2005-03-09 14:36:57.468843911 +0100 @@ -52,6 +52,13 @@ register struct obj *oobj; register int p; + if (mask&(W_ARM|W_ARMC|W_ARMH|W_ARMS|W_ARMG|W_ARMF +#ifdef TOURIST + |W_ARMU +#endif + )) + u.uconduct.armour=moves; + if ((mask & (W_ARM|I_SPECIAL)) == (W_ARM|I_SPECIAL)) { /* restoring saved game; no properties are conferred via skin */ uskin = obj;