From dde32b3da8e13cd56d43650135ab5b4bdbe28d30 Mon Sep 17 00:00:00 2001
From: Sage <SageBasilMint@gmail.com>
Date: Wed, 26 Feb 2014 21:03:23 -0800
Subject: [PATCH 1/2] New artefact: Firestarter

+7 great mace of flaming. rF++, scrollcons, inner flames monsters on hit.
---
 crawl-ref/source/art-data.txt            |   10 ++++++++++
 crawl-ref/source/art-func.h              |   30 ++++++++++++++++++++++++++++++
 crawl-ref/source/dat/descript/unrand.txt |    5 +++++
 crawl-ref/source/ouch.cc                 |    7 +++++++
 4 files changed, 52 insertions(+)

diff --git a/crawl-ref/source/art-data.txt b/crawl-ref/source/art-data.txt
index 272cb2e..47649a7 100644
--- a/crawl-ref/source/art-data.txt
+++ b/crawl-ref/source/art-data.txt
@@ -1145,6 +1145,16 @@ INSCRIP: silver, rMut
 COLOUR:  ETC_SILVER
 PLUS:    7/7
 
+ENUM:     FIRESTARTER
+NAME:     great mace "Firestarter"
+OBJ:      OBJ_WEAPONS/WPN_GREAT_MACE
+COLOUR:   RED
+#TILE:     urand_firestarter
+#TILE_EQ:  firestarter
+PLUS:     +7/+7
+BRAND:    SPWPN_FLAMING
+FIRE:    2
+
 # This is the first of two amulets used to test suppression aura.
 # Together, they confer every randart effect except for a few that are
 # determined explicitly by checking whether a certain amulet is worn
diff --git a/crawl-ref/source/art-func.h b/crawl-ref/source/art-func.h
index f109346..69f81b8 100644
--- a/crawl-ref/source/art-func.h
+++ b/crawl-ref/source/art-func.h
@@ -1026,3 +1026,33 @@ static void _ORDER_melee_effects(item_def* item, actor* attacker,
         }
     }
 }
+
+///////////////////////////////////////////////////
+
+static void _FIRESTARTER_equip(item_def *item, bool *show_msgs, bool unmeld)
+{
+    _equip_mpr(show_msgs, "You are filled with an inner flame.");
+}
+
+static void _FIRESTARTER_unequip(item_def *item, bool *show_msgs)
+{
+    _equip_mpr(show_msgs, "Your inner flame fades away.");
+}
+
+static void _FIRESTARTER_melee_effects(item_def* weapon, actor* attacker,
+                                   actor* defender, bool mondied, int dam)
+{
+    if (dam)
+    {
+        if (defender->is_monster()
+            && !mondied
+            && !defender->as_monster()->has_ench(ENCH_INNER_FLAME))
+        {
+            mprf("%s is filled with an inner flame.",
+                 defender->name(DESC_THE).c_str());
+            defender->as_monster()->add_ench(
+                mon_enchant(ENCH_INNER_FLAME, 0, attacker,
+                            (3 + random2(dam)) * BASELINE_DELAY));
+        }
+    }
+}
diff --git a/crawl-ref/source/dat/descript/unrand.txt b/crawl-ref/source/dat/descript/unrand.txt
index 20edb23..086af0b 100644
--- a/crawl-ref/source/dat/descript/unrand.txt
+++ b/crawl-ref/source/dat/descript/unrand.txt
@@ -519,6 +519,11 @@ lajatang of Order
 Legend says that once the staff was the favoured weapon of the many priests of
 Zin. Long ago Zin bestowed this gift upon a favoured worshipper.
 %%%%
+great mace "Firestarter"
+
+Alongside its obvious effects, this weapon protects its owner's inventory from
+fire, and fills monsters that it hits with an inner flame.
+%%%%
 milk chocolate
 
 This item is a debugging aid, granting a vast array of mostly beneficial
diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc
index 1821672..cee772c 100644
--- a/crawl-ref/source/ouch.cc
+++ b/crawl-ref/source/ouch.cc
@@ -531,6 +531,13 @@ static bool _expose_invent_to_element(beam_type flavour, int strength)
                 continue;
             }
 
+            if (target_class == OBJ_SCROLLS
+                && player_equip_unrand(UNRAND_FIRESTARTER)
+                && !one_chance_in(10))
+            {
+                continue;
+            }
+
             if (target_class == OBJ_POTIONS
                 && you.mutation[MUT_CONSERVE_POTIONS]
                 && !one_chance_in(10))
-- 
1.7.9.5


