diff -Nurd nethack-3.4.3/dat/data.base nethack-sins/dat/data.base --- nethack-orig/dat/data.base 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/dat/data.base 2006-04-07 23:22:31.000000000 +0100 @@ -1783,6 +1783,53 @@ the fourth part of the earth, to kill with sword, and with hunger, and with death, and with the beasts of the earth. [ Revelations of John, 6:1-8 ] +*sin* +~assassin +~moccasin +*vice* +gluttony +lust +greed +envy +wrath +sloth +pride +avarice +anger +hatred +jealousy + [Gluttony:] Thoughtless waste of everything, overindulgence, + misplaced sensuality, uncleanliness, and maliciously depriving + others. Marked by refusal to share and unreasonable consumption + of more than is necessary, especially food or drink. + + [Lust:] Depraved thought, unwholesome morality, desire for + excitement, or need to be accepted or recognized by others. + Obsessive, unlawful, or unnatural sexual desire, such as + desiring sex with a person outside marriage or engaging in + unnatural sexual appetites. + + [Greed:] A strong desire to gain, especially in money or power + Disloyalty, deliberate betrayal, or treason; especially for + personal gain or when compensated. + + [Envy:] Grieving spite and resentment of material objects, + accomplishments, or character traits of others, or wishing + others to fail or come to harm. Envy is the root of theft and + self-loathing. + + [Wrath:] Inappropriate unrighteous feelings of hatred and anger. + Denial of the truth to others or self. Impatience or revenge + outside of justice. Wishing to do evil or harm to others. + + [Sloth:] Apathy, idleness, and wastefulness of time. Laziness is + particularly condemned because others must work harder to make + up for it. Cowardice or irresponsibility. + + [Pride:] A desire to be more important or attractive to others, + failing to fice credit due others, or excessive love of self + (especially holding self out of proper position toward God). + [ Seven deadly sins, Wikipedia ] huan*ti The first of five mythical Chinese emperors, Huan Ti is known as the yellow emperor. He rules the _moving_ heavens, as Binary files nethack-orig/include/.edog.h.swp and nethack-sins/include/.edog.h.swp differ diff -Nurd nethack-3.4.3/include/hack.h nethack-sins/include/hack.h --- nethack-orig/include/hack.h 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/include/hack.h 2006-04-07 19:46:01.000000000 +0100 @@ -93,6 +93,12 @@ NEARDATA extern coord bhitpos; /* place where throw or zap hits or stops */ +/* kludges for figuring out what we're doing with the Riders each game */ +NEARDATA extern int rider_replacements; /* Used to help dodge repeat-choices */ +NEARDATA extern int rider_replacement1_pm; /* The PM_ integers for the three Riders */ +NEARDATA extern int rider_replacement2_pm; +NEARDATA extern int rider_replacement3_pm; + /* types of calls to bhit() */ #define ZAPPED_WAND 0 #define THROWN_WEAPON 1 diff -Nurd nethack-3.4.3/include/monattk.h nethack-sins/include/monattk.h --- nethack-orig/include/monattk.h 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/include/monattk.h 2006-04-07 00:33:14.000000000 +0100 @@ -79,6 +79,11 @@ #define AD_ENCH 41 /* remove enchantment (disenchanter) */ #define AD_CORR 42 /* corrode armor (black pudding) */ +#define AD_DRE2 43 /* (Wrath) drains half your current energy, or all of it if less than 10 */ +#define AD_LAZY 44 /* (Sloth) laziness attack, does all sorts of nasty things */ +#define AD_DRCH 45 /* (Pride) drains charisma */ +#define AD_DFOO 46 /* (Pride) drains a random stat, or energy, or hit points, or life level */ + #define AD_CLRC 240 /* random clerical spell */ #define AD_SPEL 241 /* random magic spell */ #define AD_RBRE 242 /* random breath weapon */ diff -Nurd nethack-3.4.3/include/mondata.h nethack-sins/include/mondata.h --- nethack-orig/include/mondata.h 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/include/mondata.h 2006-04-07 03:22:56.000000000 +0100 @@ -134,12 +134,20 @@ #define is_rider(ptr) ((ptr) == &mons[PM_DEATH] || \ (ptr) == &mons[PM_FAMINE] || \ (ptr) == &mons[PM_PESTILENCE]) +#define is_vice(ptr) ((ptr) == &mons[PM_GLUTTONY] || \ + (ptr) == &mons[PM_LUST] || \ + (ptr) == &mons[PM_GREED] || \ + (ptr) == &mons[PM_ENVY] || \ + (ptr) == &mons[PM_WRATH] || \ + (ptr) == &mons[PM_SLOTH] || \ + (ptr) == &mons[PM_PRIDE]) +#define is_endgamenasty(ptr) (is_rider(ptr) || is_vice(ptr)) #define is_placeholder(ptr) ((ptr) == &mons[PM_ORC] || \ (ptr) == &mons[PM_GIANT] || \ (ptr) == &mons[PM_ELF] || \ (ptr) == &mons[PM_HUMAN]) /* return TRUE if the monster tends to revive */ -#define is_reviver(ptr) (is_rider(ptr) || (ptr)->mlet == S_TROLL) +#define is_reviver(ptr) (is_rider(ptr) || is_vice(ptr) || (ptr)->mlet == S_TROLL) /* this returns the light's range, or 0 if none; if we add more light emitting monsters, we'll likely have to add a new light range field to mons[] */ diff -Nurd nethack-3.4.3/include/monflag.h nethack-sins/include/monflag.h --- nethack-orig/include/monflag.h 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/include/monflag.h 2006-04-07 00:22:53.000000000 +0100 @@ -48,6 +48,7 @@ #define MS_SPELL 37 /* spellcaster not matching any of the above */ #define MS_WERE 38 /* lycanthrope in human form */ #define MS_BOAST 39 /* giants */ +#define MS_VICE 40 /* alternate astral level special */ #define MR_FIRE 0x01 /* resists fire */ diff -Nurd nethack-3.4.3/include/permonst.h nethack-sins/include/permonst.h --- nethack-orig/include/permonst.h 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/include/permonst.h 2006-04-07 03:38:50.000000000 +0100 @@ -31,6 +31,8 @@ */ #define WT_HUMAN 1450 +#define WT_SKHUMAN 725 /* for Famine; WT_HUMAN/2 */ +#define WT_FTHUMAN 2900 /* for Gluttony; WT_HUMAN*2 */ #ifndef ALIGN_H #include "align.h" diff -Nurd nethack-3.4.3/src/apply.c nethack-sins/src/apply.c --- nethack-orig/src/apply.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/apply.c 2006-04-07 03:22:59.000000000 +0100 @@ -1412,6 +1412,11 @@ verbalize("Yes... But War does not preserve its enemies..."); return; } + if (is_vice(&mons[corpse->corpsenm])) { + (void) revive_corpse(corpse); + verbalize("You cannot contain that which is in the heart of every man..."); + return; + } if (mons[corpse->corpsenm].cnutrit == 0) { pline("That's too insubstantial to tin."); return; diff -Nurd nethack-3.4.3/src/do.c nethack-sins/src/do.c --- nethack-orig/src/do.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/do.c 2006-04-07 03:22:09.000000000 +0100 @@ -1580,7 +1580,7 @@ /* if we succeed, the corpse is gone, otherwise, rot it away */ if (!revive_corpse(body)) { - if (is_rider(&mons[body->corpsenm])) + if (is_endgamenasty(&mons[body->corpsenm])) You_feel("less hassled."); (void) start_timer(250L - (monstermoves-body->age), TIMER_OBJECT, ROT_CORPSE, arg); diff -Nurd nethack-3.4.3/src/dog.c nethack-sins/src/dog.c --- nethack-orig/src/dog.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/dog.c 2006-04-07 03:21:55.000000000 +0100 @@ -659,7 +659,7 @@ case FOOD_CLASS: if (obj->otyp == CORPSE && ((touch_petrifies(&mons[obj->corpsenm]) && !resists_ston(mon)) - || is_rider(fptr))) + || is_endgamenasty(fptr))) return TABU; /* Ghouls only eat old corpses... yum! */ diff -Nurd nethack-3.4.3/src/do_name.c nethack-sins/src/do_name.c --- nethack-orig/src/do_name.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/do_name.c 2006-04-08 21:46:35.000000000 +0100 @@ -11,6 +11,71 @@ extern const char what_is_an_unknown_object[]; /* from pager.c */ +static const char * const bogusmons[] = { + "jumbo shrimp", "giant pigmy", "gnu", "killer penguin", + "giant cockroach", "giant slug", "maggot", "pterodactyl", + "tyrannosaurus rex", "basilisk", "beholder", "nightmare", + "efreeti", "marid", "rot grub", "bookworm", "master lichen", + "shadow", "hologram", "jester", "attorney", "sleazoid", + "killer tomato", "amazon", "robot", "battlemech", + "rhinovirus", "harpy", "lion-dog", "rat-ant", "Y2K bug", + /* misc. */ + "grue", "Christmas-tree monster", "luck sucker", "paskald", + "brogmoid", "dornbeast", /* Quendor (Zork, &c.) */ + "Ancient Multi-Hued Dragon", "Evil Iggy", + /* Moria */ + "emu", "kestrel", "xeroc", "venus flytrap", + /* Rogue */ + "creeping coins", /* Wizardry */ + "hydra", "siren", /* Greek legend */ + "killer bunny", /* Monty Python */ + "rodent of unusual size", /* The Princess Bride */ + "Smokey the bear", /* "Only you can prevent forest fires!" */ + "Luggage", /* Discworld */ + "Ent", /* Lord of the Rings */ + "tangle tree", "nickelpede", "wiggle", /* Xanth */ + "white rabbit", "snark", /* Lewis Carroll */ + "pushmi-pullyu", /* Dr. Doolittle */ + "smurf", /* The Smurfs */ + "tribble", "Klingon", "Borg", /* Star Trek */ + "Ewok", /* Star Wars */ + "Totoro", /* Tonari no Totoro */ + "ohmu", /* Nausicaa */ + "youma", /* Sailor Moon */ + "nyaasu", /* Pokemon (Meowth) */ + "Godzilla", "King Kong", /* monster movies */ + "earthquake beast", /* old L of SH */ + "Invid", /* Robotech */ + "Terminator", /* The Terminator */ + "boomer", /* Bubblegum Crisis */ + "Dalek", /* Dr. Who ("Exterminate!") */ + "microscopic space fleet", "Ravenous Bugblatter Beast of Traal", + /* HGttG */ + "teenage mutant ninja turtle", /* TMNT */ + "samurai rabbit", /* Usagi Yojimbo */ + "aardvark", /* Cerebus */ + "Audrey II", /* Little Shop of Horrors */ + "witch doctor", "one-eyed one-horned flying purple people eater", + /* 50's rock 'n' roll */ + "Barney the dinosaur", /* saccharine kiddy TV */ + "Morgoth", /* Angband */ + "Vorlon", /* Babylon 5 */ + "questing beast", /* King Arthur */ + "Predator", /* Movie */ + "mother-in-law" /* common pest */ +}; + +static const char * const minorsins[] = { + "Farting Secretly", + "Naughtiness", + "Not Feeding The Cat", + "Music Piracy", + "Squashing Spiders", + "Eating The Last Slime Mold", + "Savescumming", + "Bad Advertising" +}; + /* the response for '?' help request in getpos() */ static void getpos_help(force, goal) @@ -679,8 +744,13 @@ /* Put the actual monster name or type into the buffer now */ /* Be sure to remember whether the buffer starts with a name */ if (do_hallu) { - Strcat(buf, rndmonnam()); - name_at_start = FALSE; + if(is_vice(mdat)) { + Strcat(buf, minorsins[rn2(SIZE(minorsins))]); + name_at_start = TRUE; + } else { + Strcat(buf, rndmonnam()); + name_at_start = FALSE; + } } else if (mtmp->mnamelth) { char *name = NAME(mtmp); @@ -885,61 +955,6 @@ return outbuf; } -static const char * const bogusmons[] = { - "jumbo shrimp", "giant pigmy", "gnu", "killer penguin", - "giant cockroach", "giant slug", "maggot", "pterodactyl", - "tyrannosaurus rex", "basilisk", "beholder", "nightmare", - "efreeti", "marid", "rot grub", "bookworm", "master lichen", - "shadow", "hologram", "jester", "attorney", "sleazoid", - "killer tomato", "amazon", "robot", "battlemech", - "rhinovirus", "harpy", "lion-dog", "rat-ant", "Y2K bug", - /* misc. */ - "grue", "Christmas-tree monster", "luck sucker", "paskald", - "brogmoid", "dornbeast", /* Quendor (Zork, &c.) */ - "Ancient Multi-Hued Dragon", "Evil Iggy", - /* Moria */ - "emu", "kestrel", "xeroc", "venus flytrap", - /* Rogue */ - "creeping coins", /* Wizardry */ - "hydra", "siren", /* Greek legend */ - "killer bunny", /* Monty Python */ - "rodent of unusual size", /* The Princess Bride */ - "Smokey the bear", /* "Only you can prevent forest fires!" */ - "Luggage", /* Discworld */ - "Ent", /* Lord of the Rings */ - "tangle tree", "nickelpede", "wiggle", /* Xanth */ - "white rabbit", "snark", /* Lewis Carroll */ - "pushmi-pullyu", /* Dr. Doolittle */ - "smurf", /* The Smurfs */ - "tribble", "Klingon", "Borg", /* Star Trek */ - "Ewok", /* Star Wars */ - "Totoro", /* Tonari no Totoro */ - "ohmu", /* Nausicaa */ - "youma", /* Sailor Moon */ - "nyaasu", /* Pokemon (Meowth) */ - "Godzilla", "King Kong", /* monster movies */ - "earthquake beast", /* old L of SH */ - "Invid", /* Robotech */ - "Terminator", /* The Terminator */ - "boomer", /* Bubblegum Crisis */ - "Dalek", /* Dr. Who ("Exterminate!") */ - "microscopic space fleet", "Ravenous Bugblatter Beast of Traal", - /* HGttG */ - "teenage mutant ninja turtle", /* TMNT */ - "samurai rabbit", /* Usagi Yojimbo */ - "aardvark", /* Cerebus */ - "Audrey II", /* Little Shop of Horrors */ - "witch doctor", "one-eyed one-horned flying purple people eater", - /* 50's rock 'n' roll */ - "Barney the dinosaur", /* saccharine kiddy TV */ - "Morgoth", /* Angband */ - "Vorlon", /* Babylon 5 */ - "questing beast", /* King Arthur */ - "Predator", /* Movie */ - "mother-in-law" /* common pest */ -}; - - /* Return a random monster name, for hallucination. * KNOWN BUG: May be a proper name (Godzilla, Barney), may not * (the Terminator, a Dalek). There's no elegant way to deal diff -Nurd nethack-3.4.3/src/dothrow.c nethack-sins/src/dothrow.c --- nethack-orig/src/dothrow.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/dothrow.c 2006-04-08 20:15:56.000000000 +0100 @@ -1273,6 +1273,19 @@ return(0); } + if(mon->data==&mons[PM_GLUTTONY] && dogfood(mon, obj) <= ACCFOOD && !obj->oartifact) { + if(obj->oartifact) { + pline("%s grabs %s, but decides to save %s for eating later.", + Monnam(mon), the(xname(obj)), (obj->quan>1L ? "them" : "it")); + (void) mpickobj(mon, obj); + } else { + pline("%s snatches %s out of the air and gobbles it down!", + Monnam(mon), the(xname(obj))); + delobj(obj); + return 1; + } + } + if (obj->oclass == WEAPON_CLASS || is_weptool(obj) || obj->oclass == GEM_CLASS) { if (is_ammo(obj)) { diff -Nurd nethack-3.4.3/src/eat.c nethack-sins/src/eat.c --- nethack-orig/src/eat.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/eat.c 2006-04-07 02:10:52.000000000 +0100 @@ -490,6 +490,13 @@ case PM_LIZARD: if (Stoned) fix_petrification(); break; + case PM_GLUTTONY: + case PM_LUST: + case PM_GREED: + case PM_ENVY: + case PM_WRATH: + case PM_SLOTH: + case PM_PRIDE: case PM_DEATH: case PM_PESTILENCE: case PM_FAMINE: diff -Nurd nethack-3.4.3/src/hack.c nethack-sins/src/hack.c --- nethack-orig/src/hack.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/hack.c 2006-04-07 03:21:38.000000000 +0100 @@ -34,7 +34,7 @@ for(otmp = level.objects[x][y]; otmp; otmp = otmp2) { otmp2 = otmp->nexthere; if (otmp->otyp == CORPSE && - (is_rider(&mons[otmp->corpsenm]) || + (is_endgamenasty(&mons[otmp->corpsenm]) || otmp->corpsenm == PM_WIZARD_OF_YENDOR)) { /* move any living monster already at that location */ if((mtmp = m_at(x,y)) && enexto(&cc, x, y, mtmp->data)) diff -Nurd nethack-3.4.3/src/makemon.c nethack-sins/src/makemon.c --- nethack-orig/src/makemon.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/makemon.c 2006-04-07 19:48:19.000000000 +0100 @@ -10,6 +10,8 @@ #include #endif +#define FORCE_VICES + STATIC_VAR NEARDATA struct monst zeromonst; /* this assumes that a human quest leader or nemesis is an archetype @@ -32,6 +34,10 @@ #endif /* OVL1 */ extern const int monstr[]; +int rider_replacements = 0; +int rider_replacement1_pm = 0; +int rider_replacement2_pm = 0; +int rider_replacement3_pm = 0; #define m_initsgrp(mtmp, x, y) m_initgrp(mtmp, x, y, 3) #define m_initlgrp(mtmp, x, y) m_initgrp(mtmp, x, y, 10) @@ -878,6 +884,49 @@ pline("Explicitly creating extinct monster %s.", mons[mndx].mname); #endif + if(is_rider(ptr)) { + if(rider_replacements==0) { /* Then haven't decided yet */ + rider_replacements = (rn2(2) ? 1 : 4); +#ifdef FORCE_VICES + rider_replacements = 1; +#endif + } + if(rider_replacements<4) { /* Decision made, we're replacing. */ + switch(rider_replacements++) { + case 1: + rider_replacement1_pm = rn1(7, PM_GLUTTONY); + mndx = rider_replacement1_pm; + break; + case 2: + while(1) { + rider_replacement2_pm = rn1(7, PM_GLUTTONY); + if(rider_replacement2_pm != rider_replacement1_pm) break; + } + mndx = rider_replacement2_pm; + break; + case 3: + while(1) { + rider_replacement3_pm = rn1(7, PM_GLUTTONY); + if((rider_replacement3_pm != rider_replacement2_pm) && (rider_replacement3_pm != rider_replacement1_pm)) break; + } + mndx = rider_replacement3_pm; + break; + } + } else { /* Decided not to replace. */ + rider_replacement1_pm = PM_DEATH; + rider_replacement2_pm = PM_FAMINE; + rider_replacement3_pm = PM_PESTILENCE; + } +#ifdef WIZARD + if(wizard && rider_replacements==4) { + pline("The Terrible Trio this game are: %s, %s, %s.", + mons[rider_replacement1_pm].mname, + mons[rider_replacement2_pm].mname, + mons[rider_replacement3_pm].mname); + } +#endif + ptr = &mons[mndx]; + } } else { /* make a random (common) monster that can survive here. * (the special levels ask for random monsters at specific @@ -917,7 +966,7 @@ mtmp->m_lev = adj_lev(ptr); if (is_golem(ptr)) { mtmp->mhpmax = mtmp->mhp = golemhp(mndx); - } else if (is_rider(ptr)) { + } else if (is_endgamenasty(ptr)) { /* We want low HP, but a high mlevel so they can attack well */ mtmp->mhpmax = mtmp->mhp = d(10,8); } else if (ptr->mlevel > 49) { @@ -1029,6 +1078,16 @@ mitem = BELL_OF_OPENING; } else if (mndx == PM_PESTILENCE) { mitem = POT_SICKNESS; + } else if (mndx == PM_GLUTTONY) { + mitem = HUGE_CHUNK_OF_MEAT; + } else if (mndx == PM_PRIDE) { + mitem = MIRROR; + } else if (mndx == PM_LUST) { + /* mitem = BULLWHIP; */ /* You guys are so immature. */ + } else if (mndx == PM_GREED || mndx == PM_ENVY) { + mitem = DIAMOND; + } else if (mndx == PM_SLOTH) { + mitem = TOWEL; /* closest thing to a pillow... */ } if (mitem && allow_minvent) (void) mongets(mtmp, mitem); diff -Nurd nethack-3.4.3/src/mhitm.c nethack-sins/src/mhitm.c --- nethack-orig/src/mhitm.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/mhitm.c 2006-04-07 22:50:19.000000000 +0100 @@ -115,6 +115,10 @@ if(resist(mtmp, RING_CLASS, 0, 0)) return(0); + /* Wrath does not fear your conflict */ + if(mtmp->data == &mons[PM_WRATH]) + return(0); + if(u.ustuck == mtmp) { /* perhaps we're holding it... */ if(itsstuck(mtmp)) @@ -623,13 +627,15 @@ switch(mattk->adtyp) { case AD_DGST: /* eating a Rider or its corpse is fatal */ - if (is_rider(mdef->data)) { + if (is_endgamenasty(mdef->data)) { if (vis) pline("%s %s!", Monnam(magr), mdef->data == &mons[PM_FAMINE] ? "belches feebly, shrivels up and dies" : mdef->data == &mons[PM_PESTILENCE] ? "coughs spasmodically and collapses" : + mdef->data == &mons[PM_GLUTTONY] ? + "chokes over the huge meal and dies" : "vomits violently and drops dead"); mondied(magr); if (magr->mhp > 0) return 0; /* lifesaved */ diff -Nurd nethack-3.4.3/src/mhitu.c nethack-sins/src/mhitu.c --- nethack-orig/src/mhitu.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/mhitu.c 2006-04-08 21:05:39.000000000 +0100 @@ -595,6 +595,7 @@ case AT_ENGL: if (!range2) { + verbalize("HUNGRY!"); if(foundyou) { if(u.uswallow || tmp > (j = rnd(20+i))) { /* Force swallowing monster to be @@ -606,15 +607,20 @@ missmu(mtmp, (tmp == j), mattk); } } else if (is_animal(mtmp->data)) { - pline("%s gulps some air!", Monnam(mtmp)); + pline("%s gulps some air!", Monnam(mtmp)); } else { - if (youseeit) - pline("%s lunges forward and recoils!", - Monnam(mtmp)); - else + if (youseeit) { + if(mtmp->data == &mons[PM_GLUTTONY]) + You("narrowly avoid %s gaping maw!", + s_suffix(Monnam(mtmp))); + else + pline("%s lunges forward and recoils!", + Monnam(mtmp)); + } else { You_hear("a %s nearby.", - is_whirly(mtmp->data) ? - "rushing noise" : "splat"); + is_whirly(mtmp->data) ? "rushing noise" : + is_vice(mtmp->data) ? "gnashing sound" : "splat"); + } } } break; @@ -1269,13 +1275,20 @@ if(!mtmp->mcan) stealgold(mtmp); break; - case AD_SITM: /* for now these are the same */ - case AD_SEDU: + case AD_SEDU: /* no longer quite the same */ + if(!rn2(5)) { + stealgold(mtmp); + break; + } + /* otherwise, fall through */ + case AD_SITM: if (is_animal(mtmp->data)) { hitmsg(mtmp, mattk); if (mtmp->mcan) break; /* Continue below */ } else if (dmgtype(youmonst.data, AD_SEDU) + || dmgtype(youmonst.data, AD_SITM) + || dmgtype(youmonst.data, AD_SGLD) #ifdef SEDUCE || dmgtype(youmonst.data, AD_SSEX) #endif @@ -1292,7 +1305,7 @@ flags.female ? "charm" : "seduce", flags.female ? "unaffected" : "uninterested"); } - if(rn2(3)) { + if(rn2(3) && !is_vice(mtmp->data)) { if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); return 3; } @@ -1305,7 +1318,14 @@ case 0: break; default: - if (!is_animal(mtmp->data) && !tele_restrict(mtmp)) + if (is_vice(mtmp->data)) { + if (canseemon(mtmp) && *buf) + pline("%s admires %s.", + Monnam(mtmp), + buf); + return 1; + } + if (!is_animal(mtmp->data) && !tele_restrict(mtmp) && !is_vice(mtmp->data)) (void) rloc(mtmp, FALSE); if (is_animal(mtmp->data) && *buf) { if (canseemon(mtmp)) @@ -1424,9 +1444,11 @@ } break; case AD_CURS: + if(mdat == &mons[PM_ENVY]) pline("%s looks jealous of your abilities...", + Monnam(mtmp)); hitmsg(mtmp, mattk); if(!night() && mdat == &mons[PM_GREMLIN]) break; - if(!mtmp->mcan && !rn2(10)) { + if((!mtmp->mcan && !rn2(10)) || (is_endgamenasty(mdat) && !rn2(4))) { if (flags.soundok) { if (Blind) You_hear("laughter."); else pline("%s chuckles.", Monnam(mtmp)); @@ -1521,6 +1543,117 @@ if (!is_fainted()) morehungry(rn1(40,40)); /* plus the normal damage */ break; + case AD_DRE2: + if(mdat == &mons[PM_WRATH]) verbalize("I'll draw the very life from your bones!"); + hitmsg(mtmp, mattk); + if(u.uen<1) { + You_feel("less energised!"); + u.uenmax -= rn1(10,10); + if(u.uenmax<0) u.uenmax = 0; + } else if(u.uen<=10) { + You_feel("your magical energy dwindle to nothing!"); + u.uen = 0; + } else { + You_feel("your magical energy dwindling rapidly!"); + u.uen /= 2; + } + break; + case AD_DRCH: + if(mdat == &mons[PM_PRIDE]) verbalize("You think you're better than me?!"); + hitmsg(mtmp, mattk); + adjattrib(A_CHA, -rn1(1,1), 0); /* does its own messages */ + break; + case AD_DFOO: /* drain something randomly (Str,Con,Dex,Int,Wis,Cha,MHp,MMp,XL) */ + if(mdat == &mons[PM_PRIDE]) pline("%s determines to take you down a peg or two...", Monnam(mtmp)); + hitmsg(mtmp, mattk); + switch(rn2(10)) { + case 0: ptmp = A_STR; goto drfoo_stat; + case 1: ptmp = A_CON; goto drfoo_stat; + case 2: ptmp = A_DEX; goto drfoo_stat; + case 3: ptmp = A_INT; goto drfoo_stat; + case 4: ptmp = A_WIS; goto drfoo_stat; + case 5: ptmp = A_CHA; goto drfoo_stat; + drfoo_stat: + adjattrib(ptmp, -rn1(1,1), 0); + break; + case 6: /* Max HP */ + You_feel("less resilient!"); + permdmg = 1; + break; + case 7: /* Max MP */ + You_feel("less energised!"); + u.uenmax -= rn1(10,10); + if(u.uen > u.uenmax) u.uen = u.uenmax; + break; + case 8: /* XL */ + if(!Drain_resistance) { + losexp("life drainage"); + } else { + You_feel("woozy for an instant, but shrug it off."); + } + break; + } + break; + case AD_LAZY: /* laziness attack; do lots of nasty things at random */ + if(!rn2(2)) { + pline("%s tries to touch you, but can't really be bothered.", + Monnam(mtmp)); + break; + } + pline("%s reaches out with an apathetic finger...", + Monnam(mtmp)); + switch(rn2(7)) { + case 0: /* destroy certain things */ + pline("%s touches you!", + Monnam(mtmp)); + destroy_item(0, AD_LAZY); + break; + case 1: /* sleep */ + if(Sleep_resistance) { + You("yawn."); + } else { + if(Blind) You("are put to sleep!"); + else You("are put to sleep by %s!", mon_nam(mtmp)); + fall_asleep(-rnd(10), TRUE); + } + break; + case 2: /* paralyse */ + if(Free_action) { + You("momentarily stiffen."); + } else { + if(Blind) You("are frozen!"); + else You("are frozen by %s!", mon_nam(mtmp)); + nomovemsg = 0; + nomul(-rnd(10)); + exercise(A_DEX, FALSE); + } + break; + case 3: /* slow */ + if(HFast && !defends(AD_SLOW, uwep)) u_slow_down(); + else You("pause momentarily."); + break; + case 4: /* drain Dex */ + adjattrib(A_DEX, -rn1(1,1), 0); + break; + case 5: /* steal teleportitis */ + if(HTeleportation & INTRINSIC) { + HTeleportation &= ~INTRINSIC; + You_feel("less jumpy."); + } else { + You("don't feel in the mood for jumping around."); + } + break; + case 6: /* steal sleep resistance */ + if(HSleep_resistance & INTRINSIC) { + HSleep_resistance &= ~INTRINSIC; + You_feel("a bit tired."); + } else { + You_feel("like you could use a nap."); + } + break; + } + dmg = 0; + break; case AD_SLIM: hitmsg(mtmp, mattk); if (!uncancelled) break; @@ -1655,7 +1788,11 @@ dismount_steed(DISMOUNT_ENGULFED); } else #endif - pline("%s engulfs you!", Monnam(mtmp)); + if(mtmp->data == &mons[PM_GLUTTONY]) { + pline("%s distends his jaw and swallows you whole!", Monnam(mtmp)); + } else { + pline("%s engulfs you!", Monnam(mtmp)); + } stop_occupation(); reset_occupations(); /* behave as if you had moved */ @@ -1687,6 +1824,7 @@ else if (tim_tmp < 0) tim_tmp = -(rnd(-tim_tmp) / 2); tim_tmp += -u.uac + 10; u.uswldtim = (unsigned)((tim_tmp < 2) ? 2 : tim_tmp); + if(u.uswldtim<2) u.uswldtim=2; /* Give the poor player *some* leeway... */ swallowed(1); for (otmp2 = invent; otmp2; otmp2 = otmp2->nobj) (void) snuff_lit(otmp2); @@ -2111,6 +2249,11 @@ boolean agrinvis, defperc; xchar genagr, gendef; + if(magr != &youmonst) { + if(magr->data == &mons[PM_LUST]) return 1; /* Lust will do it with *anything*... */ + if(magr->data == &mons[PM_GREED]) return 2; /* Greed always just charms you a bit and then takes your stuff. */ + } + if (is_animal(magr->data)) return (0); if(magr == &youmonst) { pagr = youmonst.data; @@ -2161,6 +2304,8 @@ { register struct obj *ring, *nring; boolean fem = (mon->data == &mons[PM_SUCCUBUS]); /* otherwise incubus */ + if(mon->data == &mons[PM_LUST]) fem = 1-poly_gender(); /* Assume Lust takes body of the opposite gender to player */ + if(mon->data == &mons[PM_GREED]) fem = poly_gender(); /* Assume Greed takes body of the same gender as player */ char qbuf[QBUFSZ]; if (mon->mcan || mon->mspec_used) { @@ -2183,7 +2328,7 @@ nring = ring->nobj; if (ring->otyp != RIN_ADORNMENT) continue; if (fem) { - if (rn2(20) < ACURR(A_CHA)) { + if (rn2(20) < ACURR(A_CHA) && !is_vice(mon->data)) { Sprintf(qbuf, "\"That %s looks pretty. May I have it?\"", safe_qbuf("",sizeof("\"That looks pretty. May I have it?\""), xname(ring), simple_typename(ring->otyp), "ring")); @@ -2205,7 +2350,7 @@ && uright->otyp==RIN_ADORNMENT) break; if (ring==uleft || ring==uright) continue; - if (rn2(20) < ACURR(A_CHA)) { + if (rn2(20) < ACURR(A_CHA) && !is_vice(mon->data)) { Sprintf(qbuf,"\"That %s looks pretty. Would you wear it for me?\"", safe_qbuf("", sizeof("\"That looks pretty. Would you wear it for me?\""), @@ -2254,17 +2399,31 @@ else pline("%s murmurs in your ear, while helping you undress.", Blind ? (fem ? "She" : "He") : Monnam(mon)); - mayberem(uarmc, cloak_simple_name(uarmc)); - if(!uarmc) - mayberem(uarm, "suit"); - mayberem(uarmf, "boots"); - if(!uwep || !welded(uwep)) - mayberem(uarmg, "gloves"); - mayberem(uarms, "shield"); - mayberem(uarmh, "helmet"); + + Strcpy(qbuf, "%s"); + if(is_vice(mon->data)) Strcpy(qbuf, "_%s"); + char buf[BUFSZ]; + Sprintf(buf, qbuf, cloak_simple_name(uarmc)); + mayberem(uarmc, buf); + if(!uarmc) { + Sprintf(buf, qbuf, "suit"); + mayberem(uarm, qbuf); + } + Sprintf(buf, qbuf, "boots"); + mayberem(uarmf, buf); + if(!uwep || !welded(uwep)) { + Sprintf(buf, qbuf, "gloves"); + mayberem(uarmg, qbuf); + } + Sprintf(buf, qbuf, "shield"); + mayberem(uarmc, buf); + Sprintf(buf, qbuf, "helmet"); + mayberem(uarmc, buf); #ifdef TOURIST - if(!uarmc && !uarm) - mayberem(uarmu, "shirt"); + if(!uarmc && !uarm) { + Sprintf(buf, qbuf, "shirt"); + mayberem(uarmu, buf); + } #endif if (uarm || uarmc) { @@ -2279,7 +2438,7 @@ /* 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...", noit_mon_nam(mon)); - if (rn2(35) > ACURR(A_CHA) + ACURR(A_INT)) { + if (rn2(35) > ACURR(A_CHA) + ACURR(A_INT) || is_vice(mon->data)) { /* Don't bother with mspec_used here... it didn't get tired! */ pline("%s seems to have enjoyed it more than you...", noit_Monnam(mon)); @@ -2351,7 +2510,7 @@ } if (mon->mtame) /* don't charge */ ; - else if (rn2(20) < ACURR(A_CHA)) { + else if (rn2(20) < ACURR(A_CHA) - (is_vice(mon->data) ? 10 : 0)) { pline("%s demands that you pay %s, but you refuse...", noit_Monnam(mon), Blind ? (fem ? "her" : "him") : mhim(mon)); @@ -2401,7 +2560,7 @@ } #endif } - if (!rn2(25)) mon->mcan = 1; /* monster is worn out */ + if (!rn2(25) && !is_vice(mon->data)) mon->mcan = 1; /* monster is worn out */ if (!tele_restrict(mon)) (void) rloc(mon, FALSE); return 1; } @@ -2412,10 +2571,16 @@ const char *str; { char qbuf[QBUFSZ]; + int moncha = 0; if (!obj || !obj->owornmask) return; - if (rn2(20) < ACURR(A_CHA)) { + if(str && str[0]=='_') { + str++; + moncha = 10; + } + + if (rn2(20) < ACURR(A_CHA) - moncha) { Sprintf(qbuf,"\"Shall I remove your %s, %s?\"", str, (!rn2(2) ? "lover" : !rn2(2) ? "dear" : "sweetheart")); diff -Nurd nethack-3.4.3/src/mkobj.c nethack-sins/src/mkobj.c --- nethack-orig/src/mkobj.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/mkobj.c 2006-04-07 03:20:46.000000000 +0100 @@ -661,7 +661,7 @@ when = ROT_AGE - corpse_age; when += (long)(rnz(rot_adjust) - rot_adjust); - if (is_rider(&mons[body->corpsenm])) { + if (is_endgamenasty(&mons[body->corpsenm])) { /* * Riders always revive. They have a 1/3 chance per turn * of reviving after 12 turns. Always revive by 500. @@ -889,9 +889,9 @@ #ifdef OVL1 /* return TRUE if the corpse has special timing */ -#define special_corpse(num) (((num) == PM_LIZARD) \ - || ((num) == PM_LICHEN) \ - || (is_rider(&mons[num])) \ +#define special_corpse(num) (((num) == PM_LIZARD) \ + || ((num) == PM_LICHEN) \ + || (is_endgamenasty(&mons[num])) \ || (mons[num].mlet == S_TROLL)) /* diff -Nurd nethack-3.4.3/src/mon.c nethack-sins/src/mon.c --- nethack-orig/src/mon.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/mon.c 2006-04-07 17:25:41.000000000 +0100 @@ -966,7 +966,7 @@ if (otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm]) && !(mtmp->misc_worn_check & W_ARMG) && !resists_ston(mtmp)) return FALSE; - if (otyp == CORPSE && is_rider(&mons[otmp->corpsenm])) + if (otyp == CORPSE && is_endgamenasty(&mons[otmp->corpsenm])) return FALSE; if (objects[otyp].oc_material == SILVER && hates_silver(mdat) && (otyp != BELL_OF_OPENING || !is_covetous(mdat))) @@ -1551,7 +1551,7 @@ if (bigmonst(mdat) || mdat == &mons[PM_LIZARD] || is_golem(mdat) || is_mplayer(mdat) - || is_rider(mdat)) + || is_endgamenasty(mdat)) return TRUE; return (boolean) (!rn2((int) (2 + ((int)(mdat->geno & G_FREQ)<2) + verysmall(mdat)))); @@ -1751,7 +1751,6 @@ boolean redisp = FALSE; boolean wasinside = u.uswallow && (u.ustuck == mtmp); - /* KMH, conduct */ u.uconduct.killer++; @@ -1809,7 +1808,6 @@ if((dest & 2) || LEVEL_SPECIFIC_NOCORPSE(mdat)) goto cleanup; - #ifdef MAIL if(mdat == &mons[PM_MAIL_DAEMON]) { stackobj(mksobj_at(SCR_MAIL, x, y, FALSE, FALSE)); @@ -1821,9 +1819,13 @@ /* might be mimic in wall or corpse in lava or on player's spot */ redisp = TRUE; if(wasinside) spoteffects(TRUE); + if(is_endgamenasty(mtmp->data)) { + (void) make_corpse(mtmp); + redisp = TRUE; + } } else if(x != u.ux || y != u.uy) { /* might be here after swallowed */ - if (!rn2(6) && !(mvitals[mndx].mvflags & G_NOCORPSE) + if (!rn2(6) && !is_endgamenasty(mtmp->data) && !(mvitals[mndx].mvflags & G_NOCORPSE) #ifdef KOPS && mdat->mlet != S_KOP #endif @@ -1847,8 +1849,9 @@ * different from whether or not the corpse is "special"; * if we want both, we have to specify it explicitly. */ - if (corpse_chance(mtmp, (struct monst *)0, FALSE)) + if (corpse_chance(mtmp, (struct monst *)0, FALSE)) { (void) make_corpse(mtmp); + } } if(redisp) newsym(x,y); cleanup: diff -Nurd nethack-3.4.3/src/mondata.c nethack-sins/src/mondata.c --- nethack-orig/src/mondata.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/mondata.c 2006-04-07 05:41:13.000000000 +0100 @@ -385,8 +385,8 @@ i = (int)(ptr - &mons[0]); if (i < LOW_PM || i >= NUMMONS) { /* ought to switch this to use `fmt_ptr' */ - panic("monsndx - could not index monster (%lx)", - (unsigned long)ptr); + panic("monsndx - could not index monster (%d:%lx)", + i, (unsigned long)ptr); return NON_PM; /* will not get here */ } diff -Nurd nethack-3.4.3/src/monmove.c nethack-sins/src/monmove.c --- nethack-orig/src/monmove.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/monmove.c 2006-04-07 03:19:17.000000000 +0100 @@ -134,7 +134,7 @@ if (mtmp->isshk || mtmp->isgd || mtmp->iswiz || !mtmp->mcansee || mtmp->mpeaceful || mtmp->data->mlet == S_HUMAN || is_lminion(mtmp) || mtmp->data == &mons[PM_ANGEL] || - is_rider(mtmp->data) || mtmp->data == &mons[PM_MINOTAUR]) + is_endgamenasty(mtmp->data) || mtmp->data == &mons[PM_MINOTAUR]) return(FALSE); return (boolean)(sobj_at(SCR_SCARE_MONSTER, x, y) @@ -636,7 +636,7 @@ can_tunnel = tunnels(ptr); can_open = !(nohands(ptr) || verysmall(ptr)); can_unlock = ((can_open && m_carrying(mtmp, SKELETON_KEY)) || - mtmp->iswiz || is_rider(ptr)); + mtmp->iswiz || is_endgamenasty(ptr)); doorbuster = is_giant(ptr); if(mtmp->wormno) goto not_special; /* my dog gets special treatment */ @@ -828,7 +828,7 @@ if(((likegold && otmp->oclass == COIN_CLASS) || (likeobjs && index(practical, otmp->oclass) && (otmp->otyp != CORPSE || (ptr->mlet == S_NYMPH - && !is_rider(&mons[otmp->corpsenm])))) || + && !is_endgamenasty(&mons[otmp->corpsenm]) ))) || (likemagic && index(magical, otmp->oclass)) || (uses_items && searches_for_item(mtmp, otmp)) || (likerock && otmp->otyp == BOULDER) || @@ -890,7 +890,7 @@ if (mtmp->mpeaceful && (!Conflict || resist(mtmp, RING_CLASS, 0, 0))) flag |= (ALLOW_SANCT | ALLOW_SSM); else flag |= ALLOW_U; - if (is_minion(ptr) || is_rider(ptr)) flag |= ALLOW_SANCT; + if (is_minion(ptr) || is_endgamenasty(ptr)) flag |= ALLOW_SANCT; /* unicorn may not be able to avoid hero on a noteleport level */ if (is_unicorn(ptr) && !level.flags.noteleport) flag |= NOTONL; if (passes_walls(ptr)) flag |= (ALLOW_WALL | ALLOW_ROCK); diff -Nurd nethack-3.4.3/src/monst.c nethack-sins/src/monst.c --- nethack-orig/src/monst.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/monst.c 2006-04-08 20:01:09.000000000 +0100 @@ -634,23 +634,26 @@ /* * nymphs */ + /* Their AD_SEDU attacks are turned into AD_SITM ones to make them behave normally, + * now that these are different. The whole thing was strange anyway. + */ MON("wood nymph", S_NYMPH, LVL(3, 12, 9, 20, 0), (G_GENO|2), - A(ATTK(AT_CLAW, AD_SITM, 0, 0), ATTK(AT_CLAW, AD_SEDU, 0, 0), + A(ATTK(AT_CLAW, AD_SITM, 0, 0), ATTK(AT_CLAW, AD_SITM, 0, 0), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(600, 300, 0, MS_SEDUCE, MZ_HUMAN), 0, 0, M1_HUMANOID|M1_TPORT, M2_HOSTILE|M2_FEMALE|M2_COLLECT, M3_INFRAVISIBLE, CLR_GREEN), MON("water nymph", S_NYMPH, LVL(3, 12, 9, 20, 0), (G_GENO|2), - A(ATTK(AT_CLAW, AD_SITM, 0, 0), ATTK(AT_CLAW, AD_SEDU, 0, 0), + A(ATTK(AT_CLAW, AD_SITM, 0, 0), ATTK(AT_CLAW, AD_SITM, 0, 0), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(600, 300, 0, MS_SEDUCE, MZ_HUMAN), 0, 0, M1_HUMANOID|M1_TPORT|M1_SWIM, M2_HOSTILE|M2_FEMALE|M2_COLLECT, M3_INFRAVISIBLE, CLR_BLUE), MON("mountain nymph", S_NYMPH, LVL(3, 12, 9, 20, 0), (G_GENO|2), - A(ATTK(AT_CLAW, AD_SITM, 0, 0), ATTK(AT_CLAW, AD_SEDU, 0, 0), + A(ATTK(AT_CLAW, AD_SITM, 0, 0), ATTK(AT_CLAW, AD_SITM, 0, 0), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(600, 300, 0, MS_SEDUCE, MZ_HUMAN), 0, 0, M1_HUMANOID|M1_TPORT, M2_HOSTILE|M2_FEMALE|M2_COLLECT, @@ -2762,7 +2765,83 @@ LVL(30, 12, -5, 100, 0), (G_UNIQ|G_NOGEN), A(ATTK(AT_TUCH, AD_FAMN, 8, 8), ATTK(AT_TUCH, AD_FAMN, 8, 8), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), - SIZ(WT_HUMAN, 1, 0, MS_RIDER, MZ_HUMAN), + SIZ((WT_SKHUMAN), 1, 0, MS_RIDER, MZ_HUMAN), + MR_FIRE|MR_COLD|MR_ELEC|MR_SLEEP|MR_POISON|MR_STONE, 0, + M1_FLY|M1_HUMANOID|M1_REGEN|M1_SEE_INVIS|M1_TPORT_CNTRL, + M2_NOPOLY|M2_STALK|M2_HOSTILE|M2_PNAME|M2_STRONG|M2_NASTY, + M3_INFRAVISIBLE|M3_INFRAVISION, HI_LORD), + /* Vices -- the Seven Deadly Sins + * Do not reorder, as selection code relies on Gluttony being first. + */ + MON("Gluttony", S_DEMON, + LVL(30, 12, -5, 100, 0), (G_UNIQ|G_NOGEN), + A(ATTK(AT_ENGL, AD_DGST, 8, 8), ATTK(AT_ENGL, AD_DGST, 8, 8), + NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), + SIZ(WT_FTHUMAN, 1, 0, MS_VICE, MZ_HUMAN), + MR_FIRE|MR_COLD|MR_ELEC|MR_SLEEP|MR_POISON|MR_STONE, 0, + M1_FLY|M1_HUMANOID|M1_REGEN|M1_SEE_INVIS|M1_TPORT_CNTRL|M1_OMNIVORE|M1_METALLIVORE, + M2_NOPOLY|M2_STALK|M2_HOSTILE|M2_PNAME|M2_STRONG|M2_NASTY, + M3_INFRAVISIBLE|M3_INFRAVISION, HI_LORD), +#ifdef SEDUCE +# define AD_LUST AD_SSEX +# define AD_GRED AD_SEDU +#else +# define AD_LUST AD_SEDU +# define AD_GRED AD_SGLD +#endif + MON("Lust", S_DEMON, + LVL(30, 12, -5, 100, 0), (G_UNIQ|G_NOGEN), + A(ATTK(AT_CLAW, AD_LUST, 8, 8), ATTK(AT_CLAW, AD_LUST, 8, 8), + NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), + SIZ(WT_HUMAN, 1, 0, MS_VICE, MZ_HUMAN), + MR_FIRE|MR_COLD|MR_ELEC|MR_SLEEP|MR_POISON|MR_STONE, 0, + M1_FLY|M1_HUMANOID|M1_REGEN|M1_SEE_INVIS|M1_TPORT_CNTRL, + M2_NOPOLY|M2_STALK|M2_HOSTILE|M2_PNAME|M2_STRONG|M2_NASTY, + M3_INFRAVISIBLE|M3_INFRAVISION, HI_LORD), + MON("Greed", S_DEMON, + LVL(30, 12, -5, 100, 0), (G_UNIQ|G_NOGEN), + A(ATTK(AT_CLAW, AD_GRED, 8, 8), ATTK(AT_CLAW, AD_GRED, 8, 8), + NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), + SIZ(WT_HUMAN, 1, 0, MS_VICE, MZ_HUMAN), + MR_FIRE|MR_COLD|MR_ELEC|MR_SLEEP|MR_POISON|MR_STONE, 0, + M1_FLY|M1_HUMANOID|M1_REGEN|M1_SEE_INVIS|M1_TPORT_CNTRL, + M2_NOPOLY|M2_STALK|M2_HOSTILE|M2_PNAME|M2_STRONG|M2_NASTY, + M3_COVETOUS|M3_INFRAVISIBLE|M3_INFRAVISION, HI_LORD), +#undef AD_LUST +#undef AD_GRED + MON("Envy", S_DEMON, + LVL(30, 12, -5, 100, 0), (G_UNIQ|G_NOGEN), + A(ATTK(AT_CLAW, AD_CURS, 8, 8), ATTK(AT_CLAW, AD_CURS, 8, 8), + NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), + SIZ(WT_HUMAN, 1, 0, MS_VICE, MZ_HUMAN), + MR_FIRE|MR_COLD|MR_ELEC|MR_SLEEP|MR_POISON|MR_STONE, 0, + M1_FLY|M1_HUMANOID|M1_REGEN|M1_SEE_INVIS|M1_TPORT_CNTRL, + M2_NOPOLY|M2_STALK|M2_HOSTILE|M2_PNAME|M2_STRONG|M2_NASTY, + M3_COVETOUS|M3_INFRAVISIBLE|M3_INFRAVISION, HI_LORD), + MON("Wrath", S_DEMON, + LVL(30, 12, -5, 100, 0), (G_UNIQ|G_NOGEN), + A(ATTK(AT_CLAW, AD_PHYS, 8, 8), ATTK(AT_CLAW, AD_PHYS, 8, 8), + ATTK(AT_CLAW, AD_DRE2, 8, 8), ATTK(AT_CLAW, AD_DRLI, 8, 8), + NO_ATTK, NO_ATTK), + SIZ(WT_HUMAN, 1, 0, MS_VICE, MZ_HUMAN), + MR_FIRE|MR_COLD|MR_ELEC|MR_SLEEP|MR_POISON|MR_STONE, 0, + M1_FLY|M1_HUMANOID|M1_REGEN|M1_SEE_INVIS|M1_TPORT_CNTRL, + M2_NOPOLY|M2_STALK|M2_HOSTILE|M2_PNAME|M2_STRONG|M2_NASTY, + M3_INFRAVISIBLE|M3_INFRAVISION, HI_LORD), + MON("Sloth", S_DEMON, /* Sloth only touches, he doesn't directly cause damage. 'Cause he's too lazy. */ + LVL(30, 12, -5, 100, 0), (G_UNIQ|G_NOGEN), + A(ATTK(AT_TUCH, AD_LAZY, 0, 0), ATTK(AT_TUCH, AD_LAZY, 0, 0), + NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), + SIZ(WT_HUMAN, 1, 0, MS_VICE, MZ_HUMAN), + MR_FIRE|MR_COLD|MR_ELEC|MR_SLEEP|MR_POISON|MR_STONE, 0, + M1_FLY|M1_HUMANOID|M1_REGEN|M1_SEE_INVIS|M1_TPORT_CNTRL, + M2_NOPOLY|M2_STALK|M2_HOSTILE|M2_PNAME|M2_STRONG|M2_NASTY, + M3_INFRAVISIBLE|M3_INFRAVISION, HI_LORD), + MON("Pride", S_DEMON, + LVL(30, 12, -5, 100, 0), (G_UNIQ|G_NOGEN), + A(ATTK(AT_CLAW, AD_DRCH, 8, 8), ATTK(AT_CLAW, AD_DFOO, 8, 8), + NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), + SIZ(WT_HUMAN, 1, 0, MS_VICE, MZ_HUMAN), MR_FIRE|MR_COLD|MR_ELEC|MR_SLEEP|MR_POISON|MR_STONE, 0, M1_FLY|M1_HUMANOID|M1_REGEN|M1_SEE_INVIS|M1_TPORT_CNTRL, M2_NOPOLY|M2_STALK|M2_HOSTILE|M2_PNAME|M2_STRONG|M2_NASTY, Binary files nethack-orig/src/nethack and nethack-sins/src/nethack differ Binary files nethack-orig/src/nethack-vices and nethack-sins/src/nethack-vices differ diff -Nurd nethack-3.4.3/src/pickup.c nethack-sins/src/pickup.c --- nethack-orig/src/pickup.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/pickup.c 2006-04-07 03:18:30.000000000 +0100 @@ -1317,7 +1317,7 @@ instapetrify(kbuf); return -1; } - } else if (is_rider(&mons[obj->corpsenm])) { + } else if (is_endgamenasty(&mons[obj->corpsenm])) { pline("At your %s, the corpse suddenly moves...", telekinesis ? "attempted acquisition" : "touch"); (void) revive_corpse(obj); diff -Nurd nethack-3.4.3/src/pray.c nethack-sins/src/pray.c --- nethack-orig/src/pray.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/pray.c 2006-04-07 15:39:37.000000000 +0100 @@ -497,7 +497,7 @@ mon_nam(u.ustuck)); if (!resists_disint(u.ustuck)) { pline("%s fries to a crisp!", Monnam(u.ustuck)); - xkilled(u.ustuck, 2); /* no corpse */ + xkilled(u.ustuck, (is_vice(u.ustuck->data) ? 0 : 2)); /* no message, only corpse for Gluttony */ } else pline("%s seems unaffected.", Monnam(u.ustuck)); } else { diff -Nurd nethack-3.4.3/src/priest.c nethack-sins/src/priest.c --- nethack-orig/src/priest.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/priest.c 2006-04-07 03:18:16.000000000 +0100 @@ -586,7 +586,7 @@ register struct monst *priest; if (mon) { - if (is_minion(mon->data) || is_rider(mon->data)) return FALSE; + if (is_minion(mon->data) || is_endgamenasty(mon->data)) return FALSE; x = mon->mx, y = mon->my; } if (u.ualign.record <= ALGN_SINNED) /* sinned or worse */ diff -Nurd nethack-3.4.3/src/sounds.c nethack-sins/src/sounds.c --- nethack-orig/src/sounds.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/sounds.c 2006-04-07 20:52:54.000000000 +0100 @@ -813,6 +813,37 @@ pline_msg = "is busy reading a copy of Sandman #8."; else verbl_msg = "Who do you think you are, War?"; break; + case MS_VICE: + switch(monsndx(ptr)) { + case PM_GLUTTONY: + pline_msg = "mumbles through a mouthful of food."; + break; + case PM_LUST: + pline_msg = "breathes heavily..."; + break; + case PM_GREED: + verbl_msg = "Mine! All mine!"; + break; + case PM_ENVY: +#ifndef GOLDOBJ + if(u.ugold) +#else + if(money_cnt(invent)) +#endif + verbl_msg = "Give me that gold!"; + else + pline_msg = "stares at you jealously."; + break; + case PM_WRATH: + pline_msg = "glares at you ferociously."; + break; + case PM_SLOTH: + pline_msg = "sighs."; + break; + case PM_PRIDE: + pline_msg = "doesn't deign to reply."; + break; + } } if (pline_msg) pline("%s %s", Monnam(mtmp), pline_msg); diff -Nurd nethack-3.4.3/src/steal.c nethack-sins/src/steal.c --- nethack-orig/src/steal.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/steal.c 2006-04-07 15:12:47.000000000 +0100 @@ -50,7 +50,7 @@ newsym(u.ux, u.uy); pline("%s quickly snatches some gold from between your %s!", Monnam(mtmp), makeplural(body_part(FOOT))); - if(!u.ugold || !rn2(5)) { + if((!u.ugold || !rn2(5)) && !is_vice(mtmp->data)) { if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); /* do not set mtmp->mavenge here; gold on the floor is fair game */ monflee(mtmp, 0, FALSE, FALSE); @@ -59,9 +59,11 @@ u.ugold -= (tmp = somegold()); Your("purse feels lighter."); mtmp->mgold += tmp; - if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); - mtmp->mavenge = 1; - monflee(mtmp, 0, FALSE, FALSE); + if(!is_vice(mtmp->data)) { + if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); + mtmp->mavenge = 1; + monflee(mtmp, 0, FALSE, FALSE); + } flags.botl = 1; } } @@ -119,7 +121,7 @@ newsym(u.ux, u.uy); pline("%s quickly snatches some gold from between your %s!", Monnam(mtmp), makeplural(body_part(FOOT))); - if(!ygold || !rn2(5)) { + if((!ygold || !rn2(5)) && !is_vice(mtmp->data)) { if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); monflee(mtmp, 0, FALSE, FALSE); } @@ -131,8 +133,10 @@ freeinv(ygold); add_to_minv(mtmp, ygold); Your("purse feels lighter."); - if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); - monflee(mtmp, 0, FALSE, FALSE); + if(!is_vice(mtmp->data)) { + if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); + monflee(mtmp, 0, FALSE, FALSE); + } flags.botl = 1; } } @@ -162,8 +166,10 @@ (void) mpickobj(mtmp,otmp); /* may free otmp */ /* Implies seduction, "you gladly hand over ..." so we don't set mavenge bit here. */ - monflee(mtmp, 0, FALSE, FALSE); - if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); + if(!is_vice(mtmp->data)) { + monflee(mtmp, 0, FALSE, FALSE); + if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); + } break; } } diff -Nurd nethack-3.4.3/src/teleport.c nethack-sins/src/teleport.c --- nethack-orig/src/teleport.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/teleport.c 2006-04-07 03:18:03.000000000 +0100 @@ -1166,7 +1166,7 @@ boolean restricted_fall; int try_limit = 4000; - if (obj->otyp == CORPSE && is_rider(&mons[obj->corpsenm])) { + if (obj->otyp == CORPSE && is_endgamenasty(&mons[obj->corpsenm])) { if (revive_corpse(obj)) return; } @@ -1280,7 +1280,7 @@ You("are no longer inside %s!", mon_nam(mtmp)); unstuck(mtmp); (void) rloc(mtmp, FALSE); - } else if (is_rider(mtmp->data) && rn2(13) && + } else if (is_endgamenasty(mtmp->data) && rn2(13) && enexto(&cc, u.ux, u.uy, mtmp->data)) rloc_to(mtmp, cc.x, cc.y); else diff -Nurd nethack-3.4.3/src/uhitm.c nethack-sins/src/uhitm.c --- nethack-orig/src/uhitm.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/uhitm.c 2006-04-07 15:41:07.000000000 +0100 @@ -1764,7 +1764,7 @@ switch(mattk->adtyp) { case AD_DGST: /* eating a Rider or its corpse is fatal */ - if (is_rider(mdef->data)) { + if (is_endgamenasty(mdef->data)) { pline("Unfortunately, digesting any of it is fatal."); end_engulf(); Sprintf(msgbuf, "unwisely tried to eat %s", diff -Nurd nethack-3.4.3/src/zap.c nethack-sins/src/zap.c --- nethack-orig/src/zap.c 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/src/zap.c 2006-04-08 21:01:45.000000000 +0100 @@ -468,14 +468,14 @@ if (mtmp2) { /* save_mtraits() validated mtmp2->mnum */ mtmp2->data = &mons[mtmp2->mnum]; - if (mtmp2->mhpmax <= 0 && !is_rider(mtmp2->data)) + if (mtmp2->mhpmax <= 0 && !is_endgamenasty(mtmp2->data)) return (struct monst *)0; mtmp = makemon(mtmp2->data, cc->x, cc->y, NO_MINVENT|MM_NOWAIT|MM_NOCOUNTBIRTH); if (!mtmp) return mtmp; /* heal the monster */ - if (mtmp->mhpmax > mtmp2->mhpmax && is_rider(mtmp2->data)) + if (mtmp->mhpmax > mtmp2->mhpmax && is_endgamenasty(mtmp2->data)) mtmp2->mhpmax = mtmp->mhpmax; mtmp2->mhp = mtmp2->mhpmax; /* Get these ones from mtmp */ @@ -988,7 +988,7 @@ obj->otyp == SPE_BOOK_OF_THE_DEAD || obj->otyp == CANDELABRUM_OF_INVOCATION || obj->otyp == BELL_OF_OPENING || - (obj->otyp == CORPSE && is_rider(&mons[obj->corpsenm]))) { + (obj->otyp == CORPSE && is_endgamenasty(&mons[obj->corpsenm]))) { return TRUE; } else { int chance = rn2(100); @@ -3355,7 +3355,7 @@ boolean mon_could_move = mon->mcanmove; int tmp = zhitm(mon, type, nd, &otmp); - if (is_rider(mon->data) && abs(type) == ZT_BREATH(ZT_DEATH)) { + if (is_endgamenasty(mon->data) && abs(type) == ZT_BREATH(ZT_DEATH)) { if (canseemon(mon)) { hit(fltxt, mon, "."); pline("%s disintegrates.", Monnam(mon)); @@ -3832,7 +3832,12 @@ for(obj = invent; obj; obj = obj2) { obj2 = obj->nobj; - if(obj->oclass != osym) continue; /* test only objs of type osym */ + if(dmgtyp==AD_LAZY) { + if(!(obj->otyp==SPEED_BOOTS || obj->otyp==JUMPING_BOOTS || obj->otyp==GAUNTLETS_OF_DEXTERITY || obj->otyp==RIN_FREE_ACTION || obj->otyp==SCR_TELEPORTATION || obj->otyp==WAN_TELEPORTATION || obj->otyp==RIN_TELEPORTATION || obj->otyp==POT_SPEED)) + continue; /* those were all we wanted */ + } else { + if(obj->oclass != osym) continue; /* test only objs of type osym */ + } if(obj->oartifact) continue; /* don't destroy artifacts */ if(obj->in_use && obj->quan == 1) continue; /* not available */ xresist = skip = 0; @@ -3901,6 +3906,12 @@ break; } break; + case AD_LAZY: + /* Object-type checking is done further up. For laziness. */ + quan = obj->quan; + dindx = 4; + dmg = 0; + break; default: skip++; break; Binary files nethack-orig/util/dlb and nethack-sins/util/dlb differ Binary files nethack-orig/util/makedefs and nethack-sins/util/makedefs differ Binary files nethack-orig/util/recover and nethack-sins/util/recover differ Binary files nethack-orig/util/tile2bmp and nethack-sins/util/tile2bmp differ Binary files nethack-orig/util/tile2x11 and nethack-sins/util/tile2x11 differ Binary files nethack-orig/util/tilemap and nethack-sins/util/tilemap differ Binary files nethack-orig/util/tiles.bmp and nethack-sins/util/tiles.bmp differ Binary files nethack-orig/util/tiles.png and nethack-sins/util/tiles.png differ Binary files nethack-orig/util/tiles.ppm and nethack-sins/util/tiles.ppm differ Binary files nethack-orig/util/txt2ppm and nethack-sins/util/txt2ppm differ diff -Nurd nethack-3.4.3/win/share/monsters.txt nethack-sins/win/share/monsters.txt --- nethack-orig/win/share/monsters.txt 2006-04-06 21:04:27.000000000 +0100 +++ nethack-sins/win/share/monsters.txt 2006-04-08 16:01:21.000000000 +0100 @@ -6037,6 +6037,139 @@ KMMMJJAAAJJAAMMM KMMJJAAAAAJJJAMM } +# tile 000 (Gluttony) +{ + MMMMMMMMMMMPPMMM + MMMMMMMPPPPPPPMM + MMMMMPPPPPPPPMMM + MMMMPAAAAAPPPMMM + MMMPAGGAGGAPPMMM + MMMPAAAAAAAPMMMM + MMMMPAAAAAPPMMMM + MMMMPPAAAPPAMMMM + MMPPAPAAPPAPPMMM + MPPPAPAAPPAPPPMM + LLPMPPAAPPPAPPPM + LLMMPPPAPPPPAPLL + MMMMPPPAPPPPPMLL + MMMMPPPAPPPPPMMM + MMMPPPPAPPPPMMMM + MMMPPAAAAAPPMMMM +} +# tile 000 (Lust) +{ + MMMMMMMMMMMMMMMM + MMMMMMDDMMMMMMMM + MMMMMDDDDMMMMMMM + MMMMMGLGDAMMMMMM + MMMMMLLLLAMMAAAM + MMMMPALLAPMAAAAM + MMMPPLAALPPAAAMM + MMMPLLLLLLPAAAMM + MMMLALLLLALPAAMM + MMMLALLLLALPPAAM + MMMLMJCLCALPPPAA + MMMMMCJCJPPPPPAA + MMMMMJJJCPPAAMMM + MMMMJJAAJJAMMMMM + MMMMLLAMLLAMMMMM + MMMMMMMMMMMMMMMM +} +# tile 000 (Greed) +{ + MMMMMMMMMMPPMMMM + MMMMMMMPPPPPMMMM + MMMMMMPPPPPMMMMM + MMMMMPAAAPPMMMMM + MMMMMPGAGPMMMMAA + MMMMMPAAAPMMAAAM + MMMMPPAAAPMMAAAM + MMMPAPPAPPAAAAAM + MMMPPAHHHPPPAAAM + MMMPPPHHHHPPAAMM + MMMPPPLHLPPPAAMM + MMMMAPLLLPPAAAMM + MMMPPHAAAHAAAMMM + MMMPPAAAAAPPAMMM + MMMPPAAAAAAPPMMM + MMPPAAAAAAAAPPMM +} +# tile 000 (Envy) +{ + MMMMMMMMMMMMMMMM + MMMMMMMMPPPMMMMM + MMMMMMMPPPPPPMMM + MMMMMMPAAAPPPPAM + MMMMMMPGAGPAAAAA + MMMMMMPAAAPAAAAA + GLLPMMPAAAAPAAAM + MLPPPPAAAAPPPAAM + MMPPPAPAAPPPPAAA + MMPMMPAAAPPPPAAA + MMMMMPAAAPPPPPAA + MMMMPAAAPPPPPPAA + MMMMPAAAPPPPPPAM + MMMMPAAAPPPPPPMM + MMMPAAAPPPPPPMMM + MMMPAAAAAPPPMMMM +} +# tile 000 (Wrath) +{ + MMMMMMMMMMMMMOMM + MMMMMMMPPPPPMOMM + MMMMMMPPPPPMMOMM + MMMMMPAAAPPMMOMA + MMMMPAGAGAPMAOAA + MMMMPAAAAAPAAOAA + MMMMPAAAAAPAAOAM + MMMMMPAAAPPADDDM + MMMMPAPAPPAPLLAA + MMMPPPPAPPPPLDAA + MLLPPPPAPPPPAAAM + MLLPPPPAPPPAAAMM + MMMPMPPAPPPAAMMM + MMMMMPPAPPPAAMMM + MMMMMPPAPPPPAMMM + MMMMMPPAPPPPMMMM +} +# tile 000 (Sloth) +{ + MAAMMMMMMMMMMMMM + MMAAMMMMMMMMMMMM + MMMMMMMPPPPMMMMM + MMAAMMPPPPPPMMMM + MMMAAPPAPPAPMMMM + MMMMMPAAAPMAMAAA + MMMMMPGAGPMMAAAA + MMMMMPAAAPMAAAAA + MMMMMPPAAPAAAAMA + MMMMPAPAPPAAAAMM + MMMPPPPAPAPAAAAM + MMMPPPPAPPPPAAMM + MMMPLLPAPLLPAAMM + MMMMPLPAPLPAAMMM + MMMMPPPAPPPAAMMM + MMMPPPPAPPPPMMMM +} +# tile 000 (Pride) +{ + MMMMMMMMMMMMMMMM + MMMMMMMPPPPPPMMM + MMMMMMPPPPPPMMMM + MMMMMPAAAPPMAMIM + MMMMPAGAGAPAAAOA + MMMMPAAAAAPAAAJA + LLPMPAAAAAPAAPLL + LLPPMPAAAPAAPPLL + MMPPPPIAIPPPPPJA + MMPPPPIAIPPPPPJA + MMMMMPIAIPAAAAJA + MMMMMPIAIPAAAAJM + MMMMMPIAIPAAAAMM + MMMMPPIAIPPAAAMM + MMMMPIIAIIPAAMMM + MMMPPIIAIIPPMMMM +} # tile 317 (mail daemon) { MMMOPMBEEEMPOMMM