summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorevktalo <evktalo@users.sourceforge.net>2009-10-02 00:13:21 +0300
committerevktalo <evktalo@users.sourceforge.net>2009-10-02 00:13:21 +0300
commit2a56957bec723bd5a9b842b503ba3c6e7e0f0ec0 (patch)
tree4800abc6358fd2a683820abd7ec3455f8671f936 /crawl-ref
parent60c100224a47bad1faaecaf1dba27f9562e23256 (diff)
downloadcrawl-ref-2a56957bec723bd5a9b842b503ba3c6e7e0f0ec0.tar.gz
crawl-ref-2a56957bec723bd5a9b842b503ba3c6e7e0f0ec0.zip
Applying Kiku patch by Alex MacDonald (timecircuits). Kiku now has an invocation to provide corpses, provides (partial) torment resistance, provides torment when butchering while praying, and gifts Necromancy books. As the final gift, the player can choose between blessing the wielded weapon with Pain brand, or Necronomicon.
Flavour and help texts haven't been altered yet. Signed-off-by: evktalo <evktalo@users.sourceforge.net>
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/abl-show.cc43
-rw-r--r--crawl-ref/source/effects.cc24
-rw-r--r--crawl-ref/source/enum.h4
-rw-r--r--crawl-ref/source/food.cc12
-rw-r--r--crawl-ref/source/misc.cc6
-rw-r--r--crawl-ref/source/monplace.cc68
-rw-r--r--crawl-ref/source/monplace.h6
-rw-r--r--crawl-ref/source/religion.cc129
-rw-r--r--crawl-ref/source/spells3.cc85
-rw-r--r--crawl-ref/source/spells3.h2
10 files changed, 303 insertions, 76 deletions
diff --git a/crawl-ref/source/abl-show.cc b/crawl-ref/source/abl-show.cc
index 95dbc29ccd..29303e611a 100644
--- a/crawl-ref/source/abl-show.cc
+++ b/crawl-ref/source/abl-show.cc
@@ -107,8 +107,8 @@ ability_type god_abilities[MAX_NUM_GODS][MAX_GOD_ABILITIES] =
{ ABIL_NON_ABILITY, ABIL_TSO_DIVINE_SHIELD, ABIL_NON_ABILITY,
ABIL_TSO_CLEANSING_FLAME, ABIL_TSO_SUMMON_DIVINE_WARRIOR },
// Kikubaaqudgha
- { ABIL_KIKU_RECALL_UNDEAD_SLAVES, ABIL_NON_ABILITY,
- ABIL_KIKU_ENSLAVE_UNDEAD, ABIL_NON_ABILITY, ABIL_KIKU_INVOKE_DEATH },
+ { ABIL_KIKU_RECEIVE_CORPSE, ABIL_NON_ABILITY,
+ ABIL_NON_ABILITY, ABIL_NON_ABILITY, ABIL_NON_ABILITY },
// Yredelemnul
{ ABIL_YRED_ANIMATE_REMAINS, ABIL_YRED_RECALL_UNDEAD_SLAVES,
ABIL_YRED_ANIMATE_DEAD, ABIL_YRED_DRAIN_LIFE, ABIL_YRED_ENSLAVE_SOUL },
@@ -242,10 +242,7 @@ static const ability_def Ability_List[] =
8, 0, 150, 4, ABFLAG_NONE },
// Kikubaaqudgha
- { ABIL_KIKU_RECALL_UNDEAD_SLAVES, "Recall Undead Slaves",
- 2, 0, 50, 0, ABFLAG_NONE },
- { ABIL_KIKU_ENSLAVE_UNDEAD, "Enslave Undead", 4, 0, 150, 3, ABFLAG_NONE },
- { ABIL_KIKU_INVOKE_DEATH, "Invoke Death", 4, 0, 250, 3, ABFLAG_NONE },
+ { ABIL_KIKU_RECEIVE_CORPSE, "Recieve Corpses", 5, 0, 1000, 2, ABFLAG_NONE },
// Yredelemnul
{ ABIL_YRED_INJURY_MIRROR, "Injury Mirror", 0, 0, 0, 0, ABFLAG_PIETY },
@@ -677,7 +674,6 @@ static talent _get_talent(ability_type ability, bool check_confused)
break;
case ABIL_ZIN_RECITE:
- case ABIL_KIKU_RECALL_UNDEAD_SLAVES:
case ABIL_BEOGH_RECALL_ORCISH_FOLLOWERS:
case ABIL_OKAWARU_MIGHT:
case ABIL_ELYVILON_LESSER_HEALING_SELF:
@@ -727,7 +723,7 @@ static talent _get_talent(ability_type ability, bool check_confused)
case ABIL_BEOGH_SMITING:
case ABIL_MAKHLEB_MINOR_DESTRUCTION:
case ABIL_SIF_MUNA_FORGET_SPELL:
- case ABIL_KIKU_ENSLAVE_UNDEAD:
+ case ABIL_KIKU_RECEIVE_CORPSE:
case ABIL_YRED_ANIMATE_DEAD:
case ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB:
case ABIL_ELYVILON_GREATER_HEALING_SELF:
@@ -774,7 +770,6 @@ static talent _get_talent(ability_type ability, bool check_confused)
case ABIL_ZIN_SANCTUARY:
case ABIL_TSO_SUMMON_DIVINE_WARRIOR:
- case ABIL_KIKU_INVOKE_DEATH:
case ABIL_YRED_ENSLAVE_SOUL:
case ABIL_ELYVILON_DIVINE_VIGOUR:
case ABIL_LUGONU_ABYSS_ENTER:
@@ -1625,33 +1620,9 @@ static bool _do_ability(const ability_def& abil)
exercise(SK_INVOCATIONS, 8 + random2(10));
break;
- case ABIL_KIKU_RECALL_UNDEAD_SLAVES:
- recall(1);
- exercise(SK_INVOCATIONS, 1);
- break;
-
- case ABIL_KIKU_ENSLAVE_UNDEAD:
- {
- god_acting gdact;
- beam.range = LOS_RADIUS;
- if (!spell_direction(spd, beam))
- return (false);
-
- if (!zapping(ZAP_ENSLAVE_UNDEAD, you.skills[SK_INVOCATIONS] * 8, beam,
- true))
- {
- return (false);
- }
-
- exercise(SK_INVOCATIONS, 5 + random2(5));
- break;
- }
-
- case ABIL_KIKU_INVOKE_DEATH:
- summon_demon_type(MONS_REAPER,
- 20 + you.skills[SK_INVOCATIONS] * 3,
- GOD_KIKUBAAQUDGHA);
- exercise(SK_INVOCATIONS, 10 + random2(14));
+ case ABIL_KIKU_RECEIVE_CORPSE:
+ receive_corpses(you.skills[SK_INVOCATIONS] * 4, you.pos());
+ exercise(SK_INVOCATIONS, (coinflip() ? 3 : 2));
break;
case ABIL_YRED_INJURY_MIRROR:
diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc
index 9aac28b298..0a677af6a2 100644
--- a/crawl-ref/source/effects.cc
+++ b/crawl-ref/source/effects.cc
@@ -203,6 +203,30 @@ int torment_player(int pow, int caster)
hploss = std::max(0, you.hp * (50 - player_prot_life() * 5) / 100 - 1);
}
+ // Kiku protects you from torment to a degree.
+ bool kiku_shielding_player =
+ (you.religion == GOD_KIKUBAAQUDGHA
+ && !player_res_torment()
+ && !player_under_penance()
+ && you.piety > 80
+ && you.gift_timeout == 0); // no protection during pain branding weapon
+
+ if (kiku_shielding_player)
+ {
+ if(!player_res_torment())
+ {
+ if (random2(600) < you.piety) // 13.33% to 33.33% chance
+ {
+ hploss = 0;
+ simple_god_message(" shields you entirely from torment!");
+ } else if (random2(250) < you.piety) { // 24% to 80% chance
+ hploss -= random2(hploss - 1);
+ simple_god_message(" shields you from torment!");
+ }
+ }
+ }
+
+
if (!hploss)
{
mpr("You feel a surge of unholy energy.");
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 318dd194d9..f299733d9f 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -60,9 +60,7 @@ enum ability_type
ABIL_TSO_DIVINE_SHIELD = 120, // 120
ABIL_TSO_CLEANSING_FLAME,
ABIL_TSO_SUMMON_DIVINE_WARRIOR,
- ABIL_KIKU_RECALL_UNDEAD_SLAVES = 130, // 130
- ABIL_KIKU_ENSLAVE_UNDEAD = 132,
- ABIL_KIKU_INVOKE_DEATH,
+ ABIL_KIKU_RECEIVE_CORPSE = 130, // 130
ABIL_YRED_INJURY_MIRROR = 139,
ABIL_YRED_ANIMATE_REMAINS, // 140
ABIL_YRED_RECALL_UNDEAD_SLAVES,
diff --git a/crawl-ref/source/food.cc b/crawl-ref/source/food.cc
index 12089b509c..712ffef62b 100644
--- a/crawl-ref/source/food.cc
+++ b/crawl-ref/source/food.cc
@@ -29,6 +29,7 @@ REVISION("$Rev$");
#include "command.h"
#include "debug.h"
#include "delay.h"
+#include "effects.h"
#include "initfile.h"
#include "invent.h"
#include "items.h"
@@ -360,7 +361,18 @@ static bool _butcher_corpse(int corpse_id, bool first_corpse = true,
&& god_likes_butchery(you.religion);
if (can_sac && !rotten)
+ {
start_delay(DELAY_OFFER_CORPSE, 0, corpse_id);
+
+ // Kiku torments if you butcher a corpse while praying
+ bool kiku_torments = (you.religion == GOD_KIKUBAAQUDGHA && you.piety > 120);
+ if (kiku_torments)
+ {
+ simple_god_message(" inflicts torment against the living!");
+ torment(TORMENT_GENERIC, you.pos());
+ you.piety -= 8 + random2(4); // 8 to 12
+ }
+ }
else
{
if (can_sac && rotten)
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index 2bec5b9aff..554879c05d 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -85,6 +85,12 @@ REVISION("$Rev$");
static void _create_monster_hide(const item_def corpse)
{
+ // receive_corpses() in spells3.cc creates corpses that
+ // are easily scummed for hides. We prevent this by setting
+ // "DoNotDropHide" as an item property of corpses it creates.
+ if (corpse.props.exists("DoNotDropHide"))
+ return;
+
int mons_class = corpse.plus;
int o = get_item_slot();
diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc
index 406219e0bc..ccb4e943d2 100644
--- a/crawl-ref/source/monplace.cc
+++ b/crawl-ref/source/monplace.cc
@@ -1290,6 +1290,74 @@ static monster_type _pick_random_zombie()
return (zombifiable[random2(zombifiable.size())]);
}
+monster_type pick_local_zombifiable_monster_type(int power)
+{
+ // Generates a dummy zombie likely to be found
+ // Ripped wholly from _define_zombie().
+
+ power = std::min(27, power);
+ // How OOD this zombie can be.
+ int relax = 5;
+
+ // Pick an appropriate creature to make a zombie out of,
+ // levelwise. The old code was generating absolutely
+ // incredible OOD zombies.
+ int cls;
+ while (true)
+ {
+ cls = _pick_random_zombie();
+
+ bool ignore_rarity = false;
+ // On certain branches, zombie creation will fail if we use
+ // the mons_rarity() functions, because (for example) there
+ // are NO zombifiable "native" abyss creatures. Other branches
+ // where this is a problem are hell levels and the crypt.
+ // we have to watch for summoned zombies on other levels, too,
+ // such as the Temple, HoB, and Slime Pits.
+ if (you.level_type != LEVEL_DUNGEON
+ || player_in_hell()
+ || player_in_branch(BRANCH_HALL_OF_ZOT)
+ || player_in_branch(BRANCH_VESTIBULE_OF_HELL)
+ || player_in_branch(BRANCH_ECUMENICAL_TEMPLE)
+ || player_in_branch(BRANCH_CRYPT)
+ || player_in_branch(BRANCH_TOMB)
+ || player_in_branch(BRANCH_HALL_OF_BLADES)
+ || player_in_branch(BRANCH_SNAKE_PIT)
+ || player_in_branch(BRANCH_SLIME_PITS)
+ || one_chance_in(1000))
+ {
+ ignore_rarity = true;
+ }
+
+ // Don't make out-of-rarity zombies when we don't have to.
+ if (!ignore_rarity && mons_rarity(cls) == 0)
+ continue;
+
+ // Check for rarity.. and OOD - identical to mons_place()
+ int level, diff, chance;
+
+ level = mons_level(cls) - 4;
+ diff = level - power;
+
+ chance = (ignore_rarity) ? 100
+ : mons_rarity(cls) - (diff * diff) / 2;
+
+ if (power > level - relax && power < level + relax
+ && random2avg(100, 2) <= chance)
+ {
+ break;
+ }
+
+ // Every so often, we'll relax the OOD restrictions. Avoids
+ // infinite loops (if we don't do this, things like creating
+ // a large skeleton on level 1 may hang the game!).
+ if (one_chance_in(5))
+ relax++;
+ }
+
+ return (monster_type)cls;
+}
+
static void _define_zombie(int mid, monster_type ztype, monster_type cs,
int power, coord_def pos)
{
diff --git a/crawl-ref/source/monplace.h b/crawl-ref/source/monplace.h
index 8dfab01b17..10d671382d 100644
--- a/crawl-ref/source/monplace.h
+++ b/crawl-ref/source/monplace.h
@@ -258,6 +258,12 @@ int mons_place(mgen_data mg);
* *********************************************************************** */
int place_monster(mgen_data mg, bool force_pos = false);
+/* ***********************************************************************
+ * Returns a monster class type of a zombie that would be generated
+ * on the player's current level.
+ * *********************************************************************** */
+monster_type pick_local_zombifiable_monster_type(int power);
+
// last updated 12may2000 {dlb}
/* ***********************************************************************
* called from: acr - debug - decks - effects - fight - it_use3 - item_use -
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 37930c052a..78fbe43c8f 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -123,9 +123,9 @@ static const char *_Sacrifice_Messages[NUM_GODS][NUM_PIETY_GAIN] =
},
// Kikubaaqudgha
{
- " slowly rot% away.",
- " rot% away.",
- " rot% away in an instant.",
+ " convulse% and rot% away.",
+ " convulse% madly and rot% away.",
+ " convulse% furiously and rot% away.",
},
// Yredelemnul
{
@@ -218,11 +218,11 @@ const char* god_gain_power_messages[NUM_GODS][MAX_GOD_ABILITIES] =
"channel blasts of cleansing flame",
"summon a divine warrior" },
// Kikubaaqudgha
- { "recall your undead slaves",
- "Kikubaaqudgha is protecting you from some side-effects of death magic.",
- "permanently enslave the undead",
+ { "receive cadavers from Kikubaaqudgha",
"",
- "summon an emissary of Death" },
+ "",
+ "Kikubaaqudgha is protecting you from unholy torment.",
+ "invoke torment by butchering corpses during prayer" },
// Yredelemnul
{ "animate remains",
"recall your undead slaves",
@@ -318,11 +318,11 @@ const char* god_lose_power_messages[NUM_GODS][MAX_GOD_ABILITIES] =
"channel blasts of cleansing flame",
"summon a divine warrior" },
// Kikubaaqudgha
- { "recall your undead slaves",
- "Kikubaaqudgha is no longer shielding you from miscast death magic.",
- "permanently enslave the undead",
+ { "receive cadavers from Kikubaaqudgha",
+ "",
"",
- "summon an emissary of Death" },
+ "Kikubaaqudgha will no longer protect you from unholy torment.",
+ "invoke torment by butchering corpses during prayer" },
// Yredelemnul
{ "animate remains",
"recall your undead slaves",
@@ -620,7 +620,6 @@ std::string get_god_likes(god_type which_god, bool verbose)
case GOD_KIKUBAAQUDGHA:
likes.push_back("you kill living beings");
- likes.push_back("your god-given allies kill living beings");
likes.push_back("your undead slaves kill living beings");
break;
@@ -699,7 +698,6 @@ std::string get_god_likes(god_type which_god, bool verbose)
case GOD_KIKUBAAQUDGHA:
likes.push_back("you kill holy beings");
- likes.push_back("your god-given allies kill holy beings");
likes.push_back("your undead slaves kill holy beings");
break;
@@ -2213,7 +2211,6 @@ static void _do_god_gift(bool prayed_for)
}
break;
- case GOD_KIKUBAAQUDGHA:
case GOD_SIF_MUNA:
case GOD_VEHUMET:
if (you.piety > 160 && random2(you.piety) > 100)
@@ -2222,17 +2219,6 @@ static void _do_god_gift(bool prayed_for)
switch (you.religion)
{
- case GOD_KIKUBAAQUDGHA: // gives death books
- if (!you.had_book[BOOK_NECROMANCY])
- gift = BOOK_NECROMANCY;
- else if (!you.had_book[BOOK_DEATH])
- gift = BOOK_DEATH;
- else if (!you.had_book[BOOK_UNLIFE])
- gift = BOOK_UNLIFE;
- else if (!you.had_book[BOOK_NECRONOMICON])
- gift = BOOK_NECRONOMICON;
- break;
-
case GOD_SIF_MUNA:
gift = OBJ_RANDOM; // Sif Muna - gives any
break;
@@ -3767,15 +3753,22 @@ void gain_piety(int pgn)
if (!you.num_gifts[you.religion])
{
- if (you.religion == GOD_ZIN)
- simple_god_message(" will now cure all your mutations... once.");
- else if (you.religion == GOD_SHINING_ONE
- || you.religion == GOD_LUGONU)
+ switch (you.religion)
{
- mprf("%s will now %s your weapon at an altar... once.",
- god_name(you.religion).c_str(),
- you.religion == GOD_SHINING_ONE ? "bless" : "corrupt",
- MSGCH_GOD, you.religion);
+ case GOD_ZIN:
+ simple_god_message(" will now cure all your mutations... once.");
+ break;
+ case GOD_SHINING_ONE:
+ simple_god_message(" will now bless your weapon at an altar... once.");
+ break;
+ case GOD_KIKUBAAQUDGHA:
+ simple_god_message(" will now enhance your necromancy at an altar... once.");
+ break;
+ case GOD_LUGONU:
+ simple_god_message(" will now corrupt your weapon at an altar... once.");
+ break;
+ default:
+ break;
}
}
@@ -6891,9 +6884,10 @@ static bool _bless_weapon(god_type god, brand_type brand, int colour)
you.wield_change = true;
you.num_gifts[god]++;
std::string desc = old_name + " ";
- desc += (god == GOD_SHINING_ONE ? "blessed by the Shining One" :
- god == GOD_LUGONU ? "corrupted by Lugonu"
- : "touched by the gods");
+ desc += (god == GOD_SHINING_ONE ? "blessed by the Shining One" :
+ god == GOD_LUGONU ? "corrupted by Lugonu" :
+ god == GOD_KIKUBAAQUDGHA ? "bloodied by Kikubaaqudgha"
+ : "touched by the gods");
take_note(Note(NOTE_ID_ITEM, 0, 0,
wpn.name(DESC_NOCAP_A).c_str(), desc.c_str()));
@@ -6916,6 +6910,16 @@ static bool _bless_weapon(god_type god, brand_type brand, int colour)
env.map(*ri).property &= ~(FPROP_BLOODY);
}
+ if (god == GOD_KIKUBAAQUDGHA)
+ {
+ torment(TORMENT_GENERIC, you.pos());
+
+ // Bloodify surrounding squares.
+ for (radius_iterator ri(you.pos(), 2, true, true); ri; ++ri)
+ if (random2(4) != 2) // 75% of tiles will get bloodied
+ env.map(*ri).property |= FPROP_BLOODY;
+ }
+
#ifndef USE_TILE
// Allow extra time for the flash to linger.
delay(1000);
@@ -7028,6 +7032,56 @@ static bool _altar_prayer()
did_bless = _bless_weapon(GOD_LUGONU, SPWPN_DISTORTION, MAGENTA);
}
+ // Kikubaaqudgha blesses weapons with pain, or gives you a Necronomicon
+ if (you.religion == GOD_KIKUBAAQUDGHA
+ && !you.num_gifts[GOD_KIKUBAAQUDGHA]
+ && !player_under_penance()
+ && you.piety > 160)
+ {
+ simple_god_message(
+ " will bless your weapon with pain or grant you the Necronomicon.");
+
+ bool kiku_did_bless_weapon = false;
+
+ const int wpn = get_player_wielded_weapon();
+
+ // Does the player want a pain branding?
+ if (wpn != -1 && get_weapon_brand(you.inv[wpn]) != SPWPN_PAIN)
+ {
+ kiku_did_bless_weapon =
+ _bless_weapon(GOD_KIKUBAAQUDGHA, SPWPN_PAIN, RED);
+ did_bless = kiku_did_bless_weapon;
+ }
+ else mpr("You have no weapon to bloody with pain.");
+
+ // If not, ask if the player wants a Necronomicon
+ if (!kiku_did_bless_weapon)
+ {
+ if (!yesno("Do you wish to receive the Necronomicon?", true, 'n'))
+ return(false);
+
+ int thing_created = items(1, OBJ_BOOKS, BOOK_NECRONOMICON, true, 1,
+ MAKE_ITEM_RANDOM_RACE,
+ 0, 0, you.religion);
+ if (thing_created == NON_ITEM)
+ return(false);
+
+ move_item_to_grid( &thing_created, you.pos() );
+
+ if (thing_created != NON_ITEM)
+ {
+ simple_god_message(" grants you a gift!");
+ more();
+
+ you.num_gifts[you.religion]++;
+ did_bless = true;
+ take_note(Note(NOTE_GOD_GIFT, you.religion));
+ mitm[thing_created].inscription = "god gift";
+ }
+ }
+ return(did_bless); // Return early so we don't offer our Necronomicon to Kiku
+ } // end kiku gifting
+
offer_items();
return (did_bless);
@@ -7654,7 +7708,8 @@ bool god_likes_butchery(god_type god)
return (god == GOD_OKAWARU
|| god == GOD_MAKHLEB
|| god == GOD_TROG
- || god == GOD_LUGONU);
+ || god == GOD_LUGONU
+ || (god == GOD_KIKUBAAQUDGHA && you.piety > 120));
}
bool god_hates_butchery(god_type god)
diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc
index 83f58fbb99..501b8aabdd 100644
--- a/crawl-ref/source/spells3.cc
+++ b/crawl-ref/source/spells3.cc
@@ -645,6 +645,91 @@ bool cast_summon_horrible_things(int pow, god_type god)
return (count > 0);
}
+bool receive_corpses(int pow, coord_def where)
+{
+ // pow = invocations * 4, ranges from 0 to 108
+ mprf(MSGCH_DIAGNOSTICS, "Receive_corpses power: %d", pow);
+ // Kiku gives branch-appropriate corpses (like shadow creatures)
+ int expected_extra_corpses = (pow / 36); // 1 at 0 inv, 7 at 7 inv
+ int corpse_delivery_radius = 3;
+
+ // We should get the same # of corpses in a hallway as in an open room.
+ int spaces_for_corpses = 0;
+ for (radius_iterator ri(where, corpse_delivery_radius, true, true, true); ri; ++ri)
+ if (mons_class_can_pass(MONS_HUMAN, grd(*ri)))
+ spaces_for_corpses++;
+
+ int percent_chance_a_square_receives_extra_corpse = // can be > 100
+ (int)(
+ ((float) expected_extra_corpses) /
+ ((float) spaces_for_corpses)
+ * 100.0
+ );
+
+ int corpses_generated = 0;
+
+ for (radius_iterator ri(where, corpse_delivery_radius, false, true, false); ri; ++ri)
+ {
+
+ bool square_is_walkable = mons_class_can_pass(MONS_HUMAN, grd(*ri));
+ bool square_is_player_square = (*ri == where);
+ bool square_gets_corpse =
+ (random2(100) < percent_chance_a_square_receives_extra_corpse) ||
+ (square_is_player_square && random2(100) < 97);
+ if (!square_is_walkable || !square_gets_corpse)
+ continue;
+
+ corpses_generated++;
+
+ // Find an appropriate monster corpse
+ monster_type mon_type = MONS_PROGRAM_BUG;
+ int adjusted_power = 0;
+ for (int i = 0; i < 200 && !mons_class_can_be_zombified(mon_type); i++)
+ {
+ adjusted_power = std::min(pow/4,random2(random2(pow)));
+ mon_type = pick_local_zombifiable_monster_type(adjusted_power);
+ }
+
+ // Create corpse object
+ monsters dummy;
+ dummy.type = mon_type;
+ int index_of_corpse_created = get_item_slot();
+ if (mons_genus(mon_type) == MONS_HYDRA)
+ dummy.number = random2(20) + 1;
+ int valid_corpse = fill_out_corpse(&dummy, mitm[index_of_corpse_created], false);
+ if (!valid_corpse)
+ {
+ mitm[index_of_corpse_created].clear();
+ continue;
+ }
+ mitm[index_of_corpse_created].props["DoNotDropHide"] = true;
+
+ ASSERT(valid_corpse >= 0);
+
+ // Higher power means fresher corpses.
+ // One out of ten corpses will always be rotten.
+ // (Perhaps this should be different for ghouls.)
+ int rottedness = 200 -
+ ((random2(10) == 5) ?
+ random2(175 - pow) :
+ random2(100 + random2(75)));
+ mitm[index_of_corpse_created].special = rottedness;
+
+ // Place the corpse.
+ move_item_to_grid( &index_of_corpse_created, *ri );
+ }
+
+ if (corpses_generated)
+ {
+ simple_god_message(" delivers you corpses!");
+ maybe_update_stashes();
+ return true;
+ } else {
+ simple_god_message(" can find no living being to slaughter for you!");
+ return false;
+ }
+}
+
static bool _animatable_remains(const item_def& item)
{
return (item.base_type == OBJ_CORPSES
diff --git a/crawl-ref/source/spells3.h b/crawl-ref/source/spells3.h
index 394918eea8..4bdc143a88 100644
--- a/crawl-ref/source/spells3.h
+++ b/crawl-ref/source/spells3.h
@@ -50,6 +50,8 @@ bool cast_summon_greater_demon(int pow, god_type god = GOD_NO_GOD);
bool cast_shadow_creatures(god_type god = GOD_NO_GOD);
bool cast_summon_horrible_things(int pow, god_type god = GOD_NO_GOD);
+bool receive_corpses(int pow, coord_def where);
+
void equip_undead(const coord_def &a, int corps, int monster, int monnum);
int animate_remains(const coord_def &a, corpse_type class_allowed,
beh_type beha, unsigned short hitting,