From 9d5bf769e5418a7b2a591c74d7a10db7dd483abf Mon Sep 17 00:00:00 2001
From: Sage <SageBasilMint@gmail.com>
Date: Wed, 26 Feb 2014 22:47:38 -0800
Subject: [PATCH 2/2] Make Firestarter blow you up when you die.

---
 crawl-ref/source/beam.cc      |   46 +++++++++++++++++++++++++++++++++++++++
 crawl-ref/source/beam.h       |    3 +++
 crawl-ref/source/mon-stuff.cc |   48 ++++-------------------------------------
 crawl-ref/source/ouch.cc      |   20 +++++++++++++++++
 4 files changed, 73 insertions(+), 44 deletions(-)

diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 809dcff..2c6adaf 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -6619,3 +6619,49 @@ void clear_zap_info_on_exit()
         delete zap_data[i].tohit;
     }
 }
+
+void setup_base_explosion(bolt & beam, const actor& origin)
+{
+    beam.is_tracer    = false;
+    beam.is_explosion = true;
+    beam.beam_source  = origin.mindex();
+    beam.glyph        = dchar_glyph(DCHAR_FIRED_BURST);
+    beam.source       = origin.pos();
+    if (!origin.is_monster())
+        beam.source_name = "you";
+    else
+        beam.source_name = origin.as_monster()->base_name(DESC_BASENAME, true);
+    beam.target       = origin.pos();
+    beam.noise_msg    = "You hear an explosion!";
+
+    if (!crawl_state.game_is_arena() && origin.is_player() || origin.as_monster()->attitude == ATT_FRIENDLY
+        && !origin.is_summoned())
+    {
+        beam.thrower = KILL_YOU;
+    }
+    else
+        beam.thrower = KILL_MON;
+
+    beam.aux_source.clear();
+    if (origin.is_player())
+        beam.attitude = ATT_FRIENDLY;
+    else
+        beam.attitude = origin.as_monster()->attitude;
+}
+
+void setup_inner_flame_explosion(bolt & beam, const actor& origin,
+                                         actor* agent)
+{
+    setup_base_explosion(beam, origin);
+    const int size   = origin.body_size(PSIZE_BODY);
+    beam.flavour     = BEAM_FIRE;
+    beam.damage      = (size > SIZE_BIG)  ? dice_def(3, 25) :
+                       (size > SIZE_TINY) ? dice_def(3, 20) :
+                                            dice_def(3, 15);
+    beam.name        = "fiery explosion";
+    beam.colour      = RED;
+    beam.ex_size     = (size > SIZE_BIG) ? 2 : 1;
+    beam.source_name = origin.name(DESC_A, true);
+    beam.thrower     = (agent && agent->is_player()) ? KILL_YOU_MISSILE
+                                                     : KILL_MON_MISSILE;
+}
diff --git a/crawl-ref/source/beam.h b/crawl-ref/source/beam.h
index e68b723..9e060c0 100644
--- a/crawl-ref/source/beam.h
+++ b/crawl-ref/source/beam.h
@@ -344,4 +344,7 @@ void clear_zap_info_on_exit();
 int zap_power_cap(zap_type ztype);
 void zappy(zap_type z_type, int power, bolt &pbolt);
 
+void setup_base_explosion(bolt & beam, const actor& origin);
+void setup_inner_flame_explosion(bolt & beam, const actor& origin, actor* agent);
+
 #endif
diff --git a/crawl-ref/source/mon-stuff.cc b/crawl-ref/source/mon-stuff.cc
index c3f04ed..428386b 100644
--- a/crawl-ref/source/mon-stuff.cc
+++ b/crawl-ref/source/mon-stuff.cc
@@ -1076,32 +1076,9 @@ static void _mummy_curse(monster* mons, killer_type killer, int index)
     }
 }
 
