zapping unseen wands (trunk only)
Noticed recently when a user reported that an unseen monster zapping
an unseen wand caused wand of striking to become discovered. [That was
because the zap also hit a door and the code for the latter didn't check
whether the wand had been seen, and it got fixed a couple of weeks ago.]
When the player zaps wands while the hero is blinded, it was discovering
(for the cases where the effect can be observed without sight) the wand
even though the wand's description was unknown (showed in inventory as
"a wand"). This replaces the calls to makeknown() in zap.c with calls to
new learnwand(), which checks whether the wand description is known; you
no longer discover something you've never seen. Reverse effect has also
been added: if the type of wand has been discovered earlier, zapping an
unseen wand (another of the same type, picked up when blind and zapped
while still blind) will now mark it as seen (to show up in inventory as
"a wand of <whatever>" instead of just a "a wand"). The latter aspect
really ought to be independent of prior discovery, but we currently have
no way to record "we know what this particular item does even though we
don't know what type of item it is yet". [If we add that, it would be
applicable to potions (when operating on stacks) and rings too.]
Minor change: zapping yourself with wand of opening or spell of
knock will remove attached ball&chain rather than give a "chain quivers"
message. Explicitly zapping the chain already did that; if the unlocking
magic works on the chain connected to your leg then it really should also
work on your leg connected to the chain. Zapping unlocking at yourself
probably should also scan inventory to check for carrying locked chests,
but I didn't add that. (If added, then locking magic will need to be
augmented likewise.)
This also fixes <Someone>'s recent complaint: zapping an unknown
wand of teleportation at yourself didn't make it become discovered.
Now it will be, under the same circumstances as when you're riding: if
teleport control causes you to be prompted for destination, or if random
destination moves you more than jumping distance away from your original
position. (The Stunned exception to teleport control, which was missing
in zap_steed, perhaps ought to be moved into the macro definition of
Teleport_control itself so that all code always handles it consistently.)
This commit is contained in:
@@ -109,6 +109,9 @@ fix monsndx panic which happened after currently moving monster expelled
|
|||||||
swallowed hero onto magic trap and was made tame by its effect; taming
|
swallowed hero onto magic trap and was made tame by its effect; taming
|
||||||
no longer replaces monster
|
no longer replaces monster
|
||||||
reduced message verbosity when re-entering a temple
|
reduced message verbosity when re-entering a temple
|
||||||
|
zapping a never seen wand while blinded won't make the wand a discovery
|
||||||
|
zapping an unID'd wand of teleportation at self will discover it (usually)
|
||||||
|
zapping unlocking magic at self while punished will remove attached chain
|
||||||
|
|
||||||
|
|
||||||
Platform- and/or Interface-Specific Fixes
|
Platform- and/or Interface-Specific Fixes
|
||||||
|
|||||||
297
src/zap.c
297
src/zap.c
@@ -1,4 +1,4 @@
|
|||||||
/* SCCS Id: @(#)zap.c 3.5 2005/11/02 */
|
/* SCCS Id: @(#)zap.c 3.5 2006/01/30 */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -19,8 +19,9 @@ extern boolean notonhead; /* for long worms */
|
|||||||
/* kludge to use mondied instead of killed */
|
/* kludge to use mondied instead of killed */
|
||||||
extern boolean m_using;
|
extern boolean m_using;
|
||||||
|
|
||||||
STATIC_DCL void FDECL(polyuse, (struct obj*, int, int));
|
STATIC_DCL void FDECL(learnwand, (struct obj *));
|
||||||
STATIC_DCL void FDECL(create_polymon, (struct obj *, int));
|
STATIC_DCL void FDECL(polyuse, (struct obj *,int,int));
|
||||||
|
STATIC_DCL void FDECL(create_polymon, (struct obj *,int));
|
||||||
STATIC_DCL boolean FDECL(zap_updown, (struct obj *));
|
STATIC_DCL boolean FDECL(zap_updown, (struct obj *));
|
||||||
STATIC_DCL int FDECL(zhitm, (struct monst *,int,int,struct obj **));
|
STATIC_DCL int FDECL(zhitm, (struct monst *,int,int,struct obj **));
|
||||||
STATIC_DCL void FDECL(zhitu, (int,int,const char *,XCHAR_P,XCHAR_P));
|
STATIC_DCL void FDECL(zhitu, (int,int,const char *,XCHAR_P,XCHAR_P));
|
||||||
@@ -91,6 +92,58 @@ const char * const flash_types[] = { /* also used in buzzmu(mcastu.c) */
|
|||||||
""
|
""
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Recognizing unseen wands by zapping: in 3.4.3 and earlier, zapping
|
||||||
|
* most wand types while blind would add that type to the discoveries
|
||||||
|
* list even if it had never been seen (ie, picked up while blinded
|
||||||
|
* and shown in inventory as simply "a wand"). This behavior has been
|
||||||
|
* changed; now such wands won't be discovered. But if the type is
|
||||||
|
* already discovered, then the individual wand whose effect was just
|
||||||
|
* observed will be flagged as if seen. [You already know wands of
|
||||||
|
* striking; you zap "a wand" and observe striking effect (presumeably
|
||||||
|
* by sound or touch); it'll become shown in inventory as "a wand of
|
||||||
|
* striking".]
|
||||||
|
*
|
||||||
|
* Unfortunately, the new behavior isn't really correct either. There
|
||||||
|
* should be an `eknown' bit for "effect known" added for wands (and
|
||||||
|
* for potions since quaffing one of a stack is similar) so that the
|
||||||
|
* particular wand which has been zapped would have its type become
|
||||||
|
* known (it would change from "a wand" to "a wand of striking", for
|
||||||
|
* example) without the type becoming discovered or other unknown wands
|
||||||
|
* of that type showing additional information. When blindness ends,
|
||||||
|
* all objects in inventory with the eknown bit set would be discovered
|
||||||
|
* and other items of the same type would become known as such.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* wand discovery gets special handling when hero is blinded */
|
||||||
|
STATIC_OVL void
|
||||||
|
learnwand(obj)
|
||||||
|
struct obj *obj;
|
||||||
|
{
|
||||||
|
/* For a wand (or wand-like tool) zapped by the player, if the
|
||||||
|
effect was observable (determined by caller; usually seen, but
|
||||||
|
possibly heard or felt if the hero is blinded) then discover the
|
||||||
|
object type provided that the object itself is known (as more
|
||||||
|
than just "a wand"). If object type is already discovered and
|
||||||
|
we observed the effect, mark the individual wand as having been
|
||||||
|
seen. Suppress spells (which use fake spellbook object for `obj')
|
||||||
|
so that casting a spell won't re-discover its forgotten book. */
|
||||||
|
if (obj->oclass != SPBOOK_CLASS) {
|
||||||
|
/* if type already discovered, treat this item has having been seen
|
||||||
|
even if the hero is currently blinded (skips redundant makeknown) */
|
||||||
|
if (objects[obj->otyp].oc_name_known) {
|
||||||
|
obj->dknown = 1; /* will usually be set already */
|
||||||
|
/* otherwise discover it if this item itself has been or can be seen */
|
||||||
|
} else {
|
||||||
|
/* in case it was picked up while blind and then zapped without
|
||||||
|
examining inventory after regaining sight (bypassing xname()) */
|
||||||
|
if (!Blind) obj->dknown = 1;
|
||||||
|
/* make the discovery iff we know what we're manipulating */
|
||||||
|
if (obj->dknown) makeknown(obj->otyp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Routines for IMMEDIATE wands and spells. */
|
/* Routines for IMMEDIATE wands and spells. */
|
||||||
/* bhitm: monster mtmp was hit by the effect of wand or spell otmp */
|
/* bhitm: monster mtmp was hit by the effect of wand or spell otmp */
|
||||||
int
|
int
|
||||||
@@ -99,7 +152,7 @@ struct monst *mtmp;
|
|||||||
struct obj *otmp;
|
struct obj *otmp;
|
||||||
{
|
{
|
||||||
boolean wake = TRUE; /* Most 'zaps' should wake monster */
|
boolean wake = TRUE; /* Most 'zaps' should wake monster */
|
||||||
boolean reveal_invis = FALSE;
|
boolean reveal_invis = FALSE, learn_it = FALSE;
|
||||||
boolean dbldam = Role_if(PM_KNIGHT) && u.uhave.questart;
|
boolean dbldam = Role_if(PM_KNIGHT) && u.uhave.questart;
|
||||||
int dmg, otyp = otmp->otyp;
|
int dmg, otyp = otmp->otyp;
|
||||||
const char *zap_type_text = "spell";
|
const char *zap_type_text = "spell";
|
||||||
@@ -127,7 +180,7 @@ struct obj *otmp;
|
|||||||
hit(zap_type_text, mtmp, exclam(dmg));
|
hit(zap_type_text, mtmp, exclam(dmg));
|
||||||
(void) resist(mtmp, otmp->oclass, dmg, TELL);
|
(void) resist(mtmp, otmp->oclass, dmg, TELL);
|
||||||
} else miss(zap_type_text, mtmp);
|
} else miss(zap_type_text, mtmp);
|
||||||
makeknown(otyp);
|
learn_it = TRUE;
|
||||||
break;
|
break;
|
||||||
case WAN_SLOW_MONSTER:
|
case WAN_SLOW_MONSTER:
|
||||||
case SPE_SLOW_MONSTER:
|
case SPE_SLOW_MONSTER:
|
||||||
@@ -179,7 +232,7 @@ struct obj *otmp;
|
|||||||
if (mtmp->cham == CHAM_ORDINARY && !rn2(25)) {
|
if (mtmp->cham == CHAM_ORDINARY && !rn2(25)) {
|
||||||
if (canseemon(mtmp)) {
|
if (canseemon(mtmp)) {
|
||||||
pline("%s shudders!", Monnam(mtmp));
|
pline("%s shudders!", Monnam(mtmp));
|
||||||
makeknown(otyp);
|
learn_it = TRUE;
|
||||||
}
|
}
|
||||||
/* dropped inventory shouldn't be hit by this zap */
|
/* dropped inventory shouldn't be hit by this zap */
|
||||||
for (obj = mtmp->minvent; obj; obj = obj->nobj)
|
for (obj = mtmp->minvent; obj; obj = obj->nobj)
|
||||||
@@ -190,7 +243,7 @@ struct obj *otmp;
|
|||||||
} else if (newcham(mtmp, (struct permonst *)0,
|
} else if (newcham(mtmp, (struct permonst *)0,
|
||||||
(otyp != POT_POLYMORPH), FALSE)) {
|
(otyp != POT_POLYMORPH), FALSE)) {
|
||||||
if (!Hallucination && canspotmon(mtmp))
|
if (!Hallucination && canspotmon(mtmp))
|
||||||
makeknown(otyp);
|
learn_it = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -212,7 +265,7 @@ struct obj *otmp;
|
|||||||
mon_set_minvis(mtmp);
|
mon_set_minvis(mtmp);
|
||||||
if (!oldinvis && knowninvisible(mtmp)) {
|
if (!oldinvis && knowninvisible(mtmp)) {
|
||||||
pline("%s turns transparent!", nambuf);
|
pline("%s turns transparent!", nambuf);
|
||||||
makeknown(otyp);
|
learn_it = TRUE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -225,7 +278,7 @@ struct obj *otmp;
|
|||||||
wake = FALSE;
|
wake = FALSE;
|
||||||
reveal_invis = TRUE;
|
reveal_invis = TRUE;
|
||||||
probe_monster(mtmp);
|
probe_monster(mtmp);
|
||||||
makeknown(otyp);
|
learn_it = TRUE;
|
||||||
break;
|
break;
|
||||||
case WAN_OPENING:
|
case WAN_OPENING:
|
||||||
case SPE_KNOCK:
|
case SPE_KNOCK:
|
||||||
@@ -283,7 +336,7 @@ struct obj *otmp;
|
|||||||
break;
|
break;
|
||||||
case WAN_LIGHT: /* (broken wand) */
|
case WAN_LIGHT: /* (broken wand) */
|
||||||
if (flash_hits_mon(mtmp, otmp)) {
|
if (flash_hits_mon(mtmp, otmp)) {
|
||||||
makeknown(WAN_LIGHT);
|
learn_it = TRUE;
|
||||||
reveal_invis = TRUE;
|
reveal_invis = TRUE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -293,7 +346,7 @@ struct obj *otmp;
|
|||||||
reveal_invis = TRUE;
|
reveal_invis = TRUE;
|
||||||
if (sleep_monst(mtmp, d(1 + otmp->spe, 12), WAND_CLASS))
|
if (sleep_monst(mtmp, d(1 + otmp->spe, 12), WAND_CLASS))
|
||||||
slept_monst(mtmp);
|
slept_monst(mtmp);
|
||||||
if (!Blind) makeknown(WAN_SLEEP);
|
if (!Blind) learn_it = TRUE;
|
||||||
break;
|
break;
|
||||||
case SPE_STONE_TO_FLESH:
|
case SPE_STONE_TO_FLESH:
|
||||||
if (monsndx(mtmp->data) == PM_STONE_GOLEM) {
|
if (monsndx(mtmp->data) == PM_STONE_GOLEM) {
|
||||||
@@ -351,6 +404,9 @@ struct obj *otmp;
|
|||||||
!canspotmon(mtmp))
|
!canspotmon(mtmp))
|
||||||
map_invisible(bhitpos.x, bhitpos.y);
|
map_invisible(bhitpos.x, bhitpos.y);
|
||||||
}
|
}
|
||||||
|
/* if effect was observable then discover the wand type provided
|
||||||
|
that the wand itself has been seen */
|
||||||
|
if (learn_it) learnwand(otmp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1447,8 +1503,17 @@ bhito(obj, otmp)
|
|||||||
struct obj *obj, *otmp;
|
struct obj *obj, *otmp;
|
||||||
{
|
{
|
||||||
int res = 1; /* affected object by default */
|
int res = 1; /* affected object by default */
|
||||||
|
boolean learn_it = FALSE, maybelearnit;
|
||||||
xchar refresh_x, refresh_y;
|
xchar refresh_x, refresh_y;
|
||||||
|
|
||||||
|
/* fundamental: a wand effect hitting itself doesn't do anything;
|
||||||
|
otherwise we need to guard against accessing otmp after something
|
||||||
|
strange has happened to it (along the lines of polymorph or
|
||||||
|
stone-to-flesh [which aren't good examples since polymorph wands
|
||||||
|
aren't affected by polymorph zaps and stone-to-flesh isn't
|
||||||
|
available in wand form, but the concept still applies...]) */
|
||||||
|
if (obj == otmp) return 0;
|
||||||
|
|
||||||
if (obj->bypass) {
|
if (obj->bypass) {
|
||||||
/* The bypass bit is currently only used as follows:
|
/* The bypass bit is currently only used as follows:
|
||||||
*
|
*
|
||||||
@@ -1493,8 +1558,8 @@ struct obj *obj, *otmp;
|
|||||||
res = 0;
|
res = 0;
|
||||||
} else if (obj == uchain) {
|
} else if (obj == uchain) {
|
||||||
if (otmp->otyp == WAN_OPENING || otmp->otyp == SPE_KNOCK) {
|
if (otmp->otyp == WAN_OPENING || otmp->otyp == SPE_KNOCK) {
|
||||||
|
learn_it = TRUE;
|
||||||
unpunish();
|
unpunish();
|
||||||
makeknown(otmp->otyp);
|
|
||||||
} else
|
} else
|
||||||
res = 0;
|
res = 0;
|
||||||
} else
|
} else
|
||||||
@@ -1514,8 +1579,7 @@ struct obj *obj, *otmp;
|
|||||||
if (Is_box(obj)) (void) boxlock(obj, otmp);
|
if (Is_box(obj)) (void) boxlock(obj, otmp);
|
||||||
|
|
||||||
if (obj_shudders(obj)) {
|
if (obj_shudders(obj)) {
|
||||||
if (cansee(obj->ox, obj->oy))
|
if (cansee(obj->ox, obj->oy)) learn_it = TRUE;
|
||||||
makeknown(otmp->otyp);
|
|
||||||
do_osshock(obj);
|
do_osshock(obj);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1539,23 +1603,25 @@ struct obj *obj, *otmp;
|
|||||||
}
|
}
|
||||||
res = 1;
|
res = 1;
|
||||||
}
|
}
|
||||||
if (res) makeknown(WAN_PROBING);
|
if (res) learn_it = TRUE;
|
||||||
break;
|
break;
|
||||||
case WAN_STRIKING:
|
case WAN_STRIKING:
|
||||||
case SPE_FORCE_BOLT:
|
case SPE_FORCE_BOLT:
|
||||||
if (obj->otyp == BOULDER)
|
/* learn the type if you see or hear something break
|
||||||
fracture_rock(obj);
|
(the sound could be implicit) */
|
||||||
else if (obj->otyp == STATUE)
|
maybelearnit = cansee(obj->ox, obj->oy) || !Deaf;
|
||||||
(void) break_statue(obj);
|
if (obj->otyp == BOULDER) {
|
||||||
else {
|
fracture_rock(obj);
|
||||||
if (!context.mon_moving)
|
} else if (obj->otyp == STATUE) {
|
||||||
(void)hero_breaks(obj, obj->ox, obj->oy, FALSE);
|
(void) break_statue(obj);
|
||||||
else
|
} else {
|
||||||
(void)breaks(obj, obj->ox, obj->oy);
|
if (context.mon_moving ?
|
||||||
res = 0;
|
!breaks(obj, obj->ox, obj->oy) :
|
||||||
|
!hero_breaks(obj, obj->ox, obj->oy, FALSE))
|
||||||
|
maybelearnit = FALSE; /* nothing broke */
|
||||||
|
res = 0;
|
||||||
}
|
}
|
||||||
/* BUG[?]: shouldn't this depend upon you seeing it happen? */
|
if (maybelearnit) learn_it = TRUE;
|
||||||
makeknown(otmp->otyp);
|
|
||||||
break;
|
break;
|
||||||
case WAN_CANCELLATION:
|
case WAN_CANCELLATION:
|
||||||
case SPE_CANCELLATION:
|
case SPE_CANCELLATION:
|
||||||
@@ -1586,22 +1652,17 @@ struct obj *obj, *otmp;
|
|||||||
|
|
||||||
res = !!revive(obj, TRUE);
|
res = !!revive(obj, TRUE);
|
||||||
if (res && Role_if(PM_HEALER)) {
|
if (res && Role_if(PM_HEALER)) {
|
||||||
boolean u_noticed = FALSE;
|
|
||||||
|
|
||||||
if (Hallucination && !Deaf) {
|
if (Hallucination && !Deaf) {
|
||||||
You_hear("the sound of a defibrillator.");
|
You_hear("the sound of a defibrillator.");
|
||||||
u_noticed = TRUE;
|
learn_it = TRUE;
|
||||||
} else if (!Blind) {
|
} else if (!Blind) {
|
||||||
You("observe %s %s change dramatically.",
|
You("observe %s %s change dramatically.",
|
||||||
s_suffix(an(mons[corpsenm].mname)),
|
s_suffix(an(mons[corpsenm].mname)),
|
||||||
nonliving(&mons[corpsenm]) ?
|
nonliving(&mons[corpsenm]) ?
|
||||||
"motility" : "health");
|
"motility" : "health");
|
||||||
u_noticed = TRUE;
|
learn_it = TRUE;
|
||||||
}
|
|
||||||
if (u_noticed) {
|
|
||||||
makeknown(otmp->otyp);
|
|
||||||
exercise(A_WIS, TRUE);
|
|
||||||
}
|
}
|
||||||
|
if (learn_it) exercise(A_WIS, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1613,8 +1674,7 @@ struct obj *obj, *otmp;
|
|||||||
res = boxlock(obj, otmp);
|
res = boxlock(obj, otmp);
|
||||||
else
|
else
|
||||||
res = 0;
|
res = 0;
|
||||||
if (res /* && otmp->oclass == WAND_CLASS */)
|
if (res) learn_it = TRUE;
|
||||||
makeknown(otmp->otyp);
|
|
||||||
break;
|
break;
|
||||||
case WAN_SLOW_MONSTER: /* no effect on objects */
|
case WAN_SLOW_MONSTER: /* no effect on objects */
|
||||||
case SPE_SLOW_MONSTER:
|
case SPE_SLOW_MONSTER:
|
||||||
@@ -1726,6 +1786,9 @@ smell:
|
|||||||
impossible("What an interesting effect (%d)", otmp->otyp);
|
impossible("What an interesting effect (%d)", otmp->otyp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* if effect was observable then discover the wand type provided
|
||||||
|
that the wand itself has been seen */
|
||||||
|
if (learn_it) learnwand(otmp);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1748,8 +1811,8 @@ bhitpile(obj,fhito,tx,ty)
|
|||||||
(below), rather than on the current object, if it happens to
|
(below), rather than on the current object, if it happens to
|
||||||
encounter a statue which mustn't become animated. */
|
encounter a statue which mustn't become animated. */
|
||||||
if (t && t->ttyp == STATUE_TRAP &&
|
if (t && t->ttyp == STATUE_TRAP &&
|
||||||
activate_statue_trap(t, tx, ty, TRUE) && obj->otyp == WAN_STRIKING)
|
activate_statue_trap(t, tx, ty, TRUE))
|
||||||
makeknown(obj->otyp);
|
learnwand(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
poly_zapped = -1;
|
poly_zapped = -1;
|
||||||
@@ -1823,9 +1886,12 @@ register struct obj *obj;
|
|||||||
exercise(A_WIS, TRUE);
|
exercise(A_WIS, TRUE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (known && !objects[obj->otyp].oc_name_known) {
|
if (known) {
|
||||||
makeknown(obj->otyp);
|
if (!objects[obj->otyp].oc_name_known)
|
||||||
more_experienced(0,10);
|
more_experienced(0,10);
|
||||||
|
/* effect was observable; discover the wand type provided
|
||||||
|
that the wand itself has been seen */
|
||||||
|
learnwand(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1897,12 +1963,13 @@ zapyourself(obj, ordinary)
|
|||||||
struct obj *obj;
|
struct obj *obj;
|
||||||
boolean ordinary;
|
boolean ordinary;
|
||||||
{
|
{
|
||||||
|
boolean learn_it = FALSE;
|
||||||
int damage = 0;
|
int damage = 0;
|
||||||
|
|
||||||
switch(obj->otyp) {
|
switch(obj->otyp) {
|
||||||
case WAN_STRIKING:
|
case WAN_STRIKING:
|
||||||
makeknown(WAN_STRIKING);
|
|
||||||
case SPE_FORCE_BOLT:
|
case SPE_FORCE_BOLT:
|
||||||
|
learn_it = TRUE;
|
||||||
if(Antimagic) {
|
if(Antimagic) {
|
||||||
shieldeff(u.ux, u.uy);
|
shieldeff(u.ux, u.uy);
|
||||||
pline("Boing!");
|
pline("Boing!");
|
||||||
@@ -1917,7 +1984,7 @@ boolean ordinary;
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WAN_LIGHTNING:
|
case WAN_LIGHTNING:
|
||||||
makeknown(WAN_LIGHTNING);
|
learn_it = TRUE;
|
||||||
if (!Shock_resistance) {
|
if (!Shock_resistance) {
|
||||||
You("shock yourself!");
|
You("shock yourself!");
|
||||||
damage = d(12,6);
|
damage = d(12,6);
|
||||||
@@ -1937,8 +2004,8 @@ boolean ordinary;
|
|||||||
explode(u.ux, u.uy, 11, d(6,6), WAND_CLASS, EXPL_FIERY);
|
explode(u.ux, u.uy, 11, d(6,6), WAND_CLASS, EXPL_FIERY);
|
||||||
break;
|
break;
|
||||||
case WAN_FIRE:
|
case WAN_FIRE:
|
||||||
makeknown(WAN_FIRE);
|
|
||||||
case FIRE_HORN:
|
case FIRE_HORN:
|
||||||
|
learn_it = TRUE;
|
||||||
if (Fire_resistance) {
|
if (Fire_resistance) {
|
||||||
shieldeff(u.ux, u.uy);
|
shieldeff(u.ux, u.uy);
|
||||||
You_feel("rather warm.");
|
You_feel("rather warm.");
|
||||||
@@ -1955,9 +2022,9 @@ boolean ordinary;
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WAN_COLD:
|
case WAN_COLD:
|
||||||
makeknown(WAN_COLD);
|
|
||||||
case SPE_CONE_OF_COLD:
|
case SPE_CONE_OF_COLD:
|
||||||
case FROST_HORN:
|
case FROST_HORN:
|
||||||
|
learn_it = TRUE;
|
||||||
if (Cold_resistance) {
|
if (Cold_resistance) {
|
||||||
shieldeff(u.ux, u.uy);
|
shieldeff(u.ux, u.uy);
|
||||||
You_feel("a little chill.");
|
You_feel("a little chill.");
|
||||||
@@ -1970,8 +2037,8 @@ boolean ordinary;
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WAN_MAGIC_MISSILE:
|
case WAN_MAGIC_MISSILE:
|
||||||
makeknown(WAN_MAGIC_MISSILE);
|
|
||||||
case SPE_MAGIC_MISSILE:
|
case SPE_MAGIC_MISSILE:
|
||||||
|
learn_it = TRUE;
|
||||||
if(Antimagic) {
|
if(Antimagic) {
|
||||||
shieldeff(u.ux, u.uy);
|
shieldeff(u.ux, u.uy);
|
||||||
pline_The("missiles bounce!");
|
pline_The("missiles bounce!");
|
||||||
@@ -1982,11 +2049,11 @@ boolean ordinary;
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WAN_POLYMORPH:
|
case WAN_POLYMORPH:
|
||||||
if (!Unchanging)
|
|
||||||
makeknown(WAN_POLYMORPH);
|
|
||||||
case SPE_POLYMORPH:
|
case SPE_POLYMORPH:
|
||||||
if (!Unchanging)
|
if (!Unchanging) {
|
||||||
polyself(0);
|
learn_it = TRUE;
|
||||||
|
polyself(0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WAN_CANCELLATION:
|
case WAN_CANCELLATION:
|
||||||
@@ -1995,12 +2062,12 @@ boolean ordinary;
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SPE_DRAIN_LIFE:
|
case SPE_DRAIN_LIFE:
|
||||||
if (!Drain_resistance) {
|
if (!Drain_resistance) {
|
||||||
losexp("life drainage");
|
learn_it = TRUE; /* (no effect for spells...) */
|
||||||
makeknown(obj->otyp);
|
losexp("life drainage");
|
||||||
}
|
}
|
||||||
damage = 0; /* No additional damage */
|
damage = 0; /* No additional damage */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WAN_MAKE_INVISIBLE: {
|
case WAN_MAKE_INVISIBLE: {
|
||||||
/* have to test before changing HInvis but must change
|
/* have to test before changing HInvis but must change
|
||||||
@@ -2019,7 +2086,7 @@ boolean ordinary;
|
|||||||
incr_itimeout(&HInvis, d(obj->spe, 250));
|
incr_itimeout(&HInvis, d(obj->spe, 250));
|
||||||
}
|
}
|
||||||
if (msg) {
|
if (msg) {
|
||||||
makeknown(WAN_MAKE_INVISIBLE);
|
learn_it = TRUE;
|
||||||
newsym(u.ux, u.uy);
|
newsym(u.ux, u.uy);
|
||||||
self_invis_message();
|
self_invis_message();
|
||||||
}
|
}
|
||||||
@@ -2028,19 +2095,19 @@ boolean ordinary;
|
|||||||
|
|
||||||
case WAN_SPEED_MONSTER:
|
case WAN_SPEED_MONSTER:
|
||||||
if (!(HFast & INTRINSIC)) {
|
if (!(HFast & INTRINSIC)) {
|
||||||
|
learn_it = TRUE;
|
||||||
if (!Fast)
|
if (!Fast)
|
||||||
You("speed up.");
|
You("speed up.");
|
||||||
else
|
else
|
||||||
Your("quickness feels more natural.");
|
Your("quickness feels more natural.");
|
||||||
makeknown(WAN_SPEED_MONSTER);
|
|
||||||
exercise(A_DEX, TRUE);
|
exercise(A_DEX, TRUE);
|
||||||
}
|
}
|
||||||
HFast |= FROMOUTSIDE;
|
HFast |= FROMOUTSIDE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WAN_SLEEP:
|
case WAN_SLEEP:
|
||||||
makeknown(WAN_SLEEP);
|
|
||||||
case SPE_SLEEP:
|
case SPE_SLEEP:
|
||||||
|
learn_it = TRUE;
|
||||||
if(Sleep_resistance) {
|
if(Sleep_resistance) {
|
||||||
shieldeff(u.ux, u.uy);
|
shieldeff(u.ux, u.uy);
|
||||||
You("don't feel sleepy!");
|
You("don't feel sleepy!");
|
||||||
@@ -2053,14 +2120,19 @@ boolean ordinary;
|
|||||||
case WAN_SLOW_MONSTER:
|
case WAN_SLOW_MONSTER:
|
||||||
case SPE_SLOW_MONSTER:
|
case SPE_SLOW_MONSTER:
|
||||||
if(HFast & (TIMEOUT | INTRINSIC)) {
|
if(HFast & (TIMEOUT | INTRINSIC)) {
|
||||||
|
learn_it = TRUE;
|
||||||
u_slow_down();
|
u_slow_down();
|
||||||
makeknown(obj->otyp);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WAN_TELEPORTATION:
|
case WAN_TELEPORTATION:
|
||||||
case SPE_TELEPORT_AWAY:
|
case SPE_TELEPORT_AWAY:
|
||||||
tele();
|
tele();
|
||||||
|
/* same criteria as when mounted (zap_steed) */
|
||||||
|
if ((Teleport_control && !Stunned) ||
|
||||||
|
!couldsee(u.ux0, u.uy0) ||
|
||||||
|
distu(u.ux0, u.uy0) >= 16)
|
||||||
|
learn_it = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WAN_DEATH:
|
case WAN_DEATH:
|
||||||
@@ -2071,17 +2143,17 @@ boolean ordinary;
|
|||||||
: "You seem no deader than before.");
|
: "You seem no deader than before.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
learn_it = TRUE;
|
||||||
Sprintf(killer.name,"shot %sself with a death ray",uhim());
|
Sprintf(killer.name,"shot %sself with a death ray",uhim());
|
||||||
killer.format = NO_KILLER_PREFIX;
|
killer.format = NO_KILLER_PREFIX;
|
||||||
You("irradiate yourself with pure energy!");
|
You("irradiate yourself with pure energy!");
|
||||||
You("die.");
|
You("die.");
|
||||||
makeknown(obj->otyp);
|
|
||||||
/* They might survive with an amulet of life saving */
|
/* They might survive with an amulet of life saving */
|
||||||
done(DIED);
|
done(DIED);
|
||||||
break;
|
break;
|
||||||
case WAN_UNDEAD_TURNING:
|
case WAN_UNDEAD_TURNING:
|
||||||
makeknown(WAN_UNDEAD_TURNING);
|
|
||||||
case SPE_TURN_UNDEAD:
|
case SPE_TURN_UNDEAD:
|
||||||
|
learn_it = TRUE;
|
||||||
(void) unturn_dead(&youmonst);
|
(void) unturn_dead(&youmonst);
|
||||||
if (is_undead(youmonst.data)) {
|
if (is_undead(youmonst.data)) {
|
||||||
You_feel("frightened and %sstunned.",
|
You_feel("frightened and %sstunned.",
|
||||||
@@ -2092,6 +2164,7 @@ boolean ordinary;
|
|||||||
break;
|
break;
|
||||||
case SPE_HEALING:
|
case SPE_HEALING:
|
||||||
case SPE_EXTRA_HEALING:
|
case SPE_EXTRA_HEALING:
|
||||||
|
learn_it = TRUE; /* (no effect for spells...) */
|
||||||
healup(d(6, obj->otyp == SPE_EXTRA_HEALING ? 8 : 4),
|
healup(d(6, obj->otyp == SPE_EXTRA_HEALING ? 8 : 4),
|
||||||
0, FALSE, (obj->otyp == SPE_EXTRA_HEALING));
|
0, FALSE, (obj->otyp == SPE_EXTRA_HEALING));
|
||||||
You_feel("%sbetter.",
|
You_feel("%sbetter.",
|
||||||
@@ -2104,13 +2177,15 @@ boolean ordinary;
|
|||||||
case EXPENSIVE_CAMERA:
|
case EXPENSIVE_CAMERA:
|
||||||
#endif
|
#endif
|
||||||
damage += rnd(25);
|
damage += rnd(25);
|
||||||
if (flashburn((long)damage)) makeknown(obj->otyp);
|
if (flashburn((long)damage)) learn_it = TRUE;
|
||||||
damage = 0; /* reset */
|
damage = 0; /* reset */
|
||||||
break;
|
break;
|
||||||
case WAN_OPENING:
|
case WAN_OPENING:
|
||||||
if (Punished) makeknown(WAN_OPENING);
|
|
||||||
case SPE_KNOCK:
|
case SPE_KNOCK:
|
||||||
if (Punished) Your("chain quivers for a moment.");
|
if (Punished) {
|
||||||
|
learn_it = TRUE;
|
||||||
|
unpunish();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WAN_DIGGING:
|
case WAN_DIGGING:
|
||||||
case SPE_DIG:
|
case SPE_DIG:
|
||||||
@@ -2120,25 +2195,33 @@ boolean ordinary;
|
|||||||
case SPE_WIZARD_LOCK:
|
case SPE_WIZARD_LOCK:
|
||||||
break;
|
break;
|
||||||
case WAN_PROBING:
|
case WAN_PROBING:
|
||||||
for (obj = invent; obj; obj = obj->nobj)
|
{
|
||||||
obj->dknown = 1;
|
struct obj *otmp;
|
||||||
/* note: `obj' reused; doesn't point at wand anymore */
|
|
||||||
makeknown(WAN_PROBING);
|
for (otmp = invent; otmp; otmp = otmp->nobj)
|
||||||
|
otmp->dknown = 1;
|
||||||
|
learn_it = TRUE;
|
||||||
ustatusline();
|
ustatusline();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case SPE_STONE_TO_FLESH:
|
case SPE_STONE_TO_FLESH:
|
||||||
{
|
{
|
||||||
struct obj *otemp, *onext;
|
struct obj *otmp, *onxt;
|
||||||
boolean didmerge;
|
boolean didmerge;
|
||||||
|
|
||||||
if (u.umonnum == PM_STONE_GOLEM)
|
if (u.umonnum == PM_STONE_GOLEM) {
|
||||||
|
learn_it = TRUE;
|
||||||
(void) polymon(PM_FLESH_GOLEM);
|
(void) polymon(PM_FLESH_GOLEM);
|
||||||
if (Stoned) fix_petrification(); /* saved! */
|
}
|
||||||
|
if (Stoned) {
|
||||||
|
learn_it = TRUE;
|
||||||
|
fix_petrification(); /* saved! */
|
||||||
|
}
|
||||||
/* but at a cost.. */
|
/* but at a cost.. */
|
||||||
for (otemp = invent; otemp; otemp = onext) {
|
for (otmp = invent; otmp; otmp = onxt) {
|
||||||
onext = otemp->nobj;
|
onxt = otmp->nobj;
|
||||||
(void) bhito(otemp, obj);
|
if (bhito(otmp, obj)) learn_it = TRUE;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* It is possible that we can now merge some inventory.
|
* It is possible that we can now merge some inventory.
|
||||||
* Do a higly paranoid merge. Restart from the beginning
|
* Do a higly paranoid merge. Restart from the beginning
|
||||||
@@ -2146,18 +2229,22 @@ boolean ordinary;
|
|||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
didmerge = FALSE;
|
didmerge = FALSE;
|
||||||
for (otemp = invent; !didmerge && otemp; otemp = otemp->nobj)
|
for (otmp = invent; !didmerge && otmp; otmp = otmp->nobj)
|
||||||
for (onext = otemp->nobj; onext; onext = onext->nobj)
|
for (onxt = otmp->nobj; onxt; onxt = onxt->nobj)
|
||||||
if (merged(&otemp, &onext)) {
|
if (merged(&otmp, &onxt)) {
|
||||||
didmerge = TRUE;
|
didmerge = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (didmerge);
|
} while (didmerge);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default: impossible("object %d used?",obj->otyp);
|
}
|
||||||
|
default:
|
||||||
|
impossible("zapyourself: object %d used?", obj->otyp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* if effect was observable then discover the wand type provided
|
||||||
|
that the wand itself has been seen */
|
||||||
|
if (learn_it) learnwand(obj);
|
||||||
return(damage);
|
return(damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2194,16 +2281,18 @@ struct obj *obj; /* wand or spell */
|
|||||||
*/
|
*/
|
||||||
case WAN_PROBING:
|
case WAN_PROBING:
|
||||||
probe_monster(u.usteed);
|
probe_monster(u.usteed);
|
||||||
makeknown(WAN_PROBING);
|
learnwand(obj);
|
||||||
steedhit = TRUE;
|
steedhit = TRUE;
|
||||||
break;
|
break;
|
||||||
case WAN_TELEPORTATION:
|
case WAN_TELEPORTATION:
|
||||||
case SPE_TELEPORT_AWAY:
|
case SPE_TELEPORT_AWAY:
|
||||||
/* you go together */
|
/* you go together */
|
||||||
tele();
|
tele();
|
||||||
if(Teleport_control || !couldsee(u.ux0, u.uy0) ||
|
/* same criteria as when unmounted (zapyourself) */
|
||||||
(distu(u.ux0, u.uy0) >= 16))
|
if ((Teleport_control && !Stunned) ||
|
||||||
makeknown(obj->otyp);
|
!couldsee(u.ux0, u.uy0) ||
|
||||||
|
distu(u.ux0, u.uy0) >= 16)
|
||||||
|
learnwand(obj);
|
||||||
steedhit = TRUE;
|
steedhit = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2512,9 +2601,9 @@ struct obj *obj;
|
|||||||
impossible("weffects: unexpected spell or wand");
|
impossible("weffects: unexpected spell or wand");
|
||||||
disclose = TRUE;
|
disclose = TRUE;
|
||||||
}
|
}
|
||||||
if (disclose && was_unkn) {
|
if (disclose) {
|
||||||
makeknown(otyp);
|
learnwand(obj);
|
||||||
more_experienced(0,10);
|
if (was_unkn) more_experienced(0, 10);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2711,30 +2800,34 @@ struct obj **pobj; /* object tossed/used, set to NULL
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (weapon == ZAPPED_WAND && find_drawbridge(&x,&y))
|
if (weapon == ZAPPED_WAND && find_drawbridge(&x,&y)) {
|
||||||
|
boolean learn_it = FALSE;
|
||||||
|
|
||||||
switch (obj->otyp) {
|
switch (obj->otyp) {
|
||||||
case WAN_OPENING:
|
case WAN_OPENING:
|
||||||
case SPE_KNOCK:
|
case SPE_KNOCK:
|
||||||
if (is_db_wall(bhitpos.x, bhitpos.y)) {
|
if (is_db_wall(bhitpos.x, bhitpos.y)) {
|
||||||
if (cansee(x,y) || cansee(bhitpos.x,bhitpos.y))
|
if (cansee(x,y) || cansee(bhitpos.x,bhitpos.y))
|
||||||
makeknown(obj->otyp);
|
learn_it = TRUE;
|
||||||
open_drawbridge(x,y);
|
open_drawbridge(x,y);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WAN_LOCKING:
|
case WAN_LOCKING:
|
||||||
case SPE_WIZARD_LOCK:
|
case SPE_WIZARD_LOCK:
|
||||||
if ((cansee(x,y) || cansee(bhitpos.x, bhitpos.y))
|
if ((cansee(x,y) || cansee(bhitpos.x, bhitpos.y)) &&
|
||||||
&& levl[x][y].typ == DRAWBRIDGE_DOWN)
|
levl[x][y].typ == DRAWBRIDGE_DOWN)
|
||||||
makeknown(obj->otyp);
|
learn_it = TRUE;
|
||||||
close_drawbridge(x,y);
|
close_drawbridge(x,y);
|
||||||
break;
|
break;
|
||||||
case WAN_STRIKING:
|
case WAN_STRIKING:
|
||||||
case SPE_FORCE_BOLT:
|
case SPE_FORCE_BOLT:
|
||||||
if (typ != DRAWBRIDGE_UP)
|
if (typ != DRAWBRIDGE_UP)
|
||||||
destroy_drawbridge(x,y);
|
destroy_drawbridge(x,y);
|
||||||
makeknown(obj->otyp);
|
learn_it = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (learn_it) learnwand(obj);
|
||||||
|
}
|
||||||
|
|
||||||
mtmp = m_at(bhitpos.x, bhitpos.y);
|
mtmp = m_at(bhitpos.x, bhitpos.y);
|
||||||
|
|
||||||
@@ -2833,10 +2926,10 @@ struct obj **pobj; /* object tossed/used, set to NULL
|
|||||||
case SPE_FORCE_BOLT:
|
case SPE_FORCE_BOLT:
|
||||||
if (doorlock(obj, bhitpos.x, bhitpos.y)) {
|
if (doorlock(obj, bhitpos.x, bhitpos.y)) {
|
||||||
if (cansee(bhitpos.x, bhitpos.y) ||
|
if (cansee(bhitpos.x, bhitpos.y) ||
|
||||||
(obj->otyp == WAN_STRIKING))
|
(obj->otyp == WAN_STRIKING && !Deaf))
|
||||||
makeknown(obj->otyp);
|
learnwand(obj);
|
||||||
if (levl[bhitpos.x][bhitpos.y].doormask == D_BROKEN
|
if (levl[bhitpos.x][bhitpos.y].doormask == D_BROKEN &&
|
||||||
&& *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE)) {
|
*in_rooms(bhitpos.x, bhitpos.y, SHOPBASE)) {
|
||||||
shopdoor = TRUE;
|
shopdoor = TRUE;
|
||||||
add_damage(bhitpos.x, bhitpos.y, 400L);
|
add_damage(bhitpos.x, bhitpos.y, 400L);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user