summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-11-28 18:14:42 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-11-28 18:14:42 +0000
commit95259b9b62799b2e5fe00f8833c28b8a96879e49 (patch)
tree0aa0cf24af159eb64efdef6a587ec0997c17d966 /crawl-ref
parent990a102363ff38bf95ed78baf777f2a7ba57e62c (diff)
downloadcrawl-ref-95259b9b62799b2e5fe00f8833c28b8a96879e49.tar.gz
crawl-ref-95259b9b62799b2e5fe00f8833c28b8a96879e49.zip
[1836426] Fixed penance message sequence for beams, clamped penance messages at one per turn. (Penance message sequence for melee combat not fixed yet.)
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2926 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/acr.cc3
-rw-r--r--crawl-ref/source/beam.cc14
-rw-r--r--crawl-ref/source/mon-util.cc2
-rw-r--r--crawl-ref/source/monstuff.cc15
-rw-r--r--crawl-ref/source/religion.cc156
-rw-r--r--crawl-ref/source/religion.h27
-rw-r--r--crawl-ref/source/spells2.cc2
7 files changed, 159 insertions, 60 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index ee535c1371..e061525409 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -2747,7 +2747,8 @@ static void world_reacts()
if (you.num_turns != -1)
{
- you.num_turns++;
+ if (you.num_turns < LONG_MAX)
+ you.num_turns++;
if (env.turns_on_level < INT_MAX)
env.turns_on_level++;
update_turn_count();
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index e5f1e4a706..a310f77c8c 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -3874,18 +3874,22 @@ static int affect_monster(bolt &beam, monsters *mon)
// elementals on their side - the elementals won't give a sh*t,
// after all)
+ god_conduct_trigger conduct;
+ conduct.enabled = false;
+
if (nasty_beam(mon, beam))
{
if (YOU_KILL(beam.thrower) && hurt_final > 0)
{
- const bool okay = beam.aux_source == "reading a scroll of immolation"
+ const bool okay =
+ beam.aux_source == "reading a scroll of immolation"
&& !beam.effect_known;
-
+
if (mons_friendly(mon))
- did_god_conduct( DID_ATTACK_FRIEND, 5, !okay, mon );
+ conduct.set( DID_ATTACK_FRIEND, 5, !okay, mon );
if (mons_holiness( mon ) == MH_HOLY)
- did_god_conduct( DID_ATTACK_HOLY, mon->hit_dice, !okay, mon );
+ conduct.set( DID_ATTACK_HOLY, mon->hit_dice, !okay, mon );
}
if (you.religion == GOD_BEOGH && mons_species(mon->type) == MONS_ORC
@@ -3945,6 +3949,8 @@ static int affect_monster(bolt &beam, monsters *mon)
update_hurt_or_helped(beam, mon);
+ conduct.enabled = true;
+
// the beam hit.
if (mons_near(mon))
{
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 27420cc7ba..0d6b99075c 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -4732,7 +4732,7 @@ void monsters::scale_hp(int num, int den)
kill_category monsters::kill_alignment() const
{
- return (attitude == ATT_FRIENDLY? KC_FRIENDLY : KC_OTHER);
+ return (mons_friendly(this)? KC_FRIENDLY : KC_OTHER);
}
bool monsters::sicken(int amount)
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 87f3b4c336..a851a5e73d 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -640,32 +640,33 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent)
{
if (mons_holiness(monster) == MH_NATURAL)
did_god_conduct(DID_KILL_LIVING,
- monster->hit_dice);
+ monster->hit_dice, true, monster);
if (mons_holiness(monster) == MH_UNDEAD)
did_god_conduct(DID_KILL_UNDEAD,
- monster->hit_dice);
+ monster->hit_dice, true, monster);
if (mons_holiness(monster) == MH_DEMONIC)
did_god_conduct(DID_KILL_DEMON,
- monster->hit_dice);
+ monster->hit_dice, true, monster);
if (mons_class_flag(monster->type, M_EVIL))
did_god_conduct(DID_KILL_NATURAL_EVIL,
- monster->hit_dice);
+ monster->hit_dice, true, monster);
// jmf: Trog hates wizards
if (mons_is_magic_user(monster))
did_god_conduct(DID_KILL_WIZARD,
- monster->hit_dice);
+ monster->hit_dice, true, monster);
// Beogh hates priests of other gods.
if (mons_class_flag(monster->type, M_PRIEST))
did_god_conduct(DID_KILL_PRIEST,
- monster->hit_dice);
+ monster->hit_dice, true, monster);
if (mons_holiness(monster) == MH_HOLY)
- did_god_conduct(DID_KILL_ANGEL, monster->hit_dice);
+ did_god_conduct(DID_KILL_ANGEL, monster->hit_dice,
+ true, monster);
}
// Divine health and mp restoration doesn't happen when killing
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index ff16387d9c..dc40b23e7e 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -359,6 +359,7 @@ void dec_penance(int val);
void inc_penance(god_type god, int val);
void inc_penance(int val);
static bool followers_abandon_you(void); // Beogh
+static void dock_piety(int piety_loss, int penance);
bool is_evil_god(god_type god)
{
@@ -1325,25 +1326,12 @@ bool did_god_conduct( conduct_type thing_done, int level, bool known,
break;
case DID_ATTACK_FRIEND:
- switch (you.religion)
+ if (god_hates_attacking_friend(you.religion, victim))
{
- case GOD_ZIN:
- case GOD_SHINING_ONE:
- case GOD_ELYVILON:
- case GOD_OKAWARU:
- case GOD_BEOGH: // added penance to avoid killings for loot
- // deliberately no extra punishment for killing
- if (you.religion != GOD_BEOGH ||
- (victim && mons_species(victim->id()) == MONS_ORC))
- {
- piety_change = -level;
- if (known)
- penance = level * 3;
- ret = true;
- }
- break;
- default:
- break;
+ piety_change = -level;
+ if (known)
+ penance = level * 3;
+ ret = true;
}
break;
@@ -1412,6 +1400,9 @@ bool did_god_conduct( conduct_type thing_done, int level, bool known,
case GOD_TROG:
case GOD_BEOGH:
case GOD_LUGONU:
+ if (god_hates_attacking_friend(you.religion, victim))
+ break;
+
simple_god_message(" accepts your kill.");
ret = true;
if (random2(level + 18 - you.experience_level / 2) > 5)
@@ -1432,6 +1423,9 @@ bool did_god_conduct( conduct_type thing_done, int level, bool known,
case GOD_VEHUMET:
case GOD_MAKHLEB:
case GOD_LUGONU:
+ if (god_hates_attacking_friend(you.religion, victim))
+ break;
+
simple_god_message(" accepts your kill.");
ret = true;
// Holy gods are easier to please this way
@@ -1452,6 +1446,9 @@ bool did_god_conduct( conduct_type thing_done, int level, bool known,
case GOD_SHINING_ONE:
case GOD_OKAWARU:
case GOD_MAKHLEB:
+ if (god_hates_attacking_friend(you.religion, victim))
+ break;
+
simple_god_message(" accepts your kill.");
ret = true;
// Holy gods are easier to please this way
@@ -1466,7 +1463,8 @@ bool did_god_conduct( conduct_type thing_done, int level, bool known,
break;
case DID_KILL_PRIEST:
- if (you.religion == GOD_BEOGH)
+ if (you.religion == GOD_BEOGH
+ && !god_hates_attacking_friend(you.religion, victim))
{
simple_god_message(" appreciates your killing of a "
"heretic priest.");
@@ -1477,7 +1475,8 @@ bool did_god_conduct( conduct_type thing_done, int level, bool known,
break;
case DID_KILL_WIZARD:
- if (you.religion == GOD_TROG)
+ if (you.religion == GOD_TROG
+ && !god_hates_attacking_friend(you.religion, victim))
{
// hooking this up, but is it too good?
// enjoy it while you can -- bwr
@@ -1684,31 +1683,7 @@ bool did_god_conduct( conduct_type thing_done, int level, bool known,
if (piety_change > 0)
gain_piety( piety_change );
else
- {
- const int piety_loss = -piety_change;
-
- if (piety_loss)
- {
- // output guilt message:
- mprf( "You feel%sguilty.",
- (piety_loss == 1) ? " a little " :
- (piety_loss < 5) ? " " :
- (piety_loss < 10) ? " very "
- : " extremely " );
-
- lose_piety( piety_loss );
- }
-
- if (you.piety < 1)
- excommunication();
- else if (penance) // only if still in religion
- {
- god_speaks( you.religion,
- "\"You will pay for your transgression, mortal!\"" );
-
- inc_penance( penance );
- }
- }
+ dock_piety(-piety_change, penance);
#if DEBUG_DIAGNOSTICS
if (ret)
@@ -1739,6 +1714,42 @@ bool did_god_conduct( conduct_type thing_done, int level, bool known,
return (ret);
}
+static void dock_piety(int piety_loss, int penance)
+{
+ static long last_piety_lecture = -1L;
+ static long last_penance_lecture = -1L;
+
+ if (piety_loss <= 0 && penance <= 0)
+ return;
+
+ if (piety_loss)
+ {
+ if (last_piety_lecture != you.num_turns)
+ {
+ // output guilt message:
+ mprf( "You feel%sguilty.",
+ (piety_loss == 1) ? " a little " :
+ (piety_loss < 5) ? " " :
+ (piety_loss < 10) ? " very "
+ : " extremely " );
+ }
+
+ last_piety_lecture = you.num_turns;
+ lose_piety( piety_loss );
+ }
+
+ if (you.piety < 1)
+ excommunication();
+ else if (penance) // only if still in religion
+ {
+ if (last_penance_lecture != you.num_turns)
+ god_speaks( you.religion,
+ "\"You will pay for your transgression, mortal!\"" );
+ last_penance_lecture = you.num_turns;
+ inc_penance( penance );
+ }
+}
+
void gain_piety(int pgn)
{
// Xom uses piety differently...
@@ -3129,6 +3140,27 @@ void altar_prayer(void)
offer_items();
} // end altar_prayer()
+bool god_hates_attacking_friend(god_type god, const actor *fr)
+{
+ if (!fr || fr->kill_alignment() != KC_FRIENDLY)
+ return (false);
+
+ switch (god)
+ {
+ case GOD_ZIN:
+ case GOD_SHINING_ONE:
+ case GOD_ELYVILON:
+ case GOD_OKAWARU:
+ return (true);
+
+ case GOD_BEOGH: // added penance to avoid killings for loot
+ return (fr && mons_species(fr->id()) == MONS_ORC);
+
+ default:
+ return (false);
+ }
+}
+
static bool god_likes_items(god_type god)
{
switch (god)
@@ -3709,3 +3741,37 @@ bool tso_stab_safe_monster(const actor *act)
const mon_holy_type holy = act->holiness();
return (holy != MH_NATURAL && holy != MH_HOLY);
}
+
+/////////////////////////////////////////////////////////////////////
+// god_conduct_trigger
+
+god_conduct_trigger::god_conduct_trigger(
+ conduct_type c, int pg, bool kn, const monsters *vict)
+ : conduct(c), pgain(pg), known(kn), enabled(true), victim(NULL)
+{
+ if (vict)
+ {
+ victim.reset(new monsters);
+ *(victim.get()) = *vict;
+ }
+}
+
+void god_conduct_trigger::set(conduct_type c, int pg, bool kn,
+ const monsters *vict)
+{
+ conduct = c;
+ pgain = pg;
+ known = kn;
+ victim.reset(NULL);
+ if (vict)
+ {
+ victim.reset(new monsters);
+ *victim.get() = *vict;
+ }
+}
+
+god_conduct_trigger::~god_conduct_trigger()
+{
+ if (enabled && conduct != NUM_CONDUCTS)
+ did_god_conduct(conduct, pgain, known, victim.get());
+}
diff --git a/crawl-ref/source/religion.h b/crawl-ref/source/religion.h
index 15b5d843cb..bce7b64b39 100644
--- a/crawl-ref/source/religion.h
+++ b/crawl-ref/source/religion.h
@@ -16,6 +16,7 @@
#include "enum.h"
#include "ouch.h"
+#include "externs.h"
#define MAX_PIETY 200
@@ -28,8 +29,10 @@ int piety_breakpoint(int i);
const char *god_name(god_type which_god, bool long_name = false); //mv
void dec_penance(int val);
void dec_penance(god_type god, int val);
+
bool did_god_conduct(conduct_type thing_done, int pgain, bool known = true,
const actor *victim = NULL);
+
void excommunication(void);
void gain_piety(int pgn);
void god_speaks(god_type god, const char *mesg );
@@ -56,7 +59,31 @@ bool ely_destroy_weapons();
bool trog_burn_books();
bool tso_stab_safe_monster(const actor *act);
+bool god_hates_attacking_friend(god_type god, const actor *fr);
+
bool is_evil_god(god_type god);
bool is_good_god(god_type god);
+// Calls did_god_conduct when the object goes out of scope.
+struct god_conduct_trigger
+{
+ conduct_type conduct;
+ int pgain;
+ bool known;
+ bool enabled;
+ std::auto_ptr<monsters> victim;
+
+ god_conduct_trigger(conduct_type c = NUM_CONDUCTS,
+ int pg = 0,
+ bool kn = true,
+ const monsters *vict = NULL);
+
+ void set(conduct_type c = NUM_CONDUCTS,
+ int pg = 0,
+ bool kn = true,
+ const monsters *vict = NULL);
+
+ ~god_conduct_trigger();
+};
+
#endif
diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc
index df26d89eee..b0893d8f5c 100644
--- a/crawl-ref/source/spells2.cc
+++ b/crawl-ref/source/spells2.cc
@@ -1144,9 +1144,7 @@ char burn_freeze(int pow, char flavour)
if (hurted)
{
if (mons_friendly( monster ))
- {
did_god_conduct( DID_ATTACK_FRIEND, 5, true, monster );
- }
if (mons_holiness( monster ) == MH_HOLY)
did_god_conduct( DID_ATTACK_HOLY, monster->hit_dice );