diff options
-rw-r--r-- | crawl-ref/source/beam.cc | 21 | ||||
-rw-r--r-- | crawl-ref/source/beam.h | 4 | ||||
-rw-r--r-- | crawl-ref/source/dat/descript/monsters.txt | 4 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/externs.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/fight.cc | 29 | ||||
-rw-r--r-- | crawl-ref/source/mon-data.h | 11 | ||||
-rw-r--r-- | crawl-ref/source/mon-pick.cc | 11 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 5 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/mstuff2.cc | 8 | ||||
-rw-r--r-- | crawl-ref/source/player.cc | 21 | ||||
-rw-r--r-- | crawl-ref/source/player.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/religion.cc | 118 |
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); } |