summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/fight.cc14
-rw-r--r--crawl-ref/source/monstuff.cc59
-rw-r--r--crawl-ref/source/religion.cc99
3 files changed, 169 insertions, 3 deletions
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc
index cf79b80318..90ff0255cb 100644
--- a/crawl-ref/source/fight.cc
+++ b/crawl-ref/source/fight.cc
@@ -910,7 +910,16 @@ bool melee_attack::player_aux_unarmed()
// XXX We're clobbering did_hit
did_hit = false;
- if (to_hit >= def->ev || one_chance_in(30))
+
+ bool ely_block = false;
+ if (you.religion != GOD_ELYVILON && you.penance[GOD_ELYVILON]
+ && to_hit >= def->ev && one_chance_in(20))
+ {
+ simple_god_message(" blocks your attack.", GOD_ELYVILON);
+ ely_block = true;
+ }
+
+ if (!ely_block && (to_hit >= def->ev || one_chance_in(30)))
{
if (attack_shield_blocked(true))
continue;
@@ -927,6 +936,9 @@ bool melee_attack::player_aux_unarmed()
miss_verb.empty()? unarmed_attack.c_str()
: miss_verb.c_str(),
defender->name(DESC_NOCAP_THE).c_str());
+
+ if (ely_block)
+ dec_penance(GOD_ELYVILON, 1 + random2(to_hit - def->ev));
}
}
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 2ea6e4d33c..29737e2917 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -462,14 +462,73 @@ static bool is_pet_kill(killer_type killer, int i)
&& (me.who == KC_YOU || me.who == KC_FRIENDLY));
}
+static bool ely_heals_monster(monsters *monster, killer_type killer, int i)
+{
+ god_type god = GOD_ELYVILON;
+ ASSERT(you.religion != god);
+
+ const int ely_penance = you.penance[god];
+ ASSERT(ely_penance > 0);
+
+ if (mons_holiness(monster) != MH_NATURAL
+ || mons_friendly(monster)
+ || !one_chance_in(10))
+ {
+ return (false);
+ }
+
+ if (MON_KILL(killer))
+ {
+ monsters *mon = &menv[i];
+ if (!mons_friendly(mon) || !one_chance_in(3))
+ return (false);
+
+ if (!mons_near(monster))
+ return (false);
+ }
+ else if (!YOU_KILL(killer))
+ return (false);
+
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "monster hp: %d, max hp: %d",
+ monster->hit_points, monster->max_hit_points);
+#endif
+
+ monster->hit_points = std::min(1 + random2(ely_penance/3),
+ monster->max_hit_points);
+
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "new hp: %d, ely penance: %d",
+ monster->hit_points, ely_penance);
+#endif
+
+ snprintf(info, INFO_SIZE, "%s heals %s%s",
+ god_name(god, false).c_str(),
+ monster->name(DESC_NOCAP_THE).c_str(),
+ monster->hit_points * 2 <= monster->max_hit_points ? "." : "!");
+
+ god_speaks(god, info);
+ dec_penance(god, 1 + random2(monster->hit_points/2));
+
+ return (true);
+}
+
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);
+ }
+ if (you.religion != GOD_ELYVILON && you.penance[GOD_ELYVILON]
+ && ely_heals_monster(monster, killer, i))
+ {
+ return (true);
+ }
+
bool convert = false;
if (you.religion == GOD_BEOGH
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index b68a938e2b..72287b1c6e 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -2793,6 +2793,100 @@ static bool nemelex_retribution()
return true;
}
+static void ely_destroy_inventory_weapon()
+{
+ int count = 0;
+ int item = ENDOFPACK;
+
+ for (int i = 0; i < ENDOFPACK; i++)
+ {
+ if (!is_valid_item( you.inv[i] ))
+ continue;
+
+ if (you.inv[i].base_type == OBJ_WEAPONS
+ || you.inv[i].base_type == OBJ_MISSILES)
+ {
+ if (is_artefact(you.inv[i]))
+ continue;
+
+ // item is valid for destroying, so give it a chance
+ count++;
+ if (one_chance_in( count ))
+ item = i;
+ }
+ }
+
+ // any item to destroy?
+ if (item == ENDOFPACK)
+ return;
+
+ int value = 1;
+ bool wielded = false;
+
+ // increase value wielded weapons or large stacks of ammo
+ if (you.inv[item].base_type == OBJ_WEAPONS
+ && you.inv[item].link == you.equip[EQ_WEAPON])
+ {
+ wielded = true;
+ value += 2;
+ }
+ else if (you.inv[item].quantity > random2(you.penance[GOD_ELYVILON]))
+ value += 1 + random2(2);
+
+ std::ostream& strm = msg::streams(MSGCH_GOD);
+ strm << you.inv[item].name(DESC_CAP_YOUR);
+
+ if (value == 1)
+ strm << " barely";
+
+ if ( you.inv[item].quantity == 1 )
+ strm << " shimmers and breaks into pieces." << std::endl;
+ else
+ strm << " shimmer and break into pieces." << std::endl;
+
+ if (wielded)
+ {
+ unwield_item(true);
+ you.wield_change = true;
+ }
+ // just in case
+ you.quiver_change = true;
+
+ destroy_item(you.inv[item]);
+ burden_change();
+
+ dec_penance(GOD_ELYVILON, value);
+}
+
+// comparatively lenient
+static bool elyvilon_retribution()
+{
+ const god_type god = GOD_ELYVILON;
+
+ simple_god_message("'s displeasure finds you.", god);
+
+ // healing theme and interfering with fighting
+ switch (random2(5))
+ {
+ case 0:
+ case 1:
+ confuse_player( 3 + random2(10), false );
+ break;
+
+ case 2: // mostly flavour messages
+ miscast_effect(SPTYP_POISON, 0, 0, one_chance_in(3),
+ "the will of Elyvilon");
+ break;
+
+ case 3:
+ case 4: // destroy weapons in your inventory
+ ely_destroy_inventory_weapon();
+ break;
+ }
+
+ return true;
+}
+
void divine_retribution( god_type god )
{
ASSERT(god != GOD_NO_GOD);
@@ -2821,8 +2915,8 @@ void divine_retribution( god_type god )
case GOD_VEHUMET: do_more = vehumet_retribution(); break;
case GOD_NEMELEX_XOBEH: do_more = nemelex_retribution(); break;
case GOD_SIF_MUNA: do_more = sif_muna_retribution(); break;
+ case GOD_ELYVILON: do_more = elyvilon_retribution(); break;
- case GOD_ELYVILON: // Elyvilon doesn't seek revenge
default:
do_more = false;
break;
@@ -3401,7 +3495,8 @@ void excommunication(god_type new_god)
inc_penance(old_god, 50);
break;
- case GOD_ELYVILON: // never seeks revenge
+ case GOD_ELYVILON:
+ inc_penance( old_god, 50 );
break;
case GOD_SHINING_ONE: