]> granicus.if.org Git - nethack/commitdiff
Fire sources can ignite candles, lamps, and potions of oil
authorPasi Kallinen <paxed@alt.org>
Wed, 30 Sep 2020 16:43:12 +0000 (19:43 +0300)
committerPasi Kallinen <paxed@alt.org>
Wed, 30 Sep 2020 16:49:10 +0000 (19:49 +0300)
... on the floor, in monster inventory, and in hero's inventory.

Items in your inventory being ignited produce a message even if you're
blind - you can see the lit-state by viewing inventory anyway, so just
give player the message.

(via xNetHack)

12 files changed:
doc/fixes37.0
include/extern.h
src/artifact.c
src/explode.c
src/mcastu.c
src/mhitm.c
src/mhitu.c
src/muse.c
src/polyself.c
src/trap.c
src/uhitm.c
src/zap.c

index 8897d086fa528772dda3d51d31144b57fd631897..9355123bd7969fa29fa920ef4a1c85201e285ac5 100644 (file)
@@ -263,6 +263,7 @@ when make was invoked with -j makedefs instances could end up running in
        provide a work-alike mkstemp() implementation for windows visual studio
        in mdlib.c so there is no requirement to define HAS_NO_MKSTEMP there
 make piranhas faster and give them extra bite attack
+fire sources can ignite candles, lamps, and potions of oil
 
 
 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
index 374598ae481b1f608ef8f821088658ee03e401be..7e4af0781d528f99f4124c5a33b0416b4da0b227 100644 (file)
@@ -2715,6 +2715,7 @@ E boolean NDECL(lava_effects);
 E void NDECL(sink_into_lava);
 E void NDECL(sokoban_guilt);
 E const char * FDECL(trapname, (int, BOOLEAN_P));
+E void FDECL(ignite_items, (struct obj *));
 
 /* ### u_init.c ### */
 
index 990be7b43730789e4010c2229dbd9e4402af2640..c71c0e87c11f59127ea1325747dcd477d7e35506 100644 (file)
@@ -1192,6 +1192,8 @@ int dieroll; /* needed for Magicbane and vorpal blades */
             (void) destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
         if (!rn2(7))
             (void) destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
+        if (!rn2(4))
+            ignite_items(mdef->minvent);
         if (youdefend && Slimed)
             burn_away_slime();
         return realizes_damage;
index 469eaeff2f51434a3dfeb79ae8ca91c2a200b0ee..8abe642fd4c95711f47b84dc04971bc55286540c 100644 (file)
@@ -412,6 +412,9 @@ int expltype;
                 idamnonres += destroy_mitem(mtmp, WAND_CLASS, (int) adtyp);
                 idamnonres += destroy_mitem(mtmp, RING_CLASS, (int) adtyp);
 
+                if (adtyp == AD_FIRE)
+                    ignite_items(mtmp->minvent);
+
                 if (explmask[i][j] == 1) {
                     golemeffects(mtmp, (int) adtyp, dam + idamres);
                     mtmp->mhp -= idamnonres;
@@ -500,8 +503,10 @@ int expltype;
             You("are unharmed!");
         } else if (adtyp == AD_PHYS || physical_dmg)
             damu = Maybe_Half_Phys(damu);
-        if (adtyp == AD_FIRE)
+        if (adtyp == AD_FIRE) {
             (void) burnarmor(&g.youmonst);
+            ignite_items(g.invent);
+        }
         destroy_item(SCROLL_CLASS, (int) adtyp);
         destroy_item(SPBOOK_CLASS, (int) adtyp);
         destroy_item(POTION_CLASS, (int) adtyp);
index e53195f720c644c4eb1870070a756f4160eb360d..f6b23986e31630cc01c977004d278afb854ae62a 100644 (file)
@@ -553,6 +553,7 @@ int spellnum;
         destroy_item(SCROLL_CLASS, AD_FIRE);
         destroy_item(POTION_CLASS, AD_FIRE);
         destroy_item(SPBOOK_CLASS, AD_FIRE);
