[Hide Content]From 50ae6f6f433529a03aa6440ebdf26e63dc88d19d Mon Sep 17 00:00:00 2001
From: Shayne Halvorson <N78291@gmail.com>
Date: Fri, 7 Oct 2011 20:11:19 -0400
Subject: [PATCH] Add Death's Door and Regeneration as monster spells; give both to Nergalle.
---
crawl-ref/source/enum.h | 1 +
crawl-ref/source/mon-act.cc | 2 +-
crawl-ref/source/mon-cast.cc | 44 +++++++++++++++++++++++++++++++++-------
crawl-ref/source/mon-ench.cc | 16 +++++++++++++-
crawl-ref/source/mon-info.cc | 6 +++++
crawl-ref/source/mon-info.h | 1 +
crawl-ref/source/mon-spll.h | 4 +-
crawl-ref/source/mon-stuff.cc | 6 ++++-
crawl-ref/source/monster.cc | 4 ++-
9 files changed, 69 insertions(+), 15 deletions(-)
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 833b690..2b734f1 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -1464,6 +1464,7 @@ enum enchant_type
ENCH_INNER_FLAME,
ENCH_ROUSED, // Monster has been roused to greatness
ENCH_BREATH_WEAPON, // just a simple timer for dragon breathweapon spam
+ ENCH_DEATHS_DOOR,
// Update enchantment names in monster.cc when adding or removing
// enchantments.
NUM_ENCHANTMENTS
diff --git a/crawl-ref/source/mon-act.cc b/crawl-ref/source/mon-act.cc
index 6842c24..62f88f8 100644
--- a/crawl-ref/source/mon-act.cc
+++ b/crawl-ref/source/mon-act.cc
@@ -103,7 +103,7 @@ static void _monster_regenerate(monster* mons)
if (crawl_state.disables[DIS_MON_REGEN])
return;
- if (mons->has_ench(ENCH_SICK) ||
+ if (mons->has_ench(ENCH_SICK) || mons->has_ench(ENCH_DEATHS_DOOR) ||
(!mons_can_regenerate(mons) && !(mons->has_ench(ENCH_REGENERATION))))
{
return;
diff --git a/crawl-ref/source/mon-cast.cc b/crawl-ref/source/mon-cast.cc
index 226ac65..19800c1 100644
--- a/crawl-ref/source/mon-cast.cc
+++ b/crawl-ref/source/mon-cast.cc
@@ -1118,6 +1118,7 @@ bool setup_mons_cast(monster* mons, bolt &pbolt, spell_type spell_cast,
case SPELL_SUMMON_DRAGON:
case SPELL_SUMMON_HYDRA:
case SPELL_FIRE_SUMMON:
+ case SPELL_DEATHS_DOOR:
return (true);
default:
if (check_validity)
@@ -2084,16 +2085,17 @@ void mons_cast_spectral_orcs(monster* mons)
const int abj = 3;
monster* orc;
- monster_type mon = MONS_ORC;
- if (coinflip())
- mon = MONS_ORC_WARRIOR;
- else if (one_chance_in(3))
- mon = MONS_ORC_KNIGHT;
- else if (one_chance_in(10))
- mon = MONS_ORC_WARLORD;
-
for (int i = random2(3) + 1; i > 0; --i)
{
+
+ monster_type mon = MONS_ORC;
+ if (coinflip())
+ mon = MONS_ORC_WARRIOR;
+ else if (one_chance_in(3))
+ mon = MONS_ORC_KNIGHT;
+ else if (one_chance_in(10))
+ mon = MONS_ORC_WARLORD;
+
// Use the original monster type as the zombified type here, to
// get the proper stats from it.
created = create_monster(
@@ -3594,6 +3596,25 @@ void mons_cast(monster* mons, bolt &pbolt, spell_type spell_cast,
spell_cast, mons->pos(), mons->foe, 0, god));
}
return;
+
+ case SPELL_DEATHS_DOOR:
+ if (!mons->has_ench(ENCH_DEATHS_DOOR))
+ {
+ const int dur = BASELINE_DELAY * 2 * mons->skill(SK_NECROMANCY);
+ mprf("%s stands defiantly in death's doorway!", mons->name(DESC_CAP_THE).c_str());
+ mons->hit_points = std::max(std::min(mons->hit_points, mons->skill(SK_NECROMANCY)), 1);
+ mons->add_ench(mon_enchant(ENCH_DEATHS_DOOR, 0, mons, dur));
+ }
+ return;
+
+ case SPELL_REGENERATION:
+ {
+ mprf("%s's wounds begin to heal before your eyes!", mons->name(DESC_CAP_THE).c_str());
+ const int dur = BASELINE_DELAY
+ * std::min(5 + roll_dice(2, (mons->hit_dice * 10) / 3 + 1), 100);
+ mons->add_ench(mon_enchant(ENCH_REGENERATION, 0, mons, dur));
+ return;
+ }
}
// If a monster just came into view and immediately cast a spell,
@@ -4158,6 +4179,8 @@ bool ms_low_hitpoint_cast(const monster* mon, spell_type monspell)
case SPELL_INK_CLOUD:
if (mon->type == MONS_KRAKEN)
return true;
+ case SPELL_DEATHS_DOOR:
+ return !mon->has_ench(ENCH_DEATHS_DOOR);
default:
return !targ_adj && spell_typematch(monspell, SPTYP_SUMMONING);
}
@@ -4428,6 +4451,11 @@ bool ms_waste_of_time(const monster* mon, spell_type monspell)
ret = true;
}
break;
+
+ case SPELL_DEATHS_DOOR:
+ if (mon->has_ench(ENCH_DEATHS_DOOR))
+ ret = true;
+ break;
case SPELL_NO_SPELL:
ret = true;
diff --git a/crawl-ref/source/mon-ench.cc b/crawl-ref/source/mon-ench.cc
index 1f8a920..780a661 100644
--- a/crawl-ref/source/mon-ench.cc
+++ b/crawl-ref/source/mon-ench.cc
@@ -686,6 +686,16 @@ void monster::remove_enchantment_effect(const mon_enchant &me, bool quiet)
behaviour_event(this, ME_EVAL);
break;
+ case ENCH_DEATHS_DOOR:
+ if (!quiet)
+ simple_monster_message(this, " is no longer invulnerable.");
+ break;
+
+ case ENCH_REGENERATION:
+ if (!quiet)
+ simple_monster_message(this, " is no longer regenerating.");
+ break;
+
default:
break;
}
@@ -788,7 +798,7 @@ void monster::timeout_enchantments(int levels)
case ENCH_FEAR_INSPIRING: case ENCH_REGENERATION: case ENCH_RAISED_MR:
case ENCH_MIRROR_DAMAGE: case ENCH_STONESKIN: case ENCH_LIQUEFYING:
case ENCH_SILVER_CORONA: case ENCH_DAZED: case ENCH_FAKE_ABJURATION:
- case ENCH_ROUSED: case ENCH_BREATH_WEAPON:
+ case ENCH_ROUSED: case ENCH_BREATH_WEAPON: case ENCH_DEATHS_DOOR:
lose_ench_levels(i->second, levels);
break;
@@ -993,6 +1003,7 @@ void monster::apply_enchantment(const mon_enchant &me)
case ENCH_DUMB:
case ENCH_MAD:
case ENCH_BREATH_WEAPON:
+ case ENCH_DEATHS_DOOR:
decay_enchantment(me);
break;
@@ -1694,7 +1705,7 @@ static const char *enchant_names[] =
#endif
"liquefying", "tornado", "fake_abjuration",
"dazed", "mute", "blind", "dumb", "mad", "silver_corona", "recite timer",
- "inner flame", "roused", "breath timer", "buggy",
+ "inner flame", "roused", "breath timer", "deaths_door", "buggy",
};
static const char *_mons_enchantment_name(enchant_type ench)
@@ -1842,6 +1853,7 @@ int mon_enchant::calc_duration(const monster* mons,
case ENCH_REGENERATION:
case ENCH_RAISED_MR:
case ENCH_MIRROR_DAMAGE:
+ case ENCH_DEATHS_DOOR:
cturn = 300 / _mod_speed(25, mons->speed);
break;
case ENCH_SLOW:
diff --git a/crawl-ref/source/mon-info.cc b/crawl-ref/source/mon-info.cc
index cbf207b..a9f7e70 100644
--- a/crawl-ref/source/mon-info.cc
+++ b/crawl-ref/source/mon-info.cc
@@ -136,6 +136,8 @@ static monster_info_flags ench_to_mb(const monster& mons, enchant_type ench)
return MB_INNER_FLAME;
case ENCH_BREATH_WEAPON:
return MB_BREATH_WEAPON;
+ case ENCH_DEATHS_DOOR:
+ return MB_DEATHS_DOOR;
default:
return NUM_MB_FLAGS;
}
@@ -1171,6 +1173,10 @@ std::vector<std::string> monster_info::attributes() const
v.push_back("stupefied");
if (is(MB_MAD))
v.push_back("lost in madness");
+ if (is(MB_DEATHS_DOOR))
+ v.push_back("standing in death's doorway");
+ if (is(MB_REGENERATION))
+ v.push_back("regenerating");
return v;
}
diff --git a/crawl-ref/source/mon-info.h b/crawl-ref/source/mon-info.h
index f564b92..fe18872 100644
--- a/crawl-ref/source/mon-info.h
+++ b/crawl-ref/source/mon-info.h
@@ -77,6 +77,7 @@ enum monster_info_flags
MB_UMBRAED,
MB_ROUSED,
MB_BREATH_WEAPON,
+ MB_DEATHS_DOOR,
NUM_MB_FLAGS
};
diff --git a/crawl-ref/source/mon-spll.h b/crawl-ref/source/mon-spll.h
index d05d27a..e58ae41 100644
--- a/crawl-ref/source/mon-spll.h
+++ b/crawl-ref/source/mon-spll.h
@@ -1587,10 +1587,10 @@
{
SPELL_BOLT_OF_DRAINING,
SPELL_SUMMON_SPECTRAL_ORCS,
- SPELL_NO_SPELL,
+ SPELL_REGENERATION,
SPELL_DISPEL_UNDEAD,
SPELL_HASTE_OTHER,
- SPELL_TELEPORT_SELF
+ SPELL_DEATHS_DOOR
}
},
diff --git a/crawl-ref/source/mon-stuff.cc b/crawl-ref/source/mon-stuff.cc
index cbdc88a..2a1f8c3 100644
--- a/crawl-ref/source/mon-stuff.cc
+++ b/crawl-ref/source/mon-stuff.cc
@@ -4563,7 +4563,11 @@ void debuff_monster(monster* mon)
ENCH_CHARM,
ENCH_PARALYSIS,
ENCH_PETRIFYING,
- ENCH_PETRIFIED
+ ENCH_PETRIFIED,
+ ENCH_REGENERATION,
+ ENCH_STICKY_FLAME,
+ ENCH_TP,
+ ENCH_INNER_FLAME
};
// Dispel all magical enchantments...
diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc
index c367d37..fc73c42 100644
--- a/crawl-ref/source/monster.cc
+++ b/crawl-ref/source/monster.cc
@@ -3693,7 +3693,9 @@ int monster::hurt(const actor *agent, int amount, beam_type flavour,
}
if (amount != INSTANT_DEATH)
- if (petrified())
+ if (this->has_ench(ENCH_DEATHS_DOOR))
+ return (0);
+ else if (petrified())
amount /= 3;
else if (petrifying())
amount = amount * 1000 / 1732;
--
1.6.5.1