Split arti_invoke code into smaller functions
This commit is contained in:
633
src/artifact.c
633
src/artifact.c
@@ -27,6 +27,17 @@ staticfn int spec_applies(const struct artifact *, struct monst *)
|
||||
NONNULLARG12;
|
||||
staticfn int invoke_ok(struct obj *);
|
||||
staticfn void nothing_special(struct obj *) NONNULLARG1;
|
||||
staticfn int invoke_taming(struct obj *) NONNULLARG1;
|
||||
staticfn int invoke_healing(struct obj *) NONNULLARG1;
|
||||
staticfn int invoke_energy_boost(struct obj *) NONNULLARG1;
|
||||
staticfn int invoke_untrap(struct obj *) NONNULLARG1;
|
||||
staticfn int invoke_charge_obj(struct obj *) NONNULLARG1;
|
||||
staticfn int invoke_create_portal(struct obj *) NONNULLARG1;
|
||||
staticfn int invoke_create_ammo(struct obj *) NONNULLARG1;
|
||||
staticfn int invoke_banish(struct obj *) NONNULLARG1;
|
||||
staticfn int invoke_fling_poison(struct obj *) NONNULLARG1;
|
||||
staticfn int invoke_storm_spell(struct obj *) NONNULLARG1;
|
||||
staticfn int invoke_blinding_ray(struct obj *) NONNULLARG1;
|
||||
staticfn int arti_invoke(struct obj *);
|
||||
staticfn boolean Mb_hit(struct monst * magr, struct monst *mdef,
|
||||
struct obj *, int *, int, boolean, char *);
|
||||
@@ -1750,10 +1761,331 @@ nothing_special(struct obj *obj)
|
||||
You_feel("a surge of power, but nothing seems to happen.");
|
||||
}
|
||||
|
||||
staticfn int
|
||||
invoke_taming(struct obj *obj UNUSED)
|
||||
{
|
||||
struct obj pseudo;
|
||||
|
||||
pseudo = cg.zeroobj; /* neither cursed nor blessed, zero oextra too */
|
||||
pseudo.otyp = SCR_TAMING;
|
||||
(void) seffects(&pseudo);
|
||||
return ECMD_TIME;
|
||||
}
|
||||
|
||||
staticfn int
|
||||
invoke_healing(struct obj *obj)
|
||||
{
|
||||
int healamt = (u.uhpmax + 1 - u.uhp) / 2;
|
||||
long creamed = (long) u.ucreamed;
|
||||
|
||||
if (Upolyd)
|
||||
healamt = (u.mhmax + 1 - u.mh) / 2;
|
||||
if (healamt || Sick || Slimed || Blinded > creamed)
|
||||
You_feel("better.");
|
||||
if (healamt || Sick || Slimed || BlindedTimeout > creamed)
|
||||
You_feel("%sbetter.",
|
||||
(!healamt && !Sick && !Slimed
|
||||
/* when healing temporary blindness (aside from
|
||||
goop covering face), might still be blind
|
||||
due to PermaBlind or eyeless polymorph;
|
||||
vary the message in that situation */
|
||||
&& (HBlinded & ~TIMEOUT) != 0L) ? "slightly " : "");
|
||||
else {
|
||||
nothing_special(obj);
|
||||
return ECMD_TIME;
|
||||
}
|
||||
if (healamt > 0) {
|
||||
if (Upolyd)
|
||||
u.mh += healamt;
|
||||
else
|
||||
u.uhp += healamt;
|
||||
}
|
||||
if (Sick)
|
||||
make_sick(0L, (char *) 0, FALSE, SICK_ALL);
|
||||
if (Slimed)
|
||||
make_slimed(0L, (char *) 0);
|
||||
if (BlindedTimeout > creamed)
|
||||
make_blinded(creamed, FALSE);
|
||||
disp.botl = TRUE;
|
||||
return ECMD_TIME;
|
||||
}
|
||||
|
||||
staticfn int
|
||||
invoke_energy_boost(struct obj *obj)
|
||||
{
|
||||
int epboost = (u.uenmax + 1 - u.uen) / 2;
|
||||
|
||||
if (epboost > 120)
|
||||
epboost = 120; /* arbitrary */
|
||||
else if (epboost < 12)
|
||||
epboost = u.uenmax - u.uen;
|
||||
if (epboost) {
|
||||
u.uen += epboost;
|
||||
disp.botl = TRUE;
|
||||
You_feel("re-energized.");
|
||||
} else {
|
||||
nothing_special(obj);
|
||||
return ECMD_TIME;
|
||||
}
|
||||
return ECMD_TIME;
|
||||
}
|
||||
|
||||
staticfn int
|
||||
invoke_untrap(struct obj *obj)
|
||||
{
|
||||
if (!untrap(TRUE, 0, 0, (struct obj *) 0)) {
|
||||
obj->age = 0; /* don't charge for changing their mind */
|
||||
return ECMD_CANCEL;
|
||||
}
|
||||
return ECMD_TIME;
|
||||
}
|
||||
|
||||
staticfn int
|
||||
invoke_charge_obj(struct obj *obj)
|
||||
{
|
||||
const struct artifact *oart = get_artifact(obj);
|
||||
struct obj *otmp = getobj("charge", charge_ok,
|
||||
GETOBJ_PROMPT | GETOBJ_ALLOWCNT);
|
||||
boolean b_effect;
|
||||
|
||||
if (!otmp) {
|
||||
obj->age = 0;
|
||||
return ECMD_CANCEL;
|
||||
}
|
||||
b_effect = (obj->blessed && (oart->role == Role_switch
|
||||
|| oart->role == NON_PM));
|
||||
recharge(otmp, b_effect ? 1 : obj->cursed ? -1 : 0);
|
||||
update_inventory();
|
||||
return ECMD_TIME;
|
||||
}
|
||||
|
||||
staticfn int
|
||||
invoke_create_portal(struct obj *obj)
|
||||
{
|
||||
int i, num_ok_dungeons, last_ok_dungeon = 0;
|
||||
d_level newlev;
|
||||
winid tmpwin = create_nhwindow(NHW_MENU);
|
||||
anything any;
|
||||
int clr = NO_COLOR;
|
||||
|
||||
any = cg.zeroany; /* set all bits to zero */
|
||||
start_menu(tmpwin, MENU_BEHAVE_STANDARD);
|
||||
/* use index+1 (can't use 0) as identifier */
|
||||
for (i = num_ok_dungeons = 0; i < svn.n_dgns; i++) {
|
||||
if (!svd.dungeons[i].dunlev_ureached)
|
||||
continue;
|
||||
if (i == tutorial_dnum) /* can't portal into tutorial */
|
||||
continue;
|
||||
any.a_int = i + 1;
|
||||
add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0,
|
||||
ATR_NONE, clr,
|
||||
svd.dungeons[i].dname, MENU_ITEMFLAGS_NONE);
|
||||
num_ok_dungeons++;
|
||||
last_ok_dungeon = i;
|
||||
}
|
||||
end_menu(tmpwin, "Open a portal to which dungeon?");
|
||||
if (num_ok_dungeons > 1) {
|
||||
/* more than one entry; display menu for choices */
|
||||
menu_item *selected;
|
||||
int n;
|
||||
|
||||
n = select_menu(tmpwin, PICK_ONE, &selected);
|
||||
if (n <= 0) {
|
||||
destroy_nhwindow(tmpwin);
|
||||
nothing_special(obj);
|
||||
return ECMD_TIME;
|
||||
}
|
||||
i = selected[0].item.a_int - 1;
|
||||
free((genericptr_t) selected);
|
||||
} else
|
||||
i = last_ok_dungeon; /* also first & only OK dungeon */
|
||||
destroy_nhwindow(tmpwin);
|
||||
|
||||
/*
|
||||
* i is now index into dungeon structure for the new dungeon.
|
||||
* Find the closest level in the given dungeon, open
|
||||
* a use-once portal to that dungeon and go there.
|
||||
* The closest level is either the entry or dunlev_ureached.
|
||||
*/
|
||||
newlev.dnum = i;
|
||||
if (svd.dungeons[i].depth_start >= depth(&u.uz))
|
||||
newlev.dlevel = svd.dungeons[i].entry_lev;
|
||||
else
|
||||
newlev.dlevel = svd.dungeons[i].dunlev_ureached;
|
||||
|
||||
if (u.uhave.amulet || In_endgame(&u.uz) || In_endgame(&newlev)
|
||||
|| newlev.dnum == u.uz.dnum || !next_to_u()) {
|
||||
You_feel("very disoriented for a moment.");
|
||||
} else {
|
||||
if (!Blind)
|
||||
You("are surrounded by a shimmering sphere!");
|
||||
else
|
||||
You_feel("weightless for a moment.");
|
||||
goto_level(&newlev, FALSE, FALSE, FALSE);
|
||||
}
|
||||
return ECMD_TIME;
|
||||
}
|
||||
|
||||
staticfn int
|
||||
invoke_create_ammo(struct obj *obj)
|
||||
{
|
||||
struct obj *otmp = mksobj(ARROW, TRUE, FALSE);
|
||||
|
||||
if (!otmp) {
|
||||
nothing_special(obj);
|
||||
return ECMD_TIME;
|
||||
}
|
||||
otmp->blessed = obj->blessed;
|
||||
otmp->cursed = obj->cursed;
|
||||
otmp->bknown = obj->bknown;
|
||||
otmp->oeroded = otmp->oeroded2 = 0;
|
||||
if (obj->blessed) {
|
||||
if (otmp->spe < 0)
|
||||
otmp->spe = 0;
|
||||
otmp->quan += rnd(10);
|
||||
} else if (obj->cursed) {
|
||||
if (otmp->spe > 0)
|
||||
otmp->spe = 0;
|
||||
} else
|
||||
otmp->quan += rnd(5);
|
||||
otmp->owt = weight(otmp);
|
||||
otmp = hold_another_object(otmp, "Suddenly %s out.",
|
||||
aobjnam(otmp, "fall"), (char *) 0);
|
||||
nhUse(otmp);
|
||||
return ECMD_TIME;
|
||||
}
|
||||
|
||||
staticfn int
|
||||
invoke_banish(struct obj *obj UNUSED)
|
||||
{
|
||||
int nvanished = 0, nstayed = 0;
|
||||
struct monst *mtmp, *mtmp2;
|
||||
d_level dest;
|
||||
|
||||
find_hell(&dest);
|
||||
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp2) {
|
||||
int chance = 1;
|
||||
|
||||
mtmp2 = mtmp->nmon;
|
||||
if (DEADMONSTER(mtmp) || !isok(mtmp->mx, mtmp->my))
|
||||
continue;
|
||||
if (!is_demon(mtmp->data) && mtmp->data->mlet != S_IMP)
|
||||
continue;
|
||||
if (!couldsee(mtmp->mx, mtmp->my))
|
||||
continue;
|
||||
if (mtmp->data->msound == MS_NEMESIS)
|
||||
continue;
|
||||
|
||||
if (In_quest(&u.uz) && !svq.quest_status.killed_nemesis)
|
||||
chance += 10;
|
||||
if (is_dprince(mtmp->data))
|
||||
chance += 2;
|
||||
if (is_dlord(mtmp->data))
|
||||
chance++;
|
||||
|
||||
mtmp->msleeping = mtmp->mtame = mtmp->mpeaceful = 0;
|
||||
if (chance <= 1 || !rn2(chance)) {
|
||||
if (!Inhell) {
|
||||
nvanished++;
|
||||
/* banish to a random level in Gehennom */
|
||||
dest.dlevel = rn2(dunlevs_in_dungeon(&dest));
|
||||
migrate_mon(mtmp, ledger_no(&dest), MIGR_RANDOM);
|
||||
} else {
|
||||
u_teleport_mon(mtmp, FALSE);
|
||||
}
|
||||
} else {
|
||||
nstayed++;
|
||||
}
|
||||
}
|
||||
|
||||
if (nvanished) {
|
||||
char subject[] = "demons";
|
||||
|
||||
if (nvanished == 1)
|
||||
*(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"));
|
||||
}
|
||||
return ECMD_TIME;
|
||||
}
|
||||
|
||||
staticfn int
|
||||
invoke_fling_poison(struct obj *obj)
|
||||
{
|
||||
if (getdir((char *) 0)) {
|
||||
int venom = rn2(2) ? BLINDING_VENOM : ACID_VENOM;
|
||||
struct obj *otmp = mksobj(venom, TRUE, FALSE);
|
||||
|
||||
otmp->spe = 1; /* the poison is yours */
|
||||
throwit(otmp, 0L, FALSE, (struct obj *) 0);
|
||||
} else {
|
||||
/* no direction picked */
|
||||
pline("%s", Never_mind);
|
||||
obj->age = svm.moves;
|
||||
return ECMD_CANCEL;
|
||||
}
|
||||
return ECMD_TIME;
|
||||
}
|
||||
|
||||
staticfn int
|
||||
invoke_storm_spell(struct obj *obj)
|
||||
{
|
||||
const struct artifact *oart = get_artifact(obj);
|
||||
int storm = oart->inv_prop == SNOWSTORM ? SPE_CONE_OF_COLD : SPE_FIREBALL;
|
||||
int skill = spell_skilltype(storm);
|
||||
int expertise = P_SKILL(skill);
|
||||
|
||||
P_SKILL(skill) = P_EXPERT;
|
||||
(void) spelleffects(storm, FALSE, TRUE);
|
||||
P_SKILL(skill) = expertise;
|
||||
return ECMD_TIME;
|
||||
}
|
||||
|
||||
staticfn int
|
||||
invoke_blinding_ray(struct obj *obj)
|
||||
{
|
||||
if (getdir((char *) 0)) {
|
||||
if (u.dx || u.dy) {
|
||||
do_blinding_ray(obj);
|
||||
} else if (u.dz) {
|
||||
/* up or down => light this map spot; litroom() uses
|
||||
radius 0 for Sunsword, except on Rogue level where
|
||||
whole room gets lit and corridor spots remain unlit */
|
||||
litroom(TRUE, obj);
|
||||
pline("%s", ((!Blind && levl[u.ux][u.uy].lit
|
||||
&& !levl[u.ux][u.uy].waslit)
|
||||
? "It is lit here now."
|
||||
: nothing_seems_to_happen));
|
||||
} 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)), FALSE)
|
||||
&& !vulnerable)
|
||||
pline("%s", nothing_seems_to_happen);
|
||||
}
|
||||
} else {
|
||||
/* no direction picked */
|
||||
pline("%s", Never_mind);
|
||||
obj->age = svm.moves;
|
||||
return ECMD_CANCEL;
|
||||
}
|
||||
return ECMD_TIME;
|
||||
}
|
||||
|
||||
staticfn int
|
||||
arti_invoke(struct obj *obj)
|
||||
{
|
||||
const struct artifact *oart;
|
||||
int res = ECMD_OK;
|
||||
|
||||
if (!obj) {
|
||||
impossible("arti_invoke without obj");
|
||||
@@ -1781,300 +2113,29 @@ arti_invoke(struct obj *obj)
|
||||
obj->age = svm.moves + rnz(100);
|
||||
|
||||
switch (oart->inv_prop) {
|
||||
case TAMING: {
|
||||
struct obj pseudo;
|
||||
|
||||
pseudo =
|
||||
cg.zeroobj; /* neither cursed nor blessed, zero oextra too */
|
||||
pseudo.otyp = SCR_TAMING;
|
||||
(void) seffects(&pseudo);
|
||||
break;
|
||||
}
|
||||
case HEALING: {
|
||||
int healamt = (u.uhpmax + 1 - u.uhp) / 2;
|
||||
long creamed = (long) u.ucreamed;
|
||||
|
||||
if (Upolyd)
|
||||
healamt = (u.mhmax + 1 - u.mh) / 2;
|
||||
if (healamt || Sick || Slimed || Blinded > creamed)
|
||||
You_feel("better.");
|
||||
if (healamt || Sick || Slimed || BlindedTimeout > creamed)
|
||||
You_feel("%sbetter.",
|
||||
(!healamt && !Sick && !Slimed
|
||||
/* when healing temporary blindness (aside from
|
||||
goop covering face), might still be blind
|
||||
due to PermaBlind or eyeless polymorph;
|
||||
vary the message in that situation */
|
||||
&& (HBlinded & ~TIMEOUT) != 0L) ? "slightly " : "");
|
||||
else {
|
||||
nothing_special(obj);
|
||||
return ECMD_TIME;
|
||||
}
|
||||
if (healamt > 0) {
|
||||
if (Upolyd)
|
||||
u.mh += healamt;
|
||||
else
|
||||
u.uhp += healamt;
|
||||
}
|
||||
if (Sick)
|
||||
make_sick(0L, (char *) 0, FALSE, SICK_ALL);
|
||||
if (Slimed)
|
||||
make_slimed(0L, (char *) 0);
|
||||
if (BlindedTimeout > creamed)
|
||||
make_blinded(creamed, FALSE);
|
||||
disp.botl = TRUE;
|
||||
break;
|
||||
}
|
||||
case ENERGY_BOOST: {
|
||||
int epboost = (u.uenmax + 1 - u.uen) / 2;
|
||||
|
||||
if (epboost > 120)
|
||||
epboost = 120; /* arbitrary */
|
||||
else if (epboost < 12)
|
||||
epboost = u.uenmax - u.uen;
|
||||
if (epboost) {
|
||||
u.uen += epboost;
|
||||
disp.botl = TRUE;
|
||||
You_feel("re-energized.");
|
||||
} else {
|
||||
nothing_special(obj);
|
||||
return ECMD_TIME;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UNTRAP: {
|
||||
if (!untrap(TRUE, 0, 0, (struct obj *) 0)) {
|
||||
obj->age = 0; /* don't charge for changing their mind */
|
||||
return ECMD_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CHARGE_OBJ: {
|
||||
struct obj *otmp = getobj("charge", charge_ok,
|
||||
GETOBJ_PROMPT | GETOBJ_ALLOWCNT);
|
||||
boolean b_effect;
|
||||
|
||||
if (!otmp) {
|
||||
obj->age = 0;
|
||||
return ECMD_CANCEL;
|
||||
}
|
||||
b_effect = (obj->blessed && (oart->role == Role_switch
|
||||
|| oart->role == NON_PM));
|
||||
recharge(otmp, b_effect ? 1 : obj->cursed ? -1 : 0);
|
||||
update_inventory();
|
||||
break;
|
||||
}
|
||||
case LEV_TELE:
|
||||
level_tele();
|
||||
break;
|
||||
case CREATE_PORTAL: {
|
||||
int i, num_ok_dungeons, last_ok_dungeon = 0;
|
||||
d_level newlev;
|
||||
winid tmpwin = create_nhwindow(NHW_MENU);
|
||||
anything any;
|
||||
int clr = NO_COLOR;
|
||||
|
||||
any = cg.zeroany; /* set all bits to zero */
|
||||
start_menu(tmpwin, MENU_BEHAVE_STANDARD);
|
||||
/* use index+1 (can't use 0) as identifier */
|
||||
for (i = num_ok_dungeons = 0; i < svn.n_dgns; i++) {
|
||||
if (!svd.dungeons[i].dunlev_ureached)
|
||||
continue;
|
||||
if (i == tutorial_dnum) /* can't portal into tutorial */
|
||||
continue;
|
||||
any.a_int = i + 1;
|
||||
add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0,
|
||||
ATR_NONE, clr,
|
||||
svd.dungeons[i].dname, MENU_ITEMFLAGS_NONE);
|
||||
num_ok_dungeons++;
|
||||
last_ok_dungeon = i;
|
||||
}
|
||||
end_menu(tmpwin, "Open a portal to which dungeon?");
|
||||
if (num_ok_dungeons > 1) {
|
||||
/* more than one entry; display menu for choices */
|
||||
menu_item *selected;
|
||||
int n;
|
||||
|
||||
n = select_menu(tmpwin, PICK_ONE, &selected);
|
||||
if (n <= 0) {
|
||||
destroy_nhwindow(tmpwin);
|
||||
nothing_special(obj);
|
||||
return ECMD_TIME;
|
||||
}
|
||||
i = selected[0].item.a_int - 1;
|
||||
free((genericptr_t) selected);
|
||||
} else
|
||||
i = last_ok_dungeon; /* also first & only OK dungeon */
|
||||
destroy_nhwindow(tmpwin);
|
||||
|
||||
/*
|
||||
* i is now index into dungeon structure for the new dungeon.
|
||||
* Find the closest level in the given dungeon, open
|
||||
* a use-once portal to that dungeon and go there.
|
||||
* The closest level is either the entry or dunlev_ureached.
|
||||
*/
|
||||
newlev.dnum = i;
|
||||
if (svd.dungeons[i].depth_start >= depth(&u.uz))
|
||||
newlev.dlevel = svd.dungeons[i].entry_lev;
|
||||
else
|
||||
newlev.dlevel = svd.dungeons[i].dunlev_ureached;
|
||||
|
||||
if (u.uhave.amulet || In_endgame(&u.uz) || In_endgame(&newlev)
|
||||
|| newlev.dnum == u.uz.dnum || !next_to_u()) {
|
||||
You_feel("very disoriented for a moment.");
|
||||
} else {
|
||||
if (!Blind)
|
||||
You("are surrounded by a shimmering sphere!");
|
||||
else
|
||||
You_feel("weightless for a moment.");
|
||||
goto_level(&newlev, FALSE, FALSE, FALSE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TAMING: res = invoke_taming(obj); break;
|
||||
case HEALING: res = invoke_healing(obj); break;
|
||||
case ENERGY_BOOST: res = invoke_energy_boost(obj); break;
|
||||
case UNTRAP: res = invoke_untrap(obj); break;
|
||||
case CHARGE_OBJ: res = invoke_charge_obj(obj); break;
|
||||
case LEV_TELE: level_tele(); res = ECMD_TIME; break;
|
||||
case CREATE_PORTAL: res = invoke_create_portal(obj); break;
|
||||
case ENLIGHTENING:
|
||||
enlightenment(MAGICENLIGHTENMENT, ENL_GAMEINPROGRESS);
|
||||
res = ECMD_TIME;
|
||||
break;
|
||||
case CREATE_AMMO: {
|
||||
struct obj *otmp = mksobj(ARROW, TRUE, FALSE);
|
||||
|
||||
if (!otmp) {
|
||||
nothing_special(obj);
|
||||
return ECMD_TIME;
|
||||
}
|
||||
otmp->blessed = obj->blessed;
|
||||
otmp->cursed = obj->cursed;
|
||||
otmp->bknown = obj->bknown;
|
||||
otmp->oeroded = otmp->oeroded2 = 0;
|
||||
if (obj->blessed) {
|
||||
if (otmp->spe < 0)
|
||||
otmp->spe = 0;
|
||||
otmp->quan += rnd(10);
|
||||
} else if (obj->cursed) {
|
||||
if (otmp->spe > 0)
|
||||
otmp->spe = 0;
|
||||
} else
|
||||
otmp->quan += rnd(5);
|
||||
otmp->owt = weight(otmp);
|
||||
otmp = hold_another_object(otmp, "Suddenly %s out.",
|
||||
aobjnam(otmp, "fall"), (char *) 0);
|
||||
nhUse(otmp);
|
||||
break;
|
||||
}
|
||||
case BANISH: {
|
||||
int nvanished = 0, nstayed = 0;
|
||||
struct monst *mtmp, *mtmp2;
|
||||
d_level dest;
|
||||
|
||||
find_hell(&dest);
|
||||
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp2) {
|
||||
int chance = 1;
|
||||
|
||||
mtmp2 = mtmp->nmon;
|
||||
if (DEADMONSTER(mtmp) || !isok(mtmp->mx, mtmp->my))
|
||||
continue;
|
||||
if (!is_demon(mtmp->data) && mtmp->data->mlet != S_IMP)
|
||||
continue;
|
||||
if (!couldsee(mtmp->mx, mtmp->my))
|
||||
continue;
|
||||
if (mtmp->data->msound == MS_NEMESIS)
|
||||
continue;
|
||||
|
||||
if (In_quest(&u.uz) && !svq.quest_status.killed_nemesis)
|
||||
chance += 10;
|
||||
if (is_dprince(mtmp->data))
|
||||
chance += 2;
|
||||
if (is_dlord(mtmp->data))
|
||||
chance++;
|
||||
|
||||
mtmp->msleeping = mtmp->mtame = mtmp->mpeaceful = 0;
|
||||
if (chance <= 1 || !rn2(chance)) {
|
||||
if (!Inhell) {
|
||||
nvanished++;
|
||||
/* banish to a random level in Gehennom */
|
||||
dest.dlevel = rn2(dunlevs_in_dungeon(&dest));
|
||||
migrate_mon(mtmp, ledger_no(&dest), MIGR_RANDOM);
|
||||
} else {
|
||||
u_teleport_mon(mtmp, FALSE);
|
||||
}
|
||||
} else {
|
||||
nstayed++;
|
||||
}
|
||||
}
|
||||
|
||||
if (nvanished) {
|
||||
char subject[] = "demons";
|
||||
|
||||
if (nvanished == 1)
|
||||
*(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;
|
||||
}
|
||||
case FLING_POISON:
|
||||
if (getdir((char *) 0)) {
|
||||
int venom = rn2(2) ? BLINDING_VENOM : ACID_VENOM;
|
||||
struct obj *otmp = mksobj(venom, TRUE, FALSE);
|
||||
|
||||
otmp->spe = 1; /* the poison is yours */
|
||||
throwit(otmp, 0L, FALSE, (struct obj *) 0);
|
||||
} else {
|
||||
/* no direction picked */
|
||||
pline("%s", Never_mind);
|
||||
obj->age = svm.moves;
|
||||
}
|
||||
break;
|
||||
case CREATE_AMMO: res = invoke_create_ammo(obj); break;
|
||||
case BANISH: res = invoke_banish(obj); break;
|
||||
case FLING_POISON: res = invoke_fling_poison(obj); break;
|
||||
case SNOWSTORM:
|
||||
case FIRESTORM:
|
||||
{
|
||||
int storm = oart->inv_prop == SNOWSTORM ? SPE_CONE_OF_COLD : SPE_FIREBALL;
|
||||
int skill = spell_skilltype(storm);
|
||||
int expertise = P_SKILL(skill);
|
||||
|
||||
P_SKILL(skill) = P_EXPERT;
|
||||
(void) spelleffects(storm, FALSE, TRUE);
|
||||
P_SKILL(skill) = expertise;
|
||||
}
|
||||
break;
|
||||
case BLINDING_RAY:
|
||||
if (getdir((char *) 0)) {
|
||||
if (u.dx || u.dy) {
|
||||
do_blinding_ray(obj);
|
||||
} else if (u.dz) {
|
||||
/* up or down => light this map spot; litroom() uses
|
||||
radius 0 for Sunsword, except on Rogue level where
|
||||
whole room gets lit and corridor spots remain unlit */
|
||||
litroom(TRUE, obj);
|
||||
pline("%s", ((!Blind && levl[u.ux][u.uy].lit
|
||||
&& !levl[u.ux][u.uy].waslit)
|
||||
? "It is lit here now."
|
||||
: nothing_seems_to_happen));
|
||||
} 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)), FALSE)
|
||||
&& !vulnerable)
|
||||
pline("%s", nothing_seems_to_happen);
|
||||
}
|
||||
} else {
|
||||
/* no direction picked */
|
||||
pline("%s", Never_mind);
|
||||
obj->age = svm.moves;
|
||||
}
|
||||
break;
|
||||
/*FALLTHRU*/
|
||||
case FIRESTORM: res = invoke_storm_spell(obj); break;
|
||||
case BLINDING_RAY: res = invoke_blinding_ray(obj); break;
|
||||
default:
|
||||
impossible("Unknown invoke power %d.", oart->inv_prop);
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
long eprop = (u.uprops[oart->inv_prop].extrinsic ^= W_ARTI),
|
||||
iprop = u.uprops[oart->inv_prop].intrinsic;
|
||||
|
||||
Reference in New Issue
Block a user