+        ignite_items(g.invent);
         (void) burn_floor_objects(u.ux, u.uy, TRUE, FALSE);
         break;
     case CLC_LIGHTNING: {
index e848c1d9947f9b1e67a3550e740e0e09ec3a4e23..e08ce35ba7736996af9f53ccb2dcf9c13dbbf4e3 100644 (file)
@@ -1042,6 +1042,7 @@ int dieroll;
         }
         /* only potions damage resistant players in destroy_item */
         tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
+        ignite_items(mdef->minvent);
         break;
     case AD_COLD:
         if (cancelled) {
index ddfc45453a0fbbded4f5beca7420cd79737a5470..f28f0c6b730962e71fc4bf786f0409d674b3f0d8 100644 (file)
@@ -1115,6 +1115,8 @@ register struct attack *mattk;
                 destroy_item(POTION_CLASS, AD_FIRE);
             if ((int) mtmp->m_lev > rn2(25))
                 destroy_item(SPBOOK_CLASS, AD_FIRE);
+            if ((int) mtmp->m_lev > rn2(20))
+                ignite_items(g.invent);
             burn_away_slime();
         } else
             dmg = 0;
@@ -2362,6 +2364,8 @@ struct attack *mattk;
                     destroy_item(POTION_CLASS, AD_FIRE);
                 if (lev > rn2(25))
                     destroy_item(SPBOOK_CLASS, AD_FIRE);
+                if (lev > rn2(20))
+                    ignite_items(g.invent);
                 if (dmg)
                     mdamageu(mtmp, dmg);
             }
