followup to fix for M63 - magic lamp wishes

This uses Michael's suggestion for keeping the display up to date when
removing a djinni or water demon in advance of granting a wish (so that it
won't be present in a bones file if the wish is fatal--problem with earlier
fix was that player could notice monster was already gone while responding
to the wish prompt).  It's not quite as straightforward as I was hoping for
and would get a lot messier if it needed to cope with Warning & Warn_of_mon.
This commit is contained in:
nethack.rankin
2005-04-28 04:45:20 +00:00
parent a7da903561
commit 632afa4979
4 changed files with 34 additions and 8 deletions

View File

@@ -119,6 +119,7 @@ reanimating a statue containing gold produced double gold
probing the resulting double-gold monster caused "static object freed" panic
cursed wand might explode if used to engrave
fatal wish from magic lamp left functional magic lamp in bones data
fatal wish granted by monster left that monster in bones data
Platform- and/or Interface-Specific Fixes

View File

@@ -1625,6 +1625,7 @@ E void FDECL(potionhit, (struct monst *,struct obj *,BOOLEAN_P));
E void FDECL(potionbreathe, (struct obj *));
E boolean FDECL(get_wet, (struct obj *));
E int NDECL(dodip);
E void FDECL(mongrantswish, (struct monst **));
E void FDECL(djinni_from_bottle, (struct obj *));
E struct monst *FDECL(split_mon, (struct monst *,struct monst *));
E const char *NDECL(bottlename);

View File

@@ -56,10 +56,8 @@ dowaterdemon() /* Water demon */
if (rnd(100) > (80 + level_difficulty())) {
pline("Grateful for %s release, %s grants you a wish!",
mhis(mtmp), mhe(mtmp));
/* bones prep: remove demon first in case the wish
turns out to be fatal (artifact blast) */
mongone(mtmp);
makewish();
/* give a wish and discard the monster (mtmp set to null) */
mongrantswish(&mtmp);
} else if (t_at(mtmp->mx, mtmp->my))
(void) mintrap(mtmp);
}

View File

@@ -2042,6 +2042,34 @@ dodip()
return(1);
}
/* *monp grants a wish and then leaves the game */
void
mongrantswish(monp)
struct monst **monp;
{
/* note: `mon' is still valid after mongone() (til next dmonsfree())
but it's no longer on the map--affects coordinates and visibility */
struct monst *mon = *monp;
int mx = mon->mx, my = mon->my;
boolean monspotted = canspotmon(mon),
/* no need to handle Warning since monster is peaceful */
disp_hackery = monspotted || Detect_monsters;
/* remove the monster first in case wish proves to be fatal
(blasted by artifact), to keep it out of resulting bones file */
mongone(mon);
*monp = 0; /* inform caller than monster is gone */
/* hide that removal from the player--map is visible during wish prompt */
if (disp_hackery) {
tmp_at(DISP_ALWAYS,
monspotted ? mon_to_glyph(mon) : detected_mon_to_glyph(mon));
tmp_at(mx, my);
}
/* grant the wish */
makewish();
/* clean up */
if (disp_hackery) tmp_at(DISP_END, 0);
}
void
djinni_from_bottle(obj)
@@ -2070,10 +2098,8 @@ register struct obj *obj;
switch (chance) {
case 0 : verbalize("I am in your debt. I will grant one wish!");
/* bones prep: remove djinni first in case the wish
turns out to be fatal (artifact blast) */
mongone(mtmp);
makewish();
/* give a wish and discard the monster (mtmp set to null) */
mongrantswish(&mtmp);
break;
case 1 : verbalize("Thank you for freeing me!");
(void) tamedog(mtmp, (struct obj *)0);