-static void _setup_base_explosion(bolt & beam, const monster& origin)
-{
-    beam.is_tracer    = false;
-    beam.is_explosion = true;
-    beam.beam_source  = origin.mindex();
-    beam.glyph        = dchar_glyph(DCHAR_FIRED_BURST);
-    beam.source       = origin.pos();
-    beam.source_name  = origin.base_name(DESC_BASENAME, true);
-    beam.target       = origin.pos();
-    beam.noise_msg    = "You hear an explosion!";
-
-    if (!crawl_state.game_is_arena() && origin.attitude == ATT_FRIENDLY
-        && !origin.is_summoned())
-    {
-        beam.thrower = KILL_YOU;
-    }
-    else
-        beam.thrower = KILL_MON;
-
-    beam.aux_source.clear();
-    beam.attitude = origin.attitude;
-}
-
 void setup_spore_explosion(bolt & beam, const monster& origin)
 {
-    _setup_base_explosion(beam, origin);
+    setup_base_explosion(beam, origin);
     beam.flavour = BEAM_SPORE;
     beam.damage  = dice_def(3, 15);
     beam.name    = "explosion of spores";
@@ -1111,7 +1088,7 @@ void setup_spore_explosion(bolt & beam, const monster& origin)
 
 static void _setup_lightning_explosion(bolt & beam, const monster& origin)
 {
-    _setup_base_explosion(beam, origin);
+    setup_base_explosion(beam, origin);
     beam.flavour   = BEAM_ELECTRICITY;
     beam.damage    = dice_def(3, 20);
     beam.name      = "blast of lightning";
@@ -1122,7 +1099,7 @@ static void _setup_lightning_explosion(bolt & beam, const monster& origin)
 
 static void _setup_prism_explosion(bolt& beam, const monster& origin)
 {
-    _setup_base_explosion(beam, origin);
+    setup_base_explosion(beam, origin);
     beam.flavour = BEAM_MMISSILE;
     beam.damage  = (origin.number == 2 ? dice_def(3, 6 + origin.hit_dice * 7 / 4)
                     : dice_def(2, 6 + origin.hit_dice * 7 / 4));
@@ -1131,23 +1108,6 @@ static void _setup_prism_explosion(bolt& beam, const monster& origin)
     beam.ex_size = origin.number;
 }
 
-static void _setup_inner_flame_explosion(bolt & beam, const monster& origin,
-                                         actor* agent)
-{
-    _setup_base_explosion(beam, origin);
-    const int size   = origin.body_size(PSIZE_BODY);
-    beam.flavour     = BEAM_FIRE;
-    beam.damage      = (size > SIZE_BIG)  ? dice_def(3, 25) :
-                       (size > SIZE_TINY) ? dice_def(3, 20) :
-                                            dice_def(3, 15);
-    beam.name        = "fiery explosion";
-    beam.colour      = RED;
-    beam.ex_size     = (size > SIZE_BIG) ? 2 : 1;
-    beam.source_name = origin.name(DESC_A, true);
-    beam.thrower     = (agent && agent->is_player()) ? KILL_YOU_MISSILE
-                                                     : KILL_MON_MISSILE;
-}
-
 static bool _explode_monster(monster* mons, killer_type killer,
                              int killer_index, bool pet_kill, bool wizard)
 {
@@ -1188,7 +1148,7 @@ static bool _explode_monster(monster* mons, killer_type killer,
         mon_enchant i_f = mons->get_ench(ENCH_INNER_FLAME);
         ASSERT(i_f.ench == ENCH_INNER_FLAME);
         agent = actor_by_mid(i_f.source);
-        _setup_inner_flame_explosion(beam, *mons, agent);
+        setup_inner_flame_explosion(beam, *mons, agent);
         // This might need to change if monsters ever get the ability to cast
         // Inner Flame...
         if (i_f.source == MID_ANON_FRIEND)
diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc
index cee772c..743d6b2 100644
--- a/crawl-ref/source/ouch.cc
+++ b/crawl-ref/source/ouch.cc
@@ -24,6 +24,8 @@
 #include "externs.h"
 #include "options.h"
 
+#include "cloud.h"
+#include "coordit.h"
 #include "art-enum.h"
 #include "artefact.h"
 #include "beam.h"
@@ -65,6 +67,7 @@
 #include "spl-other.h"
 #include "state.h"
 #include "stuff.h"
+#include "terrain.h"
 #include "transform.h"
 #include "tutorial.h"
 #include "view.h"
@@ -1283,6 +1286,23 @@ void ouch(int dam, int death_source, kill_method_type death_type,
     crawl_state.need_save       = false;
     crawl_state.updating_scores = true;
 
+    if (player_equip_unrand(UNRAND_FIRESTARTER))
+    {
+        bolt beam;
+        setup_base_explosion(beam, you);
+        setup_inner_flame_explosion(beam, you, &you);
+        // Without a hole in the middle, you're hurt by your own
+        // explosion--weird messages.
+        beam.explode(true, true);
+
+        for (adjacent_iterator ai(you.pos(), false); ai; ++ai)
+            if (!cell_is_solid(*ai) && env.cgrid(*ai) == EMPTY_CLOUD
+                && !one_chance_in(5))
+            {
+                place_cloud(CLOUD_FIRE, *ai, 10 + random2(10), &you);
+            }
+    }
+
     // Prevent bogus notes.
     activate_notes(false);
 
-- 
1.7.9.5

