Fire sources can ignite candles, lamps, and potions of oil

... 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)
This commit is contained in:
Pasi Kallinen
2020-09-30 19:49:10 +03:00
parent fb7b578af1
commit 6a35a84c56
12 changed files with 72 additions and 1 deletions
+1
View 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 provide a work-alike mkstemp() implementation for windows visual studio
in mdlib.c so there is no requirement to define HAS_NO_MKSTEMP there in mdlib.c so there is no requirement to define HAS_NO_MKSTEMP there
make piranhas faster and give them extra bite attack 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 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
+1
View File
@@ -2715,6 +2715,7 @@ E boolean NDECL(lava_effects);
E void NDECL(sink_into_lava); E void NDECL(sink_into_lava);
E void NDECL(sokoban_guilt); E void NDECL(sokoban_guilt);
E const char * FDECL(trapname, (int, BOOLEAN_P)); E const char * FDECL(trapname, (int, BOOLEAN_P));
E void FDECL(ignite_items, (struct obj *));
/* ### u_init.c ### */ /* ### u_init.c ### */
+2
View File
@@ -1192,6 +1192,8 @@ int dieroll; /* needed for Magicbane and vorpal blades */
(void) destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); (void) destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
if (!rn2(7)) if (!rn2(7))
(void) destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); (void) destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
if (!rn2(4))
ignite_items(mdef->minvent);
if (youdefend && Slimed) if (youdefend && Slimed)
burn_away_slime(); burn_away_slime();
return realizes_damage; return realizes_damage;
+6 -1
View File
@@ -412,6 +412,9 @@ int expltype;
idamnonres += destroy_mitem(mtmp, WAND_CLASS, (int) adtyp); idamnonres += destroy_mitem(mtmp, WAND_CLASS, (int) adtyp);
idamnonres += destroy_mitem(mtmp, RING_CLASS, (int) adtyp); idamnonres += destroy_mitem(mtmp, RING_CLASS, (int) adtyp);
if (adtyp == AD_FIRE)
ignite_items(mtmp->minvent);
if (explmask[i][j] == 1) { if (explmask[i][j] == 1) {
golemeffects(mtmp, (int) adtyp, dam + idamres); golemeffects(mtmp, (int) adtyp, dam + idamres);
mtmp->mhp -= idamnonres; mtmp->mhp -= idamnonres;
@@ -500,8 +503,10 @@ int expltype;
You("are unharmed!"); You("are unharmed!");
} else if (adtyp == AD_PHYS || physical_dmg) } else if (adtyp == AD_PHYS || physical_dmg)
damu = Maybe_Half_Phys(damu); damu = Maybe_Half_Phys(damu);
if (adtyp == AD_FIRE) if (adtyp == AD_FIRE) {
(void) burnarmor(&g.youmonst); (void) burnarmor(&g.youmonst);
ignite_items(g.invent);
}
destroy_item(SCROLL_CLASS, (int) adtyp); destroy_item(SCROLL_CLASS, (int) adtyp);
destroy_item(SPBOOK_CLASS, (int) adtyp); destroy_item(SPBOOK_CLASS, (int) adtyp);
destroy_item(POTION_CLASS, (int) adtyp); destroy_item(POTION_CLASS, (int) adtyp);
+1
View File
@@ -553,6 +553,7 @@ int spellnum;
destroy_item(SCROLL_CLASS, AD_FIRE); destroy_item(SCROLL_CLASS, AD_FIRE);
destroy_item(POTION_CLASS, AD_FIRE); destroy_item(POTION_CLASS, AD_FIRE);
destroy_item(SPBOOK_CLASS, AD_FIRE); destroy_item(SPBOOK_CLASS, AD_FIRE);
ignite_items(g.invent);
(void) burn_floor_objects(u.ux, u.uy, TRUE, FALSE); (void) burn_floor_objects(u.ux, u.uy, TRUE, FALSE);
break; break;
case CLC_LIGHTNING: { case CLC_LIGHTNING: {
+1
View File
@@ -1042,6 +1042,7 @@ int dieroll;
} }
/* only potions damage resistant players in destroy_item */ /* only potions damage resistant players in destroy_item */
tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
ignite_items(mdef->minvent);
break; break;
case AD_COLD: case AD_COLD:
if (cancelled) { if (cancelled) {
+4
View File
@@ -1115,6 +1115,8 @@ register struct attack *mattk;
destroy_item(POTION_CLASS, AD_FIRE); destroy_item(POTION_CLASS, AD_FIRE);
if ((int) mtmp->m_lev > rn2(25)) if ((int) mtmp->m_lev > rn2(25))
destroy_item(SPBOOK_CLASS, AD_FIRE); destroy_item(SPBOOK_CLASS, AD_FIRE);
if ((int) mtmp->m_lev > rn2(20))
ignite_items(g.invent);
burn_away_slime(); burn_away_slime();
} else } else
dmg = 0; dmg = 0;
@@ -2362,6 +2364,8 @@ struct attack *mattk;
destroy_item(POTION_CLASS, AD_FIRE); destroy_item(POTION_CLASS, AD_FIRE);
if (lev > rn2(25)) if (lev > rn2(25))
destroy_item(SPBOOK_CLASS, AD_FIRE); destroy_item(SPBOOK_CLASS, AD_FIRE);
if (lev > rn2(20))
ignite_items(g.invent);
if (dmg) if (dmg)
mdamageu(mtmp, dmg); mdamageu(mtmp, dmg);
} }
+1
View File
@@ -1594,6 +1594,7 @@ struct monst *mtmp;
(void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE); (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
(void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
(void) destroy_mitem(mtmp, POTION_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; num = (2 * (rn1(3, 3) + 2 * bcsign(otmp)) + 1) / 3;
if (Fire_resistance) if (Fire_resistance)
You("are not harmed."); You("are not harmed.");
+2
View File
@@ -1447,6 +1447,8 @@ dogaze()
(void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE); (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
if (lev > rn2(25)) if (lev > rn2(25))
(void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
if (lev > rn2(20))
ignite_items(mtmp->minvent);
if (dmg) if (dmg)
mtmp->mhp -= dmg; mtmp->mhp -= dmg;
if (DEADMONSTER(mtmp)) if (DEADMONSTER(mtmp))
+44
View File
@@ -2434,6 +2434,7 @@ register struct monst *mtmp;
(void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE); (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
(void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
(void) destroy_mitem(mtmp, POTION_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) if (burn_floor_objects(mtmp->mx, mtmp->my, see_it, FALSE)
&& !see_it && distu(mtmp->mx, mtmp->my) <= 3 * 3) && !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(SCROLL_CLASS, AD_FIRE);
destroy_item(SPBOOK_CLASS, AD_FIRE); destroy_item(SPBOOK_CLASS, AD_FIRE);
destroy_item(POTION_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) if (!box && burn_floor_objects(u.ux, u.uy, see_it, TRUE) && !see_it)
You("smell paper burning."); You("smell paper burning.");
@@ -5400,6 +5402,7 @@ lava_effects()
destroy_item(SCROLL_CLASS, AD_FIRE); destroy_item(SCROLL_CLASS, AD_FIRE);
destroy_item(SPBOOK_CLASS, AD_FIRE); destroy_item(SPBOOK_CLASS, AD_FIRE);
destroy_item(POTION_CLASS, AD_FIRE); destroy_item(POTION_CLASS, AD_FIRE);
ignite_items(g.invent);
return FALSE; return FALSE;
} }
@@ -5560,4 +5563,45 @@ boolean override;
return defsyms[trap_to_defsym(ttyp)].explanation; 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*/ /*trap.c*/
+1
View File
@@ -1790,6 +1790,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */
} }
/* only potions damage resistant players in destroy_item */ /* only potions damage resistant players in destroy_item */
tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
ignite_items(mdef->minvent);
break; break;
case AD_COLD: case AD_COLD:
if (negated) { if (negated) {
+8
View File
@@ -2428,6 +2428,7 @@ boolean ordinary;
destroy_item(POTION_CLASS, AD_FIRE); destroy_item(POTION_CLASS, AD_FIRE);
destroy_item(SPBOOK_CLASS, AD_FIRE); destroy_item(SPBOOK_CLASS, AD_FIRE);
destroy_item(FOOD_CLASS, AD_FIRE); /* only slime for now */ destroy_item(FOOD_CLASS, AD_FIRE); /* only slime for now */
ignite_items(g.invent);
break; break;
case WAN_COLD: 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); (void) destroy_mitem(mon, SCROLL_CLASS, AD_FIRE);
if (!rn2(5)) if (!rn2(5))
(void) destroy_mitem(mon, SPBOOK_CLASS, AD_FIRE); (void) destroy_mitem(mon, SPBOOK_CLASS, AD_FIRE);
if (!rn2(3))
ignite_items(mon->minvent);
destroy_mitem(mon, FOOD_CLASS, AD_FIRE); /* carried slime */ destroy_mitem(mon, FOOD_CLASS, AD_FIRE); /* carried slime */
} }
break; break;
@@ -3874,6 +3877,8 @@ xchar sx, sy;
destroy_item(SCROLL_CLASS, AD_FIRE); destroy_item(SCROLL_CLASS, AD_FIRE);
if (!rn2(5)) if (!rn2(5))
destroy_item(SPBOOK_CLASS, AD_FIRE); destroy_item(SPBOOK_CLASS, AD_FIRE);
if (!rn2(3))
ignite_items(g.invent);
destroy_item(FOOD_CLASS, AD_FIRE); destroy_item(FOOD_CLASS, AD_FIRE);
} }
break; 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; return cnt;
} }