diff -u -X files.exc nethack-3.4.3-orig/include/artifact.h nethack-3.4.3-banes/include/artifact.h --- nethack-3.4.3-orig/include/artifact.h Sun Dec 07 17:39:14 2003 +++ nethack-3.4.3-banes/include/artifact.h Thu Sep 22 20:51:30 2005 @@ -34,6 +34,7 @@ #define SPFX_DBONUS 0x1F00000L /* attack bonus mask */ #define SPFX_XRAY 0x2000000L /* gives X-RAY vision to player */ #define SPFX_REFLECT 0x4000000L /* Reflection */ +#define SPFX_BLIND 0x8000000L /* attack can blind */ struct artifact { diff -u -X files.exc nethack-3.4.3-orig/include/artilist.h nethack-3.4.3-banes/include/artilist.h --- nethack-3.4.3-orig/include/artilist.h Sun Dec 07 17:39:14 2003 +++ nethack-3.4.3-banes/include/artilist.h Thu Sep 22 20:52:06 2005 @@ -69,7 +69,7 @@ * Orcrist and Sting have same alignment as elves. */ A("Orcrist", ELVEN_BROADSWORD, - SPFX_DFLAG2, 0, M2_ORC, + (SPFX_WARN|SPFX_DFLAG2), 0, M2_ORC, PHYS(5,0), NO_DFNS, NO_CARY, 0, A_CHAOTIC, NON_PM, PM_ELF, 2000L ), /* @@ -98,32 +98,32 @@ FIRE(5,0), FIRE(0,0), NO_CARY, 0, A_NONE, NON_PM, NON_PM, 3000L ), A("Dragonbane", BROADSWORD, - (SPFX_RESTR|SPFX_DCLAS), 0, S_DRAGON, - PHYS(5,0), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 500L ), + (SPFX_WARN|SPFX_RESTR|SPFX_DCLAS|SPFX_REFLECT), 0, S_DRAGON, + PHYS(8,20), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 500L ), A("Demonbane", LONG_SWORD, - (SPFX_RESTR|SPFX_DFLAG2), 0, M2_DEMON, - PHYS(5,0), NO_DFNS, NO_CARY, 0, A_LAWFUL, NON_PM, NON_PM, 2500L ), + (SPFX_WARN|SPFX_RESTR|SPFX_DFLAG2), 0, M2_DEMON, + PHYS(8,20), DRLI(0,0), NO_CARY, 0, A_LAWFUL, NON_PM, NON_PM, 2500L ), A("Werebane", SILVER_SABER, - (SPFX_RESTR|SPFX_DFLAG2), 0, M2_WERE, - PHYS(5,0), DFNS(AD_WERE), NO_CARY, 0, A_NONE, NON_PM, NON_PM, 1500L ), + (SPFX_WARN|SPFX_RESTR|SPFX_DFLAG2), 0, M2_WERE, + PHYS(8,20), DFNS(AD_WERE), NO_CARY, 0, A_NONE, NON_PM, NON_PM, 1500L ), A("Grayswandir", SILVER_SABER, (SPFX_RESTR|SPFX_HALRES), 0, 0, PHYS(5,0), NO_DFNS, NO_CARY, 0, A_LAWFUL, NON_PM, NON_PM, 8000L ), A("Giantslayer", LONG_SWORD, - (SPFX_RESTR|SPFX_DFLAG2), 0, M2_GIANT, - PHYS(5,0), NO_DFNS, NO_CARY, 0, A_NEUTRAL, NON_PM, NON_PM, 200L ), + (SPFX_WARN|SPFX_RESTR|SPFX_DFLAG2), 0, M2_GIANT, + PHYS(8,20), NO_DFNS, NO_CARY, 0, A_NEUTRAL, NON_PM, NON_PM, 200L ), A("Ogresmasher", WAR_HAMMER, - (SPFX_RESTR|SPFX_DCLAS), 0, S_OGRE, - PHYS(5,0), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 200L ), + (SPFX_WARN|SPFX_RESTR|SPFX_DCLAS), 0, S_OGRE, + PHYS(8,20), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 200L ), A("Trollsbane", MORNING_STAR, - (SPFX_RESTR|SPFX_DCLAS), 0, S_TROLL, - PHYS(5,0), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 200L ), + (SPFX_WARN|SPFX_RESTR|SPFX_DCLAS|SPFX_REGEN), 0, S_TROLL, + PHYS(8,20), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 200L ), /* * Two problems: 1) doesn't let trolls regenerate heads, * 2) doesn't give unusual message for 2-headed monsters (but @@ -131,7 +131,7 @@ */ A("Vorpal Blade", LONG_SWORD, (SPFX_RESTR|SPFX_BEHEAD), 0, 0, - PHYS(5,1), NO_DFNS, NO_CARY, 0, A_NEUTRAL, NON_PM, NON_PM, 4000L ), + PHYS(5,8), NO_DFNS, NO_CARY, 0, A_NEUTRAL, NON_PM, NON_PM, 4000L ), /* * Ah, never shall I forget the cry, * or the shriek that shrieked he, @@ -145,8 +145,8 @@ PHYS(0,8), NO_DFNS, NO_CARY, 0, A_LAWFUL, PM_SAMURAI, NON_PM, 1200L ), A("Sunsword", LONG_SWORD, - (SPFX_RESTR|SPFX_DFLAG2), 0, M2_UNDEAD, - PHYS(5,0), DFNS(AD_BLND), NO_CARY, 0, A_LAWFUL, NON_PM, NON_PM, 1500L ), + (SPFX_BLIND|SPFX_WARN|SPFX_RESTR|SPFX_DFLAG2), 0, M2_UNDEAD, + PHYS(8,20), DFNS(AD_BLND), NO_CARY, 0, A_LAWFUL, NON_PM, NON_PM, 1500L ), /* * The artifacts for the quest dungeon, all self-willed. @@ -209,7 +209,7 @@ A("The Tsurugi of Muramasa", TSURUGI, (SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL|SPFX_BEHEAD|SPFX_LUCK), 0, 0, - PHYS(0,8), NO_DFNS, NO_CARY, + PHYS(2,0), NO_DFNS, NO_CARY, 0, A_LAWFUL, PM_SAMURAI, NON_PM, 4500L ), #ifdef TOURIST diff -u -X files.exc nethack-3.4.3-orig/include/hack.h nethack-3.4.3-banes/include/hack.h --- nethack-3.4.3-orig/include/hack.h Sun Dec 07 17:39:14 2003 +++ nethack-3.4.3-banes/include/hack.h Thu Aug 18 16:44:34 2005 @@ -101,7 +101,7 @@ #define INVIS_BEAM 4 #define MATCH_WARN_OF_MON(mon) (Warn_of_mon && flags.warntype && \ - (flags.warntype & (mon)->data->mflags2)) + (flags.warntype&0x80000000 ? (flags.warntype&0x7fffffff)==(mon)->data->mlet : (flags.warntype & (mon)->data->mflags2))) #include "trap.h" #include "flag.h" diff -u -X files.exc nethack-3.4.3-orig/include/obj.h nethack-3.4.3-banes/include/obj.h --- nethack-3.4.3-orig/include/obj.h Sun Dec 07 17:39:14 2003 +++ nethack-3.4.3-banes/include/obj.h Thu Sep 22 10:43:46 2005 @@ -165,9 +165,10 @@ #define is_multigen(otmp) (otmp->oclass == WEAPON_CLASS && \ objects[otmp->otyp].oc_skill >= -P_SHURIKEN && \ objects[otmp->otyp].oc_skill <= -P_BOW) -#define is_poisonable(otmp) (otmp->oclass == WEAPON_CLASS && \ +#define is_poisonable(otmp) ( (otmp->oclass == WEAPON_CLASS && \ objects[otmp->otyp].oc_skill >= -P_SHURIKEN && \ - objects[otmp->otyp].oc_skill <= -P_BOW) + objects[otmp->otyp].oc_skill <= -P_BOW) \ + || otmp->oartifact==ART_GRIMTOOTH ) #define uslinging() (uwep && objects[uwep->otyp].oc_skill == P_SLING) /* Armor */ diff -u -X files.exc nethack-3.4.3-orig/src/artifact.c nethack-3.4.3-banes/src/artifact.c --- nethack-3.4.3-orig/src/artifact.c Sun Dec 07 17:39:14 2003 +++ nethack-3.4.3-banes/src/artifact.c Fri Sep 23 09:54:26 2005 @@ -26,6 +26,8 @@ STATIC_DCL boolean FDECL(Mb_hit, (struct monst *magr,struct monst *mdef, struct obj *,int *,int,BOOLEAN_P,char *)); +STATIC_DCL int FDECL(brave_little_tailor, (struct monst *magr,BOOLEAN_P)); + /* The amount added to the victim's total hit points to insure that the victim will be killed even after damage bonus/penalty adjustments. Most such penalties are small, and 200 is plenty; the exception is @@ -158,6 +160,11 @@ /* nothing appropriate could be found; return the original object */ if (by_align) otmp = 0; /* (there was no original object) */ } + + /* poison Grimtooth */ + if(otmp->oartifact==ART_GRIMTOOTH) + otmp->opoisoned=1; + return otmp; } @@ -443,10 +450,12 @@ if (spec_m2(otmp)) { if (on) { EWarn_of_mon |= wp_mask; - flags.warntype |= spec_m2(otmp); + /* Right now I'm going to assume that you can only be warned of one type at a time */ + flags.warntype = spec_m2(otmp)|((spfx & SPFX_DCLAS) ? 0x80000000:0); } else { EWarn_of_mon &= ~wp_mask; - flags.warntype &= ~spec_m2(otmp); + /* flags.warntype &= ~spec_m2(otmp); */ + flags.warntype = 0; } see_monsters(); } else { @@ -1011,6 +1020,27 @@ return Mb_hit(magr, mdef, otmp, dmgptr, dieroll, vis, hittee); } + /* Blinding attack */ + if (spec_ability(otmp, SPFX_BLIND) && !resists_blnd(mdef) && !rn2(3)) { + long rnd_tmp; + if (realizes_damage && mdef->mcansee) + pline_The("brilliant blade blinds %s!", hittee); + rnd_tmp = rn2(5)+otmp->spe; + if(rnd_tmp<2) rnd_tmp = 2; + if(youdefend) { + make_blinded(Blinded+rnd_tmp, FALSE); + if (!Blind) Your(vision_clears); + } else { + if ((rnd_tmp += mdef->mblinded) > 127) rnd_tmp = 127; + mdef->mblinded = rnd_tmp; + mdef->mcansee = 0; + mdef->mstrategy &= ~STRAT_WAITFORU; + } + } + + if(otmp->oartifact==ART_GIANTSLAYER && spec_dbon_applies && magr && dieroll==1) + return brave_little_tailor(magr,realizes_damage) > 1; + if (!spec_dbon_applies) { /* since damage bonus didn't apply, nothing more to do; no further attacks have side-effects on inventory */ @@ -1454,6 +1484,58 @@ return (artilist[(int) otmp->oartifact].cost); else return (100L * (long)objects[otmp->otyp].oc_cost); +} + +/* Kills multiple giants at one blow */ +STATIC_OVL int +brave_little_tailor(magr,vis) +struct monst *magr; /* attacker */ +boolean vis; /* whether the action can be seen */ +{ + int blow,count, i,j, x,y; + struct monst* mtmp; + boolean youattack = (magr == &youmonst); + static const char *numbers[] = { "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven" }; + + if(youattack) { + x = u.ux; y = u.uy; + } else { + x = magr->mx; y = magr->my; + } + blow = 0; + for(i=0;i<3;i++) for(j=0;j<3;j++) { + if (isok(i+x-1, j+y-1) && (i!=1 || j!=1)) { + mtmp = m_at(i+x-1, j+y-1); + if(mtmp && is_giant(mtmp->data)) + blow++; + } + } + if(blow > 7) blow=7; + if(blow > 1) { + if(vis) pline("%s at one blow!",numbers[blow]); + count = blow; + for(i=0;i<3 && count;i++) for(j=0;j<3 && count;j++) { + if (isok(i+x-1, j+y-1) && (i!=1 || j!=1)) { + mtmp = m_at(i+x-1, j+y-1); + if(mtmp && is_giant(mtmp->data)) { + count--; + if(mtmp==&youmonst) { + mdamageu(magr,2 * mtmp->mhp + FATAL_DAMAGE_MODIFIER); + } else { + mtmp->mhp=0; + if(youattack) { + killed(mtmp); + if(mtmp->mhp > 0) + setmangry(mtmp); + } else { + monkilled(mtmp,"",AD_PHYS); + } + } + } + } + } + } + return blow; } #endif /* OVLB */ diff -u -X files.exc nethack-3.4.3-orig/src/cmd.c nethack-3.4.3-banes/src/cmd.c --- nethack-3.4.3-orig/src/cmd.c Sun Dec 07 17:39:14 2003 +++ nethack-3.4.3-banes/src/cmd.c Thu Aug 18 16:59:40 2005 @@ -930,9 +930,18 @@ if (Warning) you_are("warned"); if (Warn_of_mon && flags.warntype) { Sprintf(buf, "aware of the presence of %s", + (flags.warntype & 0x80000000) ? + ((flags.warntype==(0x80000000|S_OGRE)) ? "ogres" : + (flags.warntype==(0x80000000|S_TROLL)) ? "trolls" : + (flags.warntype==(0x80000000|S_DRAGON)) ? "dragons" : something) + : ( (flags.warntype & M2_ORC) ? "orcs" : (flags.warntype & M2_DEMON) ? "demons" : - something); + (flags.warntype & M2_WERE) ? "lycanthropes" : + (flags.warntype & M2_GIANT) ? "giants" : + (flags.warntype & M2_UNDEAD) ? "undead" : + something) + ); you_are(buf); } if (Undead_warning) you_are("warned of undead"); diff -u -X files.exc nethack-3.4.3-orig/src/mhitm.c nethack-3.4.3-banes/src/mhitm.c --- nethack-3.4.3-orig/src/mhitm.c Sun Dec 07 17:39:14 2003 +++ nethack-3.4.3-banes/src/mhitm.c Thu Sep 22 09:39:36 2005 @@ -694,9 +694,13 @@ tmp += dmgval(otmp, mdef); if (otmp->oartifact) { (void)artifact_hit(magr,mdef, otmp, &tmp, dieroll); - if (mdef->mhp <= 0) - return (MM_DEF_DIED | - (grow_up(magr,mdef) ? 0 : MM_AGR_DIED)); + if (mdef->mhp <= 0) { + if(otmp->oartifact==ART_TROLLSBANE) + /* so that makecorpstat can mark the corpse as norevive */ + mdef->m_ap_type = 1; + return (MM_DEF_DIED | + (grow_up(magr,mdef) ? 0 : MM_AGR_DIED)); + } } if (tmp) mrustm(magr, mdef, otmp); @@ -1132,6 +1136,10 @@ if(!tmp) return(MM_MISS); if((mdef->mhp -= tmp) < 1) { + if(mattk->adtyp == AD_PHYS && mattk->aatyp == AT_WEAP && + otmp && otmp->oartifact==ART_TROLLSBANE) + /* so that makecorpstat can mark the corpse as norevive */ + mdef->m_ap_type = 1; if (m_at(mdef->mx, mdef->my) == magr) { /* see gulpmm() */ remove_monster(mdef->mx, mdef->my); mdef->mhp = 1; /* otherwise place_monster will complain */ diff -u -X files.exc nethack-3.4.3-orig/src/mhitu.c nethack-3.4.3-banes/src/mhitu.c --- nethack-3.4.3-orig/src/mhitu.c Sun Dec 07 17:39:14 2003 +++ nethack-3.4.3-banes/src/mhitu.c Wed Sep 21 16:04:20 2005 @@ -478,7 +478,9 @@ if(!mtmp->cham && is_demon(mdat) && !range2 && mtmp->data != &mons[PM_BALROG] && mtmp->data != &mons[PM_SUCCUBUS] - && mtmp->data != &mons[PM_INCUBUS]) + && mtmp->data != &mons[PM_INCUBUS] + && (!uwep || uwep->oartifact!=ART_DEMONBANE) + ) if(!mtmp->mcan && !rn2(13)) msummon(mtmp); /* Special lycanthrope handling code */ diff -u -X files.exc nethack-3.4.3-orig/src/mkobj.c nethack-3.4.3-banes/src/mkobj.c --- nethack-3.4.3-orig/src/mkobj.c Sun Dec 07 17:39:14 2003 +++ nethack-3.4.3-banes/src/mkobj.c Fri Sep 23 10:01:48 2005 @@ -924,6 +924,12 @@ if (mtmp) { struct obj *otmp2; + /* NDA - I'm using the m_ap_type field to mark that a troll was killed by Trollsbane. + * Yes, it's a filthy kludge. I feel so dirty. + */ + if(mtmp->m_ap_type!=0) + otmp->norevive = 1; + if (!ptr) ptr = mtmp->data; /* save_mtraits frees original data pointed to by otmp */ otmp2 = save_mtraits(otmp, mtmp); diff -u -X files.exc nethack-3.4.3-orig/src/objnam.c nethack-3.4.3-banes/src/objnam.c --- nethack-3.4.3-orig/src/objnam.c Sun Dec 07 17:39:14 2003 +++ nethack-3.4.3-banes/src/objnam.c Thu Sep 22 20:46:34 2005 @@ -571,9 +571,10 @@ * combining both into one function taking a parameter. */ /* must check opoisoned--someone can have a weirdly-named fruit */ - if (!strncmp(bp, "poisoned ", 9) && obj->opoisoned) { - bp += 9; + if(obj->opoisoned) { ispoisoned = TRUE; + if (!strncmp(bp, "poisoned ", 9)) + bp += 9; } if(obj->quan != 1L) @@ -2687,6 +2688,9 @@ otmp->quan = 1L; u.uconduct.wisharti++; /* KMH, conduct */ } + /* poison Grimtooth */ + if(otmp->oartifact==ART_GRIMTOOTH) + otmp->opoisoned=1; } /* more wishing abuse: don't allow wishing for certain artifacts */ diff -u -X files.exc nethack-3.4.3-orig/src/potion.c nethack-3.4.3-banes/src/potion.c --- nethack-3.4.3-orig/src/potion.c Sun Dec 07 17:39:14 2003 +++ nethack-3.4.3-banes/src/potion.c Thu Sep 22 10:37:52 2005 @@ -1744,7 +1744,7 @@ } #endif - if(is_poisonable(obj)) { + if(is_poisonable(obj) && !obj->oartifact) { if(potion->otyp == POT_SICKNESS && !obj->opoisoned) { char buf[BUFSZ]; if (potion->quan > 1L) diff -u -X files.exc nethack-3.4.3-orig/src/timeout.c nethack-3.4.3-banes/src/timeout.c --- nethack-3.4.3-orig/src/timeout.c Sun Dec 07 17:39:14 2003 +++ nethack-3.4.3-banes/src/timeout.c Wed Sep 21 15:40:24 2005 @@ -1095,7 +1095,7 @@ if (artifact_light(obj)) { obj->lamplit = 1; do_timer = FALSE; - radius = 2; + radius = 3; } else { impossible("begin burn: unexpected %s", xname(obj)); turns = obj->age; diff -u -X files.exc nethack-3.4.3-orig/src/uhitm.c nethack-3.4.3-banes/src/uhitm.c --- nethack-3.4.3-orig/src/uhitm.c Sun Dec 07 17:39:14 2003 +++ nethack-3.4.3-banes/src/uhitm.c Thu Sep 22 20:07:22 2005 @@ -640,8 +640,12 @@ if (obj->oartifact && artifact_hit(&youmonst, mon, obj, &tmp, dieroll)) { - if(mon->mhp <= 0) /* artifact killed monster */ + if(mon->mhp <= 0) /* artifact killed monster */ { + if(obj->oartifact==ART_TROLLSBANE) + /* so that makecorpstat can mark the corpse as norevive */ + mon->m_ap_type = 1; return FALSE; + } if (tmp == 0) return TRUE; hittxt = TRUE; } @@ -670,9 +674,9 @@ uwep->otyp == ELVEN_BOW) tmp++; } + } if(obj->opoisoned && is_poisonable(obj)) ispoisoned = TRUE; - } } } else if(obj->oclass == POTION_CLASS) { if (obj->quan > 1L) @@ -917,7 +921,7 @@ You_feel("like an evil coward for using a poisoned weapon."); adjalign(-1); } - if (obj && !rn2(nopoison)) { + if (obj && !obj->oartifact && !rn2(nopoison)) { obj->opoisoned = FALSE; Your("%s %s no longer poisoned.", xname(obj), otense(obj, "are")); @@ -990,8 +994,12 @@ /* adjustments might have made tmp become less than what a level draining artifact has already done to max HP */ if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax; - if (mon->mhp < 1) + if (mon->mhp < 1) { destroyed = TRUE; + if(obj && obj->oartifact==ART_TROLLSBANE) + /* so that makecorpstat can mark the corpse as norevive */ + mon->m_ap_type=1; + } if (mon->mtame && (!mon->mflee || mon->mfleetim) && tmp > 0) { abuse_dog(mon); monflee(mon, 10 * rnd(tmp), FALSE, FALSE); @@ -1287,7 +1295,8 @@ if (is_demon(youmonst.data) && !rn2(13) && !uwep && u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS - && u.umonnum != PM_BALROG) { + && u.umonnum != PM_BALROG + && (!MON_WEP(mdef) || MON_WEP(mdef)->oartifact!=ART_DEMONBANE) ) { demonpet(); return(0); }