... 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)
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
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 ### */
(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;
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;
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);
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: {
}
/* 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) {
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;
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);
}
(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.");
(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))
(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)
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.");
destroy_item(SCROLL_CLASS, AD_FIRE);
destroy_item(SPBOOK_CLASS, AD_FIRE);
destroy_item(POTION_CLASS, AD_FIRE);
+ ignite_items(g.invent);
return FALSE;
}
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*/
}
/* 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) {
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:
(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;
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;
}
}
}
+ /* This also ignites floor items, but does not change cnt
+ because they weren't consumed. */
+ ignite_items(g.level.objects[x][y]);
return cnt;
}