summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/fight.cc21
-rw-r--r--crawl-ref/source/mgrow.cc10
-rw-r--r--crawl-ref/source/mon-util.cc2
-rw-r--r--crawl-ref/source/monstuff.cc38
-rw-r--r--crawl-ref/source/mstuff2.cc6
-rw-r--r--crawl-ref/source/religion.cc98
-rw-r--r--crawl-ref/source/religion.h4
-rw-r--r--crawl-ref/source/view.cc59
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