diff options
-rw-r--r-- | crawl-ref/source/abl-show.cc | 48 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 20 | ||||
-rw-r--r-- | crawl-ref/source/food.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 37 | ||||
-rw-r--r-- | crawl-ref/source/ouch.cc | 14 | ||||
-rw-r--r-- | crawl-ref/source/religion.cc | 204 | ||||
-rw-r--r-- | crawl-ref/source/religion.h | 2 |
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) { |