diff options
-rw-r--r-- | crawl-ref/source/fight.cc | 21 | ||||
-rw-r--r-- | crawl-ref/source/mgrow.cc | 10 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 38 | ||||
-rw-r--r-- | crawl-ref/source/mstuff2.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/religion.cc | 98 | ||||
-rw-r--r-- | crawl-ref/source/religion.h | 4 | ||||
-rw-r--r-- | crawl-ref/source/view.cc | 59 |
8 files changed, 167 insertions, 71 deletions
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc index a41fbe6564..9bc54edda8 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -552,26 +552,27 @@ bool melee_attack::player_attack() // always upset monster regardless of damage behaviour_event(def, ME_WHACK, MHITYOU); - if (player_hurt_monster()) + player_hurt_monster(); + + if (damage_done > 0 || !defender_visible) + player_announce_hit(); + else if (damage_done <= 0) + no_damage_message = + make_stringf("You %s %s.", + attack_verb.c_str(), + defender->name(DESC_NOCAP_THE).c_str()); + + if (damage_done) player_exercise_combat_skills(); if (player_check_monster_died()) return (true); player_sustain_passive_damage(); - - if (damage_done < 1) - no_damage_message = - make_stringf("You %s %s.", - attack_verb.c_str(), - defender->name(DESC_NOCAP_THE).c_str()); } else player_warn_miss(); - if (did_hit && (damage_done > 0 || !player_monster_visible(def))) - player_announce_hit(); - if (did_hit && player_monattk_hit_effects(false)) return (true); diff --git a/crawl-ref/source/mgrow.cc b/crawl-ref/source/mgrow.cc index a620132677..ea08169523 100644 --- a/crawl-ref/source/mgrow.cc +++ b/crawl-ref/source/mgrow.cc @@ -13,9 +13,9 @@ #include "stuff.h" // Base experience required by a monster to reach HD 1. -const int monster_xp_base = 8; +const int monster_xp_base = 10; // Experience multiplier to determine the experience needed to gain levels. -const int monster_xp_multiplier = 120; +const int monster_xp_multiplier = 130; const mons_experience_levels mexplevs; // Monster growing-up sequences. You can specify a chance to indicate that @@ -70,7 +70,7 @@ mons_experience_levels::mons_experience_levels() delta = std::min( std::max(delta, monster_xp_base * monster_xp_multiplier / 100), - 3000); + 2500); experience += delta; } } @@ -143,6 +143,10 @@ bool monsters::level_up() if (max_hit_points < 1000) { int hpboost = hit_dice > 3? max_hit_points / 8 : max_hit_points / 4; +#ifdef DEBUG_DIAGNOSTICS + mprf(MSGCH_DIAGNOSTICS, "%s: HD: %d, maxhp: %d, boost: %d", + name(DESC_PLAIN).c_str(), hit_dice, max_hit_points, hpboost); +#endif if (hpboost < 2) hpboost = 2; if (hpboost > 20) diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 2e6d55ce3a..aafec13798 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -1489,6 +1489,7 @@ void define_monster(monsters &mons) mons.speed_increment = 70; mons.number = monnumber; mons.flags = 0L; + mons.experience = 0L; mons.colour = col; mons_load_spells( &mons, spells ); @@ -3814,6 +3815,7 @@ void monsters::reset() inv.init(NON_ITEM); flags = 0; + experience = 0L; type = -1; hit_points = 0; max_hit_points = 0; diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index aee12608a2..3fa1b16f82 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -428,10 +428,48 @@ static bool is_pet_kill(killer_type killer, int i) && (me.who == KC_YOU || me.who == KC_FRIENDLY)); } +static bool monster_avoided_death(monsters *monster, killer_type killer, int i) +{ + if (monster->hit_points < -25 + || monster->hit_points < -monster->max_hit_points + || monster->max_hit_points <= 0 + || monster->hit_dice < 1) + return (false); + + // Orcs may convert to Beogh under threat of death. + if (YOU_KILL(killer) + && mons_near(monster) + && !mons_friendly(monster) + && mons_species(monster->type) == MONS_ORC + && you.species == SP_HILL_ORC && you.religion == GOD_BEOGH + && !player_under_penance() && you.piety >= 75) + { +#ifdef DEBUG_DIAGNOSTICS + mprf(MSGCH_DIAGNOSTICS, "Death convert attempt on %s, HD: %d, " + "your xl: %d", + monster->name(DESC_PLAIN).c_str(), + monster->hit_dice, + you.experience_level); +#endif + if (random2(you.piety) > 30 + && random2(you.experience_level) >= random2(monster->hit_dice) + // bias beaten-up-conversion towards the stronger orcs. + && random2(monster->hit_dice) > 2) + { + beogh_convert_orc(monster); + return (true); + } + } + return (false); +} + void monster_die(monsters *monster, killer_type killer, int i, bool silent) { if (monster->type == -1) return; + + if (!silent && monster_avoided_death(monster, killer, i)) + return; if (mons_is_caught(monster)) { diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc index bef3fa7ddd..bd118219df 100644 --- a/crawl-ref/source/mstuff2.cc +++ b/crawl-ref/source/mstuff2.cc @@ -2210,7 +2210,9 @@ bool orange_statue_effects(monsters *mons) bool orc_battle_cry(monsters *chief) { const actor *foe = chief->get_foe(); - if (foe && !silenced(chief->x, chief->y) + if (foe + && (foe != &you || !mons_friendly(chief)) + && !silenced(chief->x, chief->y) && chief->can_see(foe) && coinflip()) { @@ -2234,7 +2236,7 @@ bool orc_battle_cry(monsters *chief) if (ench.ench == ENCH_NONE || ench.degree < level) { const int dur = - random_range(9, 15) * speed_to_duration(mons->speed); + random_range(12, 20) * speed_to_duration(mons->speed); if (ench.ench != ENCH_NONE) { diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index 63ad249a3f..d5231756b3 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -2792,6 +2792,104 @@ void beogh_idol_revenge() } } +static void beogh_orc_emergency_conversion_speech( + std::ostream &chan, + const monsters *orc) +{ + switch (random2(3)) + { + case 0: chan << " surrenders. "; break; + case 1: chan << " falls to " << orc->pronoun(PRONOUN_NOCAP_POSSESSIVE) + << " knees. "; break; + case 2: chan << " raises " << orc->pronoun(PRONOUN_NOCAP_POSSESSIVE) + << " hands in surrender. "; break; + } + chan << std::endl; + + static const char *mercy_message[] = + { + " shouts, \"I'll follow you, let me live!\"", + " says, \"You must be the Messiah, I see it now!\"", + " yells, \"Beogh is my god, I swear it!\"" + }; + msg::streams(MSGCH_TALK) << orc->pronoun(PRONOUN_CAP) + << RANDOM_ELEMENT(mercy_message) + << std::endl; +} + +static void beogh_orc_spontaneous_conversion_speech( + std::ostream &chan, + const monsters *orc) +{ + switch (random2(3)) + { + case 0: + chan << " stares at you in amazement and kneels."; + break; + case 1: + chan << " relaxes " << orc->pronoun(PRONOUN_NOCAP_POSSESSIVE) + << " fighting stance and smiles at you."; + break; + case 2: + chan << " falls on " << orc->pronoun(PRONOUN_NOCAP_POSSESSIVE) + << " knees before you."; + break; + } + chan << std::endl; + + if (!one_chance_in(3)) + { + std::ostream& tchan = msg::streams(MSGCH_TALK); + tchan << orc->pronoun(PRONOUN_CAP) << " "; + switch (random2(4)) + { + case 0: + tchan << "shouts, \"I'll follow thee gladly!\""; + break; + case 1: + tchan << "shouts, \"Surely Beogh must have " + "sent you!\""; + break; + case 2: + tchan << "asks, \"Are you our saviour?\""; + break; + case 3: + tchan << "says, \"I'm so glad you are here now.\""; + break; + } + tchan << std::endl; + } +} + +void beogh_convert_orc(monsters *orc) +{ + ASSERT(mons_species(orc->type) == MONS_ORC); + + if (player_monster_visible(orc)) // show reaction + { + std::ostream& chan = msg::streams(MSGCH_MONSTER_ENCHANT); + chan << orc->name(DESC_CAP_THE); + + if (orc->hit_points <= 0) + beogh_orc_emergency_conversion_speech(chan, orc); + else + beogh_orc_spontaneous_conversion_speech(chan, orc); + } + + orc->attitude = ATT_FRIENDLY; + + // not really "created" friendly, but should it become + // hostile later on, it won't count as a good kill + orc->flags |= MF_CREATED_FRIENDLY; + orc->flags |= MF_GOD_GIFT; + + if (orc->hit_points <= 0) + orc->hit_points = std::min(random_range(1, 4), orc->max_hit_points); + + // to avoid immobile "followers" + behaviour_event(orc, ME_ALERT, MHITNOT); +} + void excommunication(void) { const god_type old_god = you.religion; diff --git a/crawl-ref/source/religion.h b/crawl-ref/source/religion.h index 0a11005dfc..26dad22080 100644 --- a/crawl-ref/source/religion.h +++ b/crawl-ref/source/religion.h @@ -19,6 +19,7 @@ #define MAX_PIETY 200 class actor; +class monsters; bool is_priest_god(god_type god); void simple_god_message( const char *event, god_type which_deity = GOD_NO_GOD ); @@ -46,8 +47,9 @@ void divine_retribution(god_type god); bool beogh_water_walk(); void beogh_idol_revenge(); +void beogh_convert_orc(monsters *orc); bool ely_destroy_weapons(); bool trog_burn_books(); - bool tso_stab_safe_monster(const actor *act); + #endif diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index ff8ad57325..774d8818fb 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -58,6 +58,7 @@ #include "mon-util.h" #include "overmap.h" #include "player.h" +#include "religion.h" #include "skills2.h" #include "stuff.h" #include "spells4.h" @@ -678,7 +679,7 @@ inline static void beogh_follower_convert(monsters *monster) const int hd = monster->hit_dice; if (you.piety >= 75 && !you.penance[GOD_BEOGH] && - random2(you.piety/18) + random2( you.skills[SK_INVOCATIONS]-4 ) + random2(you.piety / 15) + random2(12) > random2(hd) + hd + random2(5)) { int wpn = you.equip[EQ_WEAPON]; @@ -692,59 +693,7 @@ inline static void beogh_follower_convert(monsters *monster) << std::endl; return; } - - if (player_monster_visible(monster)) // show reaction - { - std::ostream& chan = msg::streams(MSGCH_MONSTER_ENCHANT); - chan << monster->name(DESC_CAP_THE); - - switch (random2(3)) - { - case 0: - chan << " stares at you in amazement and kneels."; - break; - case 1: - chan << " relaxes its fighting stance and smiles at you."; - break; - case 2: - chan << " falls on its knees before you."; - break; - } - chan << std::endl; - - if (!one_chance_in(3)) - { - std::ostream& tchan = msg::streams(MSGCH_TALK); - tchan << "He "; - switch (random2(4)) - { - case 0: - tchan << "shouts, \"I'll follow thee gladly!\""; - break; - case 1: - tchan << "shouts, \"Surely Beogh must have " - "sent you!\""; - break; - case 2: - tchan << "asks, \"Are you our saviour?\""; - break; - case 3: - tchan << "says, \"I'm so glad you are here now.\""; - break; - } - tchan << std::endl; - } - } - - monster->attitude = ATT_FRIENDLY; - monster->behaviour = BEH_GOD_GIFT; // alternative to BEH_FRIENDLY - // not really "created" friendly, but should it become - // hostile later on, it won't count as a good kill - monster->flags |= MF_CREATED_FRIENDLY; - monster->flags |= MF_GOD_GIFT; - - // to avoid immobile "followers" - behaviour_event(monster, ME_ALERT, MHITYOU); + beogh_convert_orc(monster); } } else if (is_orc @@ -757,7 +706,7 @@ inline static void beogh_follower_convert(monsters *monster) { // reconversion if no longer Beogh monster->attitude = ATT_HOSTILE; - monster->behaviour = BEH_HOSTILE; + behaviour_event(monster, ME_ALERT, MHITYOU); // CREATED_FRIENDLY stays -> no piety bonus on killing these // give message only sometimes |