index 424a444c5a555d22f3a260f804e2a4feaa3d7224..f14f979ffc1e1c8e85e37c2b589b6dcfc2e13ee4 100644 (file)
@@ -1594,6 +1594,7 @@ struct monst *mtmp;
             (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
             (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
             (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
+            ignite_items(mtmp->minvent);
             num = (2 * (rn1(3, 3) + 2 * bcsign(otmp)) + 1) / 3;
             if (Fire_resistance)
                 You("are not harmed.");
index fbfe59fd1ea87a7923b8cd251690a06f23c14318..5beef979f6d30e4d26c21429f6eb260bfd21c88a 100644 (file)
@@ -1447,6 +1447,8 @@ dogaze()
                         (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
                     if (lev > rn2(25))
                         (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
+                    if (lev > rn2(20))
+                        ignite_items(mtmp->minvent);
                     if (dmg)
                         mtmp->mhp -= dmg;
                     if (DEADMONSTER(mtmp))
index c2e30afd532d6af86412d406074b817d36a8ad45..7aa3f3e71ed3b6750c0fb3941258f460281e5937 100644 (file)
@@ -2434,6 +2434,7 @@ register struct monst *mtmp;
                 (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
                 (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
                 (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
+                ignite_items(mtmp->minvent);
             }
             if (burn_floor_objects(mtmp->mx, mtmp->my, see_it, FALSE)
                 && !see_it && distu(mtmp->mx, mtmp->my) <= 3 * 3)
@@ -3196,6 +3197,7 @@ struct obj *box; /* null for floor trap */
         destroy_item(SCROLL_CLASS, AD_FIRE);
         destroy_item(SPBOOK_CLASS, AD_FIRE);
         destroy_item(POTION_CLASS, AD_FIRE);
+        ignite_items(g.invent);
     }
     if (!box && burn_floor_objects(u.ux, u.uy, see_it, TRUE) && !see_it)
         You("smell paper burning.");
@@ -5400,6 +5402,7 @@ lava_effects()
     destroy_item(SCROLL_CLASS, AD_FIRE);
     destroy_item(SPBOOK_CLASS, AD_FIRE);
     destroy_item(POTION_CLASS, AD_FIRE);
+    ignite_items(g.invent);
     return FALSE;
 }
 
@@ -5560,4 +5563,45 @@ boolean override;
     return defsyms[trap_to_defsym(ttyp)].explanation;
 }
 
+/* Ignite ignitable items in the given object chain, due to some external source
+ * of fire. The object chain should be somewhere exposed, like someone's open
+ * inventory or the floor.
+ * This is modeled after destroy_item() somewhat and hopefully will be able to
+ * merge into it in the future.
+ */
+void
+ignite_items(objchn)
+struct obj *objchn;
+{
+    struct obj *obj;
+    boolean vis = FALSE;
+    if (!objchn)
+        return;
+
+    if (objchn->where == OBJ_INVENT)
+        vis = TRUE; /* even when blind; lit-state can be seen in inventory */
+    else if (objchn->where == OBJ_MINVENT)
+        vis = canseemon(objchn->ocarry);
+    else if (objchn->where == OBJ_FLOOR)
+        vis = cansee(objchn->ox, objchn->oy);
+    else {
+        impossible("igniting item in a weird location %d", objchn->where);
+        return;
+    }
+
+    for (obj = objchn; obj; obj = obj->nobj) {
+        if (!(ignitable(obj) || obj->otyp == MAGIC_LAMP)
+            /* The Candelabrum requires intention to be lit */
+            || obj->otyp == CANDELABRUM_OF_INVOCATION
+            || obj->otyp == BRASS_LANTERN /* doesn't ignite via fire */
+            || obj->in_use     /* not available */
+            || obj->lamplit) { /* already burning */
+            continue;
+        }
+        begin_burn(obj, FALSE);
+        if (vis)
+            pline("%s on fire!", Yobjnam2(obj, "catch"));
+    }
+}
+
 /*trap.c*/
index 4a0b6f7e7b90a21c373717f5126c80f970af2144..53a82d7d3dbc1e0140ba407c8bf6c17dc5b716d9 100644 (file)
@@ -1790,6 +1790,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */
         }
         /* only potions damage resistant players in destroy_item */
         tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
+        ignite_items(mdef->minvent);
         break;
     case AD_COLD:
         if (negated) {
index 049090edce1aba246a9357f3bb44c0209bde8680..3910b909a97a9225ca591bd1a5f8346e2f8f9f62 100644 (file)
--- a/src/zap.c
+++ b/src/zap.c
@@ -2428,6 +2428,7 @@ boolean ordinary;
         destroy_item(POTION_CLASS, AD_FIRE);
         destroy_item(SPBOOK_CLASS, AD_FIRE);
         destroy_item(FOOD_CLASS, AD_FIRE); /* only slime for now */
+        ignite_items(g.invent);
         break;
 
     case WAN_COLD:
@@ -3717,6 +3718,8 @@ struct obj **ootmp; /* to return worn armor for caller to disintegrate */
                 (void) destroy_mitem(mon, SCROLL_CLASS, AD_FIRE);
             if (!rn2(5))
                 (void) destroy_mitem(mon, SPBOOK_CLASS, AD_FIRE);
+            if (!rn2(3))
+                ignite_items(mon->minvent);
             destroy_mitem(mon, FOOD_CLASS, AD_FIRE); /* carried slime */
         }
         break;
@@ -3874,6 +3877,8 @@ xchar sx, sy;
                 destroy_item(SCROLL_CLASS, AD_FIRE);
             if (!rn2(5))
                 destroy_item(SPBOOK_CLASS, AD_FIRE);
+            if (!rn2(3))
+                ignite_items(g.invent);
             destroy_item(FOOD_CLASS, AD_FIRE);
         }
         break;
@@ -4035,6 +4040,9 @@ boolean u_caused;
             }
         }
     }
+    /* This also ignites floor items, but does not change cnt
+       because they weren't consumed. */
+    ignite_items(g.level.objects[x][y]);
     return cnt;
 }