summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Feinberg <pleasingfung@gmail.com>2014-07-01 23:02:29 -0700
committerNicholas Feinberg <pleasingfung@gmail.com>2014-07-01 23:24:51 -0700
commit22f25ab0e848bb3f03d7bd4c0331fda178b879c3 (patch)
treea3e9023d6803619e7763bbbabde03b488a1b788d
parentd20dde44ce56c0dfcf7ade7f691b479748ebcafe (diff)
downloadcrawl-ref-22f25ab0e848bb3f03d7bd4c0331fda178b879c3.tar.gz
crawl-ref-22f25ab0e848bb3f03d7bd4c0331fda178b879c3.zip
Split butchering/bottling into a new file
-rw-r--r--crawl-ref/source/Makefile.obj1
-rw-r--r--crawl-ref/source/butcher.cc288
-rw-r--r--crawl-ref/source/butcher.h22
-rw-r--r--crawl-ref/source/dbg-scan.cc2
-rw-r--r--crawl-ref/source/delay.cc1
-rw-r--r--crawl-ref/source/dungeon.cc1
-rw-r--r--crawl-ref/source/effects.cc1
-rw-r--r--crawl-ref/source/food.cc1
-rw-r--r--crawl-ref/source/godabil.cc1
-rw-r--r--crawl-ref/source/godprayer.cc1
-rw-r--r--crawl-ref/source/item_use.cc1
-rw-r--r--crawl-ref/source/misc.cc268
-rw-r--r--crawl-ref/source/misc.h15
-rw-r--r--crawl-ref/source/mon-act.cc1
-rw-r--r--crawl-ref/source/mon-death.cc1
-rw-r--r--crawl-ref/source/rot.cc1
-rw-r--r--crawl-ref/source/rot.h2
-rw-r--r--crawl-ref/source/spl-clouds.cc1
-rw-r--r--crawl-ref/source/spl-damage.cc1
-rw-r--r--crawl-ref/source/spl-summoning.cc1
20 files changed, 327 insertions, 284 deletions
diff --git a/crawl-ref/source/Makefile.obj b/crawl-ref/source/Makefile.obj
index 19ffbbb653..1ef2f3395e 100644
--- a/crawl-ref/source/Makefile.obj
+++ b/crawl-ref/source/Makefile.obj
@@ -15,6 +15,7 @@ beam.o \
behold.o \
bitary.o \
branch.o \
+butcher.o \
chardump.o \
cio.o \
cloud.o \
diff --git a/crawl-ref/source/butcher.cc b/crawl-ref/source/butcher.cc
new file mode 100644
index 0000000000..335ef446de
--- /dev/null
+++ b/crawl-ref/source/butcher.cc
@@ -0,0 +1,288 @@
+/**
+ * @file
+ * @brief Functions for corpse butchering & bottling.
+ **/
+
+#include "AppHdr.h"
+
+#include "butcher.h"
+
+#include "env.h"
+#include "food.h"
+#include "itemprop.h"
+#include "itemprop-enum.h"
+#include "items.h"
+#include "makeitem.h"
+#include "misc.h"
+#include "mon-death.h"
+#include "random.h"
+#include "rot.h"
+#include "stuff.h"
+
+static void _create_monster_hide(const item_def corpse)
+{
+ // kiku_receive_corpses() creates corpses that are easily scummed
+ // for hides. We prevent this by setting "never_hide" as an item
+ // property of corpses it creates.
+ if (corpse.props.exists("never_hide"))
+ return;
+
+ monster_type mons_class = corpse.mon_type;
+ armour_type type;
+
+ // These values cannot be set by a reasonable formula: {dlb}
+ if (mons_genus(mons_class) == MONS_TROLL)
+ mons_class = MONS_TROLL;
+ switch (mons_class)
+ {
+ case MONS_FIRE_DRAGON: type = ARM_FIRE_DRAGON_HIDE; break;
+ case MONS_TROLL: type = ARM_TROLL_HIDE; break;
+ case MONS_ICE_DRAGON: type = ARM_ICE_DRAGON_HIDE; break;
+ case MONS_STEAM_DRAGON: type = ARM_STEAM_DRAGON_HIDE; break;
+ case MONS_MOTTLED_DRAGON: type = ARM_MOTTLED_DRAGON_HIDE; break;
+ case MONS_STORM_DRAGON: type = ARM_STORM_DRAGON_HIDE; break;
+ case MONS_GOLDEN_DRAGON: type = ARM_GOLD_DRAGON_HIDE; break;
+ case MONS_SWAMP_DRAGON: type = ARM_SWAMP_DRAGON_HIDE; break;
+ case MONS_PEARL_DRAGON: type = ARM_PEARL_DRAGON_HIDE; break;
+ default:
+ die("an unknown hide drop");
+ }
+
+ int o = items(0, OBJ_ARMOUR, type, true, 0, 0, 0, -1, true);
+ if (o == NON_ITEM)
+ return;
+ item_def& item = mitm[o];
+
+ do_uncurse_item(item, false);
+
+ // Automatically identify the created hide.
+ set_ident_flags(item, ISFLAG_IDENT_MASK);
+
+ const monster_type montype =
+ static_cast<monster_type>(corpse.orig_monnum);
+ if (!invalid_monster_type(montype) && mons_is_unique(montype))
+ item.inscription = mons_type_name(montype, DESC_PLAIN);
+
+ const coord_def pos = item_pos(corpse);
+ if (!pos.origin())
+ move_item_to_grid(&o, pos);
+}
+
+void maybe_drop_monster_hide(const item_def corpse)
+{
+ if (mons_class_leaves_hide(corpse.mon_type) && !one_chance_in(3))
+ _create_monster_hide(corpse);
+}
+
+int get_max_corpse_chunks(monster_type mons_class)
+{
+ return mons_weight(mons_class) / 150;
+}
+
+/** Skeletonise this corpse.
+ *
+ * @param item the corpse to be turned into a skeleton.
+ * @returns whether a valid skeleton could be made.
+ */
+bool turn_corpse_into_skeleton(item_def &item)
+{
+ ASSERT(item.base_type == OBJ_CORPSES);
+ ASSERT(item.sub_type == CORPSE_BODY);
+
+ // Some monsters' corpses lack the structure to leave skeletons
+ // behind.
+ if (!mons_skeleton(item.mon_type))
+ return false;
+
+ item.sub_type = CORPSE_SKELETON;
+ item.special = FRESHEST_CORPSE; // reset rotting counter
+ item.colour = LIGHTGREY;
+ return true;
+}
+
+static void _maybe_bleed_monster_corpse(const item_def corpse)
+{
+ // Only fresh corpses bleed enough to colour the ground.
+ if (!food_is_rotten(corpse))
+ {
+ const coord_def pos = item_pos(corpse);
+ if (!pos.origin())
+ {
+ const int max_chunks = get_max_corpse_chunks(corpse.mon_type);
+ bleed_onto_floor(pos, corpse.mon_type, max_chunks, true);
+ }
+ }
+}
+
+void turn_corpse_into_chunks(item_def &item, bool bloodspatter,
+ bool make_hide)
+{
+ ASSERT(item.base_type == OBJ_CORPSES);
+ ASSERT(item.sub_type == CORPSE_BODY);
+ const item_def corpse = item;
+ const int max_chunks = get_max_corpse_chunks(item.mon_type);
+
+ // Only fresh corpses bleed enough to colour the ground.
+ if (bloodspatter)
+ _maybe_bleed_monster_corpse(corpse);
+
+ item.base_type = OBJ_FOOD;
+ item.sub_type = FOOD_CHUNK;
+ item.quantity = 1 + random2(max_chunks);
+ item.quantity = stepdown_value(item.quantity, 4, 4, 12, 12);
+
+ bool wants_for_spells = you.has_spell(SPELL_SUBLIMATION_OF_BLOOD);
+ // Don't mark it as dropped if we are forcing autopickup of chunks.
+ if (you.force_autopickup[OBJ_FOOD][FOOD_CHUNK] <= 0
+ && is_bad_food(item) && !wants_for_spells)
+ {
+ item.flags |= ISFLAG_DROPPED;
+ }
+ else if (you.species != SP_VAMPIRE)
+ clear_item_pickup_flags(item);
+
+ // Happens after the corpse has been butchered.
+ if (make_hide)
+ maybe_drop_monster_hide(corpse);
+}
+
+static void _turn_corpse_into_skeleton_and_chunks(item_def &item, bool prefer_chunks)
+{
+ item_def copy = item;
+
+ // Complicated logic, but unless we use the original, both could fail if
+ // mitm[] is overstuffed.
+ if (prefer_chunks)
+ {
+ turn_corpse_into_chunks(item);
+ turn_corpse_into_skeleton(copy);
+ }
+ else
+ {
+ turn_corpse_into_chunks(copy);
+ turn_corpse_into_skeleton(item);
+ }
+
+ copy_item_to_grid(copy, item_pos(item));
+}
+
+void butcher_corpse(item_def &item, maybe_bool skeleton, bool chunks)
+{
+ item_was_destroyed(item);
+ if (!mons_skeleton(item.mon_type))
+ skeleton = MB_FALSE;
+ if (skeleton == MB_TRUE || skeleton == MB_MAYBE && one_chance_in(3))
+ {
+ if (chunks)
+ _turn_corpse_into_skeleton_and_chunks(item, skeleton != MB_TRUE);
+ else
+ {
+ _maybe_bleed_monster_corpse(item);
+ maybe_drop_monster_hide(item);
+ turn_corpse_into_skeleton(item);
+ }
+ }
+ else
+ {
+ if (chunks)
+ turn_corpse_into_chunks(item);
+ else
+ {
+ _maybe_bleed_monster_corpse(item);
+ maybe_drop_monster_hide(item);
+ destroy_item(item.index());
+ }
+ }
+}
+
+bool check_blood_corpses_on_ground()
+{
+ for (stack_iterator si(you.pos(), true); si; ++si)
+ {
+ if (si->base_type == OBJ_CORPSES && si->sub_type == CORPSE_BODY
+ && !food_is_rotten(*si)
+ && mons_has_blood(si->mon_type))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Deliberately don't check for rottenness here, so this check
+// can also be used to verify whether you *could* have bottled
+// a now rotten corpse.
+bool can_bottle_blood_from_corpse(monster_type mons_class)
+{
+ if (you.species != SP_VAMPIRE || you.experience_level < 6
+ || !mons_has_blood(mons_class))
+ {
+ return false;
+ }
+
+ int chunk_type = mons_corpse_effect(mons_class);
+ if (chunk_type == CE_CLEAN)
+ return true;
+
+ return false;
+}
+
+int num_blood_potions_from_corpse(monster_type mons_class, int chunk_type)
+{
+ if (chunk_type == -1)
+ chunk_type = mons_corpse_effect(mons_class);
+
+ // Max. amount is about one third of the max. amount for chunks.
+ const int max_chunks = get_max_corpse_chunks(mons_class);
+
+ // Max. amount is about one third of the max. amount for chunks.
+ int pot_quantity = max_chunks / 3;
+ pot_quantity = stepdown_value(pot_quantity, 2, 2, 6, 6);
+
+ if (pot_quantity < 1)
+ pot_quantity = 1;
+
+ return pot_quantity;
+}
+
+// If autopickup is active, the potions are auto-picked up after creation.
+void turn_corpse_into_blood_potions(item_def &item)
+{
+ ASSERT(item.base_type == OBJ_CORPSES);
+ ASSERT(!food_is_rotten(item));
+
+ const item_def corpse = item;
+ const monster_type mons_class = corpse.mon_type;
+
+ ASSERT(can_bottle_blood_from_corpse(mons_class));
+
+ item.base_type = OBJ_POTIONS;
+ item.sub_type = POT_BLOOD;
+ item_colour(item);
+ clear_item_pickup_flags(item);
+
+ item.quantity = num_blood_potions_from_corpse(mons_class);
+
+ // Initialise timer depending on corpse age:
+ // almost rotting: age = 100 --> potion timer = 500 --> will coagulate soon
+ // freshly killed: age = 200 --> potion timer = 2500 --> fresh !blood
+ init_stack_blood_potions(item, (item.special - 100) * 20 + 500);
+
+ // Happens after the blood has been bottled.
+ maybe_drop_monster_hide(corpse);
+}
+
+void turn_corpse_into_skeleton_and_blood_potions(item_def &item)
+{
+ item_def blood_potions = item;
+
+ if (mons_skeleton(item.mon_type))
+ turn_corpse_into_skeleton(item);
+
+ int o = get_mitm_slot();
+ if (o != NON_ITEM)
+ {
+ turn_corpse_into_blood_potions(blood_potions);
+ copy_item_to_grid(blood_potions, you.pos());
+ }
+}
diff --git a/crawl-ref/source/butcher.h b/crawl-ref/source/butcher.h
new file mode 100644
index 0000000000..1c4cf4d137
--- /dev/null
+++ b/crawl-ref/source/butcher.h
@@ -0,0 +1,22 @@
+/**
+ * @file
+ * @brief Functions for corpse butchering & bottling.
+ **/
+
+#ifndef BUTCHER_H
+#define BUTCHER_H
+
+void maybe_drop_monster_hide(const item_def corpse);
+int get_max_corpse_chunks(monster_type mons_class);
+bool turn_corpse_into_skeleton(item_def &item);
+void turn_corpse_into_chunks(item_def &item, bool bloodspatter = true,
+ bool make_hide = true);
+void butcher_corpse(item_def &item, maybe_bool skeleton = MB_MAYBE,
+ bool chunks = true);
+bool check_blood_corpses_on_ground();
+bool can_bottle_blood_from_corpse(monster_type mons_class);
+int num_blood_potions_from_corpse(monster_type mons_class, int chunk_type = -1);
+void turn_corpse_into_blood_potions(item_def &item);
+void turn_corpse_into_skeleton_and_blood_potions(item_def &item);
+
+#endif
diff --git a/crawl-ref/source/dbg-scan.cc b/crawl-ref/source/dbg-scan.cc
index 160ce3af87..45ae0283b3 100644
--- a/crawl-ref/source/dbg-scan.cc
+++ b/crawl-ref/source/dbg-scan.cc
@@ -12,6 +12,7 @@
#include "artefact.h"
#include "branch.h"
+#include "butcher.h"
#include "chardump.h"
#include "coord.h"
#include "coordit.h"
@@ -29,7 +30,6 @@
#include "libutil.h"
#include "maps.h"
#include "message.h"
-#include "misc.h"
#include "mon-util.h"
#include "ng-init.h"
#include "shopping.h"
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc
index 8cf17bfba7..05eeb0b90f 100644
--- a/crawl-ref/source/delay.cc
+++ b/crawl-ref/source/delay.cc
@@ -14,6 +14,7 @@
#include "ability.h"
#include "areas.h"
#include "artefact.h"
+#include "butcher.h"
#include "clua.h"
#include "command.h"
#include "coord.h"
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index c0a4e64f93..5690fa7357 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -21,6 +21,7 @@
#include "artefact.h"
#include "attitude-change.h"
#include "branch.h"
+#include "butcher.h"
#include "chardump.h"
#include "cloud.h"
#include "coordit.h"
diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc
index 10bb01fef1..49e053347e 100644
--- a/crawl-ref/source/effects.cc
+++ b/crawl-ref/source/effects.cc
@@ -24,6 +24,7 @@
#include "artefact.h"
#include "beam.h"
#include "branch.h"
+#include "butcher.h"
#include "cloud.h"
#include "colour.h"
#include "coordit.h"
diff --git a/crawl-ref/source/food.cc b/crawl-ref/source/food.cc
index 51d5449046..a1f040fd55 100644
--- a/crawl-ref/source/food.cc
+++ b/crawl-ref/source/food.cc
@@ -17,6 +17,7 @@
#include "options.h"
#include "artefact.h"
+#include "butcher.h"
#include "cio.h"
#include "clua.h"
#include "command.h"
diff --git a/crawl-ref/source/godabil.cc b/crawl-ref/source/godabil.cc
index 82e4b53e05..3865e53c50 100644
--- a/crawl-ref/source/godabil.cc
+++ b/crawl-ref/source/godabil.cc
@@ -14,6 +14,7 @@
#include "attitude-change.h"
#include "beam.h"
#include "branch.h"
+#include "butcher.h"
#include "cloud.h"
#include "colour.h"
#include "coordit.h"
diff --git a/crawl-ref/source/godprayer.cc b/crawl-ref/source/godprayer.cc
index e8e460e41b..4300f80c60 100644
--- a/crawl-ref/source/godprayer.cc
+++ b/crawl-ref/source/godprayer.cc
@@ -5,6 +5,7 @@
#include <cmath>
#include "artefact.h"
+#include "butcher.h"
#include "coordit.h"
#include "database.h"
#include "effects.h"
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 7425cd4fce..62a61d2119 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -12,6 +12,7 @@
#include "areas.h"
#include "art-enum.h"
#include "artefact.h"
+#include "butcher.h"
#include "cloud.h"
#include "colour.h"
#include "coordit.h"
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index 2c7e5ebcc8..c6cfa02f4d 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -83,182 +83,6 @@
#include "shout.h"
#include "xom.h"
-static void _create_monster_hide(const item_def corpse)
-{
- // kiku_receive_corpses() creates corpses that are easily scummed
- // for hides. We prevent this by setting "never_hide" as an item
- // property of corpses it creates.
- if (corpse.props.exists("never_hide"))
- return;
-
- monster_type mons_class = corpse.mon_type;
- armour_type type;
-
- // These values cannot be set by a reasonable formula: {dlb}
- if (mons_genus(mons_class) == MONS_TROLL)
- mons_class = MONS_TROLL;
- switch (mons_class)
- {
- case MONS_FIRE_DRAGON: type = ARM_FIRE_DRAGON_HIDE; break;
- case MONS_TROLL: type = ARM_TROLL_HIDE; break;
- case MONS_ICE_DRAGON: type = ARM_ICE_DRAGON_HIDE; break;
- case MONS_STEAM_DRAGON: type = ARM_STEAM_DRAGON_HIDE; break;
- case MONS_MOTTLED_DRAGON: type = ARM_MOTTLED_DRAGON_HIDE; break;
- case MONS_STORM_DRAGON: type = ARM_STORM_DRAGON_HIDE; break;
- case MONS_GOLDEN_DRAGON: type = ARM_GOLD_DRAGON_HIDE; break;
- case MONS_SWAMP_DRAGON: type = ARM_SWAMP_DRAGON_HIDE; break;
- case MONS_PEARL_DRAGON: type = ARM_PEARL_DRAGON_HIDE; break;
- default:
- die("an unknown hide drop");
- }
-
- int o = items(0, OBJ_ARMOUR, type, true, 0, 0, 0, -1, true);
- if (o == NON_ITEM)
- return;
- item_def& item = mitm[o];
-
- do_uncurse_item(item, false);
-
- // Automatically identify the created hide.
- set_ident_flags(item, ISFLAG_IDENT_MASK);
-
- const monster_type montype =
- static_cast<monster_type>(corpse.orig_monnum);
- if (!invalid_monster_type(montype) && mons_is_unique(montype))
- item.inscription = mons_type_name(montype, DESC_PLAIN);
-
- const coord_def pos = item_pos(corpse);
- if (!pos.origin())
- move_item_to_grid(&o, pos);
-}
-
-void maybe_drop_monster_hide(const item_def corpse)
-{
- if (mons_class_leaves_hide(corpse.mon_type) && !one_chance_in(3))
- _create_monster_hide(corpse);
-}
-
-int get_max_corpse_chunks(monster_type mons_class)
-{
- return mons_weight(mons_class) / 150;
-}
-
-/** Skeletonise this corpse.
- *
- * @param item the corpse to be turned into a skeleton.
- * @returns whether a valid skeleton could be made.
- */
-bool turn_corpse_into_skeleton(item_def &item)
-{
- ASSERT(item.base_type == OBJ_CORPSES);
- ASSERT(item.sub_type == CORPSE_BODY);
-
- // Some monsters' corpses lack the structure to leave skeletons
- // behind.
- if (!mons_skeleton(item.mon_type))
- return false;
-
- item.sub_type = CORPSE_SKELETON;
- item.special = FRESHEST_CORPSE; // reset rotting counter
- item.colour = LIGHTGREY;
- return true;
-}
-
-static void _maybe_bleed_monster_corpse(const item_def corpse)
-{
- // Only fresh corpses bleed enough to colour the ground.
- if (!food_is_rotten(corpse))
- {
- const coord_def pos = item_pos(corpse);
- if (!pos.origin())
- {
- const int max_chunks = get_max_corpse_chunks(corpse.mon_type);
- bleed_onto_floor(pos, corpse.mon_type, max_chunks, true);
- }
- }
-}
-
-void turn_corpse_into_chunks(item_def &item, bool bloodspatter,
- bool make_hide)
-{
- ASSERT(item.base_type == OBJ_CORPSES);
- ASSERT(item.sub_type == CORPSE_BODY);
- const item_def corpse = item;
- const int max_chunks = get_max_corpse_chunks(item.mon_type);
-
- // Only fresh corpses bleed enough to colour the ground.
- if (bloodspatter)
- _maybe_bleed_monster_corpse(corpse);
-
- item.base_type = OBJ_FOOD;
- item.sub_type = FOOD_CHUNK;
- item.quantity = 1 + random2(max_chunks);
- item.quantity = stepdown_value(item.quantity, 4, 4, 12, 12);
-
- bool wants_for_spells = you.has_spell(SPELL_SUBLIMATION_OF_BLOOD);
- // Don't mark it as dropped if we are forcing autopickup of chunks.
- if (you.force_autopickup[OBJ_FOOD][FOOD_CHUNK] <= 0
- && is_bad_food(item) && !wants_for_spells)
- {
- item.flags |= ISFLAG_DROPPED;
- }
- else if (you.species != SP_VAMPIRE)
- clear_item_pickup_flags(item);
-
- // Happens after the corpse has been butchered.
- if (make_hide)
- maybe_drop_monster_hide(corpse);
-}
-
-static void _turn_corpse_into_skeleton_and_chunks(item_def &item, bool prefer_chunks)
-{
- item_def copy = item;
-
- // Complicated logic, but unless we use the original, both could fail if
- // mitm[] is overstuffed.
- if (prefer_chunks)
- {
- turn_corpse_into_chunks(item);
- turn_corpse_into_skeleton(copy);
- }
- else
- {
- turn_corpse_into_chunks(copy);
- turn_corpse_into_skeleton(item);
- }
-
- copy_item_to_grid(copy, item_pos(item));
-}
-
-void butcher_corpse(item_def &item, maybe_bool skeleton, bool chunks)
-{
- item_was_destroyed(item);
- if (!mons_skeleton(item.mon_type))
- skeleton = MB_FALSE;
- if (skeleton == MB_TRUE || skeleton == MB_MAYBE && one_chance_in(3))
- {
- if (chunks)
- _turn_corpse_into_skeleton_and_chunks(item, skeleton != MB_TRUE);
- else
- {
- _maybe_bleed_monster_corpse(item);
- maybe_drop_monster_hide(item);
- turn_corpse_into_skeleton(item);
- }
- }
- else
- {
- if (chunks)
- turn_corpse_into_chunks(item);
- else
- {
- _maybe_bleed_monster_corpse(item);
- maybe_drop_monster_hide(item);
- destroy_item(item.index());
- }
- }
-}
-
string get_desc_quantity(const int quant, const int total, string whose)
{
if (total == quant)
@@ -273,98 +97,6 @@ string get_desc_quantity(const int quant, const int total, string whose)
return "Some of " + whose;
}
-bool check_blood_corpses_on_ground()
-{
- for (stack_iterator si(you.pos(), true); si; ++si)
- {
- if (si->base_type == OBJ_CORPSES && si->sub_type == CORPSE_BODY
- && !food_is_rotten(*si)
- && mons_has_blood(si->mon_type))
- {
- return true;
- }
- }
- return false;
-}
-
-// Deliberately don't check for rottenness here, so this check
-// can also be used to verify whether you *could* have bottled
-// a now rotten corpse.
-bool can_bottle_blood_from_corpse(monster_type mons_class)
-{
- if (you.species != SP_VAMPIRE || you.experience_level < 6
- || !mons_has_blood(mons_class))
- {
- return false;
- }
-
- int chunk_type = mons_corpse_effect(mons_class);
- if (chunk_type == CE_CLEAN)
- return true;
-
- return false;
-}
-
-int num_blood_potions_from_corpse(monster_type mons_class, int chunk_type)
-{
- if (chunk_type == -1)
- chunk_type = mons_corpse_effect(mons_class);
-
- // Max. amount is about one third of the max. amount for chunks.
- const int max_chunks = get_max_corpse_chunks(mons_class);
-
- // Max. amount is about one third of the max. amount for chunks.
- int pot_quantity = max_chunks / 3;
- pot_quantity = stepdown_value(pot_quantity, 2, 2, 6, 6);
-
- if (pot_quantity < 1)
- pot_quantity = 1;
-
- return pot_quantity;
-}
-
-// If autopickup is active, the potions are auto-picked up after creation.
-void turn_corpse_into_blood_potions(item_def &item)
-{
- ASSERT(item.base_type == OBJ_CORPSES);
- ASSERT(!food_is_rotten(item));
-
- const item_def corpse = item;
- const monster_type mons_class = corpse.mon_type;
-
- ASSERT(can_bottle_blood_from_corpse(mons_class));
-
- item.base_type = OBJ_POTIONS;
- item.sub_type = POT_BLOOD;
- item_colour(item);
- clear_item_pickup_flags(item);
-
- item.quantity = num_blood_potions_from_corpse(mons_class);
-
- // Initialise timer depending on corpse age:
- // almost rotting: age = 100 --> potion timer = 500 --> will coagulate soon
- // freshly killed: age = 200 --> potion timer = 2500 --> fresh !blood
- init_stack_blood_potions(item, (item.special - 100) * 20 + 500);
-
- // Happens after the blood has been bottled.
- maybe_drop_monster_hide(corpse);
-}
-
-void turn_corpse_into_skeleton_and_blood_potions(item_def &item)
-{
- item_def blood_potions = item;
-
- if (mons_skeleton(item.mon_type))
- turn_corpse_into_skeleton(item);
-
- int o = get_mitm_slot();
- if (o != NON_ITEM)
- {
- turn_corpse_into_blood_potions(blood_potions);
- copy_item_to_grid(blood_potions, you.pos());
- }
-}
-
static bool allow_bleeding_on_square(const coord_def& where)
{
// No bleeding onto sanctuary ground, please.
diff --git a/crawl-ref/source/misc.h b/crawl-ref/source/misc.h
index 776c65faa4..65f5230322 100644
--- a/crawl-ref/source/misc.h
+++ b/crawl-ref/source/misc.h
@@ -23,19 +23,8 @@ void emergency_untransform();
void merfolk_start_swimming(bool step = false);
void merfolk_stop_swimming();
void trackers_init_new_level(bool transit);
-void maybe_drop_monster_hide(const item_def corpse);
-int get_max_corpse_chunks(monster_type mons_class);
-bool turn_corpse_into_skeleton(item_def &item);
-void turn_corpse_into_chunks(item_def &item, bool bloodspatter = true,
- bool make_hide = true);
-void butcher_corpse(item_def &item, maybe_bool skeleton = MB_MAYBE,
- bool chunks = true);
-
-bool check_blood_corpses_on_ground();
-bool can_bottle_blood_from_corpse(monster_type mons_class);
-int num_blood_potions_from_corpse(monster_type mons_class, int chunk_type = -1);
-void turn_corpse_into_blood_potions(item_def &item);
-void turn_corpse_into_skeleton_and_blood_potions(item_def &item);
+string get_desc_quantity(const int quant, const int total,
+ string whose = "your");
void bleed_onto_floor(const coord_def& where, monster_type mon, int damage,
bool spatter = false, bool smell_alert = true,
diff --git a/crawl-ref/source/mon-act.cc b/crawl-ref/source/mon-act.cc
index 588e118004..5c305545e4 100644
--- a/crawl-ref/source/mon-act.cc
+++ b/crawl-ref/source/mon-act.cc
@@ -12,6 +12,7 @@
#include "artefact.h"
#include "attitude-change.h"
#include "beam.h"
+#include "butcher.h"
#include "cloud.h"
#include "coordit.h"
#include "dbg-scan.h"
diff --git a/crawl-ref/source/mon-death.cc b/crawl-ref/source/mon-death.cc
index 3080ff8e62..0d7c80cf7f 100644
--- a/crawl-ref/source/mon-death.cc
+++ b/crawl-ref/source/mon-death.cc
@@ -13,6 +13,7 @@
#include "artefact.h"
#include "attitude-change.h"
#include "beam.h"
+#include "butcher.h"
#include "cluautil.h"
#include "cloud.h"
#include "coordit.h"
diff --git a/crawl-ref/source/rot.cc b/crawl-ref/source/rot.cc
index 9b1b717a98..c7c263c378 100644
--- a/crawl-ref/source/rot.cc
+++ b/crawl-ref/source/rot.cc
@@ -13,6 +13,7 @@
#include "items.h"
#include "libutil.h"
#include "makeitem.h"
+#include "misc.h"
#include "player.h"
#include "stuff.h"
diff --git a/crawl-ref/source/rot.h b/crawl-ref/source/rot.h
index bbd83b5ff6..4dfab30525 100644
--- a/crawl-ref/source/rot.h
+++ b/crawl-ref/source/rot.h
@@ -9,8 +9,6 @@
#include "externs.h"
void init_stack_blood_potions(item_def &stack, int age = -1);
-string get_desc_quantity(const int quant, const int total,
- string whose = "your");
void maybe_coagulate_blood_potions_floor(int obj);
void maybe_coagulate_blood_potions_inv(item_def &blood);
int remove_oldest_blood_potion(item_def &stack);
diff --git a/crawl-ref/source/spl-clouds.cc b/crawl-ref/source/spl-clouds.cc
index 3170c402e2..a19f388223 100644
--- a/crawl-ref/source/spl-clouds.cc
+++ b/crawl-ref/source/spl-clouds.cc
@@ -12,6 +12,7 @@
#include "act-iter.h"
#include "beam.h"
+#include "butcher.h"
#include "cloud.h"
#include "coord.h"
#include "coordit.h"
diff --git a/crawl-ref/source/spl-damage.cc b/crawl-ref/source/spl-damage.cc
index bbc05fda26..6a8912e82d 100644
--- a/crawl-ref/source/spl-damage.cc
+++ b/crawl-ref/source/spl-damage.cc
@@ -13,6 +13,7 @@
#include "areas.h"
#include "art-enum.h"
#include "beam.h"
+#include "butcher.h"
#include "cloud.h"
#include "colour.h"
#include "coord.h"
diff --git a/crawl-ref/source/spl-summoning.cc b/crawl-ref/source/spl-summoning.cc
index 2999623c33..a666665dde 100644
--- a/crawl-ref/source/spl-summoning.cc
+++ b/crawl-ref/source/spl-summoning.cc
@@ -13,6 +13,7 @@
#include "act-iter.h"
#include "areas.h"
#include "artefact.h"
+#include "butcher.h"
#include "cloud.h"
#include "colour.h"
#include "coordit.h"