summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/enum.h2
-rw-r--r--crawl-ref/source/religion.cc136
-rw-r--r--crawl-ref/source/religion.h2
-rw-r--r--crawl-ref/source/view.cc63
4 files changed, 200 insertions, 3 deletions
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index fbfb3181b1..a77826dd1e 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -1865,7 +1865,7 @@ enum monster_flag_type
// or that the player has inspected with ?
MF_BANISHED = 0x200, // Monster that has been banished.
MF_HARD_RESET = 0x400, // Summoned, should not drop gear on reset
- MF_CONVERT_ATTEMPT = 0x800, // Orcs only: seen player and was converted
+ MF_CONVERT_ATTEMPT = 0x800, // Seen player and was converted
// (or not)
MF_WAS_IN_VIEW = 0x1000, // Was in view during previous turn
MF_BAND_MEMBER = 0x2000 // Created as a member of a band
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index a369a7edcc..b5ecc698d8 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -360,6 +360,7 @@ void dec_penance(god_type god, int val);
void dec_penance(int val);
void inc_penance(god_type god, int val);
void inc_penance(int val);
+static bool holy_beings_reconvert();
static bool beogh_followers_abandon_you(void);
static void dock_piety(int piety_loss, int penance);
@@ -404,6 +405,11 @@ void dec_penance(god_type god, int val)
take_note(Note(NOTE_MOLLIFY_GOD, god));
you.penance[god] = 0;
+ // When you've worked through all your penance, you get
+ // another chance to make hostile holy beings neutral.
+ if (is_good_god(you.religion))
+ holy_beings_reconvert();
+
// bonuses now once more effective
if ( god == GOD_BEOGH && you.religion == GOD_BEOGH)
you.redraw_armour_class = true;
@@ -1791,6 +1797,11 @@ void gain_piety(int pgn)
}
learned_something_new(TUT_NEW_ABILITY);
}
+
+ // When you gain a piety level, you get another chance to
+ // make hostile holy beings neutral.
+ if (is_good_god(you.religion))
+ holy_beings_reconvert();
}
}
@@ -1808,7 +1819,7 @@ void gain_piety(int pgn)
do_god_gift(false);
}
-static bool is_evil_weapon(const item_def& weap)
+bool is_evil_weapon(const item_def& weap)
{
if (weap.base_type != OBJ_WEAPONS)
return false;
@@ -2694,6 +2705,61 @@ void divine_retribution( god_type god )
dec_penance( god, 1 + random2(3) );
}
+static bool holy_beings_on_level_reconvert()
+{
+ bool success = false;
+
+ for ( int i = 0; i < MAX_MONSTERS; ++i )
+ {
+ monsters *monster = &menv[i];
+ if (monster->type != -1
+ && mons_class_holiness(monster->type) == MH_HOLY)
+ {
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "Reconverting: %s on level %d, branch %d",
+ monster->name(DESC_PLAIN).c_str(),
+ static_cast<int>(you.your_level),
+ static_cast<int>(you.where_are_you));
+#endif
+
+ // If you worship a good god, you get another chance to make
+ // hostile holy beings neutral.
+ if (is_good_god(you.religion))
+ {
+ if ((monster->flags & MF_CONVERT_ATTEMPT)
+ && monster->attitude == ATT_HOSTILE)
+ {
+ monster->flags &= ~MF_CONVERT_ATTEMPT;
+
+ success = true;
+ }
+ }
+
+ // If you worship an exil god, you make all neutral and
+ // friendly holy beings hostile.
+ if (is_evil_god(you.religion))
+ {
+ if (monster->attitude == ATT_NEUTRAL ||
+ monster->attitude == ATT_FRIENDLY)
+ {
+ monster->attitude = ATT_HOSTILE;
+ monster->behaviour = BEH_HOSTILE;
+ // for now CREATED_FRIENDLY stays
+
+ success = true;
+ }
+ }
+ }
+ }
+
+ return success;
+}
+
+static bool holy_beings_reconvert()
+{
+ return apply_to_all_dungeons(holy_beings_on_level_reconvert);
+}
+
static bool orcish_followers_on_level_abandon_you()
{
bool success = false;
@@ -2881,6 +2947,45 @@ void beogh_idol_revenge()
}
}
+static void good_god_holy_being_conversion_speech(
+ std::ostream &chan,
+ const monsters *holy)
+{
+ switch (random2(3))
+ {
+ case 0:
+ chan << " is calmed by your holy aura.";
+ break;
+ case 1:
+ chan << " relaxes its fighting stance.";
+ break;
+ case 2:
+ chan << " salutes you.";
+ break;
+ }
+ chan << std::endl;
+
+ if (!one_chance_in(3))
+ {
+ std::ostream& tchan = msg::streams(MSGCH_TALK);
+ tchan << holy->pronoun(PRONOUN_CAP) << " ";
+ switch (random2(3))
+ {
+ case 0:
+ tchan << "shouts, \"Continue thy quest, mortal!\"";
+ break;
+ case 1:
+ tchan << "says, \"Forge ahead, servant of "
+ << god_name(you.religion) << "!\"";
+ break;
+ case 2:
+ tchan << "says, \"Carry on, mortal.\"";
+ break;
+ }
+ tchan << std::endl;
+ }
+}
+
static void beogh_orc_emergency_conversion_speech(
std::ostream &chan,
const monsters *orc)
@@ -2950,6 +3055,24 @@ static void beogh_orc_spontaneous_conversion_speech(
}
}
+void good_god_convert_holy(monsters *holy)
+{
+ ASSERT(mons_class_holiness(holy->type) == MH_HOLY);
+
+ if (player_monster_visible(holy)) // show reaction
+ {
+ std::ostream& chan = msg::streams(MSGCH_MONSTER_ENCHANT);
+ chan << holy->name(DESC_CAP_THE);
+
+ good_god_holy_being_conversion_speech(chan, holy);
+ }
+
+ holy->attitude = ATT_NEUTRAL;
+
+ // to avoid immobile "followers"
+ behaviour_event(holy, ME_ALERT, MHITNOT);
+}
+
void beogh_convert_orc(monsters *orc, bool emergency)
{
ASSERT(mons_species(orc->type) == MONS_ORC);
@@ -3599,9 +3722,18 @@ void god_pitch(god_type which_god)
if (is_evil_god(you.religion))
{
+ // When you leave one of the good gods for an evil god, you make
+ // all neutral and friendly holy beings hostile.
+ if (you.penance[GOD_ZIN] || you.penance[GOD_SHINING_ONE] ||
+ you.penance[GOD_ELYVILON])
+ {
+ if (holy_beings_reconvert())
+ mpr("The divine host forsakes you.", MSGCH_MONSTER_ENCHANT);
+ }
+
// Note: Using worshipped[] we could make this sort of grudge
// permanent instead of based off of penance. -- bwr
- if (you.penance[GOD_SHINING_ONE] > 0)
+ if (you.penance[GOD_SHINING_ONE])
{
inc_penance(GOD_SHINING_ONE, 30);
god_speaks(GOD_SHINING_ONE,
diff --git a/crawl-ref/source/religion.h b/crawl-ref/source/religion.h
index 04df6bddfa..76eae4ae65 100644
--- a/crawl-ref/source/religion.h
+++ b/crawl-ref/source/religion.h
@@ -63,7 +63,9 @@ void divine_retribution(god_type god);
bool beogh_water_walk();
void beogh_idol_revenge();
+void good_god_convert_holy(monsters *holy);
void beogh_convert_orc(monsters *orc, bool emergency);
+bool is_evil_weapon(const item_def& weap);
bool ely_destroy_weapons();
bool trog_burn_books();
bool tso_stab_safe_monster(const actor *act);
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 19e042eead..11dd9ae101 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -742,6 +742,68 @@ static bool mons_was_seen_this_turn(const monsters *mons)
monsters_seen_this_turn.end());
}
+static void good_god_follower_convert(monsters *monster)
+{
+ if (you.is_undead || you.species == SP_DEMONSPAWN)
+ return;
+
+ const bool is_holy = mons_class_holiness(monster->type) == MH_HOLY;
+ // for followers of good gods, decide whether holy beings will be
+ // neutral towards you
+ if (is_good_god(you.religion)
+ && monster->foe == MHITYOU
+ && !(monster->flags & MF_CONVERT_ATTEMPT)
+ && is_holy
+ && !mons_neutral(monster)
+ && !mons_friendly(monster)
+ && mons_player_visible(monster) && !mons_is_sleeping(monster)
+ && !mons_is_confused(monster) && !mons_is_paralysed(monster)
+ && !mons_is_caught(monster))
+ {
+ monster->flags |= MF_CONVERT_ATTEMPT;
+
+ if (you.piety > random2(200) && !you.penance[you.religion])
+ {
+ int wpn = you.equip[EQ_WEAPON];
+ if (wpn != -1
+ && you.inv[wpn].base_type == OBJ_WEAPONS
+ && is_evil_weapon( you.inv[wpn] )
+ && coinflip()) // 50% chance of conversion failing
+ {
+ msg::stream << monster->name(DESC_CAP_THE)
+ << " glares at your weapon."
+ << std::endl;
+ return;
+ }
+ good_god_convert_holy(monster);
+ stop_running();
+ }
+ }
+ else if (is_holy
+ && is_evil_god(you.religion)
+ && (monster->attitude == ATT_NEUTRAL
+ || monster->attitude == ATT_FRIENDLY)
+ && (monster->flags & MF_CONVERT_ATTEMPT)
+ && mons_player_visible(monster) && !mons_is_sleeping(monster)
+ && !mons_is_confused(monster) && !mons_is_paralysed(monster)
+ && !mons_is_caught(monster))
+ { // reconversion if evil god
+
+ monster->attitude = ATT_HOSTILE;
+ behaviour_event(monster, ME_ALERT, MHITYOU);
+ // CREATED_FRIENDLY stays -> no piety bonus on killing these
+
+ // give message only sometimes
+ if (player_monster_visible(monster) && random2(4))
+ {
+ msg::streams(MSGCH_MONSTER_ENCHANT)
+ << monster->name(DESC_CAP_THE)
+ << " turns against you."
+ << std::endl;
+ }
+ }
+}
+
void beogh_follower_convert(monsters *monster, bool orc_hit)
{
if (you.species != SP_HILL_ORC)
@@ -1086,6 +1148,7 @@ void monster_grid(bool do_updates)
monsters_seen_this_turn.insert(monster);
}
+ good_god_follower_convert(monster);
beogh_follower_convert(monster);
}
}