summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2007-08-03 20:51:16 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2007-08-03 20:51:16 +0000
commit55772ba95bacafb30770fcddf422da5cdc8038d9 (patch)
tree3d457d34ab466a289d13c29bbec0042097cac045 /crawl-ref
parent606e14406ef0ae5f12dccad44b6f0f0b3433f013 (diff)
downloadcrawl-ref-55772ba95bacafb30770fcddf422da5cdc8038d9.tar.gz
crawl-ref-55772ba95bacafb30770fcddf422da5cdc8038d9.zip
First part of godly changes.
Ely now has "Destroy Weapon" ability, and Trog "Burn Books". The latter is very powerful as it explicitly allows burning monsters, which is cool but might be too strong. I couldn't think of a rationale for Trog not to allow this, though. Also, all killings are now accepted without prayer, and sacrifice-loving gods won't acccept rotten corpses anymore. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1959 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-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)
{