From 2bec685bae641cc25aab40ff80154044c6aadf07 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 2 Jun 2024 10:50:58 +0300 Subject: [PATCH] Pyrolisk eggs explode when broken --- doc/fixes3-7-0.txt | 1 + src/dog.c | 2 ++ src/dothrow.c | 5 +++++ src/eat.c | 18 +++++++++++++++--- src/mon.c | 5 +++++ src/uhitm.c | 6 ++++++ 6 files changed, 34 insertions(+), 3 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index c4358c629..684b92b46 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -2587,6 +2587,7 @@ if hero is punished or tethered to a buried iron ball and has no inventory (or in the status display so that it will be visible for screenshots or during streaming video 'query_menu' option to use a menu when asked certain yes/no questions +pyrolisk eggs explode when broken Platform- and/or Interface-Specific New Features diff --git a/src/dog.c b/src/dog.c index a856c4a05..d1f0ae6ae 100644 --- a/src/dog.c +++ b/src/dog.c @@ -991,6 +991,8 @@ dogfood(struct monst *mon, struct obj *obj) case ENORMOUS_MEATBALL: return carni ? DOGFOOD : MANFOOD; case EGG: + if (obj->corpsenm == PM_PYROLISK && !likes_fire(mptr)) + return POISON; return carni ? CADAVER : MANFOOD; case CORPSE: if ((peek_at_iced_corpse_age(obj) + 50L <= gm.moves diff --git a/src/dothrow.c b/src/dothrow.c index da634c810..34b4c4c2c 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -2438,6 +2438,7 @@ breakobj( boolean from_invent) { boolean fracture = FALSE; + boolean explosion = FALSE; if (is_crackable(obj)) /* if erodeproof, erode_obj() will say so */ return (erode_obj(obj, armor_simple_name(obj), ERODE_CRACK, @@ -2479,6 +2480,8 @@ breakobj( /* breaking your own eggs is bad luck */ if (hero_caused && obj->spe && ismnum(obj->corpsenm)) change_luck((schar) -min(obj->quan, 5L)); + if (obj->corpsenm == PM_PYROLISK) + explosion = TRUE; break; case BOULDER: case STATUE: @@ -2519,6 +2522,8 @@ breakobj( } if (!fracture) delobj(obj); + if (explosion) + explode(x, y, -11, d(3, 6), 0, EXPL_FIERY); return 1; } diff --git a/src/eat.c b/src/eat.c index f6c6d0eca..67a8ae698 100644 --- a/src/eat.c +++ b/src/eat.c @@ -28,7 +28,7 @@ staticfn void start_tin(struct obj *); staticfn int eatcorpse(struct obj *); staticfn void start_eating(struct obj *, boolean); staticfn void garlic_breath(struct monst *); -staticfn void fprefx(struct obj *); +staticfn boolean fprefx(struct obj *); staticfn void fpostfx(struct obj *); staticfn int bite(void); staticfn int edibility_prompts(struct obj *); @@ -2020,11 +2020,19 @@ garlic_breath(struct monst *mtmp) * marked it 'partly eaten'. Used for non-rotten non-tin non-corpse food. * Messages should use present tense since multi-turn food won't be * finishing at the time they're issued. + * Returns FALSE if eating should not succeed for whatever reason. */ -staticfn void +staticfn boolean fprefx(struct obj *otmp) { switch (otmp->otyp) { + case EGG: + if (otmp->corpsenm == PM_PYROLISK) { + useup(otmp); + explode(u.ux, u.uy, -11, d(3, 6), 0, EXPL_FIERY); + return FALSE; + } + break; case FOOD_RATION: /* nutrition 800 */ /* 200+800 remains below 1000+1, the satiation threshold */ if (u.uhunger <= 200) @@ -2127,6 +2135,7 @@ fprefx(struct obj *otmp) } break; /* default */ } /* switch */ + return TRUE; } /* increment a combat intrinsic with limits on its growth */ @@ -2946,7 +2955,10 @@ doeat(void) } consume_oeaten(otmp, 1); /* oeaten >>= 1 */ } else if (!already_partly_eaten) { - fprefx(otmp); + if (!fprefx(otmp)) { + do_reset_eat(); + return ECMD_TIME; + } } else { You("%s %s.", (gc.context.victual.reqtime == 1) ? "eat" : "begin eating", diff --git a/src/mon.c b/src/mon.c index 5d3e37824..ad222c5a0 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1402,6 +1402,8 @@ m_consume_obj(struct monst *mtmp, struct obj *otmp) mcureblindness(mtmp, canseemon(mtmp)); if (ispet && deadmimic) quickmimic(mtmp); + if (otmp->otyp == EGG && corpsenm == PM_PYROLISK) + explode(mtmp->mx, mtmp->my, -11, d(3, 6), 0, EXPL_FIERY); if (corpsenm != NON_PM) mon_givit(mtmp, &mons[corpsenm]); } @@ -1729,6 +1731,9 @@ mon_givit(struct monst *mtmp, struct permonst *ptr) int prop = corpse_intrinsic(ptr); boolean vis = canseemon(mtmp); + if (DEADMONSTER(mtmp)) + return; + if (ptr == &mons[PM_STALKER]) { /* * Invisible stalker isn't flagged as conferring invisibility diff --git a/src/uhitm.c b/src/uhitm.c index 7f33c8777..39adc1649 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1212,6 +1212,12 @@ hmon_hitmon_misc_obj( obj->owt = weight(obj); if (hmd->thrown) place_object(obj, mon->mx, mon->my); + } else if (obj->corpsenm == PM_PYROLISK) { + useup_eggs(obj); + explode(mon->mx, mon->my, -11, d(3, 6), 0, EXPL_FIERY); + hmd->doreturn = TRUE; + hmd->retval = !DEADMONSTER(mon); + return; } else { pline("Splat!"); useup_eggs(obj);