Heart of Ahriman hack (trunk only)
From a four year old news posting: hero was levitating via #invoke
on the Heart of Ahriman, then dropping that artifact yielded:
You drop a gray stone named The Heart of Ahriman.
You float gently to the floor.
A gray stone named The Heart of Ahriman hits the floor.
That might be strictly correct, assuming that both hero and stone fall at
the same speed; if the stone was dropped from perhaps waist height then
the hero's feet would touch first. But it looks strange, like a cartoon
where something hangs in midair until someone notices that it should fall.
Removing the artifact from inventory causes the #invoke property to
toggle off. Unfortunately it has to be done here before the object can
be placed at its destination. Modifying message order seemed unviable;
this fix fiddles with the Levitation property in order to defer hero's
descent until after object handling is finished. Now same setup gives:
You drop a gray stone named The Heart of Ahriman.
A gray stone named The Heart of Ahriman hits the floor.
You float gently to the floor.
You see here a gray stone named The Heart of Ahriman.
This commit is contained in:
@@ -241,6 +241,7 @@ engulfer under influence of conflict or confusion could swallow monster at
|
|||||||
unicorn horn restoration no longer overrides sustain ability characteristic
|
unicorn horn restoration no longer overrides sustain ability characteristic
|
||||||
hider monster revived from corpse would start out hidden (even if own corpse
|
hider monster revived from corpse would start out hidden (even if own corpse
|
||||||
was only object around to hide under)
|
was only object around to hide under)
|
||||||
|
fix sequencing issues with dropping #invoked Heart of Ahriman
|
||||||
|
|
||||||
|
|
||||||
Platform- and/or Interface-Specific Fixes
|
Platform- and/or Interface-Specific Fixes
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ E int FDECL(disp_artifact_discoveries, (winid));
|
|||||||
E boolean FDECL(artifact_hit, (struct monst *,struct monst *,
|
E boolean FDECL(artifact_hit, (struct monst *,struct monst *,
|
||||||
struct obj *,int *,int));
|
struct obj *,int *,int));
|
||||||
E int NDECL(doinvoke);
|
E int NDECL(doinvoke);
|
||||||
|
E boolean FDECL(finesse_ahriman, (struct obj *));
|
||||||
E void FDECL(arti_speak, (struct obj *));
|
E void FDECL(arti_speak, (struct obj *));
|
||||||
E boolean FDECL(artifact_light, (struct obj *));
|
E boolean FDECL(artifact_light, (struct obj *));
|
||||||
E long FDECL(spec_m2, (struct obj *));
|
E long FDECL(spec_m2, (struct obj *));
|
||||||
|
|||||||
@@ -1475,6 +1475,33 @@ nothing_special:
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* will freeing this object from inventory cause levitation to end? */
|
||||||
|
boolean
|
||||||
|
finesse_ahriman(obj)
|
||||||
|
struct obj *obj;
|
||||||
|
{
|
||||||
|
const struct artifact *oart;
|
||||||
|
struct prop save_Lev;
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
/* if we aren't levitating or this isn't an artifact which confers
|
||||||
|
levitation via #invoke then freeinv() won't toggle levitation */
|
||||||
|
if (!Levitation || (oart = get_artifact(obj)) == 0 ||
|
||||||
|
oart->inv_prop != LEVITATION || !(ELevitation & W_ARTI))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* arti_invoke(off) -> float_down() clears I_SPECIAL|TIMEOUT & W_ARTI;
|
||||||
|
probe ahead to see whether that actually results in floating down;
|
||||||
|
(this assumes that there aren't two simultaneously invoked artifacts
|
||||||
|
both conferring levitation--safe, since if there were two of them,
|
||||||
|
invoking the 2nd would negate the 1st rather than stack with it) */
|
||||||
|
save_Lev = u.uprops[LEVITATION];
|
||||||
|
HLevitation &= ~(I_SPECIAL|TIMEOUT);
|
||||||
|
ELevitation &= ~W_ARTI;
|
||||||
|
result = (boolean)!Levitation;
|
||||||
|
u.uprops[LEVITATION] = save_Lev;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* WAC return TRUE if artifact is always lit */
|
/* WAC return TRUE if artifact is always lit */
|
||||||
boolean
|
boolean
|
||||||
|
|||||||
7
src/do.c
7
src/do.c
@@ -484,6 +484,12 @@ register struct obj *obj;
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!can_reach_floor(TRUE)) {
|
if (!can_reach_floor(TRUE)) {
|
||||||
|
/* we might be levitating due to #invoke Heart of Ahriman;
|
||||||
|
if so, levitation would end during call to freeinv()
|
||||||
|
and we want hitfloor() to happen before float_down() */
|
||||||
|
boolean levhack = finesse_ahriman(obj);
|
||||||
|
|
||||||
|
if (levhack) ELevitation = W_ART; /* other than W_ARTI */
|
||||||
if(flags.verbose) You("drop %s.", doname(obj));
|
if(flags.verbose) You("drop %s.", doname(obj));
|
||||||
#ifndef GOLDOBJ
|
#ifndef GOLDOBJ
|
||||||
if (obj->oclass != COIN_CLASS || obj == invent) freeinv(obj);
|
if (obj->oclass != COIN_CLASS || obj == invent) freeinv(obj);
|
||||||
@@ -493,6 +499,7 @@ register struct obj *obj;
|
|||||||
freeinv(obj);
|
freeinv(obj);
|
||||||
#endif
|
#endif
|
||||||
hitfloor(obj);
|
hitfloor(obj);
|
||||||
|
if (levhack) float_down(I_SPECIAL|TIMEOUT, W_ARTI|W_ART);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
if (!IS_ALTAR(levl[u.ux][u.uy].typ) && flags.verbose)
|
if (!IS_ALTAR(levl[u.ux][u.uy].typ) && flags.verbose)
|
||||||
|
|||||||
Reference in New Issue
Block a user