summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/abl-show.cc48
-rw-r--r--crawl-ref/source/enum.h20
-rw-r--r--crawl-ref/source/food.cc3
-rw-r--r--crawl-ref/source/monstuff.cc37
-rw-r--r--crawl-ref/source/ouch.cc14
-rw-r--r--crawl-ref/source/religion.cc204
-rw-r--r--crawl-ref/source/religion.h2
7 files changed, 260 insertions, 68 deletions
diff --git a/crawl-ref/source/abl-show.cc b/crawl-ref/source/abl-show.cc
index 5765404e8d..928290b2bb 100644
--- a/crawl-ref/source/abl-show.cc
+++ b/crawl-ref/source/abl-show.cc
@@ -113,7 +113,7 @@ ability_type god_abilities[MAX_NUM_GODS][MAX_GOD_ABILITIES] =
{ ABIL_NON_ABILITY, ABIL_NON_ABILITY, ABIL_NON_ABILITY,
ABIL_NON_ABILITY, ABIL_NON_ABILITY },
// Okawaru
- { ABIL_OKAWARU_MIGHT, ABIL_OKAWARU_HEALING, ABIL_NON_ABILITY,
+ { ABIL_OKAWARU_MIGHT, ABIL_NON_ABILITY, ABIL_NON_ABILITY,
ABIL_NON_ABILITY, ABIL_OKAWARU_HASTE },
// Makhleb
{ ABIL_NON_ABILITY, ABIL_MAKHLEB_MINOR_DESTRUCTION,
@@ -242,7 +242,6 @@ static const ability_def Ability_List[] =
// Okawaru
{ ABIL_OKAWARU_MIGHT, "Might", 2, 0, 50, 1, ABFLAG_NONE },
- { ABIL_OKAWARU_HEALING, "Healing", 2, 0, 75, 1, ABFLAG_NONE },
{ ABIL_OKAWARU_HASTE, "Haste", 5, 0, 100, 3, ABFLAG_NONE },
// Makhleb
@@ -256,11 +255,13 @@ static const ability_def Ability_List[] =
{ ABIL_SIF_MUNA_FORGET_SPELL, "Forget Spell", 5, 0, 0, 8, ABFLAG_NONE },
// Trog
+ { ABIL_TROG_BURN_BOOKS, "Burn Books", 0, 0, 10, 0, ABFLAG_NONE },
{ ABIL_TROG_BERSERK, "Berserk", 0, 0, 200, 0, ABFLAG_NONE },
{ ABIL_TROG_MIGHT, "Might", 0, 0, 200, 1, ABFLAG_NONE },
{ ABIL_TROG_HASTE_SELF, "Haste Self", 0, 0, 250, 3, ABFLAG_NONE },
// Elyvilon
+ { ABIL_ELYVILON_DESTROY_WEAPONS, "Destroy Weapons", 0, 0, 0, 0, ABFLAG_NONE },
{ ABIL_ELYVILON_LESSER_HEALING, "Lesser Healing", 1, 0, 100, 0,
ABFLAG_CONF_OK },
{ ABIL_ELYVILON_PURIFICATION, "Purification", 2, 0, 150, 1,
@@ -618,7 +619,18 @@ static talent get_talent(ability_type ability, bool check_confused)
invoc = true;
failure = 30 - (you.piety / 20) - (6 * you.skills[SK_INVOCATIONS]);
break;
+
+ // destroying stuff doesn't train anything
+ case ABIL_ELYVILON_DESTROY_WEAPONS:
+ invoc = true;
+ failure = 0;
+ break;
+ case ABIL_TROG_BURN_BOOKS:
+ invoc = true;
+ failure = 0;
+ break;
+
// These three are Trog abilities... Invocations means nothing -- bwr
case ABIL_TROG_BERSERK: // piety >= 30
invoc = true;
@@ -643,7 +655,6 @@ static talent get_talent(ability_type ability, bool check_confused)
case ABIL_ZIN_HEALING:
case ABIL_TSO_SMITING:
case ABIL_BEOGH_SMITING:
- case ABIL_OKAWARU_HEALING:
case ABIL_MAKHLEB_MINOR_DESTRUCTION:
case ABIL_SIF_MUNA_FORGET_SPELL:
case ABIL_KIKU_ENSLAVE_UNDEAD:
@@ -1378,13 +1389,6 @@ static bool do_ability(const ability_def& abil)
exercise(SK_INVOCATIONS, 1 + random2(3));
break;
- case ABIL_OKAWARU_HEALING:
- if (!cast_healing( 3 + (you.skills[SK_INVOCATIONS] / 6) ))
- break;
-
- exercise(SK_INVOCATIONS, 2 + random2(5));
- break;
-
case ABIL_OKAWARU_HASTE:
potion_effect( POT_SPEED, you.skills[SK_INVOCATIONS] * 8 );
exercise(SK_INVOCATIONS, 3 + random2(7));
@@ -1477,6 +1481,10 @@ static bool do_ability(const ability_def& abil)
exercise(SK_INVOCATIONS, 6 + random2(6));
break;
+ case ABIL_TROG_BURN_BOOKS:
+ trog_burn_books();
+ break;
+
case ABIL_TROG_BERSERK:
// Trog abilities don't use or train invocations.
if (you.hunger_state < HS_SATIATED)
@@ -1502,6 +1510,17 @@ static bool do_ability(const ability_def& abil)
cast_selective_amnesia(true);
break;
+ case ABIL_ELYVILON_DESTROY_WEAPONS:
+ {
+ int i = igrd[you.x_pos][you.y_pos];
+ if (i != NON_ITEM)
+ {
+ ely_destroy_weapons();
+ break;
+ }
+ mpr("There are no items here.");
+ break;
+ }
case ABIL_ELYVILON_LESSER_HEALING:
if (!cast_healing( 3 + (you.skills[SK_INVOCATIONS] / 6) ))
break;
@@ -1873,6 +1892,15 @@ std::vector<talent> your_talents( bool check_confused )
add_talent(talents, ABIL_TRAN_BAT, check_confused );
}
+ if (you.religion == GOD_ELYVILON)
+ {
+ add_talent(talents, ABIL_ELYVILON_DESTROY_WEAPONS, check_confused );
+ }
+ else if (you.religion == GOD_TROG)
+ {
+ add_talent(talents, ABIL_TROG_BURN_BOOKS, check_confused );
+ }
+
//jmf: alternately put check elsewhere
if ((you.level_type == LEVEL_DUNGEON && you.mutation[MUT_MAPPING]) ||
(you.level_type == LEVEL_PANDEMONIUM && you.mutation[MUT_MAPPING]==3))
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index d9ed05cb3c..8a651cfeda 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -93,7 +93,7 @@ enum ability_type
ABIL_YRED_CONTROL_UNDEAD, // 144
// 160 - reserved for Vehumet
ABIL_OKAWARU_MIGHT = 170, // 170
- ABIL_OKAWARU_HEALING,
+ // Okawaru no longer heals (JPEG)
ABIL_OKAWARU_HASTE, // 172
ABIL_MAKHLEB_MINOR_DESTRUCTION = 180, // 180
ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB,
@@ -101,9 +101,11 @@ enum ability_type
ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB, // 183
ABIL_SIF_MUNA_CHANNEL_ENERGY = 190, // 190
ABIL_SIF_MUNA_FORGET_SPELL,
+ ABIL_TROG_BURN_BOOKS,
ABIL_TROG_BERSERK = 200, // 200
ABIL_TROG_MIGHT,
ABIL_TROG_HASTE_SELF, // 202
+ ABIL_ELYVILON_DESTROY_WEAPONS,
ABIL_ELYVILON_LESSER_HEALING = 220, // 220
ABIL_ELYVILON_PURIFICATION,
ABIL_ELYVILON_HEALING,
@@ -780,15 +782,13 @@ enum conduct_type
DID_STABBING,
DID_POISON,
DID_DEDICATED_BUTCHERY,
- DID_DEDICATED_KILL_LIVING,
- DID_DEDICATED_KILL_UNDEAD,
- DID_DEDICATED_KILL_DEMON,
- DID_DEDICATED_KILL_NATURAL_EVIL, // unused
- DID_DEDICATED_KILL_WIZARD,
- DID_DEDICATED_KILL_PRIEST,
-
- // [dshaligram] No distinction between killing Angels during prayer or
- // otherwise, borrowed from bwr 4.1.
+ // killings need no longer be dedicated (JPEG)
+ DID_KILL_LIVING,
+ DID_KILL_UNDEAD,
+ DID_KILL_DEMON,
+ DID_KILL_NATURAL_EVIL, // unused
+ DID_KILL_WIZARD,
+ DID_KILL_PRIEST,
DID_KILL_ANGEL,
DID_LIVING_KILLED_BY_UNDEAD_SLAVE,
DID_LIVING_KILLED_BY_SERVANT,
diff --git a/crawl-ref/source/food.cc b/crawl-ref/source/food.cc
index 3287040fec..069f97a3fd 100644
--- a/crawl-ref/source/food.cc
+++ b/crawl-ref/source/food.cc
@@ -325,7 +325,8 @@ bool butchery(void)
else
mpr("You start hacking away.");
- if (you.duration[DUR_PRAYER] &&
+ bool rotten = (mitm[objl].special < 100);
+ if (you.duration[DUR_PRAYER] && !rotten &&
god_likes_butchery(you.religion))
{
offer_corpse(objl);
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index dfe32abfe5..79b63d9752 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -557,30 +557,27 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent)
// Only affects monsters friendly when created.
if (!created_friendly)
{
- if (you.duration[DUR_PRAYER])
- {
- if (mons_holiness(monster) == MH_NATURAL)
- did_god_conduct(DID_DEDICATED_KILL_LIVING,
- monster->hit_dice);
+ if (mons_holiness(monster) == MH_NATURAL)
+ did_god_conduct(DID_KILL_LIVING,
+ monster->hit_dice);
- if (mons_holiness(monster) == MH_UNDEAD)
- did_god_conduct(DID_DEDICATED_KILL_UNDEAD,
- monster->hit_dice);
+ if (mons_holiness(monster) == MH_UNDEAD)
+ did_god_conduct(DID_KILL_UNDEAD,
+ monster->hit_dice);
- if (mons_holiness(monster) == MH_DEMONIC)
- did_god_conduct(DID_DEDICATED_KILL_DEMON,
- monster->hit_dice);
+ if (mons_holiness(monster) == MH_DEMONIC)
+ did_god_conduct(DID_KILL_DEMON,
+ monster->hit_dice);
- //jmf: Trog hates wizards
- if (mons_is_magic_user(monster))
- did_god_conduct(DID_DEDICATED_KILL_WIZARD,
- monster->hit_dice);
+ //jmf: Trog hates wizards
+ if (mons_is_magic_user(monster))
+ did_god_conduct(DID_KILL_WIZARD,
+ monster->hit_dice);
- //jmf: maybe someone hates priests?
- if (mons_class_flag(monster->type, M_PRIEST))
- did_god_conduct(DID_DEDICATED_KILL_PRIEST,
- monster->hit_dice);
- }
+ //Beogh hates priests
+ if (mons_class_flag(monster->type, M_PRIEST))
+ did_god_conduct(DID_KILL_PRIEST,
+ monster->hit_dice);
if (mons_holiness(monster) == MH_HOLY)
did_god_conduct(DID_KILL_ANGEL, monster->hit_dice);
diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc
index 01ef978f6d..bace0db54d 100644
--- a/crawl-ref/source/ouch.cc
+++ b/crawl-ref/source/ouch.cc
@@ -768,13 +768,23 @@ void ouch( int dam, int death_source, kill_method_type death_type,
break;
}
- // Damage applied here:
- dec_hp( dam, true );
// Even if we have low HP messages off, we'll still give a
// big hit warning (in this case, a hit for half our HPs) -- bwr
if (dam > 0 && you.hp_max <= dam * 2)
+ {
+ if (you.religion == GOD_ELYVILON && one_chance_in(3))
+ {
+ simple_god_message( " shields you from harm!" );
+ return;
+ }
+ // Damage applied here:
+ dec_hp( dam, true );
mpr( "Ouch! That really hurt!", MSGCH_DANGER );
+ }
+ else
+ dec_hp( dam, true );
+
if (you.hp > 0)
{
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 91a6a7f741..aa2f3161e7 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -36,6 +36,7 @@
#include "abl-show.h"
#include "beam.h"
#include "chardump.h"
+#include "cloud.h"
#include "debug.h"
#include "decks.h"
#include "describe.h"
@@ -62,6 +63,7 @@
#include "spells1.h"
#include "spells2.h"
#include "spells3.h"
+#include "spl-book.h"
#include "spl-cast.h"
#include "stuff.h"
#include "tutorial.h"
@@ -1056,14 +1058,18 @@ bool did_god_conduct( conduct_type thing_done, int level )
}
break;
- case DID_DEDICATED_KILL_LIVING:
+ case DID_KILL_LIVING:
switch (you.religion)
{
case GOD_ELYVILON:
- simple_god_message(" did not appreciate that!");
- ret = true;
- piety_change = -level;
- penance = level * 2;
+ // killing only disapproved during prayer
+ if (you.duration[DUR_PRAYER])
+ {
+ simple_god_message(" did not appreciate that!");
+ ret = true;
+ piety_change = -level;
+ penance = level * 2;
+ }
break;
case GOD_KIKUBAAQUDGHA:
@@ -1085,7 +1091,7 @@ bool did_god_conduct( conduct_type thing_done, int level )
}
break;
- case DID_DEDICATED_KILL_UNDEAD:
+ case DID_KILL_UNDEAD:
switch (you.religion)
{
case GOD_ZIN:
@@ -1106,7 +1112,7 @@ bool did_god_conduct( conduct_type thing_done, int level )
}
break;
- case DID_DEDICATED_KILL_DEMON:
+ case DID_KILL_DEMON:
switch (you.religion)
{
case GOD_ZIN:
@@ -1125,7 +1131,7 @@ bool did_god_conduct( conduct_type thing_done, int level )
}
break;
- case DID_DEDICATED_KILL_PRIEST:
+ case DID_KILL_PRIEST:
if (you.religion == GOD_BEOGH)
{
simple_god_message(" appreciates your killing of a "
@@ -1136,7 +1142,7 @@ bool did_god_conduct( conduct_type thing_done, int level )
}
break;
- case DID_DEDICATED_KILL_WIZARD:
+ case DID_KILL_WIZARD:
if (you.religion == GOD_TROG)
{
// hooking this up, but is it too good?
@@ -1309,7 +1315,7 @@ bool did_god_conduct( conduct_type thing_done, int level )
case DID_STIMULANTS: // unused
case DID_EAT_MEAT: // unused
case DID_CREATED_LIFE: // unused
- case DID_DEDICATED_KILL_NATURAL_EVIL: // unused
+ case DID_KILL_NATURAL_EVIL: // unused
case DID_NATURAL_EVIL_KILLED_BY_SERVANT: // unused
case DID_SPELL_NONUTILITY: // unused
case NUM_CONDUCTS:
@@ -1476,6 +1482,167 @@ static bool need_water_walking()
grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER;
}
+void ely_destroy_weapons()
+{
+ if (you.religion != GOD_ELYVILON)
+ return;
+
+ bool success;
+ int i = igrd[you.x_pos][you.y_pos];
+ while (i != NON_ITEM)
+ {
+ const int next = mitm[i].link; // in case we can't get it later.
+
+ if (mitm[i].base_type != OBJ_WEAPONS
+ && mitm[i].base_type != OBJ_MISSILES)
+ {
+ i = next;
+ continue;
+ }
+
+ const char *ssuffix = mitm[i].quantity == 1? "s" : "";
+ std::string text = mitm[i].name(DESC_CAP_THE);
+ text += " shimmer"; text += ssuffix;
+ text += " and break"; text += ssuffix;
+ text += " into pieces.";
+
+ mpr(text.c_str());
+
+ const int value = item_value( mitm[i], true );
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "Destroyed weapon value: %d", value);
+#endif
+
+ if (random2(value) >= random2(50)
+ || (mitm[i].base_type == OBJ_WEAPONS
+ && (you.piety < 30 || player_under_penance())))
+ {
+ gain_piety(1);
+ }
+
+ destroy_item(i);
+ success = true;
+ i = next;
+ }
+ if (!success)
+ {
+ mpr("There are no weapons here to destroy!");
+ }
+}
+
+void trog_burn_books()
+{
+ if (you.religion != GOD_TROG)
+ return;
+
+ int i = igrd[you.x_pos][you.y_pos];
+ while (i != NON_ITEM)
+ {
+ const int next = mitm[i].link; // in case we can't get it later.
+
+ if (mitm[i].base_type == OBJ_BOOKS
+ && mitm[i].sub_type != BOOK_MANUAL)
+ {
+ mpr("Burning your own feet might not be such a smart idea!");
+ return;
+ }
+ i = next;
+ }
+
+ int totalcount = 0;
+ for (int xpos = you.x_pos - 8; xpos < you.x_pos + 8; xpos++)
+ for (int ypos = you.y_pos - 8; ypos < you.y_pos + 8; ypos++)
+ {
+ // checked above
+ if (xpos == you.x_pos && ypos == you.y_pos)
+ {
+ continue;
+ }
+
+ // burn only squares in sight
+ if (!see_grid(xpos, ypos))
+ {
+ continue;
+ }
+
+ // if a grid is blocked, books lying there will be ignored
+ // allow bombing of monsters
+ const int cloud = env.cgrid[xpos][ypos];
+ if (grid_is_solid(grd[ xpos ][ ypos ]) ||
+// mgrd[ xpos ][ ypos ] != NON_MONSTER ||
+ (cloud != EMPTY_CLOUD && env.cloud[cloud].type != CLOUD_FIRE))
+ {
+ continue;
+ }
+
+ int count = 0;
+ int rarity = 0;
+ i = igrd[xpos][ypos];
+ while (i != NON_ITEM)
+ {
+ const int next = mitm[i].link; // in case we can't get it later.
+
+ if (mitm[i].base_type != OBJ_BOOKS
+ || mitm[i].sub_type == BOOK_MANUAL)
+ {
+ i = next;
+ continue;
+ }
+
+ rarity += book_rarity(mitm[i].sub_type);
+
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "Burned book rarity: %d", rarity);
+#endif
+
+ destroy_item(i);
+ count++;
+ i = next;
+ }
+
+ if (count)
+ {
+ totalcount += count;
+ if ( cloud != EMPTY_CLOUD )
+ {
+ // reinforce the cloud
+ mpr( "The fire roars with new energy!" );
+ const int extra_dur = count + random2(rarity/2);
+ env.cloud[cloud].decay += extra_dur * 5;
+ env.cloud[cloud].whose = KC_YOU;
+ continue;
+ }
+
+ int durat = 4 + count + random2(rarity/2);
+
+ if (durat > 23)
+ durat = 23;
+
+ place_cloud( CLOUD_FIRE, xpos, ypos, durat, KC_YOU );
+
+ const char *plural = count == 1? "" : "s";
+ const char *ssuffix = count == 1? "s" : "";
+
+ std::string text = "The book"; text += plural;
+ text += " burst"; text += ssuffix;
+ text += " into flames.";
+
+ mpr(text.c_str());
+ }
+
+ }
+
+ if (!totalcount)
+ {
+ mpr("There are no books in sight to burn!");
+ }
+ else
+ {
+ simple_god_message(" is delighted!", GOD_TROG);
+ gain_piety(totalcount*5);
+ }
+}
+
void lose_piety(int pgn)
{
const int old_piety = you.piety;
@@ -2512,11 +2679,12 @@ static bool god_likes_items(god_type god)
{
case GOD_ZIN: case GOD_KIKUBAAQUDGHA: case GOD_OKAWARU:
case GOD_MAKHLEB: case GOD_SIF_MUNA: case GOD_TROG:
- case GOD_NEMELEX_XOBEH: case GOD_ELYVILON:
+ case GOD_NEMELEX_XOBEH:
return true;
case GOD_SHINING_ONE: case GOD_YREDELEMNUL: case GOD_XOM:
case GOD_VEHUMET: case GOD_LUGONU: case GOD_BEOGH:
+ case GOD_ELYVILON:
return false;
case GOD_NO_GOD: case NUM_GODS: case GOD_RANDOM:
@@ -2533,11 +2701,6 @@ static bool god_likes_item(god_type god, const item_def& item)
switch (god)
{
- case GOD_ELYVILON:
- return
- item.base_type == OBJ_WEAPONS ||
- item.base_type == OBJ_MISSILES;
-
case GOD_KIKUBAAQUDGHA: case GOD_TROG:
return item.base_type == OBJ_CORPSES;
@@ -2612,15 +2775,6 @@ void offer_items()
gain_piety(1);
break;
- case GOD_ELYVILON:
- if (random2(value) >= random2(50)
- || (mitm[i].base_type == OBJ_WEAPONS
- && (you.piety < 30 || player_under_penance())))
- {
- gain_piety(1);
- }
- break;
-
default:
break;
}
diff --git a/crawl-ref/source/religion.h b/crawl-ref/source/religion.h
index 77c3fb032b..7b8eacc1ec 100644
--- a/crawl-ref/source/religion.h
+++ b/crawl-ref/source/religion.h
@@ -46,6 +46,8 @@ const char *describe_xom_favour();
bool beogh_water_walk();
void beogh_idol_revenge();
+void ely_destroy_weapons();
+void trog_burn_books();
inline void xom_acts(int sever)
{