Sunsword's #invoke for blinding ray

Support aiming at self (to become blinded) and aiming up/down (to
light the hero's current map spot only, persistently rather than
temporarily).  Also, recognize cancel at the "direction?" prompt to
not leave the #invoke cooldown count set when aborted.

Aiming at self was a little trickier than expected to test because
you're blindness-resistant when wielding Sunsword.  But it doesn't
have to be wielded to be invoked.
This commit is contained in:
PatR
2024-04-02 19:56:39 -07:00
parent e821274382
commit 6aaab97044
2 changed files with 43 additions and 10 deletions

View File

@@ -1668,11 +1668,13 @@ doinvoke(void)
staticfn int staticfn int
arti_invoke(struct obj *obj) arti_invoke(struct obj *obj)
{ {
const struct artifact *oart = get_artifact(obj); const struct artifact *oart;
if (!obj) { if (!obj) {
impossible("arti_invoke without obj"); impossible("arti_invoke without obj");
return ECMD_OK; return ECMD_OK;
} }
oart = get_artifact(obj);
if (oart == &artilist[ART_NONARTIFACT] || !oart->inv_prop) { if (oart == &artilist[ART_NONARTIFACT] || !oart->inv_prop) {
if (obj->otyp == CRYSTAL_BALL) if (obj->otyp == CRYSTAL_BALL)
use_crystal_ball(&obj); use_crystal_ball(&obj);
@@ -1909,16 +1911,47 @@ arti_invoke(struct obj *obj)
} }
if (nvanished) { if (nvanished) {
pline("%she demon%s disappear%s in a cloud of brimstone!", char subject[] = "demons";
nstayed ? (nvanished > nstayed ? "Most of t" : "Some of t") : "T",
nvanished > 1 ? "s" : "", if (nvanished == 1)
nvanished > 1 ? "" : "s"); *(eos(subject) - 1) = '\0'; /* remove 's' */
pline("%s %s %s in a cloud of brimstone!",
nstayed ? ((nvanished > nstayed)
? "Most of the"
: "Some of the")
: "The",
subject, vtense(subject, "disappear"));
} }
break; break;
} }
case BLINDING_RAY: case BLINDING_RAY:
if (getdir((char *) 0) && (u.dx || u.dy)) if (getdir((char *) 0)) {
do_blinding_ray(obj); if (u.dx || u.dy) {
do_blinding_ray(obj);
} else if (u.dz) {
/* up or down; light this map spot */
levl[u.ux][u.uy].lit = 1;
pline("%s", ((Blind || levl[u.ux][u.uy].waslit)
? nothing_seems_to_happen
: "It is lit here now."));
} else { /* zapyourself() */
boolean vulnerable = (u.umonnum == PM_GREMLIN);
int damg = obj->blessed ? 15 : !obj->cursed ? 10 : 5;
if (vulnerable) /* could be fatal if Unchanging */
(void) lightdamage(obj, TRUE, 2 * damg);
if (!flashburn((long) (damg + rnd(damg))) && !vulnerable)
pline("%s", nothing_seems_to_happen);
}
} else {
/* no direction picked */
pline("%s", Never_mind);
obj->age = gm.moves;
}
break;
default:
impossible("Unknown invoke power %d.", oart->inv_prop);
break; break;
} }
} else { } else {

View File

@@ -2958,9 +2958,9 @@ lightdamage(
of death will always be "killed while stuck in creature form"] */ of death will always be "killed while stuck in creature form"] */
if (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS) if (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS)
ordinary = FALSE; /* say blasted rather than zapped */ ordinary = FALSE; /* say blasted rather than zapped */
how = (obj->oclass != SPBOOK_CLASS) how = (obj->oclass == SPBOOK_CLASS) ? "spell of light"
? (const char *) ansimpleoname(obj) : (!obj->oartifact) ? ansimpleoname(obj)
: "spell of light"; : bare_artifactname(obj);
Sprintf(buf, "%s %sself with %s", ordinary ? "zapped" : "blasted", Sprintf(buf, "%s %sself with %s", ordinary ? "zapped" : "blasted",
uhim(), how); uhim(), how);
/* might rehumanize(); could be fatal, but only for Unchanging */ /* might rehumanize(); could be fatal, but only for Unchanging */