summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/beam.cc21
-rw-r--r--crawl-ref/source/beam.h4
-rw-r--r--crawl-ref/source/dat/descript/monsters.txt4
-rw-r--r--crawl-ref/source/enum.h3
-rw-r--r--crawl-ref/source/externs.h3
-rw-r--r--crawl-ref/source/fight.cc29
-rw-r--r--crawl-ref/source/mon-data.h11
-rw-r--r--crawl-ref/source/mon-pick.cc11
-rw-r--r--crawl-ref/source/mon-util.cc5
-rw-r--r--crawl-ref/source/mon-util.h3
-rw-r--r--crawl-ref/source/mstuff2.cc8
-rw-r--r--crawl-ref/source/player.cc21
-rw-r--r--crawl-ref/source/player.h2
-rw-r--r--crawl-ref/source/religion.cc118
14 files changed, 167 insertions, 76 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 88ce887423..15cc03ae90 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -80,7 +80,6 @@
static FixedArray < bool, 19, 19 > explode_map;
// Helper functions (some of these should probably be public).
-static void _sticky_flame_monster(int mn, kill_category who, int hurt_final);
static bool _affects_wall(const bolt &beam, int wall_feature);
static bool _isBouncy(bolt &beam, unsigned char gridtype);
static int _beam_source(const bolt &beam);
@@ -2774,8 +2773,14 @@ bool poison_monster( monsters *monster,
return (new_pois.degree > old_pois.degree);
}
-// Actually napalms a monster (w/ message).
-void _sticky_flame_monster(int mn, kill_category who, int levels)
+// Actually napalms the player.
+void sticky_flame_player()
+{
+ you.duration[DUR_LIQUID_FLAMES] += random2avg(7, 3) + 1;
+}
+
+// Actually napalms a monster (with message).
+void sticky_flame_monster(int mn, kill_category who, int levels)
{
monsters *monster = &menv[mn];
@@ -4237,13 +4242,11 @@ static int _affect_player( bolt &beam, item_def *item )
}
// Sticky flame.
- if (beam.name == "sticky flame"
- && (you.species != SP_MOTTLED_DRACONIAN
- || you.experience_level < 6))
+ if (beam.name == "sticky flame")
{
- if (!player_equip(EQ_BODY_ARMOUR, ARM_MOTTLED_DRAGON_ARMOUR))
+ if (!player_res_sticky_flame())
{
- you.duration[DUR_LIQUID_FLAMES] += random2avg(7, 3) + 1;
+ sticky_flame_player();
was_affected = true;
}
}
@@ -4790,7 +4793,7 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item)
{
int levels = std::min(4, 1 + random2(hurt_final) / 2);
- _sticky_flame_monster(tid, _whose_kill(beam), levels);
+ sticky_flame_monster(tid, _whose_kill(beam), levels);
}
// Handle missile effects.
diff --git a/crawl-ref/source/beam.h b/crawl-ref/source/beam.h
index e062a78c5e..5c5959c7ae 100644
--- a/crawl-ref/source/beam.h
+++ b/crawl-ref/source/beam.h
@@ -169,6 +169,10 @@ public:
killer_type killer() const;
};
+void sticky_flame_player();
+
+void sticky_flame_monster(int mn, kill_category who, int hurt_final);
+
dice_def calc_dice( int num_dice, int max_damage );
// Test if the to-hit (attack) beats evasion (defence).
diff --git a/crawl-ref/source/dat/descript/monsters.txt b/crawl-ref/source/dat/descript/monsters.txt
index 94b7601703..b4069a71d0 100644
--- a/crawl-ref/source/dat/descript/monsters.txt
+++ b/crawl-ref/source/dat/descript/monsters.txt
@@ -578,6 +578,10 @@ firedrake
A small dragon, puffing clouds of smoke.
%%%%
+flaming corpse
+
+The remains of an adventurer who was burned to death, it now rushes madly through the dungeon seeking others to ignite.
+%%%%
flayed ghost
A hideous undead creature, with torn skin hanging from an emaciated body.
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 70e7ca616f..96952719ca 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -1701,7 +1701,8 @@ enum monster_type // (int) menv[].type
MONS_SIMULACRUM_SMALL,
MONS_SIMULACRUM_LARGE,
MONS_MERFOLK,
- MONS_MERMAID, // 194
+ MONS_MERMAID,
+ MONS_FLAMING_CORPSE, // 195
//jmf: end new monsters
MONS_WHITE_IMP = 220, // 220
MONS_LEMURE,
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index 04c5ebb6da..2fa78812ee 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -331,6 +331,7 @@ public:
virtual mon_holy_type holiness() const = 0;
virtual int res_fire() const = 0;
+ virtual int res_sticky_flame() const = 0;
virtual int res_steam() const = 0;
virtual int res_cold() const = 0;
virtual int res_elec() const = 0;
@@ -885,6 +886,7 @@ public:
mon_holy_type holiness() const;
int res_fire() const;
+ int res_sticky_flame() const;
int res_steam() const;
int res_cold() const;
int res_elec() const;
@@ -1226,6 +1228,7 @@ public:
mon_holy_type holiness() const;
int res_fire() const;
+ int res_sticky_flame() const;
int res_steam() const;
int res_cold() const;
int res_elec() const;
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc
index f0ce3aaaa4..f9b7c40db2 100644
--- a/crawl-ref/source/fight.cc
+++ b/crawl-ref/source/fight.cc
@@ -1885,6 +1885,7 @@ static bool is_boolean_resist(beam_type flavour)
switch (flavour)
{
case BEAM_ELECTRICITY:
+ case BEAM_NAPALM:
return (true);
default:
return (false);
@@ -1928,9 +1929,9 @@ int resist_adjust_damage(actor *defender, beam_type flavour,
const bool monster = (defender->atype() == ACT_MONSTER);
- // Check if this is a resist that pretends to be boolean for
- // damage purposes - only electricity at the moment, raw poison
- // damage uses the normal formula.
+ // Check if this is a resist that pretends to be boolean for damage
+ // damage purposes - only electricity and sticky flame (napalm) at
+ // the moment, raw poison damage uses the normal formula.
int res_base = (is_boolean_resist(flavour) ? 2 : 1);
const int resistible_fraction = get_resistible_fraction(flavour);
@@ -3833,6 +3834,28 @@ void melee_attack::mons_apply_attack_flavour(const mon_attack_def &attk)
defender->go_berserk(false);
break;
+
+ case AF_NAPALM:
+ if (one_chance_in(20) || (damage_done > 0 && one_chance_in(3)))
+ {
+ if (needs_message)
+ {
+ mprf("%s %s covered in liquid flames%s",
+ def_name(DESC_CAP_THE).c_str(),
+ defender->conj_verb("are").c_str(),
+ special_attack_punctuation().c_str());
+ }
+
+ if (defender->atype() == ACT_PLAYER)
+ sticky_flame_player();
+ else
+ {
+ sticky_flame_monster(monster_index(def),
+ mons_friendly(atk) ? KC_FRIENDLY : KC_OTHER,
+ std::min(4, 1 + random2(atk->hit_dice) / 2));
+ }
+ }
+ break;
}
}
diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h
index d5e806273b..8319ccbd80 100644
--- a/crawl-ref/source/mon-data.h
+++ b/crawl-ref/source/mon-data.h
@@ -1613,6 +1613,17 @@ static monsterentry mondata[] = {
HT_LAND, 12, MOVE_ENERGY(20), MONUSE_NOTHING, SIZE_TINY
},
+{
+ MONS_FLAMING_CORPSE, 'z', LIGHTRED, "flaming corpse",
+ M_EVIL,
+ MR_RES_POISON | MR_VUL_COLD | mrd(MR_RES_FIRE, 3) | MR_RES_STICKY_FLAME,
+ 0, 17, MONS_FLAMING_CORPSE, MONS_FLAMING_CORPSE, MH_UNDEAD, -4,
+ { {AT_HIT, AF_NAPALM, 20}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
+ { 8, 3, 5, 0 },
+ 12, 13, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SCREAM, I_NORMAL,
+ HT_LAND, 12, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_MEDIUM
+},
+
// angelic beings ('A')
{
MONS_ANGEL, 'A', WHITE, "Angel",
diff --git a/crawl-ref/source/mon-pick.cc b/crawl-ref/source/mon-pick.cc
index e02a013110..5ea034be96 100644
--- a/crawl-ref/source/mon-pick.cc
+++ b/crawl-ref/source/mon-pick.cc
@@ -201,6 +201,7 @@ bool mons_abyss(int mcls)
case MONS_EYE_OF_DEVASTATION:
case MONS_EYE_OF_DRAINING:
case MONS_FIRE_ELEMENTAL:
+ case MONS_FLAMING_CORPSE:
case MONS_FLAYED_GHOST:
case MONS_FLYING_SKULL:
case MONS_FREEZING_WRAITH:
@@ -348,6 +349,7 @@ int mons_rare_abyss(int mcls)
return 15;
case MONS_EYE_OF_DRAINING:
+ case MONS_FLAMING_CORPSE:
case MONS_LICH:
return 14;
@@ -474,6 +476,7 @@ bool mons_pan(int mcls)
case MONS_JELLY:
case MONS_SLIME_CREATURE:
// undead
+ case MONS_FLAMING_CORPSE:
case MONS_FLAYED_GHOST:
case MONS_FLYING_SKULL:
case MONS_FREEZING_WRAITH:
@@ -597,6 +600,7 @@ int mons_dis_level(int mcls)
case MONS_BLUE_DEVIL:
case MONS_DANCING_WEAPON:
+ case MONS_FLAMING_CORPSE:
case MONS_ICE_DEVIL:
case MONS_ICE_DRAGON:
case MONS_LICH:
@@ -664,6 +668,7 @@ int mons_dis_rare(int mcls)
case MONS_ICE_DEVIL:
return 30;
+ case MONS_FLAMING_CORPSE:
case MONS_FLAYED_GHOST:
case MONS_SKELETON_LARGE:
case MONS_NECROPHAGE:
@@ -748,6 +753,7 @@ int mons_gehenna_level(int mcls)
break;
case MONS_EFREET:
+ case MONS_FLAMING_CORPSE:
case MONS_FLAYED_GHOST:
case MONS_HELLION:
case MONS_TORMENTOR:
@@ -816,6 +822,7 @@ int mons_gehenna_rare(int mcls)
case MONS_HELL_HOUND:
return 41;
+ case MONS_FLAMING_CORPSE:
case MONS_FLAYED_GHOST:
case MONS_PHANTOM:
return 32;
@@ -1640,6 +1647,7 @@ int mons_crypt_level(int mcls)
case MONS_NECROMANCER:
case MONS_PULSATING_LUMP:
case MONS_FLAYED_GHOST:
+ case MONS_FREEZING_WRAITH:
case MONS_GHOUL:
case MONS_ROTTING_HULK:
case MONS_WRAITH:
@@ -1647,6 +1655,7 @@ int mons_crypt_level(int mcls)
mlev += 3;
break;
+ case MONS_FLAMING_CORPSE:
case MONS_SPECTRAL_WARRIOR:
case MONS_SHADOW_WRAITH:
case MONS_VAMPIRE_KNIGHT:
@@ -1724,8 +1733,10 @@ int mons_crypt_rare(int mcls)
case MONS_FLYING_SKULL:
case MONS_FLAYED_GHOST:
+ case MONS_FREEZING_WRAITH:
return 13;
+ case MONS_FLAMING_CORPSE:
case MONS_HUNGRY_GHOST:
return 12;
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 40cffed0c8..024676cb51 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -4810,6 +4810,11 @@ int monsters::res_fire() const
return (mons_res_fire(this));
}
+int monsters::res_sticky_flame() const
+{
+ return (mons_res_sticky_flame(this));
+}
+
int monsters::res_steam() const
{
return (mons_res_steam(this));
diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h
index aabc2142c7..30b0cd0bc0 100644
--- a/crawl-ref/source/mon-util.h
+++ b/crawl-ref/source/mon-util.h
@@ -80,7 +80,8 @@ enum mon_attack_flavour
AF_VAMPIRIC,
AF_KLOWN,
AF_DISTORT,
- AF_RAGE
+ AF_RAGE,
+ AF_NAPALM
};
// properties of the monster class (other than resists/vulnerabilities)
diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc
index 6aca0af5ed..cc36629e20 100644
--- a/crawl-ref/source/mstuff2.cc
+++ b/crawl-ref/source/mstuff2.cc
@@ -461,10 +461,10 @@ static monster_type _pick_undead_summon()
{
MONS_NECROPHAGE, MONS_GHOUL, MONS_HUNGRY_GHOST, MONS_FLAYED_GHOST,
MONS_ZOMBIE_SMALL, MONS_SKELETON_SMALL, MONS_SIMULACRUM_SMALL,
- MONS_FLYING_SKULL, MONS_MUMMY, MONS_VAMPIRE, MONS_WIGHT, MONS_WRAITH,
- MONS_SHADOW_WRAITH, MONS_FREEZING_WRAITH, MONS_SPECTRAL_WARRIOR,
- MONS_ZOMBIE_LARGE, MONS_SKELETON_LARGE, MONS_SIMULACRUM_LARGE,
- MONS_SHADOW
+ MONS_FLYING_SKULL, MONS_FLAMING_CORPSE, MONS_MUMMY, MONS_VAMPIRE,
+ MONS_WIGHT, MONS_WRAITH, MONS_SHADOW_WRAITH, MONS_FREEZING_WRAITH,
+ MONS_SPECTRAL_WARRIOR, MONS_ZOMBIE_LARGE, MONS_SKELETON_LARGE,
+ MONS_SIMULACRUM_LARGE, MONS_SHADOW
};
return undead[random2(sizeof(undead) / sizeof(*undead))];
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index 11cc2a9088..6b55e10e24 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -1285,6 +1285,22 @@ int player_res_fire(bool calc_unid, bool temp, bool items)
return (rf);
}
+int player_res_sticky_flame(bool calc_unid, bool temp, bool items)
+{
+ int res = 0;
+
+ if (you.species == SP_MOTTLED_DRACONIAN && you.experience_level > 5)
+ res++;
+
+ if (items && player_equip(EQ_BODY_ARMOUR, ARM_MOTTLED_DRAGON_ARMOUR))
+ res++;
+
+ if (res > 1)
+ res = 1;
+
+ return (res);
+}
+
int player_res_steam(bool calc_unid, bool temp, bool items)
{
int res = 0;
@@ -6336,6 +6352,11 @@ int player::res_fire() const
return (player_res_fire());
}
+int player::res_sticky_flame() const
+{
+ return (player_res_sticky_flame());
+}
+
int player::res_steam() const
{
return (player_res_steam());
diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h
index 6cef3c124f..807483aa4b 100644
--- a/crawl-ref/source/player.h
+++ b/crawl-ref/source/player.h
@@ -194,6 +194,8 @@ int player_res_electricity(bool calc_unid = true, bool temp = true,
* *********************************************************************** */
int player_res_fire(bool calc_unid = true, bool temp = true,
bool items = true);
+int player_res_sticky_flame(bool calc_unid = true, bool temp = true,
+ bool items = true);
int player_res_steam(bool calc_unid = true, bool temp = true,
bool items = true);
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index bbf6fc2972..fc1d1eb32c 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -810,45 +810,68 @@ static void _inc_gift_timeout(int val)
} // end inc_gift_timeout()
// Only Yredelemnul and Okawaru use this for now.
-static monster_type _random_servant(god_type god)
+static int _random_servants(god_type god, bool force_hostile = false)
{
// error trapping {dlb}
- monster_type thing_called = MONS_PROGRAM_BUG;
+ monster_type mon = MONS_PROGRAM_BUG;
+ int how_many = 1;
int temp_rand = random2(100);
switch (god)
{
case GOD_YREDELEMNUL:
// undead
- thing_called = ((temp_rand > 66) ? MONS_WRAITH : // 33%
- (temp_rand > 52) ? MONS_WIGHT : // 13%
- (temp_rand > 40) ? MONS_SPECTRAL_WARRIOR : // 11%
- (temp_rand > 31) ? MONS_ROTTING_HULK : // 8%
- (temp_rand > 23) ? MONS_SKELETAL_WARRIOR : // 7%
- (temp_rand > 16) ? MONS_VAMPIRE : // 6%
- (temp_rand > 10) ? MONS_GHOUL : // 5%
- (temp_rand > 4) ? MONS_MUMMY // 5%
- : MONS_FLAYED_GHOST); // 4%
+ mon = ((temp_rand > 74) ? MONS_WRAITH : // 25%
+ (temp_rand > 64) ? MONS_WIGHT : // 10%
+ (temp_rand > 54) ? MONS_FLYING_SKULL : // 10%
+ (temp_rand > 45) ? MONS_SPECTRAL_WARRIOR : // 9%
+ (temp_rand > 38) ? MONS_ROTTING_HULK : // 7%
+ (temp_rand > 32) ? MONS_SKELETAL_WARRIOR : // 6%
+ (temp_rand > 27) ? MONS_FREEZING_WRAITH : // 5%
+ (temp_rand > 22) ? MONS_FLAMING_CORPSE : // 5%
+ (temp_rand > 18) ? MONS_GHOUL : // 5%
+ (temp_rand > 13) ? MONS_MUMMY : // 5%
+ (temp_rand > 9) ? MONS_VAMPIRE : // 4%
+ (temp_rand > 5) ? MONS_FLAYED_GHOST : // 4%
+ (temp_rand > 2) ? MONS_SKELETAL_DRAGON // 3%
+ : MONS_DEATH_COB); // 2%
+
+ if (mon == MONS_FLYING_SKULL)
+ how_many = 2 + random2(4);
break;
case GOD_OKAWARU:
// warriors
- thing_called = ((temp_rand > 84) ? MONS_ORC_WARRIOR : // 15%
- (temp_rand > 69) ? MONS_ORC_KNIGHT : // 14%
- (temp_rand > 59) ? MONS_NAGA_WARRIOR : // 9%
- (temp_rand > 49) ? MONS_CENTAUR_WARRIOR : // 9%
- (temp_rand > 39) ? MONS_STONE_GIANT : // 9%
- (temp_rand > 29) ? MONS_FIRE_GIANT : // 9%
- (temp_rand > 19) ? MONS_FROST_GIANT : // 9%
- (temp_rand > 9) ? MONS_CYCLOPS : // 9%
- (temp_rand > 4) ? MONS_HILL_GIANT // 4%
- : MONS_TITAN); // 4%
-
+ mon = ((temp_rand > 84) ? MONS_ORC_WARRIOR : // 15%
+ (temp_rand > 69) ? MONS_ORC_KNIGHT : // 14%
+ (temp_rand > 59) ? MONS_NAGA_WARRIOR : // 9%
+ (temp_rand > 49) ? MONS_CENTAUR_WARRIOR : // 9%
+ (temp_rand > 39) ? MONS_STONE_GIANT : // 9%
+ (temp_rand > 29) ? MONS_FIRE_GIANT : // 9%
+ (temp_rand > 19) ? MONS_FROST_GIANT : // 9%
+ (temp_rand > 9) ? MONS_CYCLOPS : // 9%
+ (temp_rand > 4) ? MONS_HILL_GIANT // 4%
+ : MONS_TITAN); // 4%
break;
default:
break;
}
- return (thing_called);
+ int count = 0;
+
+ for (int i = 0; i < how_many; ++i)
+ {
+ if (create_monster(
+ mgen_data(mon,
+ !force_hostile ? BEH_FRIENDLY : BEH_HOSTILE,
+ 0, you.pos(),
+ !force_hostile ? you.pet_target : MHITYOU,
+ 0, god)) != -1)
+ {
+ count++;
+ }
+ }
+
+ return (count);
}
static const item_def* _find_missile_launcher(int skill)
@@ -1764,14 +1787,13 @@ static void _do_god_gift(bool prayed_for)
case GOD_YREDELEMNUL:
if (random2(you.piety) > 80 && one_chance_in(5))
{
- monster_type mon = _random_servant(GOD_YREDELEMNUL);
+ int how_many = _random_servants(GOD_YREDELEMNUL);
- if (create_monster(
- mgen_data(mon, BEH_FRIENDLY, 0,
- you.pos(), you.pet_target,
- 0, GOD_YREDELEMNUL)) != -1)
+ if (how_many > 0)
{
- simple_god_message(" grants you an undead servant!");
+ simple_god_message(
+ how_many > 1 ? " grants you several undead servants!"
+ : " grants you an undead servant!");
more();
_inc_gift_timeout(4 + random2avg(7, 2));
you.num_gifts[you.religion]++;
@@ -3685,20 +3707,11 @@ static bool _yredelemnul_retribution()
if (random2(you.experience_level) > 4)
{
- int count = 0;
int how_many = 1 + random2(1 + (you.experience_level / 5));
+ int count = 0;
- for (int i = 0; i < how_many; ++i)
- {
- monster_type punisher = _random_servant(GOD_YREDELEMNUL);
-
- if (create_monster(
- mgen_data::hostile_at(punisher,
- you.pos(), 0, 0, true, GOD_YREDELEMNUL)) != -1)
- {
- count++;
- }
- }
+ for (; how_many > 0; --how_many)
+ count += _random_servants(GOD_YREDELEMNUL, true);
simple_god_message(count > 1 ? " sends servants to punish you." :
count > 0 ? " sends a servant to punish you." :
@@ -3935,25 +3948,14 @@ static bool _okawaru_retribution()
// warrior theme
const god_type god = GOD_OKAWARU;
- bool success = false;
- const int how_many = 1 + (you.experience_level / 5);
-
- for (int i = 0; i < how_many; ++i)
- {
- monster_type punisher = _random_servant(GOD_OKAWARU);
+ int how_many = 1 + (you.experience_level / 5);
+ int count = 0;
- if (create_monster(
- mgen_data::hostile_at(punisher,
- you.pos(), 0, 0, true, GOD_OKAWARU)) != -1)
- {
- success = true;
- }
- }
+ for (; how_many > 0; --how_many)
+ count += _random_servants(GOD_OKAWARU, true);
- simple_god_message(success ?
- " sends forces against you!" :
- "'s forces are busy with other wars.",
- god);
+ simple_god_message(count > 0 ? " sends forces against you!"
+ : "'s forces are busy with other wars.", god);
return (true);
}