diff -rwBE --context=4 nethack-3.4.1-orig/dat/data.base nethack-3.4.1-disint/dat/data.base *** nethack-3.4.1-orig/dat/data.base Sun Feb 23 08:43:16 2003 --- nethack-3.4.1-disint/dat/data.base Fri Mar 21 14:48:26 2003 *************** *** 900,907 **** --- 900,913 ---- A wolflike wild dog, Canis dingo, of Australia, having a reddish- or yellowish-brown coat, believed to have been introduced by the aborigines. [Webster's Encyclopedic Unabridged Dictionary of the English Language] + disint*grator + Disintegrators are nightmares made real. You will know them + by the pale green glow of almost anything larger than dust + disintegrating as it hits their skin. Except by some preternatural + mystery only the floor beneath their feet is completely immune to + their touch. dispater Dispater is an arch-devil who rules the city of Dis. He is a powerful mage. djinn* diff -rwBE --context=4 nethack-3.4.1-orig/include/config.h nethack-3.4.1-disint/include/config.h *** nethack-3.4.1-orig/include/config.h Sun Feb 23 08:43:20 2003 --- nethack-3.4.1-disint/include/config.h Fri Mar 21 13:46:18 2003 *************** *** 350,357 **** --- 350,360 ---- * bugs left here. */ /*#define GOLDOBJ */ /* Gold is kept on obj chains - Helge Hafting */ + #define WEBB_DISINT + + #define MAIL /* End of Section 5 */ #include "global.h" /* Define everything else according to choices above */ diff -rwBE --context=4 nethack-3.4.1-orig/include/extern.h nethack-3.4.1-disint/include/extern.h *** nethack-3.4.1-orig/include/extern.h Sun Feb 23 08:43:20 2003 --- nethack-3.4.1-disint/include/extern.h Fri Mar 21 13:47:58 2003 *************** *** 960,967 **** --- 959,967 ---- E int FDECL(could_seduce, (struct monst *,struct monst *,struct attack *)); #ifdef SEDUCE E int FDECL(doseduce, (struct monst *)); #endif + E void FDECL(hurtarmor, (int)); /* ### minion.c ### */ E void FDECL(msummon, (struct monst *)); *************** *** 1104,1111 **** --- 1104,1114 ---- E void FDECL(replmon, (struct monst *,struct monst *)); E void FDECL(relmon, (struct monst *)); E struct obj *FDECL(mlifesaver, (struct monst *)); E boolean FDECL(corpse_chance,(struct monst *,struct monst *,BOOLEAN_P)); + #ifdef WEBB_DISINT + E void FDECL(mondead_helper, (struct monst *, uchar)); + #endif E void FDECL(mondead, (struct monst *)); E void FDECL(mondied, (struct monst *)); E void FDECL(mongone, (struct monst *)); E void FDECL(monstone, (struct monst *)); *************** *** 1980,1987 **** --- 1983,1994 ---- E void FDECL(seetrap, (struct trap *)); E int FDECL(mintrap, (struct monst *)); E void FDECL(instapetrify, (const char *)); E void FDECL(minstapetrify, (struct monst *,BOOLEAN_P)); + #ifdef WEBB_DISINT + E int FDECL(instadisintegrate, (const char *)); + E int FDECL(minstadisintegrate, (struct monst *)); + #endif E void FDECL(selftouch, (const char *)); E void FDECL(mselftouch, (struct monst *,const char *,BOOLEAN_P)); E void NDECL(float_up); E void FDECL(fill_pit, (int,int)); diff -rwBE --context=4 nethack-3.4.1-orig/include/hack.h nethack-3.4.1-disint/include/hack.h *** nethack-3.4.1-orig/include/hack.h Sun Feb 23 08:43:20 2003 --- nethack-3.4.1-disint/include/hack.h Fri Mar 21 13:48:04 2003 *************** *** 73,86 **** --- 73,96 ---- #define DISSOLVED 6 #define CRUSHING 7 #define STONING 8 #define TURNED_SLIME 9 + #ifdef WEBB_DISINT + # define DISINTEGRATED 10 + # define GENOCIDED 11 + # define PANICKED 12 + # define TRICKED 13 + # define QUIT 14 + # define ESCAPED 15 + # define ASCENDED 16 + #else #define GENOCIDED 10 #define PANICKED 11 #define TRICKED 12 #define QUIT 13 #define ESCAPED 14 #define ASCENDED 15 + #endif #include "align.h" #include "dungeon.h" #include "monsym.h" diff -rwBE --context=4 nethack-3.4.1-orig/include/mondata.h nethack-3.4.1-disint/include/mondata.h *** nethack-3.4.1-orig/include/mondata.h Sun Feb 23 08:43:22 2003 --- nethack-3.4.1-disint/include/mondata.h Fri Mar 21 13:48:44 2003 *************** *** 157,164 **** --- 157,168 ---- #define touch_petrifies(ptr) ((ptr) == &mons[PM_COCKATRICE] || \ (ptr) == &mons[PM_CHICKATRICE]) + #ifdef WEBB_DISINT + # define touch_disintegrates(ptr) ((ptr) == &mons[PM_DISINTEGRATOR]) + #endif + #define is_mind_flayer(ptr) ((ptr) == &mons[PM_MIND_FLAYER] || \ (ptr) == &mons[PM_MASTER_MIND_FLAYER]) #define nonliving(ptr) (is_golem(ptr) || is_undead(ptr) || \ diff -rwBE --context=4 nethack-3.4.1-orig/include/obj.h nethack-3.4.1-disint/include/obj.h *** nethack-3.4.1-orig/include/obj.h Sun Feb 23 08:43:22 2003 --- nethack-3.4.1-disint/include/obj.h Fri Mar 21 13:50:22 2003 *************** *** 272,280 **** --- 274,292 ---- (otmp)->otyp == RUBBER_HOSE) #else #define is_flimsy(otmp) (objects[(otmp)->otyp].oc_material <= LEATHER) #endif + #ifdef WEBB_DISINT + # define oresist_disintegration(obj) \ + (objects[obj->otyp].oc_oprop == DISINT_RES || \ + obj_resists(obj, 5, 50) || is_quest_artifact(obj) ) + # define weight_dmg(i) { \ + i = (i<=100)?1:i/100; \ + i = rnd(i); \ + if(i > 6) i = 6; \ + } + #endif /* helpers, simple enough to be macros */ #define is_plural(o) ((o)->quan > 1 || \ (o)->oartifact == ART_EYES_OF_THE_OVERWORLD) diff -rwBE --context=4 nethack-3.4.1-orig/src/dogmove.c nethack-3.4.1-disint/src/dogmove.c *** nethack-3.4.1-orig/src/dogmove.c Sun Feb 23 08:43:26 2003 --- nethack-3.4.1-disint/src/dogmove.c Fri Mar 21 13:54:16 2003 *************** *** 615,622 **** --- 615,626 ---- ((mtmp->mhp*4 < mtmp->mhpmax || mtmp2->data->msound == MS_GUARDIAN || mtmp2->data->msound == MS_LEADER) && mtmp2->mpeaceful && !Conflict) || + #ifdef WEBB_DISINT + (touch_disintegrates(mtmp2->data) && + !resists_disint(mtmp)) || + #endif (touch_petrifies(mtmp2->data) && !resists_ston(mtmp))) continue; diff -rwBE --context=4 nethack-3.4.1-orig/src/dokick.c nethack-3.4.1-disint/src/dokick.c *** nethack-3.4.1-orig/src/dokick.c Sun Feb 23 08:43:26 2003 --- nethack-3.4.1-disint/src/dokick.c Fri Mar 21 13:54:28 2003 *************** *** 145,153 **** uattk = &youmonst.data->mattk[i]; /* we only care about kicking attacks here */ if (uattk->aatyp != AT_KICK) continue; ! if (mon->data == &mons[PM_SHADE] && (!uarmf || !uarmf->blessed)) { /* doesn't matter whether it would have hit or missed, and shades have no passive counterattack */ --- 145,171 ---- uattk = &youmonst.data->mattk[i]; /* we only care about kicking attacks here */ if (uattk->aatyp != AT_KICK) continue; ! #ifdef WEBB_DISINT ! if (touch_disintegrates(mon->data) && !mon->mcan && mon->mhp>6){ ! if(uarmf) { ! if(!oresist_disintegration(uarmf)){ ! tmp = uarmf->owt; ! weight_dmg(tmp); ! destroy_arm(uarmf); ! break; ! } ! } else { ! char kbuf[BUFSZ]; ! int dis_dmg; ! Sprintf(kbuf, "barefootedly kicking %s", ! an(mon->data->mname)); ! dis_dmg = instadisintegrate(kbuf); ! break; ! } ! } else ! #endif if (mon->data == &mons[PM_SHADE] && (!uarmf || !uarmf->blessed)) { /* doesn't matter whether it would have hit or missed, and shades have no passive counterattack */ *************** *** 236,243 **** --- 254,275 ---- ghitm(mtmp, gold) register struct monst *mtmp; register struct obj *gold; { + #ifdef WEBB_DISINT + if( touch_disintegrates(mtmp->data) && !mtmp->mcan && mtmp->mhp >6 && + # ifdef GOLDOBJ + !oresist_disintegration + # else + rn2(20) + # endif + ){ + if(cansee(mtmp->mx, mtmp->my)) + pline_The("%s %s!", xname(gold), vtense(xname(gold),"disintegrate")); + dealloc_obj(gold); + return 1; + } + #endif if(!likes_gold(mtmp->data) && !mtmp->isshk && !mtmp->ispriest && !is_mercenary(mtmp->data)) { wakeup(mtmp); } else if (!mtmp->mcanmove) { --- 349,356 ---- diff -rwBE --context=4 nethack-3.4.1-orig/src/dothrow.c nethack-3.4.1-disint/src/dothrow.c *** nethack-3.4.1-orig/src/dothrow.c Sun Feb 23 08:43:26 2003 --- nethack-3.4.1-disint/src/dothrow.c Fri Mar 21 13:55:10 2003 *************** *** 1164,1171 **** --- 1165,1176 ---- register int tmp; /* Base chance to hit */ register int disttmp; /* distance modifier */ int otyp = obj->otyp; boolean guaranteed_hit = (u.uswallow && mon == u.ustuck); + #ifdef WEBB_DISINT + boolean obj_disint = (touch_disintegrates(mon->data) && !mon->mcan && + (mon->mhp > 1) && !oresist_disintegration(obj)); + #endif /* Differences from melee weapons: * * Dex still gives a bonus, but strength does not. *************** *** 1295,1315 **** if (hmon(mon,obj,1)) { /* mon still alive */ cutworm(mon, bhitpos.x, bhitpos.y, obj); } exercise(A_DEX, TRUE); /* projectiles other than magic stones sometimes disappear when thrown */ ! if (objects[otyp].oc_skill < P_NONE && objects[otyp].oc_skill > -P_BOOMERANG && ! !objects[otyp].oc_magic && rn2(3)) { if (*u.ushops) check_shop_obj(obj, bhitpos.x,bhitpos.y, TRUE); obfree(obj, (struct obj *)0); return 1; } passive_obj(mon, obj, (struct attack *)0); ! } else { ! tmiss(obj, mon); } } else if (otyp == HEAVY_IRON_BALL) { exercise(A_STR, TRUE); --- 1300,1324 ---- if (hmon(mon,obj,1)) { /* mon still alive */ cutworm(mon, bhitpos.x, bhitpos.y, obj); } exercise(A_DEX, TRUE); + /* projectiles other than magic stones sometimes disappear when thrown */ ! if ((objects[otyp].oc_skill < P_NONE && objects[otyp].oc_skill > -P_BOOMERANG && ! !objects[otyp].oc_magic && rn2(3)) ! #ifdef WEBB_DISINT ! || obj_disint ! #endif ! ){ if (*u.ushops) check_shop_obj(obj, bhitpos.x,bhitpos.y, TRUE); obfree(obj, (struct obj *)0); return 1; } passive_obj(mon, obj, (struct attack *)0); ! } else { tmiss(obj, mon); } } else if (otyp == HEAVY_IRON_BALL) { exercise(A_STR, TRUE); *************** *** 1320,1327 **** --- 1329,1344 ---- if (!hmon(mon,obj,1)) { /* mon killed */ if (was_swallowed && !u.uswallow && obj == uball) return 1; /* already did placebc() */ } + #ifdef WEBB_DISINT + if (obj_disint){ + if (*u.ushops) + check_shop_obj(obj, bhitpos.x,bhitpos.y, TRUE); + obfree(obj, (struct obj *)0); + return 1; + } + #endif } else { tmiss(obj, mon); } *************** *** 1329,1336 **** --- 1346,1361 ---- exercise(A_STR, TRUE); if (tmp >= rnd(20)) { exercise(A_DEX, TRUE); (void) hmon(mon,obj,1); + #ifdef WEBB_DISINT + if (obj_disint){ + if (*u.ushops) + check_shop_obj(obj, bhitpos.x,bhitpos.y, TRUE); + obfree(obj, (struct obj *)0); + return 1; + } + #endif } else { tmiss(obj, mon); } diff -rwBE --context=4 nethack-3.4.1-orig/src/end.c nethack-3.4.1-disint/src/end.c *** nethack-3.4.1-orig/src/end.c Sun Feb 23 08:43:26 2003 --- nethack-3.4.1-disint/src/end.c Fri Mar 21 13:56:20 2003 *************** *** 71,87 **** static NEARDATA const char *deaths[] = { /* the array of death */ "died", "choked", "poisoned", "starvation", "drowning", "burning", "dissolving under the heat and pressure", "crushed", "turned to stone", "turned into slime", ! "genocided", "panic", "trickery", "quit", "escaped", "ascended" }; static NEARDATA const char *ends[] = { /* "when you..." */ "died", "choked", "were poisoned", "starved", "drowned", "burned", "dissolved in the lava", "were crushed", "turned to stone", "turned into slime", ! "were genocided", "panicked", "were tricked", "quit", "escaped", "ascended" }; extern const char * const killed_by_prefix[]; /* from topten.c */ --- 71,95 ---- static NEARDATA const char *deaths[] = { /* the array of death */ "died", "choked", "poisoned", "starvation", "drowning", "burning", "dissolving under the heat and pressure", "crushed", "turned to stone", "turned into slime", ! "genocided", ! #ifdef WEBB_DISINT ! "disintegrated", ! #endif ! "panic", "trickery", "quit", "escaped", "ascended" }; static NEARDATA const char *ends[] = { /* "when you..." */ "died", "choked", "were poisoned", "starved", "drowned", "burned", "dissolved in the lava", "were crushed", "turned to stone", "turned into slime", ! "were genocided", ! #ifdef WEBB_DISINT ! "were disintegrated", ! #endif ! "panicked", "were tricked", "quit", "escaped", "ascended" }; extern const char * const killed_by_prefix[]; /* from topten.c */ *************** *** 570,578 **** makeknown(AMULET_OF_LIFE_SAVING); Your("medallion %s!", !Blind ? "begins to glow" : "feels warm"); if (how == CHOKING) You("vomit ..."); ! You_feel("much better!"); pline_The("medallion crumbles to dust!"); if (uamul) useup(uamul); (void) adjattrib(A_CON, -1, TRUE); --- 578,590 ---- makeknown(AMULET_OF_LIFE_SAVING); Your("medallion %s!", !Blind ? "begins to glow" : "feels warm"); if (how == CHOKING) You("vomit ..."); ! #ifdef WEBB_DISINT ! if (how == DISINTEGRATED) You("reconstitute!"); ! else ! #endif ! You_feel("much better!", how); pline_The("medallion crumbles to dust!"); if (uamul) useup(uamul); (void) adjattrib(A_CON, -1, TRUE); diff -rwBE --context=4 nethack-3.4.1-orig/src/mhitm.c nethack-3.4.1-disint/src/mhitm.c *** nethack-3.4.1-orig/src/mhitm.c Sun Feb 23 08:43:28 2003 --- nethack-3.4.1-disint/src/mhitm.c Fri Mar 21 14:01:10 2003 *************** *** 263,272 **** /* Monsters won't attack cockatrices physically if they * have a weapon instead. This instinct doesn't work for * players, or under conflict or confusion. */ ! if (!magr->mconf && !Conflict && otmp && ! mattk->aatyp != AT_WEAP && touch_petrifies(mdef->data)) { strike = 0; break; } dieroll = rnd(20 + i); --- 264,277 ---- /* Monsters won't attack cockatrices physically if they * have a weapon instead. This instinct doesn't work for * players, or under conflict or confusion. */ ! if (!magr->mconf && !Conflict && otmp && ( ! #ifdef WEBB_DISINT ! (touch_disintegrates(mdef->data) && ! (mattk->aatyp == AT_WEAP || !(resists_disint(magr))) ) || ! #endif ! mattk->aatyp != AT_WEAP && touch_petrifies(mdef->data))) { strike = 0; break; } dieroll = rnd(20 + i); *************** *** 574,582 **** char buf[BUFSZ]; struct permonst *pa = magr->data, *pd = mdef->data; int armpro, num, tmp = d((int)mattk->damn, (int)mattk->damd); boolean cancelled; ! if (touch_petrifies(pd) && !resists_ston(magr)) { long protector = attk_protection((int)mattk->aatyp), wornitems = magr->misc_worn_check; --- 579,705 ---- char buf[BUFSZ]; struct permonst *pa = magr->data, *pd = mdef->data; int armpro, num, tmp = d((int)mattk->damn, (int)mattk->damd); boolean cancelled; ! #ifdef WEBB_DISINT ! if (touch_disintegrates(pd)&& mdef->mhp>6 && !mdef->mcan){ ! int touched = 0; ! int mass = 0; ! struct obj * otch = 0; ! switch (attk_protection((int)mattk->aatyp)){ ! case (W_ARMC|W_ARMG): ! if (otch = which_armor(magr, W_ARMG)){ ! if(!oresist_disintegration(otch)){ ! if(canseemon(magr)) ! pline("%s %s disintegrates!", ! s_suffix(Monnam(magr)), distant_name(otch, xname)); ! mass += otch->owt; ! m_useup(magr,otch); ! otch = 0; ! touched = 1; ! } ! } else touched = 1; ! if (otch = which_armor(magr, W_ARMC)) { ! if(!oresist_disintegration(otch)) { ! if(canseemon(magr)) ! pline("%s %s disintegrates!", ! s_suffix(Monnam(magr)), distant_name(otch, xname)); ! mass += otch->owt; ! m_useup(magr,otch); ! touched = 1; ! } ! } else touched = 1; ! if (!(magr->misc_worn_check & W_ARMC) && ! (otch = which_armor(magr,W_ARM)) && ! (!oresist_disintegration(otch))) { ! if (canseemon(magr)) ! pline("%s %s disintegrates!", ! s_suffix(Monnam(magr)), distant_name(otch, xname)); ! mass += otch->owt; ! m_useup(magr,otch); ! } ! #ifdef TOURIST ! if (!(magr->misc_worn_check & (W_ARMC|W_ARM)) && ! (otch = which_armor(magr,W_ARMU)) && ! (!oresist_disintegration(otch))) { ! if (canseemon(magr)) ! pline("%s %s disintegrates!", ! s_suffix(Monnam(magr)), distant_name(otch, xname)); ! mass += otch->owt; ! m_useup(magr,otch); ! } ! #endif ! break; ! case (W_ARMG): ! if(otmp){ ! if(!oresist_disintegration(otmp)){ ! if (canseemon(magr)) ! pline("%s %s disintegrates!", ! s_suffix(Monnam(magr)), distant_name(otmp, xname)); ! mass += otmp->owt; ! tmp = 0; ! m_useup(magr,otmp); ! } ! } else if (otch = which_armor(magr,W_ARMG)){ ! if(!oresist_disintegration(otch)){ ! if(canseemon(magr)) ! pline("%s %s disintegrates!", ! s_suffix(Monnam(magr)), distant_name(otch, xname)); ! mass += otch->owt; ! m_useup(magr,otch); ! touched = 1; ! } ! } else touched = 1; ! break; ! case (W_ARMH): ! if (otch = which_armor(magr,W_ARMH)){ ! if(!oresist_disintegration(otch)){ ! if(canseemon(magr)) ! pline("%s %s disintegrates!", ! s_suffix(Monnam(magr)), distant_name(otch, xname)); ! mass += otch->owt; ! m_useup(magr,otch); ! touched = 1; ! } ! } else touched = 1; ! break; ! case (W_ARMF): ! if (otch = which_armor(magr,W_ARMF)){ ! if(!oresist_disintegration(otch)){ ! if(canseemon(magr)) ! pline("%s %s disintegrates!", ! s_suffix(Monnam(magr)), distant_name(otch, xname)); ! mass += otch->owt; ! m_useup(magr,otch); ! touched = 1; ! } ! } else touched = 1; ! break; ! case (0L): ! touched = 1; ! break; ! default: ! break; ! } ! if (!touched || resists_disint(magr)) { ! if(mass) ! weight_dmg(mass); ! tmp = mass; ! } else { ! struct obj * lifesave = mlifesaver(magr); ! mass += magr->data->cwt; ! weight_dmg(mass); ! if(mass) ! mdef->mhp -= mass ; ! if (vis) pline("%s disintegrates!", Monnam(magr)); ! mondead_helper(magr,mattk->adtyp); ! if (magr->mhp > 0) return 0; ! else if (magr->mtame && !vis) ! You(brief_feeling, "peculiarly sad"); ! return MM_AGR_DIED; ! } ! } else ! #endif if (touch_petrifies(pd) && !resists_ston(magr)) { long protector = attk_protection((int)mattk->aatyp), wornitems = magr->misc_worn_check; *************** *** 1109,1116 **** --- 1232,1279 ---- case AD_ENCH: /* there's no msomearmor() function, so just do damage */ /* if (cancelled) break; */ break; + #ifdef WEBB_DISINT + case AD_DISN: /* only hit torso aromor */ + if (!magr->mcan && magr->mhp > 6){ + struct obj * otch = 0; + int recip_dam = 0; + if (otch = which_armor(mdef, W_ARMS)){ + if(oresist_disintegration(otch)) + otch = 0; + } else if (otch = which_armor(mdef, W_ARMC)) { + if (oresist_disintegration(otch)) + otch = 0; + } else if (otch = which_armor(mdef, W_ARM)) { + if (oresist_disintegration(otch)) + otch = 0; + #ifdef TOURIST + } else if (otch = which_armor(mdef, W_ARMU)) { + if (oresist_disintegration(otch)) + otch = 0; + #endif + } else { + recip_dam = minstadisintegrate(mdef); + } + if (recip_dam) { + tmp = 0; + } else if (otch) { + recip_dam = otch->owt; + weight_dmg(recip_dam); + if(canseemon(mdef)) + pline("%s %s disintegrates!", + s_suffix(Monnam(mdef)), distant_name(otch, xname)); + m_useup(mdef,otch); + tmp = 0; + } + magr->mhp -= recip_dam; + if (!mdef->mhp) + return (MM_DEF_DIED | (grow_up(magr,mdef) ? + 0 : MM_AGR_DIED)); + } + break; + #endif default: tmp = 0; break; } if(!tmp) return(MM_MISS); diff -rwBE --context=4 nethack-3.4.1-orig/src/mhitu.c nethack-3.4.1-disint/src/mhitu.c *** nethack-3.4.1-orig/src/mhitu.c Sun Feb 23 08:43:28 2003 --- nethack-3.4.1-disint/src/mhitu.c Fri Mar 21 14:51:44 2003 *************** *** 1514,1528 **** /* uncancelled is sufficient enough; please don't make this attack less frequent */ if (uncancelled) { struct obj *obj = some_armor(&youmonst); - if (drain_item(obj)) { Your("%s less effective.", aobjnam(obj, "seem")); } } break; ! default: dmg = 0; break; } if(u.uhp < 1) done_in_by(mtmp); --- 1516,1618 ---- /* uncancelled is sufficient enough; please don't make this attack less frequent */ if (uncancelled) { struct obj *obj = some_armor(&youmonst); if (drain_item(obj)) { Your("%s less effective.", aobjnam(obj, "seem")); } + + } + break; + #ifdef WEBB_DISINT + case AD_DISN: + hitmsg(mtmp, mattk); + if (!mtmp->mcan && mtmp->mhp>6){ + int mass = 0, touched = 0; + struct obj * destroyme = 0; + if (Disint_resistance) { + break; + } + if (uarms) { + if(!oresist_disintegration(uarms)) + destroyme = uarms; + } else { + switch (rn2(10)){ /* where it hits you */ + case 0: /* head */ + case 1: + if (uarmc && (uarmc->otyp == DWARVISH_CLOAK || + uarmc->otyp == MUMMY_WRAPPING)){ + if(!oresist_disintegration(uarmc)){ + destroyme = uarmc; + } + } else if (uarmh) { + if(!oresist_disintegration(uarmh)){ + destroyme = uarmh; } + } else + touched = 1; break; ! case 2: /* feet */ ! if (uarmf) { ! if(!oresist_disintegration(uarmf)) ! destroyme = uarmf; ! } else ! touched = 1; ! break; ! case 3: /* hands (right) */ ! case 4: ! if (uwep) { ! if (!oresist_disintegration(uwep)){ ! struct obj * otmp = uwep; ! mass = otmp->owt; ! u.twoweap = FALSE; ! uwepgone(); ! useup(otmp); ! dmg = 0; ! } ! } else if (uarmg) { ! if (!oresist_disintegration(uarmg)) ! destroyme = uarmg; ! } else ! touched = 1; ! break; ! default: /* main body hit */ ! if (uarmc){ ! if(!oresist_disintegration(uarmc)) ! destroyme = uarmc; ! } else if (uarm){ ! if(!oresist_disintegration(uarm)) ! destroyme = uarm; ! #ifdef TOURIST ! } else if (uarmu) { ! if(!oresist_disintegration(uarmu)) ! destroyme = uarmu; ! #endif ! } else ! touched = 1; ! break; ! } ! } ! if (destroyme){ ! mass = destroyme->owt; ! destroy_arm(destroyme); ! dmg = 0; ! } else if(touched){ ! int recip_damage = instadisintegrate(mtmp->data->mname); ! if (recip_damage){ ! dmg=0; ! mtmp->mhp -= recip_damage; ! } ! } ! if (mass){ ! weight_dmg(mass); ! mtmp->mhp -= mass; ! } ! } ! break; ! #endif ! default: ! dmg = 0; break; } if(u.uhp < 1) done_in_by(mtmp); diff -rwBE --context=4 nethack-3.4.1-orig/src/mon.c nethack-3.4.1-disint/src/mon.c *** nethack-3.4.1-orig/src/mon.c Sun Feb 23 08:43:28 2003 --- nethack-3.4.1-disint/src/mon.c Fri Mar 21 14:05:30 2003 *************** *** 49,58 **** STATIC_VAR short cham_to_pm[]; #else STATIC_DCL struct obj *FDECL(make_corpse,(struct monst *)); STATIC_DCL void FDECL(m_detach, (struct monst *, struct permonst *)); STATIC_DCL void FDECL(lifesaved_monster, (struct monst *)); ! /* convert the monster index of an undead to its living counterpart */ int undead_to_corpse(mndx) int mndx; --- 49,61 ---- STATIC_VAR short cham_to_pm[]; #else STATIC_DCL struct obj *FDECL(make_corpse,(struct monst *)); STATIC_DCL void FDECL(m_detach, (struct monst *, struct permonst *)); + #ifdef WEBB_DISINT + STATIC_DCL void FDECL(lifesaved_monster, (struct monst *, uchar)); + #else STATIC_DCL void FDECL(lifesaved_monster, (struct monst *)); ! #endif /* convert the monster index of an undead to its living counterpart */ int undead_to_corpse(mndx) int mndx; *************** *** 1320,1329 **** --- 1327,1342 ---- return (struct obj *)0; } STATIC_OVL void + #ifdef WEBB_DISINT + lifesaved_monster(mtmp,adtyp) + struct monst *mtmp; + uchar adtyp; + #else lifesaved_monster(mtmp) struct monst *mtmp; + #endif { struct obj *lifesave = mlifesaver(mtmp); if (lifesave) { *************** *** 1336,1344 **** pline("%s medallion begins to glow!", s_suffix(Monnam(mtmp))); makeknown(AMULET_OF_LIFE_SAVING); if (attacktype(mtmp->data, AT_EXPL) ! || attacktype(mtmp->data, AT_BOOM)) pline("%s reconstitutes!", Monnam(mtmp)); else pline("%s looks much better!", Monnam(mtmp)); pline_The("medallion crumbles to dust!"); --- 1349,1361 ---- pline("%s medallion begins to glow!", s_suffix(Monnam(mtmp))); makeknown(AMULET_OF_LIFE_SAVING); if (attacktype(mtmp->data, AT_EXPL) ! || attacktype(mtmp->data, AT_BOOM) ! #ifdef WEBB_DISINT ! || adtyp == AD_DISN ! #endif ! ) pline("%s reconstitutes!", Monnam(mtmp)); else pline("%s looks much better!", Monnam(mtmp)); pline_The("medallion crumbles to dust!"); *************** *** 1360,1380 **** --- 1377,1415 ---- } mtmp->mhp = 0; } + #ifndef WEBB_DISINT + void + mondead(mtmp) + register struct monst * mtmp; + #else void mondead(mtmp) register struct monst *mtmp; { + mondead_helper(mtmp, 0); /* mmm... default parameter values */ + } + + void + mondead_helper(mtmp, adtyp) + register struct monst * mtmp; + uchar adtyp; + #endif + { struct permonst *mptr; int tmp; if(mtmp->isgd) { /* if we're going to abort the death, it *must* be before * the m_detach or there will be relmon problems later */ if(!grddead(mtmp)) return; } + #ifdef WEBB_DISINT + lifesaved_monster(mtmp, adtyp); + #else lifesaved_monster(mtmp); + #endif if (mtmp->mhp > 0) return; #ifdef STEED /* Player is thrown from his steed when it dies */ *************** *** 1447,1455 **** { struct permonst *mdat = mon->data; int i, tmp; ! if (mdat == &mons[PM_VLAD_THE_IMPALER] || mdat->mlet == S_LICH) { if (cansee(mon->mx, mon->my) && !was_swallowed) pline("%s body crumbles into dust.", s_suffix(Monnam(mon))); return FALSE; } --- 1482,1494 ---- { struct permonst *mdat = mon->data; int i, tmp; ! if (mdat == &mons[PM_VLAD_THE_IMPALER] || mdat->mlet == S_LICH ! #ifdef WEBB_DISINT ! || mdat == &mons[PM_DISINTEGRATOR] ! #endif ! ) { if (cansee(mon->mx, mon->my) && !was_swallowed) pline("%s body crumbles into dust.", s_suffix(Monnam(mon))); return FALSE; } *************** *** 1552,1560 **** --- 1590,1602 ---- /* we have to make the statue before calling mondead, to be able to * put inventory in it, and we have to check for lifesaving before * making the statue.... */ + #ifdef WEBB_DISINT + lifesaved_monster(mdef, AD_STON); + #else lifesaved_monster(mdef); + #endif if (mdef->mhp > 0) return; mdef->mtrapped = 0; /* (see m_detach) */ *************** *** 1645,1654 **** else be_sad = (mdef->mtame != 0); /* no corpses if digested or disintegrated */ ! if(how == AD_DGST || how == -AD_RBRE) mondead(mdef); else mondied(mdef); if (be_sad && mdef->mhp <= 0) --- 1687,1702 ---- else be_sad = (mdef->mtame != 0); /* no corpses if digested or disintegrated */ ! if(how == AD_DGST || how == -AD_RBRE ! #ifdef WEBB_DISINT ! || how == AD_DISN) ! mondead_helper(mdef, how); ! #else ! ) mondead(mdef); + #endif else mondied(mdef); if (be_sad && mdef->mhp <= 0) diff -rwBE --context=4 nethack-3.4.1-orig/src/monst.c nethack-3.4.1-disint/src/monst.c *** nethack-3.4.1-orig/src/monst.c Sun Feb 23 08:43:28 2003 --- nethack-3.4.1-disint/src/monst.c Fri Mar 21 14:13:28 2003 *************** *** 1875,1882 **** --- 1879,1897 ---- NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(750, 200, 0, MS_GROWL, MZ_LARGE), 0, 0, M1_ANIMAL|M1_CARNIVORE, M2_HOSTILE, M3_INFRAVISIBLE, CLR_BLUE), + #ifdef WEBB_DISINT + MON("disintegrator", S_RUSTMONST, + LVL(18, 8, 0, 20, -3), (G_HELL|G_GENO|G_NOCORPSE|1), + A(ATTK(AT_CLAW, AD_DISN, 4, 4), /* don't want passive, disintegration + has to intercept attacks */ + NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), + SIZ(1000, 0, 0, MS_HISS, MZ_LARGE), MR_DISINT|MR_STONE, 0, + M1_ANIMAL|M1_TUNNEL|M1_NOTAKE|M1_NOHANDS|M1_REGEN, + M2_NOPOLY|M2_HOSTILE|M2_WANDER|M2_NASTY, + M3_INFRAVISIBLE, CLR_BRIGHT_GREEN), + #endif /* * Snakes */ MON("garter snake", S_SNAKE, diff -rwBE --context=4 nethack-3.4.1-orig/src/mthrowu.c nethack-3.4.1-disint/src/mthrowu.c *** nethack-3.4.1-orig/src/mthrowu.c Sun Feb 23 08:43:28 2003 --- nethack-3.4.1-disint/src/mthrowu.c Fri Mar 21 14:15:08 2003 *************** *** 186,194 **** if (ismimic) seemimic(mtmp); mtmp->msleeping = 0; if (vis) hit(distant_name(otmp,mshot_xname), mtmp, exclam(damage)); else if (verbose) pline("%s is hit%s", Monnam(mtmp), exclam(damage)); ! if (otmp->opoisoned && is_poisonable(otmp)) { if (resists_poison(mtmp)) { if (vis) pline_The("poison doesn't seem to affect %s.", mon_nam(mtmp)); --- 186,205 ---- if (ismimic) seemimic(mtmp); mtmp->msleeping = 0; if (vis) hit(distant_name(otmp,mshot_xname), mtmp, exclam(damage)); else if (verbose) pline("%s is hit%s", Monnam(mtmp), exclam(damage)); ! #ifdef WEBB_DISINT ! if (touch_disintegrates(mtmp->data) && !mtmp->mcan && mtmp->mhp>6 && ! !oresist_disintegration(otmp)){ ! damage = otmp->owt; ! weight_dmg(damage); ! mtmp->mhp-=damage; ! if(vis) ! pline("It disintegrates!"); ! obfree(otmp, (struct obj*) 0); ! return 1; ! } ! #endif if (otmp->opoisoned && is_poisonable(otmp)) { if (resists_poison(mtmp)) { if (vis) pline_The("poison doesn't seem to affect %s.", mon_nam(mtmp)); diff -rwBE --context=4 nethack-3.4.1-orig/src/objnam.c nethack-3.4.1-disint/src/objnam.c *** nethack-3.4.1-orig/src/objnam.c Sun Feb 23 08:43:28 2003 --- nethack-3.4.1-disint/src/objnam.c Fri Mar 21 14:18:48 2003 *************** *** 1261,1269 **** !strcmp(spot-4, "shito") || !strcmp(spot-7, "shuriken") || !strcmp(spot-4, "tengu") || !strcmp(spot-4, "manes"))) || ! (len >= 6 && !strcmp(spot-5, "ki-rin")) || (len >= 7 && !strcmp(spot-6, "gunyoki"))) goto bottom; /* man/men ("Wiped out all cavemen.") */ --- 1261,1274 ---- !strcmp(spot-4, "shito") || !strcmp(spot-7, "shuriken") || !strcmp(spot-4, "tengu") || !strcmp(spot-4, "manes"))) || ! (len >= 6 && (!strcmp(spot-5, "ki-rin") ! #ifdef WEBB_DISINT /* not really disint patch */ ! || !strcmp(spot-5, "danish") ! #endif ! )) || ! (len >= 7 && !strcmp(spot-6, "gunyoki"))) goto bottom; /* man/men ("Wiped out all cavemen.") */ diff -rwBE --context=4 nethack-3.4.1-orig/src/potion.c nethack-3.4.1-disint/src/potion.c *** nethack-3.4.1-orig/src/potion.c Sun Feb 23 08:43:30 2003 --- nethack-3.4.1-disint/src/potion.c Fri Mar 21 18:51:34 2003 *************** *** 956,963 **** --- 956,1201 ---- { return bottlenames[rn2(SIZE(bottlenames))]; } + + #ifdef WEBB_DISINT /* this is poor patching style, but this is this + function is resisting patching correctly otherwise */ + + void + potionhit(mon, obj, your_fault) + register struct monst *mon; + register struct obj *obj; + boolean your_fault; + { + register const char *botlnam = bottlename(); + boolean isyou = (mon == &youmonst); + int distance; + boolean disint = (touch_disintegrates(mon->data) && + !oresist_disintegration(obj) && !mon->mcan && mon->mhp>6); + + + if(isyou) { + distance = 0; + pline_The("%s crashes on your %s and breaks into shards.", botlnam, + body_part(HEAD)); + losehp(rnd(2), "thrown potion", KILLED_BY_AN); + } else { + distance = distu(mon->mx,mon->my); + if (!cansee(mon->mx,mon->my)) pline(disint?"Vip!":"Crash!"); + else { + char *mnam = mon_nam(mon); + char buf[BUFSZ]; + + if(has_head(mon->data)) { + Sprintf(buf, "%s %s", + s_suffix(mnam), + (notonhead ? "body" : "head")); + } else { + Strcpy(buf, mnam); + } + pline_The("%s crashes on %s breaks into shards.", + botlnam, buf); + } + if(rn2(5) && mon->mhp > 1) + mon->mhp--; + } + + /* oil doesn't instantly evaporate */ + if (obj->otyp != POT_OIL && cansee(mon->mx,mon->my) && !disint) + pline("%s.", Tobjnam(obj, "evaporate")); + + if (isyou) { + switch (obj->otyp) { + case POT_OIL: + if (obj->lamplit) + splatter_burning_oil(u.ux, u.uy); + break; + case POT_POLYMORPH: + You_feel("a little %s.", Hallucination ? "normal" : "strange"); + if (!Unchanging && !Antimagic) polyself(FALSE); + break; + case POT_ACID: + if (!Acid_resistance) { + pline("This burns%s!", obj->blessed ? " a little" : + obj->cursed ? " a lot" : ""); + losehp(d(obj->cursed ? 2 : 1, obj->blessed ? 4 : 8), + "potion of acid", KILLED_BY_AN); + } + break; + } + } else { + boolean angermon = TRUE; + + if (!your_fault) angermon = FALSE; + if (!disint) { + switch (obj->otyp) { + case POT_HEALING: + case POT_EXTRA_HEALING: + case POT_FULL_HEALING: + if (mon->data == &mons[PM_PESTILENCE]) goto do_illness; + /*FALLTHRU*/ + case POT_RESTORE_ABILITY: + case POT_GAIN_ABILITY: + do_healing: + angermon = FALSE; + if(mon->mhp < mon->mhpmax) { + mon->mhp = mon->mhpmax; + if (canseemon(mon)) + pline("%s looks sound and hale again.", Monnam(mon)); + } + break; + case POT_SICKNESS: + if (mon->data == &mons[PM_PESTILENCE]) goto do_healing; + if (dmgtype(mon->data, AD_DISE) || + dmgtype(mon->data, AD_PEST) || /* won't happen, see prior goto */ + resists_poison(mon)) { + if (canseemon(mon)) + pline("%s looks unharmed.", Monnam(mon)); + break; + } + do_illness: + if((mon->mhpmax > 3) && !resist(mon, POTION_CLASS, 0, NOTELL)) + mon->mhpmax /= 2; + if((mon->mhp > 2) && !resist(mon, POTION_CLASS, 0, NOTELL)) + mon->mhp /= 2; + if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax; + if (canseemon(mon)) + pline("%s looks rather ill.", Monnam(mon)); + break; + case POT_CONFUSION: + case POT_BOOZE: + if(!resist(mon, POTION_CLASS, 0, NOTELL)) mon->mconf = TRUE; + break; + case POT_INVISIBILITY: + angermon = FALSE; + mon_set_minvis(mon); + break; + case POT_SLEEPING: + /* wakeup() doesn't rouse victims of temporary sleep */ + if (sleep_monst(mon, rnd(12), POTION_CLASS)) { + pline("%s falls asleep.", Monnam(mon)); + slept_monst(mon); + } + break; + case POT_PARALYSIS: + if (mon->mcanmove) { + mon->mcanmove = 0; + /* really should be rnd(5) for consistency with players + * breathing potions, but... + */ + mon->mfrozen = rnd(25); + } + break; + case POT_SPEED: + angermon = FALSE; + mon_adjust_speed(mon, 1, obj); + break; + case POT_BLINDNESS: + if(haseyes(mon->data)) { + register int btmp = 64 + rn2(32) + + rn2(32) * !resist(mon, POTION_CLASS, 0, NOTELL); + btmp += mon->mblinded; + mon->mblinded = min(btmp,127); + mon->mcansee = 0; + } + break; + case POT_WATER: + if (is_undead(mon->data) || is_demon(mon->data) || + is_were(mon->data)) { + if (obj->blessed) { + pline("%s %s in pain!", Monnam(mon), + is_silent(mon->data) ? "writhes" : "shrieks"); + mon->mhp -= d(2,6); + /* should only be by you */ + if (mon->mhp < 1) killed(mon); + else if (is_were(mon->data) && !is_human(mon->data)) + new_were(mon); /* revert to human */ + } else if (obj->cursed) { + angermon = FALSE; + if (canseemon(mon)) + pline("%s looks healthier.", Monnam(mon)); + mon->mhp += d(2,6); + if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax; + if (is_were(mon->data) && is_human(mon->data) && + !Protection_from_shape_changers) + new_were(mon); /* transform into beast */ + } + } else if(mon->data == &mons[PM_GREMLIN]) { + angermon = FALSE; + (void)split_mon(mon, (struct monst *)0); + } else if(mon->data == &mons[PM_IRON_GOLEM]) { + if (canseemon(mon)) + pline("%s rusts.", Monnam(mon)); + mon->mhp -= d(1,6); + /* should only be by you */ + if (mon->mhp < 1) killed(mon); + } + break; + case POT_OIL: + if (obj->lamplit) + splatter_burning_oil(mon->mx, mon->my); + break; + case POT_ACID: + if (!resists_acid(mon) && !resist(mon, POTION_CLASS, 0, NOTELL)) { + pline("%s %s in pain!", Monnam(mon), + is_silent(mon->data) ? "writhes" : "shrieks"); + mon->mhp -= d(obj->cursed ? 2 : 1, obj->blessed ? 4 : 8); + if (mon->mhp < 1) { + if (your_fault) + killed(mon); + else + monkilled(mon, "", AD_ACID); + } + } + break; + case POT_POLYMORPH: + (void) bhitm(mon, obj); + break; + /* + case POT_GAIN_LEVEL: + case POT_LEVITATION: + case POT_FRUIT_JUICE: + case POT_MONSTER_DETECTION: + case POT_OBJECT_DETECTION: + break; + */ + } + } + if (angermon) + wakeup(mon); + else + mon->msleeping = 0; + } + if (!disint) { + + /* Note: potionbreathe() does its own docall() */ + if ((distance==0 || ((distance < 3) && rn2(5))) && + (!breathless(youmonst.data) || haseyes(youmonst.data))) + potionbreathe(obj); + else if (obj->dknown && !objects[obj->otyp].oc_name_known && + !objects[obj->otyp].oc_uname && cansee(mon->mx,mon->my)) + docall(obj); + + } + + if(*u.ushops && obj->unpaid) { + register struct monst *shkp = + shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE)); + + if(!shkp) + obj->unpaid = 0; + else { + (void)stolen_value(obj, u.ux, u.uy, + (boolean)shkp->mpeaceful, FALSE); + subfrombill(obj, shkp); + } + } + obfree(obj, (struct obj *)0); + } + + #else /* potionhit, !WEBB_DISINT */ + void potionhit(mon, obj, your_fault) register struct monst *mon; register struct obj *obj; *************** *** 1178,1185 **** --- 1416,1425 ---- } } obfree(obj, (struct obj *)0); } + #endif /* potionhiti: WEBB_DISINT ^ !WEBB_DISINT */ + /* vapors are inhaled or get in your eyes */ void potionbreathe(obj) diff -rwBE --context=4 nethack-3.4.1-orig/src/steed.c nethack-3.4.1-disint/src/steed.c *** nethack-3.4.1-orig/src/steed.c Sun Feb 23 08:43:30 2003 --- nethack-3.4.1-disint/src/steed.c Fri Mar 21 14:22:36 2003 *************** *** 87,94 **** --- 87,106 ---- Sprintf(kbuf, "attempting to saddle %s", a_monnam(mtmp)); instapetrify(kbuf); } } + #ifdef WEBB_DISINT + if (touch_disintegrates(ptr)){ + char kbuf[BUFSZ]; + if(!oresist_disintegration(otmp)){ + pline("%s disintegrates!", Yname2(otmp)); + useup(otmp); + } + Sprintf(kbuf,"attempting to saddle %s", a_monnam(mtmp)); + instadisintegrate(kbuf); + } + #endif + if (ptr == &mons[PM_INCUBUS] || ptr == &mons[PM_SUCCUBUS]) { pline("Shame on you!"); exercise(A_WIS, FALSE); return 1; diff -rwBE --context=4 nethack-3.4.1-orig/src/topten.c nethack-3.4.1-disint/src/topten.c *** nethack-3.4.1-orig/src/topten.c Sun Feb 23 08:43:30 2003 --- nethack-3.4.1-disint/src/topten.c Fri Mar 21 14:23:14 2003 *************** *** 78,86 **** /* must fit with end.c; used in rip.c */ NEARDATA const char * const killed_by_prefix[] = { "killed by ", "choked on ", "poisoned by ", "", "drowned in ", "burned by ", "dissolved in ", "crushed to death by ", "petrified by ", ! "turned to slime by ", "killed by ", "", "", "", "", "" }; static winid toptenwin = WIN_ERR; --- 78,90 ---- /* must fit with end.c; used in rip.c */ NEARDATA const char * const killed_by_prefix[] = { "killed by ", "choked on ", "poisoned by ", "", "drowned in ", "burned by ", "dissolved in ", "crushed to death by ", "petrified by ", ! "turned to slime by ", "killed by ", ! #ifdef WEBB_DISINT ! "disintegrated by ", ! #endif ! "", "", "", "", "" }; static winid toptenwin = WIN_ERR; diff -rwBE --context=4 nethack-3.4.1-orig/src/trap.c nethack-3.4.1-disint/src/trap.c *** nethack-3.4.1-orig/src/trap.c Sun Feb 23 08:43:32 2003 --- nethack-3.4.1-disint/src/trap.c Fri Mar 21 14:23:30 2003 *************** *** 1521,1528 **** --- 1521,1532 ---- register struct trap *trap = t_at(mtmp->mx, mtmp->my); boolean trapkilled = FALSE; struct permonst *mptr = mtmp->data; struct obj *otmp; + #ifdef WEBB_DISINT + boolean can_disint =(touch_disintegrates(mtmp->data) && + !mtmp->mcan && mtmp->mhp>6 && rn2(20)); + #endif if (!trap) { mtmp->mtrapped = 0; /* perhaps teleported? */ } else if (mtmp->mtrapped) { /* is currently in the trap */ *************** *** 1565,1572 **** --- 1569,1579 ---- } } else { register int tt = trap->ttyp; boolean in_sight, tear_web, see_it, + #ifdef WEBB_DISINT + trap_visible = (trap->tseen && cansee(trap->tx,trap->ty)) , + #endif inescapable = ((tt == HOLE || tt == PIT) && In_sokoban(&u.uz) && !trap->madeby_u); const char *fallverb; *************** *** 1635,1642 **** --- 1642,1665 ---- case BEAR_TRAP: if(mptr->msize > MZ_SMALL && !amorphous(mptr) && !is_flyer(mptr) && !is_whirly(mptr) && !unsolid(mptr)) { + #ifdef WEBB_DISINT + if (can_disint){ + if (in_sight) + pline("%s beartrap disintegrates on %s leg!", + A_Your[trap->madeby_u], s_suffix(mon_nam(mtmp))); + else if(trap_visible) + pline("%s beartrap disintegrates!", + A_Your[trap->madeby_u]); + deltrap(trap); + newsym(mtmp->mx,mtmp->my); + mtmp->mhp -= rnd(2); /* beartrap weighs 200 */ + } + else { + #else + { + #endif mtmp->mtrapped = 1; if(in_sight) { pline("%s is caught in %s bear trap!", Monnam(mtmp), a_your[trap->madeby_u]); *************** *** 1647,1654 **** --- 1670,1678 ---- && flags.soundok) You_hear("the roaring of an angry bear!"); } } + } break; case SLP_GAS_TRAP: if (!resists_sleep(mtmp) && !breathless(mptr) && *************** *** 1726,1733 **** --- 1750,1761 ---- mon_nam(mtmp)); mondied(mtmp); if (mtmp->mhp <= 0) trapkilled = TRUE; + #ifdef WEBB_DISINT + } else if (can_disint){ + pline("The water vanishes in a green twinkling."); + #endif } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) { (void)split_mon(mtmp, (struct monst *)0); } break; *************** *** 1802,1809 **** --- 1830,1845 ---- if (mptr == &mons[PM_PIT_VIPER] || mptr == &mons[PM_PIT_FIEND]) pline("How pitiful. Isn't that the pits?"); seetrap(trap); } + #ifdef WEBB_DISINT + if(can_disint && tt == SPIKED_PIT){ + trap->ttyp = PIT; + if(trap_visible){ + pline("Some spikes dinsintegrate."); + } + } + #endif mselftouch(mtmp, "Falling, ", FALSE); if (mtmp->mhp <= 0 || thitm(0, mtmp, (struct obj *)0, rnd((tt == PIT) ? 6 : 10), FALSE)) *************** *** 1848,1855 **** --- 1884,1905 ---- case WEB: /* Monster in a web. */ if (webmaker(mptr)) break; + #ifdef WEBB_DISINT + if (can_disint){ + if (in_sight){ + pline("%s dissolves %s spider web!", Monnam(mtmp), + a_your[trap->madeby_u]); + } else if (trap_visible){ + pline("%s spider web disintegrates in a green twinkling!", + A_Your[trap->madeby_u]); + } + deltrap(trap); + newsym(mtmp->mx, mtmp->my); + break; + } else + #endif if (amorphous(mptr) || is_whirly(mptr) || unsolid(mptr)){ if(acidic(mptr) || mptr == &mons[PM_GELATINOUS_CUBE] || mptr == &mons[PM_FIRE_ELEMENTAL]) { *************** *** 2044,2051 **** --- 2094,2146 ---- xkilled(mon,0); } else monstone(mon); } + #ifdef WEBB_DISINT + int + instadisintegrate(str) + const char * str; + { + int result; + if(Disint_resistance || !rn2(20)) + return 0; + You("disintegrate!"); + result = (youmonst.data->cwt); + weight_dmg(result); + result = min(6, result); + killer_format = KILLED_BY; + killer = str; + u.ugrave_arise = -3; + done(DISINTEGRATED); + + return (result); + } + + int + minstadisintegrate(mon) + struct monst *mon; + { + int result = mon->data->cwt; + if (resists_disint(mon) || !rn2(20)) return 0; + weight_dmg(result); + if (canseemon(mon)) + pline("%s disintegrates!", Monnam(mon)); + if (is_rider(mon->data)){ + if (canseemon(mon)){ + pline("%s body reintegrates before your %s!", + s_suffix(Monnam(mon)), + (eyecount(youmonst.data) == 1)? + body_part(EYE) : makeplural(body_part(EYE))); + mon->mhp = mon->mhpmax; + } + return result; + } else { + mondead_helper(mon, AD_DISN); + return result; + } + } + #endif + void selftouch(arg) const char *arg; { *************** *** 3146,3153 **** --- 3241,3253 ---- { int wt; struct obj *otmp; boolean uprob; + #ifdef WEBB_DISINT + boolean udied; + boolean can_disint =(touch_disintegrates(mtmp->data) && + !mtmp->mcan && mtmp->mhp>6); + #endif /* * This works when levitating too -- consistent with the ability * to hit monsters while levitating. *************** *** 3188,3197 **** --- 3290,3314 ---- instapetrify(kbuf); return 1; } } + /* need to do cockatrice check first if sleeping or paralyzed */ if (uprob) { + #ifdef WEBB_DISINT + if(can_disint && (!(uarmg) || !oresist_disintegration(uarmg))){ + char kbuf[BUFSZ]; + Sprintf(kbuf, "trying to help %s out of a pit", + an(mtmp->data->mname)); + You("try to grab %s, but...", mon_nam(mtmp)); + if (uarmg) { + destroy_arm(uarmg); + } else { + if (!instadisintegrate(kbuf)) + You("cannot get a firm grasp."); + } + } else + #endif You("try to grab %s, but cannot get a firm grasp.", mon_nam(mtmp)); if(mtmp->msleeping) { mtmp->msleeping = 0; *************** *** 3199,3209 **** --- 3316,3344 ---- } return 1; } + + + You("reach out your %s and grab %s.", makeplural(body_part(ARM)), mon_nam(mtmp)); + #ifdef WEBB_DISINT + if(can_disint){ + char kbuf[BUFSZ]; + Sprintf(kbuf, "trying to help %s out of a pit", + an(mtmp->data->mname)); + if(uarmg){ + if(!oresist_disintegration(uarmg)){ + destroy_arm(uarmg); + udied = (instadisintegrate(kbuf))?1:0; + } + } else + udied = (instadisintegrate(kbuf))?1:0; + } + #endif + if (mtmp->msleeping) { mtmp->msleeping = 0; pline("%s awakens.", Monnam(mtmp)); } else if (mtmp->mfrozen && !rn2(mtmp->mfrozen)) { *************** *** 3211,3219 **** mtmp->mcanmove = 1; mtmp->mfrozen = 0; pline("%s stirs.", Monnam(mtmp)); } ! /* is the monster too heavy? */ wt = inv_weight() + mtmp->data->cwt; if (!try_lift(mtmp, ttmp, wt, FALSE)) return 1; --- 3346,3356 ---- mtmp->mcanmove = 1; mtmp->mfrozen = 0; pline("%s stirs.", Monnam(mtmp)); } ! #ifdef WEBB_DISINT ! if (udied) return 1; ! #endif /* is the monster too heavy? */ wt = inv_weight() + mtmp->data->cwt; if (!try_lift(mtmp, ttmp, wt, FALSE)) return 1; *************** *** 3718,3725 **** --- 3855,3875 ---- else if (obj) { dam = dmgval(obj, mon); if (dam < 1) dam = 1; } + + #ifdef WEBB_DISINT + if(obj && touch_disintegrates(mon->data) && + !mon->mcan && (mon->mhp > 6) && !oresist_disintegration(obj)){ + dam = obj->owt; + weight_dmg(dam); + if (cansee(mon->mx, mon->my)) + pline("It disintegrates!"); + dealloc_obj(obj); + obj = 0; + } + #endif + if ((mon->mhp -= dam) <= 0) { int xx = mon->mx; int yy = mon->my; diff -rwBE --context=4 nethack-3.4.1-orig/src/uhitm.c nethack-3.4.1-disint/src/uhitm.c *** nethack-3.4.1-orig/src/uhitm.c Sun Feb 23 08:43:32 2003 --- nethack-3.4.1-disint/src/uhitm.c Fri Mar 21 14:55:18 2003 *************** *** 520,527 **** --- 524,534 ---- boolean hittxt = FALSE, destroyed = FALSE, already_killed = FALSE; boolean get_dmg_bonus = TRUE; boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE; boolean silvermsg = FALSE; + #ifdef WEBB_DISINT + boolean disint_obj = FALSE; + #endif boolean valid_weapon_attack = FALSE; boolean unarmed = !uwep && !uarm && !uarms; #ifdef STEED int jousting = 0; *************** *** 555,567 **** if (barehand_silver_rings && hates_silver(mdat)) { tmp += rnd(20); silvermsg = TRUE; } } } else { if(obj->oclass == WEAPON_CLASS || is_weptool(obj) || obj->oclass == GEM_CLASS) { - /* is it not a melee weapon? */ if (/* if you strike with a bow... */ is_launcher(obj) || /* or strike with a missile in your hand... */ --- 562,613 ---- if (barehand_silver_rings && hates_silver(mdat)) { tmp += rnd(20); silvermsg = TRUE; } + #ifdef WEBB_DISINT + if (touch_disintegrates(mdat) && !mon->mcan && (mon->mhp>6)){ + int dis_dmg; + valid_weapon_attack =0; + Sprintf(unconventional,"barehandedly striking %s", + an(mdat->mname)); + if (!flags.verbose) You("hit it."); + else You("%s %s%s", Role_if(PM_BARBARIAN) ? "smite" : "hit", + mon_nam(mon), canseemon(mon) ? exclam(tmp) : "."); + dis_dmg = instadisintegrate(unconventional); + tmp = min( dis_dmg, tmp); + unconventional[0] = '\0'; + disint_obj = TRUE; + hittxt = TRUE; + } + } else { + if(touch_disintegrates(mdat) && !mon->mcan && (mon->mhp>6) && + !oresist_disintegration(uarmg)){ + int dis_dmg = uarmg->owt; + weight_dmg(dis_dmg); + if (!flags.verbose) You("hit it."); + else You("%s %s%s", Role_if(PM_BARBARIAN) ? "smite" : "hit", + mon_nam(mon), canseemon(mon) ? exclam(tmp) : "."); + hittxt = TRUE; + destroy_arm(uarmg); + tmp = min( dis_dmg, tmp); + disint_obj = TRUE; + valid_weapon_attack =0; + } + #endif } } else { + #ifdef WEBB_DISINT + if (touch_disintegrates(mdat) && !oresist_disintegration(obj) && + mon->mhp>6 && !mon->mcan){ + disint_obj = TRUE; + valid_weapon_attack = FALSE; + tmp = obj->owt; + weight_dmg(tmp); + } else + #endif + { if(obj->oclass == WEAPON_CLASS || is_weptool(obj) || obj->oclass == GEM_CLASS) { /* is it not a melee weapon? */ if (/* if you strike with a bow... */ is_launcher(obj) || /* or strike with a missile in your hand... */ *************** *** 862,869 **** --- 908,916 ---- } } } } + } /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) * *OR* if attacking bare-handed!! */ *************** *** 901,908 **** --- 948,960 ---- obj->opoisoned = FALSE; Your("%s %s no longer poisoned.", xname(obj), otense(obj, "are")); } + #ifdef WEBB_DISINT + if (disint_obj) + ; + else + #endif if (resists_poison(mon)) needpoismsg = TRUE; else if (rn2(10)) tmp += rnd(6); *************** *** 923,931 **** } else { if (get_dmg_bonus) tmp = 1; } } ! #ifdef STEED if (jousting) { tmp += d(2, (obj == uwep) ? 10 : 2); /* [was in dmgval()] */ You("joust %s%s", --- 975,1002 ---- } else { if (get_dmg_bonus) tmp = 1; } } ! #ifdef WEBB_DISINT ! if(disint_obj && obj){ /* all the hit msgs, no object destruction */ ! if(obj->oclass == POTION_CLASS || obj->oclass == VENOM_CLASS || ! obj->otyp == EGG || obj->otyp == CREAM_PIE){ ! if (cansee(mon->mx, mon->my)) ! pline_The("%s %s in a %s of green light!", ! xname(obj), vtense(xname(obj),"vanish"), ! (obj->oclass == VENOM_CLASS)?"twinkle":"flash"); ! else ! pline("Vip!"); ! hittxt=TRUE; ! } else if (u.usteed && !thrown && tmp > 0 && ! weapon_type(obj) == P_LANCE && mon != u.ustuck && joust(mon,obj)) { ! You("joust %s%s", ! mon_nam(mon), canseemon(mon) ? exclam(tmp) : "."); ! Your("%s vanishes on impact!", xname(obj)); ! hittxt = TRUE; ! } ! } else ! #endif #ifdef STEED if (jousting) { tmp += d(2, (obj == uwep) ? 10 : 2); /* [was in dmgval()] */ You("joust %s%s", *************** *** 946,956 **** } hittxt = TRUE; } else #endif - /* VERY small chance of stunning opponent if unarmed. */ ! if (unarmed && tmp > 1 && !thrown && !obj && !Upolyd) { if (rnd(100) < P_SKILL(P_BARE_HANDED_COMBAT) && !bigmonst(mdat) && !thick_skinned(mdat)) { if (canspotmon(mon)) pline("%s %s from your powerful strike!", Monnam(mon), --- 1017,1027 ---- } hittxt = TRUE; } else #endif /* VERY small chance of stunning opponent if unarmed. */ ! if (unarmed && tmp > 1 && !thrown && !obj && !Upolyd ! ) { if (rnd(100) < P_SKILL(P_BARE_HANDED_COMBAT) && !bigmonst(mdat) && !thick_skinned(mdat)) { if (canspotmon(mon)) pline("%s %s from your powerful strike!", Monnam(mon), *************** *** 992,999 **** --- 1063,1091 ---- else You("%s %s%s", Role_if(PM_BARBARIAN) ? "smite" : "hit", mon_nam(mon), canseemon(mon) ? exclam(tmp) : "."); } + #ifdef WEBB_DISINT + if (disint_obj && obj) { + if(!hittxt){ + if(cansee(mon->mx,mon->my)){ + pline_The("%s %s!", mshot_xname(obj), + (obj->oartifact)?"dissolves":"disintegrates"); + } else { + pline("Vip!%s", + (!thrown)? " Your weapon vanishes from your grip!":""); + } + } + if (!thrown) { + u.twoweap = FALSE; /* untwoweapon() is too verbose here */ + if (obj == uwep) uwepgone(); /* set unweapon */ + useupall(obj); + obj = 0; + } else { + /*obfree(obj, (struct obj *) 0 ); handled: elsewhere */ + } + } + #endif if (silvermsg) { const char *fmt; char *whom = mon_nam(mon); *************** *** 1509,1516 **** --- 1601,1614 ---- if (touch_petrifies(mdef->data) && !Stone_resistance && !Stoned) { Stoned = 5; killer_format = KILLED_BY_AN; delayed_killer = mdef->data->mname; + #ifdef WEBB_DISINT + /* handled in tohit + + } else if (touch_disintegrates(mdef->data)) { + tmp += instadisintegrate(mdef->data->mname); */ + #endif } if (!vegan(mdef->data)) u.uconduct.unvegan++; if (!vegetarian(mdef->data)) *************** *** 1724,1733 **** if(u.uhunger < 1500 && !u.uswallow) { for (otmp = mdef->minvent; otmp; otmp = otmp->nobj) (void) snuff_lit(otmp); ! ! if(!touch_petrifies(mdef->data) || Stone_resistance) { #ifdef LINT /* static char msgbuf[BUFSZ]; */ char msgbuf[BUFSZ]; #else static char msgbuf[BUFSZ]; --- 1822,1834 ---- if(u.uhunger < 1500 && !u.uswallow) { for (otmp = mdef->minvent; otmp; otmp = otmp->nobj) (void) snuff_lit(otmp); ! if((!touch_petrifies(mdef->data) || Stone_resistance) ! #ifdef WEBB_DISINT ! && (!touch_disintegrates(mdef->data) || Disint_resistance) ! #endif ! ) { #ifdef LINT /* static char msgbuf[BUFSZ]; */ char msgbuf[BUFSZ]; #else static char msgbuf[BUFSZ]; *************** *** 1869,1876 **** --- 1970,1980 ---- You("bite into %s.", mon_nam(mdef)); Sprintf(kbuf, "swallowing %s whole", an(mdef->data->mname)); instapetrify(kbuf); + #ifdef WEBB_DISINT + instadisintegrate(kbuf); + #endif } } return(0); } *************** *** 1989,1996 **** --- 2093,2132 ---- You("touch %s.", mon_nam(mon)); else if (mattk->aatyp == AT_TENT) Your("tentacles suck %s.", mon_nam(mon)); else You("hit %s.", mon_nam(mon)); + #ifdef WEBB_DISINT + if (touch_disintegrates(mon->data) && !mon->mcan && mon->mhp>1){ + int dis_dmg = 0; + if(mattk->aatyp == AT_KICK && uarmf){ + if(!oresist_disintegration(uarmf)){ + dis_dmg += uarmf->owt; + destroy_arm(uarmf); + } + } else if(uarmg && (mattk->aatyp == AT_WEAP || + mattk->aatyp == AT_CLAW || mattk->aatyp == AT_TUCH)){ + if(!oresist_disintegration(uarmg)){ + dis_dmg += uarmg->owt; + destroy_arm(uarmg); + } + } else if(mattk->aatyp == AT_BUTT && uarmh) { + if(!oresist_disintegration(uarmh)){ + dis_dmg += (uarmh->owt); + destroy_arm(uarmh); + } + } else { + char kbuf[BUFSZ]; + Sprintf(kbuf, "touching %s", an(mon->data->mname)); + mon->mhp -= instadisintegrate(kbuf); + } + sum[i] = 1; + if(dis_dmg){ + weight_dmg(dis_dmg); + } + mon->mhp -= dis_dmg; + if (mon->mhp < 1) mon->mhp = 1; + } else + #endif sum[i] = damageum(mon, mattk); } else missum(mon, mattk); break; diff -rwBE --context=4 nethack-3.4.1-orig/src/version.c nethack-3.4.1-disint/src/version.c *** nethack-3.4.1-orig/src/version.c Sun Feb 23 08:43:32 2003 --- nethack-3.4.1-disint/src/version.c Fri Mar 21 13:43:58 2003 *************** *** 81,91 **** (VERSION_FEATURES & ~IGNORED_FEATURES) || #endif version_data->entity_count != VERSION_SANITY1 || version_data->struct_sizes != VERSION_SANITY2) { ! if (complain) ! pline("Configuration incompatibility for file \"%s\".", filename); return FALSE; } return TRUE; } --- 81,92 ---- (VERSION_FEATURES & ~IGNORED_FEATURES) || #endif version_data->entity_count != VERSION_SANITY1 || version_data->struct_sizes != VERSION_SANITY2) { ! if (complain){ ! pline("Configuration incompatibility for file \"%s\". Verify data and executable are same version.", filename); + } return FALSE; } return TRUE; } diff -rwBE --context=4 nethack-3.4.1-orig/src/zap.c nethack-3.4.1-disint/src/zap.c *** nethack-3.4.1-orig/src/zap.c Sun Feb 23 08:43:32 2003 --- nethack-3.4.1-disint/src/zap.c Fri Mar 21 14:27:32 2003 *************** *** 3102,3110 **** --- 3102,3114 ---- killer_format = KILLED_BY_AN; killer = fltxt; /* when killed by disintegration breath, don't leave corpse */ u.ugrave_arise = (type == -ZT_BREATH(ZT_DEATH)) ? -3 : NON_PM; + #ifdef WEBB_DISINT + done((type== -ZT_BREATH(ZT_DEATH)) ? DISINTEGRATED : DIED); + #else done(DIED); + #endif return; /* lifesaved */ case ZT_LIGHTNING: if (Shock_resistance) { shieldeff(sx, sy); *************** *** 3346,3361 **** mon->mgold = 0L; #endif /* note: worn amulet of life saving must be preserved in order to operate */ #define oresist_disintegration(obj) \ (objects[obj->otyp].oc_oprop == DISINT_RES || \ obj_resists(obj, 5, 50) || is_quest_artifact(obj) || \ obj == m_amulet) ! for (otmp = mon->minvent; otmp; otmp = otmp2) { otmp2 = otmp->nobj; ! if (!oresist_disintegration(otmp)) { obj_extract_self(otmp); obfree(otmp, (struct obj *)0); } } --- 3350,3370 ---- mon->mgold = 0L; #endif /* note: worn amulet of life saving must be preserved in order to operate */ + #ifndef oresist_disintegration #define oresist_disintegration(obj) \ (objects[obj->otyp].oc_oprop == DISINT_RES || \ obj_resists(obj, 5, 50) || is_quest_artifact(obj) || \ obj == m_amulet) ! #endif for (otmp = mon->minvent; otmp; otmp = otmp2) { otmp2 = otmp->nobj; ! if ( ! #ifdef WEBB_DISINT ! otmp == m_amulet || ! #endif ! !oresist_disintegration(otmp)) { obj_extract_self(otmp); obfree(otmp, (struct obj *)0); } } diff -rwBE --context=4 nethack-3.4.1-orig/util/makedefs.c nethack-3.4.1/util/makedefs.c *** nethack-3.4.1-orig/util/makedefs.c Sun Feb 23 08:43:44 2003 --- nethack-3.4.1/util/makedefs.c Fri Mar 21 18:20:38 2003 *************** *** 643,650 **** --- 643,653 ---- #endif #ifdef KOPS "Keystone Kops", #endif + #ifdef WEBB_DISINT + "monster: Disintegrator v0.2B", + #endif #ifdef HOLD_LOCKFILE_OPEN "exlusive lock on level 0 file", #endif #ifdef LOGFILE diff -rwBE --context=4 nethack-3.4.1-orig/win/share/monsters.txt nethack-3.4.1-disint/win/share/monsters.txt *** nethack-3.4.1-orig/win/share/monsters.txt Sun Feb 23 08:43:46 2003 --- nethack-3.4.1-disint/win/share/monsters.txt Fri Mar 21 14:40:00 2003 *************** *** 4098,4105 **** --- 4098,4124 ---- MMMMMPPPPPAAMMAM MMMMMMAAAAMMMMMM MMMMMMMMMMMMMMMM } + # tile 214 (disntegrator) + { + MMMMMMMMMMMMMMMM + MMMMGGGGMMMMMMMM + MMMGGAAAGMMMMMMM + MMMGAAGAGMMMMMMM + MMMGAOAOGMMMMMMM + MMMGOAAGOMMMGMMM + MMMMGGGGMGGGGMMM + MMMMGGGGGAAGGGMM + MMMGGAAAAAGAAGGM + MMGPGAAGAAAAAMMM + MMGGAGAAGAAAGAMM + MMGGAAAAAAGAGAAM + MMMMGAGAGAAGAAAM + MMMMMGGGGGGAMMAM + MMMMMMAAAAMMMMMM + MMMMMMMMMMMMMMMM + } # tile 215 (garter snake) { MMMMMMMMMMMMMMMM MMMMMMMMMMMMMMMM diff -rwBE --context=4 nethack-3.4.1-orig/win/share/tilemap.c nethack-3.4.1-disint/win/share/tilemap.c *** nethack-3.4.1-orig/win/share/tilemap.c Sun Feb 23 08:43:46 2003 --- nethack-3.4.1-disint/win/share/tilemap.c Fri Mar 21 14:32:20 2003 *************** *** 44,51 **** --- 44,54 ---- { MON_GLYPH, PM_JABBERWOCK, "Keystone Kop" }, { MON_GLYPH, PM_JABBERWOCK, "Kop Sergeant" }, { MON_GLYPH, PM_JABBERWOCK, "Kop Lieutenant" }, { MON_GLYPH, PM_JABBERWOCK, "Kop Kaptain" }, + #ifndef WEBB_DISINT + { MON_GLYPH, PM_DISINTEGRATOR, "disintegrator"}, + #endif #endif { MON_GLYPH, PM_VAMPIRE_LORD, "vampire mage" }, #ifndef CHARON /* not supported yet */ { MON_GLYPH, PM_CROESUS, "Charon" },