From: nethack.rankin Date: Sat, 1 Oct 2011 00:25:57 +0000 (+0000) Subject: intrinsics revamp (trunk only) X-Git-Tag: MOVE2GIT~173 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=84f02bd336b16a9ed656b2c29082cd92f10a9913;p=nethack intrinsics revamp (trunk only) Simplify many of the intrinsics macros from #define xxx_resistance (Hxxx || Exxx || resists_xxx(&youmonst)) down to #define xxx_resistance (Hxxx || Exxx) by setting or clearing an extra bit in Hxxx during polymorph so that the resists_xxx() check becomes implicit. Unfornately there were lots of places in the code that treat Hxxx as a timeout number--primarily for Stunned, Confused, and Hallucination; Stunned happens to be one of the revised macros--rather than as a bit mask, so this patch needed a lot more changes than originally antipated. --- diff --git a/include/patchlevel.h b/include/patchlevel.h index 609e808be..1b85ed42d 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -13,7 +13,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 48 +#define EDITLEVEL 49 #define COPYRIGHT_BANNER_A \ "NetHack, Copyright 1985-2011" diff --git a/include/prop.h b/include/prop.h index 5b3a572d6..d0a8a8772 100644 --- a/include/prop.h +++ b/include/prop.h @@ -132,7 +132,8 @@ struct prop { # define FROMOUTSIDE 0x04000000L /* By corpses, prayer, thrones, etc. */ # define INTRINSIC (FROMOUTSIDE|FROMRACE|FROMEXPER) /* Control flags */ -# define I_SPECIAL 0x10000000L /* Property is controllable */ +# define FROMFORM 0x10000000L /* Polyd; conferred by monster form */ +# define I_SPECIAL 0x20000000L /* Property is controllable */ }; /*** Definitions for backwards compatibility ***/ diff --git a/include/youprop.h b/include/youprop.h index ae7b72cf3..19fe7a73e 100644 --- a/include/youprop.h +++ b/include/youprop.h @@ -17,6 +17,8 @@ * EXxx refers to extrinsic bitfields from worn objects. * BXxx refers to the cause of the property being blocked. * Xxx refers to any source, including polymorph forms. + * [Post-3.4.3: HXxx now includes a FROMFORM bit to handle + * intrinsic conferred by being polymorphed.] */ @@ -27,68 +29,60 @@ /* With intrinsics and extrinsics */ #define HFire_resistance u.uprops[FIRE_RES].intrinsic #define EFire_resistance u.uprops[FIRE_RES].extrinsic -#define Fire_resistance (HFire_resistance || EFire_resistance || \ - resists_fire(&youmonst)) +#define Fire_resistance (HFire_resistance || EFire_resistance) #define HCold_resistance u.uprops[COLD_RES].intrinsic #define ECold_resistance u.uprops[COLD_RES].extrinsic -#define Cold_resistance (HCold_resistance || ECold_resistance || \ - resists_cold(&youmonst)) +#define Cold_resistance (HCold_resistance || ECold_resistance) #define HSleep_resistance u.uprops[SLEEP_RES].intrinsic #define ESleep_resistance u.uprops[SLEEP_RES].extrinsic -#define Sleep_resistance (HSleep_resistance || ESleep_resistance || \ - resists_sleep(&youmonst)) +#define Sleep_resistance (HSleep_resistance || ESleep_resistance) #define HDisint_resistance u.uprops[DISINT_RES].intrinsic #define EDisint_resistance u.uprops[DISINT_RES].extrinsic -#define Disint_resistance (HDisint_resistance || EDisint_resistance || \ - resists_disint(&youmonst)) +#define Disint_resistance (HDisint_resistance || EDisint_resistance) #define HShock_resistance u.uprops[SHOCK_RES].intrinsic #define EShock_resistance u.uprops[SHOCK_RES].extrinsic -#define Shock_resistance (HShock_resistance || EShock_resistance || \ - resists_elec(&youmonst)) +#define Shock_resistance (HShock_resistance || EShock_resistance) #define HPoison_resistance u.uprops[POISON_RES].intrinsic #define EPoison_resistance u.uprops[POISON_RES].extrinsic -#define Poison_resistance (HPoison_resistance || EPoison_resistance || \ - resists_poison(&youmonst)) +#define Poison_resistance (HPoison_resistance || EPoison_resistance) #define HDrain_resistance u.uprops[DRAIN_RES].intrinsic #define EDrain_resistance u.uprops[DRAIN_RES].extrinsic -#define Drain_resistance (HDrain_resistance || EDrain_resistance || \ - resists_drli(&youmonst)) +#define Drain_resistance (HDrain_resistance || EDrain_resistance) -/* Intrinsics only */ -#define HSick_resistance u.uprops[SICK_RES].intrinsic -#define Sick_resistance (HSick_resistance || \ - youmonst.data->mlet == S_FUNGUS || \ - youmonst.data == &mons[PM_GHOUL] || \ - defends(AD_DISE,uwep)) -#define Invulnerable u.uprops[INVULNERABLE].intrinsic /* [Tom] */ - -/* Extrinsics only */ +/* Hxxx due to FROMFORM only */ +#define HAntimagic u.uprops[ANTIMAGIC].intrinsic #define EAntimagic u.uprops[ANTIMAGIC].extrinsic -#define Antimagic (EAntimagic || \ - (Upolyd && resists_magm(&youmonst))) +#define Antimagic (HAntimagic || EAntimagic) +#define HAcid_resistance u.uprops[ACID_RES].intrinsic #define EAcid_resistance u.uprops[ACID_RES].extrinsic -#define Acid_resistance (EAcid_resistance || resists_acid(&youmonst)) +#define Acid_resistance (HAcid_resistance || EAcid_resistance) +#define HStone_resistance u.uprops[STONE_RES].intrinsic #define EStone_resistance u.uprops[STONE_RES].extrinsic -#define Stone_resistance (EStone_resistance || resists_ston(&youmonst)) +#define Stone_resistance (HStone_resistance || EStone_resistance) + +/* Intrinsics only */ +#define HSick_resistance u.uprops[SICK_RES].intrinsic +#define Sick_resistance (HSick_resistance || \ + defends(AD_DISE,uwep)) + +#define Invulnerable u.uprops[INVULNERABLE].intrinsic /* [Tom] */ /*** Troubles ***/ /* Pseudo-property */ -#define Punished (uball) +#define Punished (uball != 0) /* Those implemented solely as timeouts (we use just intrinsic) */ #define HStun u.uprops[STUNNED].intrinsic -#define Stunned (HStun || u.umonnum == PM_STALKER || \ - youmonst.data->mlet == S_BAT) - /* Note: birds will also be stunned */ +#define Stunned HStun #define HConfusion u.uprops[CONFUSION].intrinsic #define Confusion HConfusion @@ -111,11 +105,11 @@ #define Glib u.uprops[GLIB].intrinsic #define Slimed u.uprops[SLIMED].intrinsic /* [Tom] */ -/* Hallucination is solely a timeout; its resistance is extrinsic */ +/* Hallucination is solely a timeout */ #define HHallucination u.uprops[HALLUC].intrinsic +#define HHalluc_resistance u.uprops[HALLUC_RES].intrinsic #define EHalluc_resistance u.uprops[HALLUC_RES].extrinsic -#define Halluc_resistance (EHalluc_resistance || \ - (Upolyd && dmgtype(youmonst.data, AD_HALU))) +#define Halluc_resistance (HHalluc_resistance || EHalluc_resistance) #define Hallucination (HHallucination && !Halluc_resistance) /* Timeout, plus a worn mask */ @@ -143,13 +137,11 @@ /*** Vision and senses ***/ #define HSee_invisible u.uprops[SEE_INVIS].intrinsic #define ESee_invisible u.uprops[SEE_INVIS].extrinsic -#define See_invisible (HSee_invisible || ESee_invisible || \ - perceives(youmonst.data)) +#define See_invisible (HSee_invisible || ESee_invisible) #define HTelepat u.uprops[TELEPAT].intrinsic #define ETelepat u.uprops[TELEPAT].extrinsic -#define Blind_telepat (HTelepat || ETelepat || \ - telepathic(youmonst.data)) +#define Blind_telepat (HTelepat || ETelepat) #define Unblind_telepat (ETelepat) #define HWarning u.uprops[WARNING].intrinsic @@ -171,13 +163,12 @@ #define HClairvoyant u.uprops[CLAIRVOYANT].intrinsic #define EClairvoyant u.uprops[CLAIRVOYANT].extrinsic #define BClairvoyant u.uprops[CLAIRVOYANT].blocked -#define Clairvoyant ((HClairvoyant || EClairvoyant) &&\ +#define Clairvoyant ((HClairvoyant || EClairvoyant) && \ !BClairvoyant) #define HInfravision u.uprops[INFRAVISION].intrinsic #define EInfravision u.uprops[INFRAVISION].extrinsic -#define Infravision (HInfravision || EInfravision || \ - infravision(youmonst.data)) +#define Infravision (HInfravision || EInfravision) #define HDetect_monsters u.uprops[DETECT_MONSTERS].intrinsic #define EDetect_monsters u.uprops[DETECT_MONSTERS].extrinsic @@ -190,8 +181,7 @@ #define HInvis u.uprops[INVIS].intrinsic #define EInvis u.uprops[INVIS].extrinsic #define BInvis u.uprops[INVIS].blocked -#define Invis ((HInvis || EInvis || \ - pm_invisible(youmonst.data)) && !BInvis) +#define Invis ((HInvis || EInvis) && !BInvis) #define Invisible (Invis && !See_invisible) /* Note: invisibility also hides inventory and steed */ @@ -219,31 +209,28 @@ #define HTeleportation u.uprops[TELEPORT].intrinsic #define ETeleportation u.uprops[TELEPORT].extrinsic -#define Teleportation (HTeleportation || ETeleportation || \ - can_teleport(youmonst.data)) +#define Teleportation (HTeleportation || ETeleportation) #define HTeleport_control u.uprops[TELEPORT_CONTROL].intrinsic #define ETeleport_control u.uprops[TELEPORT_CONTROL].extrinsic -#define Teleport_control (HTeleport_control || ETeleport_control || \ - control_teleport(youmonst.data)) +#define Teleport_control (HTeleport_control || ETeleport_control) #define HLevitation u.uprops[LEVITATION].intrinsic #define ELevitation u.uprops[LEVITATION].extrinsic -#define Levitation (HLevitation || ELevitation || \ - is_floater(youmonst.data)) +#define Levitation (HLevitation || ELevitation) /* Can't touch surface, can't go under water; overrides all others */ #define Lev_at_will (((HLevitation & I_SPECIAL) != 0L || \ (ELevitation & W_ARTI) != 0L) && \ (HLevitation & ~(I_SPECIAL|TIMEOUT)) == 0L && \ - (ELevitation & ~W_ARTI) == 0L && \ - !is_floater(youmonst.data)) + (ELevitation & ~W_ARTI) == 0L) +#define HFlying u.uprops[FLYING].intrinsic #define EFlying u.uprops[FLYING].extrinsic #ifdef STEED -# define Flying (EFlying || is_flyer(youmonst.data) || \ +# define Flying (HFlying || EFlying || \ (u.usteed && is_flyer(u.usteed->data))) #else -# define Flying (EFlying || is_flyer(youmonst.data)) +# define Flying (HFlying || EFlying) #endif /* May touch surface; does not override any others */ @@ -256,11 +243,9 @@ #define ESwimming u.uprops[SWIMMING].extrinsic /* [Tom] */ #ifdef STEED # define Swimming (HSwimming || ESwimming || \ - is_swimmer(youmonst.data) || \ (u.usteed && is_swimmer(u.usteed->data))) #else -# define Swimming (HSwimming || ESwimming || \ - is_swimmer(youmonst.data)) +# define Swimming (HSwimming || ESwimming) #endif /* Get wet, don't go under water unless if amphibious */ @@ -280,8 +265,7 @@ #define HPasses_walls u.uprops[PASSES_WALLS].intrinsic #define EPasses_walls u.uprops[PASSES_WALLS].extrinsic -#define Passes_walls (HPasses_walls || EPasses_walls || \ - passes_walls(youmonst.data)) +#define Passes_walls (HPasses_walls || EPasses_walls) /*** Physical attributes ***/ @@ -313,8 +297,7 @@ #define HRegeneration u.uprops[REGENERATION].intrinsic #define ERegeneration u.uprops[REGENERATION].extrinsic -#define Regeneration (HRegeneration || ERegeneration || \ - regenerates(youmonst.data)) +#define Regeneration (HRegeneration || ERegeneration) #define HEnergy_regeneration u.uprops[ENERGY_REGENERATION].intrinsic #define EEnergy_regeneration u.uprops[ENERGY_REGENERATION].extrinsic @@ -349,9 +332,9 @@ #define Fast (HFast || EFast) #define Very_fast ((HFast & ~INTRINSIC) || EFast) +#define HReflecting u.uprops[REFLECTING].intrinsic #define EReflecting u.uprops[REFLECTING].extrinsic -#define Reflecting (EReflecting || \ - (youmonst.data == &mons[PM_SILVER_DRAGON])) +#define Reflecting (HReflecting || EReflecting) #define Free_action u.uprops[FREE_ACTION].extrinsic /* [Tom] */ diff --git a/src/apply.c b/src/apply.c index 5c3eee86e..ddaf2ca82 100644 --- a/src/apply.c +++ b/src/apply.c @@ -102,7 +102,7 @@ use_towel(obj) switch (rn2(3)) { case 2: old = Glib; - Glib += rn1(10, 3); + incr_itimeout(&Glib, rn1(10, 3)); Your("%s %s!", makeplural(body_part(HAND)), (old ? "are filthier than ever" : "get slimy")); return 1; @@ -1628,21 +1628,23 @@ struct obj *obj; long lcount = (long) rnd(100); switch (rn2(6)) { - case 0: make_sick(Sick ? Sick/3L + 1L : (long)rn1(ACURR(A_CON),20), - xname(obj), TRUE, SICK_NONVOMITABLE); + case 0: make_sick((Sick & TIMEOUT) ? (Sick & TIMEOUT) / 3L + 1L : + (long)rn1(ACURR(A_CON),20), + xname(obj), TRUE, SICK_NONVOMITABLE); break; - case 1: make_blinded(Blinded + lcount, TRUE); + case 1: make_blinded((Blinded & TIMEOUT) + lcount, TRUE); break; case 2: if (!Confusion) You("suddenly feel %s.", Hallucination ? "trippy" : "confused"); - make_confused(HConfusion + lcount, TRUE); + make_confused((HConfusion & TIMEOUT) + lcount, TRUE); break; - case 3: make_stunned(HStun + lcount, TRUE); + case 3: make_stunned((HStun & TIMEOUT) + lcount, TRUE); break; case 4: (void) adjattrib(rn2(A_MAX), -1, FALSE); break; - case 5: (void) make_hallucinated(HHallucination + lcount, TRUE, 0L); + case 5: (void) make_hallucinated((HHallucination & TIMEOUT) + + lcount, TRUE, 0L); break; } return; @@ -1655,19 +1657,20 @@ struct obj *obj; #define attr2trbl(Y) (Y) #define prop_trouble(X) trouble_list[trouble_count++] = prop2trbl(X) #define attr_trouble(Y) trouble_list[trouble_count++] = attr2trbl(Y) +#define TimedTrouble(P) (((P) && !((P) & ~TIMEOUT)) ? ((P) & TIMEOUT) : 0L) trouble_count = unfixable_trbl = did_prop = did_attr = 0; /* collect property troubles */ - if (Sick) prop_trouble(SICK); - if (Blinded > (long)u.ucreamed && + if (TimedTrouble(Sick)) prop_trouble(SICK); + if (TimedTrouble(Blinded) > (long)u.ucreamed && !(u.uswallow && attacktype_fordmg(u.ustuck->data, AT_ENGL, AD_BLND))) prop_trouble(BLINDED); - if (HHallucination) prop_trouble(HALLUC); - if (Vomiting) prop_trouble(VOMITING); - if (HConfusion) prop_trouble(CONFUSION); - if (HStun) prop_trouble(STUNNED); + if (TimedTrouble(HHallucination)) prop_trouble(HALLUC); + if (TimedTrouble(Vomiting)) prop_trouble(VOMITING); + if (TimedTrouble(HConfusion)) prop_trouble(CONFUSION); + if (TimedTrouble(HStun)) prop_trouble(STUNNED); unfixable_trbl = unfixable_trouble_count(TRUE); @@ -1768,6 +1771,7 @@ struct obj *obj; #undef attr2trbl #undef prop_trouble #undef attr_trouble +#undef TimedTrouble } /* @@ -2001,7 +2005,7 @@ struct obj *obj; makeplural(body_part(HAND))); } } else { - Glib += rnd(15); + incr_itimeout(&Glib, rnd(15)); You("coat your %s with grease.", makeplural(body_part(FINGER))); } @@ -3316,15 +3320,12 @@ unfixable_trouble_count(is_horn) /* lycanthropy is not desirable, but it doesn't actually make you feel bad */ - /* we'll assume that intrinsic stunning from being a bat/stalker - doesn't make you feel bad */ - if (!is_horn) { - if (Confusion) unfixable_trbl++; - if (Sick) unfixable_trbl++; - if (HHallucination) unfixable_trbl++; - if (Vomiting) unfixable_trbl++; - if (HStun) unfixable_trbl++; - } + if (!is_horn || (Confusion & ~TIMEOUT)) unfixable_trbl++; + if (!is_horn || (Sick & ~TIMEOUT)) unfixable_trbl++; + if (!is_horn || (HHallucination & ~TIMEOUT)) unfixable_trbl++; + if (!is_horn || (Vomiting & ~TIMEOUT)) unfixable_trbl++; + if (!is_horn || (HStun & ~TIMEOUT)) unfixable_trbl++; + return unfixable_trbl; } diff --git a/src/artifact.c b/src/artifact.c index fdfe1de2e..8b2907074 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -1013,7 +1013,7 @@ char *hittee; /* target's name: "you" or mon_nam(mdef) */ /* stun if that was selected and a worse effect didn't occur */ if (do_stun) { if (youdefend) - make_stunned((HStun + 3), FALSE); + make_stunned(((HStun & TIMEOUT) + 3L), FALSE); else mdef->mstun = 1; /* avoid extra stun message below if we used mb_verb["stun"] above */ @@ -1023,7 +1023,7 @@ char *hittee; /* target's name: "you" or mon_nam(mdef) */ do_confuse = !rn2(12); if (do_confuse) { if (youdefend) - make_confused(HConfusion + 4, FALSE); + make_confused((HConfusion & TIMEOUT) + 4L, FALSE); else mdef->mconf = 1; } diff --git a/src/attrib.c b/src/attrib.c index e43ea5103..02c8babcb 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -627,7 +627,7 @@ check_innate_abil(ability, frommask) long *ability; long frommask; { - const struct innate *abil; + const struct innate *abil = 0; if (frommask == FROMEXPER) switch (Role_switch) { @@ -646,7 +646,7 @@ long frommask; #endif case PM_VALKYRIE: abil = val_abil; break; case PM_WIZARD: abil = wiz_abil; break; - default: abil = 0; break; + default: break; } else if (frommask == FROMRACE) switch (Race_switch) { @@ -655,7 +655,7 @@ long frommask; case PM_HUMAN: case PM_DWARF: case PM_GNOME: - default: abil = 0; break; + default: break; } while (abil && abil->ability) { @@ -676,12 +676,11 @@ innately(ability) long *ability; { const struct innate *iptr; - if ((iptr=check_innate_abil(ability, FROMRACE))) + + if ((iptr = check_innate_abil(ability, FROMRACE)) != 0) return 1; - else if ((iptr=check_innate_abil(ability, FROMEXPER))) { - if (iptr->ulevel == 1) return 1; - return 2; - } + else if ((iptr = check_innate_abil(ability, FROMEXPER)) != 0) + return (iptr->ulevel == 1) ? 1 : 2; return 0; } @@ -759,8 +758,7 @@ adjabil(oldlevel,newlevel) int oldlevel, newlevel; { register const struct innate *abil, *rabil; - long mask = FROMEXPER; - + long prevabil, mask = FROMEXPER; switch (Role_switch) { case PM_ARCHEOLOGIST: abil = arc_abil; break; @@ -791,15 +789,14 @@ int oldlevel, newlevel; } while (abil || rabil) { - long prevabil; - /* Have we finished with the intrinsics list? */ - if (!abil || !abil->ability) { - /* Try the race intrinsics */ - if (!rabil || !rabil->ability) break; - abil = rabil; - rabil = 0; - mask = FROMRACE; - } + /* Have we finished with the intrinsics list? */ + if (!abil || !abil->ability) { + /* Try the race intrinsics */ + if (!rabil || !rabil->ability) break; + abil = rabil; + rabil = 0; + mask = FROMRACE; + } prevabil = *(abil->ability); if(oldlevel < abil->ulevel && newlevel >= abil->ulevel) { /* Abilities gained at level 1 can never be lost diff --git a/src/cmd.c b/src/cmd.c index 079b184fe..fd7df4d9e 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1748,7 +1748,7 @@ int final; else if (Invis) you_are("invisible to others",from_what(INVIS)); /* ordinarily "visible" is redundant; this is a special case for the situation when invisibility would be an expected attribute */ - else if ((HInvis || EInvis || pm_invisible(youmonst.data)) && BInvis) + else if ((HInvis || EInvis) && BInvis) you_are("visible", from_what(-INVIS)); if (Displaced) you_are("displaced",from_what(DISPLACED)); if (Stealth) you_are("stealthy",from_what(STEALTH)); @@ -1821,6 +1821,8 @@ int final; if (wizard) Sprintf(eos(buf), " (%d)", u.mtimedone); #endif you_are(buf,""); + if (lays_eggs(youmonst.data) && flags.female) + you_can("lay eggs", ""); } if (Unchanging) you_can("not change from your current form", from_what(UNCHANGING)); diff --git a/src/detect.c b/src/detect.c index bb77ec0e3..f20312c3a 100644 --- a/src/detect.c +++ b/src/detect.c @@ -862,11 +862,11 @@ struct obj *obj; case 1 : pline("%s too much to comprehend!", Tobjnam(obj, "are")); break; case 2 : pline("%s you!", Tobjnam(obj, "confuse")); - make_confused(HConfusion + rnd(100),FALSE); + make_confused((HConfusion & TIMEOUT) + (long)rnd(100), FALSE); break; case 3 : if (!resists_blnd(&youmonst)) { pline("%s your vision!", Tobjnam(obj, "damage")); - make_blinded(Blinded + rnd(100),FALSE); + make_blinded((Blinded & TIMEOUT) + (long)rnd(100), FALSE); if (!Blind) Your(vision_clears); } else { pline("%s your vision.", Tobjnam(obj, "assault")); @@ -874,7 +874,8 @@ struct obj *obj; } break; case 4 : pline("%s your mind!", Tobjnam(obj, "zap")); - (void) make_hallucinated(HHallucination + rnd(100),FALSE,0L); + (void) make_hallucinated((HHallucination & TIMEOUT) + + (long)rnd(100), FALSE, 0L); break; case 5 : pline("%s!", Tobjnam(obj, "explode")); useup(obj); diff --git a/src/do_wear.c b/src/do_wear.c index a7fc41a90..a5d8858f1 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -282,7 +282,7 @@ Cloak_on(VOID_ARGS) break; case MUMMY_WRAPPING: /* Note: it's already being worn, so we have to cheat here. */ - if ((HInvis || EInvis || pm_invisible(youmonst.data)) && !Blind) { + if ((HInvis || EInvis) && !Blind) { newsym(u.ux,u.uy); You("can %s!", See_invisible ? "no longer see through yourself" @@ -861,8 +861,7 @@ register struct obj *obj; see_objects(); #endif - if (Invis && !oldprop && !HSee_invisible && - !perceives(youmonst.data) && !Blind) { + if (Invis && !oldprop && !HSee_invisible && !Blind) { newsym(u.ux,u.uy); pline("Suddenly you are transparent, but there!"); learnring(obj, TRUE); diff --git a/src/eat.c b/src/eat.c index 8c21bf576..fde283f03 100644 --- a/src/eat.c +++ b/src/eat.c @@ -997,10 +997,10 @@ register int pm; case PM_YELLOW_LIGHT: /* fall into next case */ case PM_GIANT_BAT: - make_stunned(HStun + 30,FALSE); + make_stunned((HStun & TIMEOUT) + 30L, FALSE); /* fall into next case */ case PM_BAT: - make_stunned(HStun + 30,FALSE); + make_stunned((HStun & TIMEOUT) + 30L, FALSE); break; case PM_GIANT_MIMIC: tmp += 10; @@ -1048,8 +1048,8 @@ register int pm; } break; case PM_LIZARD: - if (HStun > 2) make_stunned(2L,FALSE); - if (HConfusion > 2) make_confused(2L,FALSE); + if ((HStun & TIMEOUT) > 2) make_stunned(2L, FALSE); + if ((HConfusion & TIMEOUT) > 2) make_confused(2L, FALSE); break; case PM_CHAMELEON: case PM_DOPPELGANGER: @@ -1090,7 +1090,8 @@ register int pm; if (dmgtype(ptr, AD_STUN) || dmgtype(ptr, AD_HALU) || pm == PM_VIOLET_FUNGUS) { pline("Oh wow! Great stuff!"); - (void)make_hallucinated(HHallucination + 200L, FALSE, 0L); + (void)make_hallucinated((HHallucination & TIMEOUT) + 200L, + FALSE, 0L); } /* Check the monster for all of the intrinsics. If this @@ -1785,7 +1786,7 @@ struct obj *otmp; #endif if (otmp->otyp == EGG && stale_egg(otmp)) { pline("Ugh. Rotten egg."); /* perhaps others like it */ - make_vomiting(Vomiting+d(10,4), TRUE); + make_vomiting((Vomiting & TIMEOUT) + (long)d(10,4), TRUE); } else give_feedback: pline("This %s is %s", singular(otmp, xname), @@ -2356,7 +2357,7 @@ doeat() /* generic "eat" command funtion (see cmd.c) */ pline("Ulch - that %s was rustproofed!", xname(otmp)); /* The regurgitated object's rustproofing is gone now */ otmp->oerodeproof = 0; - make_stunned(HStun + rn2(10), TRUE); + make_stunned((HStun & TIMEOUT) + (long)rn2(10), TRUE); You("spit %s out onto the %s.", the(xname(otmp)), surface(u.ux, u.uy)); if (carried(otmp)) { @@ -2587,9 +2588,8 @@ gethungry() /* as time goes by - called by moveloop() and domove() */ if (moves % 2) { /* odd turns */ /* Regeneration uses up food, unless due to an artifact */ - if (HRegeneration || ((ERegeneration & (~W_ART)) && - (ERegeneration != W_WEP || !uwep->oartifact))) - u.uhunger--; + if ((HRegeneration & ~FROMFORM) || + (ERegeneration & ~(W_ARTI|W_WEP))) u.uhunger--; if (near_capacity() > SLT_ENCUMBER) u.uhunger--; } else { /* even turns */ if (Hunger) u.uhunger--; diff --git a/src/end.c b/src/end.c index 080353ab4..78c96fd16 100644 --- a/src/end.c +++ b/src/end.c @@ -686,9 +686,9 @@ int how; newuhs(FALSE); } /* cure impending doom of sickness hero won't have time to fix */ - if ((Sick & TIMEOUT) == 1) { + if ((Sick & TIMEOUT) == 1L) { u.usick_type = 0; - Sick = 0; + set_itimeout(&Sick, 0L); } if (how == CHOKING) init_uhunger(); nomovemsg = "You survived that attempt on your life."; diff --git a/src/hack.c b/src/hack.c index 77820e514..9cd0d4b15 100644 --- a/src/hack.c +++ b/src/hack.c @@ -497,7 +497,7 @@ dosinkfall() register struct obj *obj; int dmg; - if (is_floater(youmonst.data) || (HLevitation & FROMOUTSIDE)) { + if (HLevitation & (FROMOUTSIDE|FROMFORM)) { You("wobble unsteadily for a moment."); } else { long save_ELev = ELevitation, save_HLev = HLevitation; @@ -1755,9 +1755,10 @@ boolean pick; turn, allowing it to do so could give the perception that a trap here is being triggered twice, so adjust the timeout to prevent that */ - if (trap && (HLevitation & TIMEOUT) == 1L) { + if (trap && (HLevitation & TIMEOUT) == 1L && + !ELevitation && !(HLevitation & ~TIMEOUT)) { if (rn2(2)) { /* defer timeout */ - HLevitation += 1L; + incr_itimeout(&HLevitation, 1L); } else { /* timeout early */ if (float_down(I_SPECIAL|TIMEOUT, 0L)) { /* levitation has ended; we've already triggered diff --git a/src/mcastu.c b/src/mcastu.c index dc02b28a9..f48044214 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -441,7 +441,7 @@ int spellnum; You(Stunned ? "struggle to keep your balance." : "reel..."); dmg = d(ACURR(A_DEX) < 12 ? 6 : 4, 4); if (Half_spell_damage) dmg = (dmg + 1) / 2; - make_stunned(HStun + dmg, FALSE); + make_stunned((HStun & TIMEOUT) + (long)dmg, FALSE); } dmg = 0; break; diff --git a/src/mhitu.c b/src/mhitu.c index 0de5ee1cc..e469264f9 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1446,7 +1446,7 @@ dopois: case AD_STUN: hitmsg(mtmp, mattk); if(!mtmp->mcan && !rn2(4)) { - make_stunned(HStun + dmg, TRUE); + make_stunned((HStun & TIMEOUT) + (long)dmg, TRUE); dmg /= 2; } break; @@ -2053,7 +2053,7 @@ gazemu(mtmp, mattk) /* monster gazes at you */ mtmp->mspec_used = mtmp->mspec_used + (stun + rn2(6)); pline("%s stares piercingly at you!", Monnam(mtmp)); - make_stunned(HStun + stun, TRUE); + make_stunned((HStun & TIMEOUT) + (long)stun, TRUE); stop_occupation(); } } diff --git a/src/polyself.c b/src/polyself.c index 9d2b6c1b3..16fc9f0ac 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -37,11 +37,60 @@ STATIC_VAR const char no_longer_petrify_resistant[] = change sex (ought to be an arg to polymon() and newman() instead) */ STATIC_VAR int sex_change_ok = 0; -/* update the youmonst.data structure pointer */ +/* update the youmonst.data structure pointer and intrinsics */ void set_uasmon() { - set_mon_data(&youmonst, &mons[u.umonnum], 0); + struct permonst *mdat = &mons[u.umonnum]; + + set_mon_data(&youmonst, mdat, 0); + +#define PROPSET(PropIndx, ON) do { \ + if (ON) u.uprops[PropIndx].intrinsic |= FROMFORM; \ + else u.uprops[PropIndx].intrinsic &= ~FROMFORM; } while (0) + + PROPSET(FIRE_RES, resists_fire(&youmonst)); + PROPSET(COLD_RES, resists_cold(&youmonst)); + PROPSET(SLEEP_RES, resists_sleep(&youmonst)); + PROPSET(DISINT_RES, resists_disint(&youmonst)); + PROPSET(SHOCK_RES, resists_elec(&youmonst)); + PROPSET(POISON_RES, resists_poison(&youmonst)); + PROPSET(ACID_RES, resists_acid(&youmonst)); + PROPSET(STONE_RES, resists_ston(&youmonst)); + { + /* resists_drli() takes wielded weapon into account; suppress it */ + struct obj *save_uwep = uwep; + + uwep = 0; + PROPSET(DRAIN_RES, resists_drli(&youmonst)); + uwep = save_uwep; + } + /* resists_magm() takes wielded, worn, and carried equipment into + into account; cheat and duplicate its monster-specific part */ + PROPSET(ANTIMAGIC, (dmgtype(mdat, AD_MAGM) || + mdat == &mons[PM_BABY_GRAY_DRAGON] || + dmgtype(mdat, AD_RBRE))); + PROPSET(SICK_RES, (mdat->mlet == S_FUNGUS || mdat == &mons[PM_GHOUL])); + + PROPSET(STUNNED, (mdat == &mons[PM_STALKER] || is_bat(mdat))); + PROPSET(HALLUC_RES, dmgtype(mdat, AD_HALU)); + PROPSET(SEE_INVIS, perceives(mdat)); + PROPSET(TELEPAT, telepathic(mdat)); + PROPSET(INFRAVISION, infravision(mdat)); + PROPSET(INVIS, pm_invisible(mdat)); + PROPSET(TELEPORT, can_teleport(mdat)); + PROPSET(TELEPORT_CONTROL, control_teleport(mdat)); + PROPSET(LEVITATION, is_floater(mdat)); + PROPSET(FLYING, is_flyer(mdat)); + PROPSET(SWIMMING, is_swimmer(mdat)); + /* [don't touch MAGICAL_BREATHING here; both Amphibious and Breathless + key off of it but include different monster forms...] */ + PROPSET(PASSES_WALLS, passes_walls(mdat)); + PROPSET(REGENERATION, regenerates(mdat)); + PROPSET(REFLECTING, (mdat == &mons[PM_SILVER_DRAGON])); + +#undef PROPSET + #ifdef STATUS_VIA_WINDOWPORT status_initialize(REASSESS_ONLY); #endif diff --git a/src/potion.c b/src/potion.c index ba5da82b1..a0ad86e4c 100644 --- a/src/potion.c +++ b/src/potion.c @@ -703,7 +703,7 @@ peffects(otmp) if (Detect_monsters) nothing++; unkn++; /* after a while, repeated uses become less effective */ - if (HDetect_monsters >= 300L) + if ((HDetect_monsters & TIMEOUT) >= 300L) i = 1; else i = rn1(40,21); @@ -906,10 +906,10 @@ peffects(otmp) if (otmp->cursed) HLevitation &= ~I_SPECIAL; if(!Levitation) { /* kludge to ensure proper operation of float_up() */ - HLevitation = 1; + set_itimeout(&HLevitation, 1L); float_up(); /* reverse kludge */ - HLevitation = 0; + set_itimeout(&HLevitation, 0L); if (otmp->cursed && !Is_waterlevel(&u.uz)) { if((u.ux != xupstair || u.uy != yupstair) && (u.ux != sstairs.sx || u.uy != sstairs.sy || !sstairs.up) diff --git a/src/pray.c b/src/pray.c index 923d39c22..96fddf852 100644 --- a/src/pray.c +++ b/src/pray.c @@ -224,10 +224,10 @@ in_trouble() && !u.usteed #endif ) return (TROUBLE_WOUNDED_LEGS); - if(u.uhs >= HUNGRY) return(TROUBLE_HUNGRY); - if(HStun) return (TROUBLE_STUNNED); - if(HConfusion) return (TROUBLE_CONFUSED); - if(Hallucination) return(TROUBLE_HALLUCINATION); + if (u.uhs >= HUNGRY) return TROUBLE_HUNGRY; + if (HStun & TIMEOUT) return TROUBLE_STUNNED; + if (HConfusion & TIMEOUT) return TROUBLE_CONFUSED; + if (HHallucination & TIMEOUT) return TROUBLE_HALLUCINATION; return(0); } @@ -1019,7 +1019,9 @@ pleased(g_align) break; } case 5: { - const char *msg="\"and thus I grant thee the gift of %s!\""; + static NEARDATA const char + msg[] = "\"and thus I grant thee the gift of %s!\""; + godvoice(u.ualign.type, "Thou hast pleased me with thy progress,"); if (!(HTelepat & INTRINSIC)) { HTelepat |= FROMOUTSIDE; diff --git a/src/read.c b/src/read.c index 70ede8718..55bbd7fdb 100644 --- a/src/read.c +++ b/src/read.c @@ -900,7 +900,7 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */ otmp->spe += -1; adj_abon(otmp, -1); } - make_stunned(HStun + rn1(10, 10), TRUE); + make_stunned((HStun & TIMEOUT) + (long)rn1(10, 10), TRUE); } } break; diff --git a/src/sit.c b/src/sit.c index 394a0767c..54a202f91 100644 --- a/src/sit.c +++ b/src/sit.c @@ -1,5 +1,4 @@ /* NetHack 3.5 sit.c $Date$ $Revision$ */ -/* SCCS Id: @(#)sit.c 3.5 2006/03/15 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -236,13 +235,12 @@ dosit() case 10: if (Luck < 0 || (HSee_invisible & INTRINSIC)) { if (level.flags.nommap) { - pline( - "A terrible drone fills your head!"); - make_confused(HConfusion + rnd(30), - FALSE); + pline("A terrible drone fills your head!"); + make_confused((HConfusion & TIMEOUT) + + (long)rnd(30), FALSE); } else { - pline("An image forms in your mind."); - do_mapping(); + pline("An image forms in your mind."); + do_mapping(); } } else { Your("vision becomes clear."); @@ -269,7 +267,8 @@ dosit() break; case 13: Your("mind turns into a pretzel!"); - make_confused(HConfusion + rn1(7,16),FALSE); + make_confused((HConfusion & TIMEOUT) + (long)rn1(7,16), + FALSE); break; default: impossible("throne effect"); break; @@ -292,16 +291,13 @@ dosit() struct obj *uegg; if (!flags.female) { - if(Hallucination) -pline("You may think you are a platypus but a male still can't lay eggs!"); - else - pline("Males can't lay eggs!"); + pline(Hallucination ? + "You may think you are a platypus but a male still can't lay eggs!" : + "Males can't lay eggs!"); + return 0; + } else if (u.uhunger < (int)objects[EGG].oc_nutrition) { + You("don't have enough energy to lay an egg."); return 0; - } - - if (u.uhunger < (int)objects[EGG].oc_nutrition) { - You("don't have enough energy to lay an egg."); - return 0; } uegg = mksobj(EGG, FALSE, FALSE); diff --git a/src/teleport.c b/src/teleport.c index d32a3a7a4..9ce210912 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -63,17 +63,22 @@ unsigned gpflags; mdat = mtmp->data; if (is_pool(x,y) && !ignorewater) { if (mtmp == &youmonst) - return !!(HLevitation || Flying || Wwalking || - Swimming || Amphibious); - else return (is_flyer(mdat) || is_swimmer(mdat) || - is_clinger(mdat)); + return (Levitation || Flying || Wwalking || + Swimming || Amphibious); + else + return (is_floater(mdat) || is_flyer(mdat) || + is_swimmer(mdat) || is_clinger(mdat)); } else if (mdat->mlet == S_EEL && rn2(13) && !ignorewater) { return FALSE; } else if (is_lava(x,y)) { if (mtmp == &youmonst) - return !!HLevitation; + return (Levitation || Flying || + (Fire_resistance && Wwalking && + uarmf && uarmf->oerodeproof) || + (Upolyd && likes_lava(youmonst.data))); else - return (is_flyer(mdat) || likes_lava(mdat)); + return (is_floater(mdat) || is_flyer(mdat) || + likes_lava(mdat)); } if (passes_walls(mdat) && may_passwall(x,y)) return TRUE; if (amorphous(mdat) && closed_door(x,y)) return TRUE; diff --git a/src/timeout.c b/src/timeout.c index e59cbebc7..84bc8ab7c 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -73,11 +73,11 @@ vomiting_dialogue() case 14: txt = vomiting_texts[0]; break; case 11: txt = vomiting_texts[1]; break; case 6: - make_stunned(HStun + d(2,4), FALSE); + make_stunned((HStun & TIMEOUT) + (long)d(2,4), FALSE); if (!Popeye(VOMITING)) stop_occupation(); /*FALLTHRU*/ case 9: - make_confused(HConfusion + d(2,4), FALSE); + make_confused((HConfusion & TIMEOUT) + (long)d(2,4), FALSE); if (multi > 0) nomul(0); break; case 8: txt = vomiting_texts[2]; break; @@ -293,24 +293,26 @@ nh_timeout() Fast ? " a bit" : ""); break; case CONFUSION: - HConfusion = 1; /* So make_confused works properly */ + /* So make_confused works properly */ + set_itimeout(&HConfusion, 1L); make_confused(0L, TRUE); - stop_occupation(); + if (!Confusion) stop_occupation(); break; case STUNNED: - HStun = 1; + set_itimeout(&HStun, 1L); make_stunned(0L, TRUE); - stop_occupation(); + if (!Stunned) stop_occupation(); break; case BLINDED: - Blinded = 1; + set_itimeout(&Blinded, 1L); make_blinded(0L, TRUE); - stop_occupation(); + if (!Blind) stop_occupation(); break; case DEAF: - if (!Deaf) + if (!Deaf) { You("can hear again."); - stop_occupation(); + stop_occupation(); + } break; case INVIS: newsym(u.ux,u.uy); @@ -332,18 +334,18 @@ nh_timeout() stop_occupation(); break; case HALLUC: - HHallucination = 1; + set_itimeout(&HHallucination, 1L); (void) make_hallucinated(0L, TRUE, 0L); - stop_occupation(); + if (!Hallucination) stop_occupation(); break; case SLEEPY: - if (unconscious() || Sleep_resistance) - HSleepy += rnd(100); - else if (Sleepy) { + if (unconscious() || Sleep_resistance) { + incr_itimeout(&HSleepy, rnd(100)); + } else if (Sleepy) { You("fall asleep."); sleeptime = rnd(20); fall_asleep(-sleeptime, TRUE); - HSleepy += sleeptime + rnd(100); + incr_itimeout(&HSleepy, sleeptime + rnd(100)); } break; case LEVITATION: @@ -381,7 +383,7 @@ nh_timeout() counter if that's the only fumble reason */ HFumbling &= ~FROMOUTSIDE; if (Fumbling) - HFumbling += rnd(20); + incr_itimeout(&HFumbling, rnd(20)); break; case DETECT_MONSTERS: see_monsters(); diff --git a/src/trap.c b/src/trap.c index 67371fcd6..7d383e9fe 100644 --- a/src/trap.c +++ b/src/trap.c @@ -4407,8 +4407,10 @@ boolean disarm; Blind ? " and get dizzy" : " and your vision blurs"); } - make_stunned(HStun + rn1(7, 16),FALSE); - (void) make_hallucinated(HHallucination + rn1(5, 16),FALSE,0L); + make_stunned((HStun & TIMEOUT) + (long)rn1(7, 16), + FALSE); + (void) make_hallucinated((HHallucination & TIMEOUT) + + (long)rn1(5, 16), FALSE, 0L); break; default: impossible("bad chest trap"); break; @@ -4587,7 +4589,7 @@ register int bodypart; losehp(Maybe_Half_Phys(dmg), "explosion", KILLED_BY_AN); exercise(A_STR, FALSE); if (bodypart) exercise(A_CON, FALSE); - make_stunned(HStun + dmg, TRUE); + make_stunned((HStun & TIMEOUT) + (long)dmg, TRUE); } /* Monster is hit by trap. */ diff --git a/src/u_init.c b/src/u_init.c index def0f6462..77cd0c080 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -1,5 +1,4 @@ /* NetHack 3.5 u_init.c $Date$ $Revision$ */ -/* SCCS Id: @(#)u_init.c 3.5 2006/12/13 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -563,6 +562,7 @@ u_init() u.umonnum = u.umonster = (flags.female && urole.femalenum != NON_PM) ? urole.femalenum : urole.malenum; + u.ulycn = NON_PM; set_uasmon(); u.ulevel = 0; /* set up some of the initial attributes */ @@ -577,7 +577,6 @@ u_init() u.ublesscnt = 300; /* no prayers just yet */ u.ualignbase[A_CURRENT] = u.ualignbase[A_ORIGINAL] = u.ualign.type = aligns[flags.initalign].value; - u.ulycn = NON_PM; #if defined(BSD) && !defined(POSIX_TYPES) (void) time((long *)&ubirthday); diff --git a/src/zap.c b/src/zap.c index ac22d7781..16382e615 100644 --- a/src/zap.c +++ b/src/zap.c @@ -2187,7 +2187,7 @@ boolean ordinary; if (ordinary || !rn2(10)) { /* permanent */ HInvis |= FROMOUTSIDE; } else { /* temporary */ - incr_itimeout(&HInvis, d(obj->spe, 250)); + incr_itimeout(&HInvis, d(obj->spe, 250)); } if (msg) { learn_it = TRUE; @@ -2262,7 +2262,7 @@ boolean ordinary; if (is_undead(youmonst.data)) { You_feel("frightened and %sstunned.", Stunned ? "even more " : ""); - make_stunned(HStun + rnd(30), FALSE); + make_stunned((HStun & TIMEOUT) + (long)rnd(30), FALSE); } else You("shudder in dread."); break;