diff options
Diffstat (limited to 'crawl-ref/source/religion.cc')
-rw-r--r-- | crawl-ref/source/religion.cc | 1090 |
1 files changed, 676 insertions, 414 deletions
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index fc51bc28bd..805c652d77 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -27,6 +27,10 @@ #include <string.h> #include <stdio.h> +#ifdef DOS +#include <dos.h> +#endif + #include "externs.h" #include "abl-show.h" @@ -39,13 +43,17 @@ #include "food.h" #include "it_use2.h" #include "itemname.h" +#include "itemprop.h" +#include "item_use.h" #include "items.h" #include "misc.h" #include "monplace.h" #include "mutation.h" #include "newgame.h" +#include "notes.h" #include "ouch.h" #include "player.h" +#include "randart.h" #include "shopping.h" #include "skills2.h" #include "spells1.h" @@ -53,6 +61,7 @@ #include "spells3.h" #include "spl-cast.h" #include "stuff.h" +#include "view.h" const char *sacrifice[] = { " glows silver and disappears.", @@ -115,9 +124,25 @@ static void inc_gift_timeout(int val) you.gift_timeout += val; } // end inc_gift_timeout() +static int random_undead_servant(int religion) +{ + // error trapping {dlb} + int thing_called = MONS_PROGRAM_BUG; + int temp_rand = random2(100); + thing_called = ((temp_rand > 66) ? MONS_WRAITH : // 33% + (temp_rand > 52) ? MONS_WIGHT : // 12% + (temp_rand > 40) ? MONS_SPECTRAL_WARRIOR : // 16% + (temp_rand > 31) ? MONS_ROTTING_HULK : // 9% + (temp_rand > 23) ? MONS_SKELETAL_WARRIOR : // 8% + (temp_rand > 16) ? MONS_VAMPIRE : // 7% + (temp_rand > 10) ? MONS_GHOUL : // 6% + (temp_rand > 4) ? MONS_MUMMY // 6% + : MONS_FLAYED_GHOST); // 5% + return (thing_called); +} + void pray(void) { - int temp_rand = 0; unsigned char was_praying = you.duration[DUR_PRAYER]; bool success = false; @@ -128,7 +153,7 @@ void pray(void) } // all prayers take time - you.turn_is_over = 1; + you.turn_is_over = true; if (you.religion != GOD_NO_GOD && grd[you.x_pos][you.y_pos] == 179 + you.religion) @@ -155,7 +180,7 @@ void pray(void) strcat(info, "un"); strcat(info, "life."); - mpr(info); + mpr(info, MSGCH_PRAY); return; } else if (you.religion == GOD_XOM) @@ -187,7 +212,7 @@ void pray(void) strcpy( info, "You offer a prayer to " ); strcat( info, god_name( you.religion ) ); strcat( info, "." ); - mpr(info); + mpr(info, MSGCH_PRAY); you.duration[DUR_PRAYER] = 9 + (random2(you.piety) / 20) + (random2(you.piety) / 20); @@ -208,7 +233,7 @@ void pray(void) : "displeased"); strcat(info, "."); - god_speaks(you.religion, info); + mpr( info, MSGCH_PRAY, you.religion ); if (you.piety > 130) you.duration[DUR_PRAYER] *= 3; @@ -226,197 +251,222 @@ void pray(void) if (!you.penance[you.religion] && !you.gift_timeout && !was_praying) { // Remember to check for water/lava - //jmf: "good" god will sometimes feed you (a la Nethack) - if (you.religion == GOD_ZIN - && you.hunger_state == HS_STARVING - && random2(250) <= you.piety) - { - god_speaks(you.religion, "Your stomach feels content."); - set_hunger(6000, true); - lose_piety(5 + random2avg(10, 2)); - inc_gift_timeout(30 + random2avg(10, 2)); - return; - } - - if (you.religion == GOD_NEMELEX_XOBEH - && random2(200) <= you.piety - && (!you.attribute[ATTR_CARD_TABLE] || one_chance_in(3)) - && !you.attribute[ATTR_CARD_COUNTDOWN] - && grd[you.x_pos][you.y_pos] != DNGN_LAVA - && grd[you.x_pos][you.y_pos] != DNGN_DEEP_WATER) + switch (you.religion) { - int thing_created = NON_ITEM; - unsigned char gift_type = MISC_DECK_OF_TRICKS; - - if (!you.attribute[ATTR_CARD_TABLE]) - { - thing_created = items( 1, OBJ_MISCELLANY, - MISC_PORTABLE_ALTAR_OF_NEMELEX, - true, 1, 250 ); + default: + break; - if (thing_created != NON_ITEM) - you.attribute[ATTR_CARD_TABLE] = 1; - } - else + case GOD_ZIN: + //jmf: "good" god will sometimes feed you (a la Nethack) + if (you.hunger_state == HS_STARVING + && random2(250) <= you.piety) { - if (random2(200) <= you.piety && one_chance_in(4)) - gift_type = MISC_DECK_OF_SUMMONINGS; - if (random2(200) <= you.piety && coinflip()) - gift_type = MISC_DECK_OF_WONDERS; - if (random2(200) <= you.piety && one_chance_in(4)) - gift_type = MISC_DECK_OF_POWER; - - thing_created = items( 1, OBJ_MISCELLANY, gift_type, - true, 1, 250 ); + god_speaks(you.religion, "Your stomach feels content."); + set_hunger(6000, true); + lose_piety(5 + random2avg(10, 2)); + inc_gift_timeout(30 + random2avg(10, 2)); } + break; - if (thing_created != NON_ITEM) + case GOD_NEMELEX_XOBEH: + if (random2(200) <= you.piety + && (!you.attribute[ATTR_CARD_TABLE] || one_chance_in(3)) + && !you.attribute[ATTR_CARD_COUNTDOWN] + && !grid_destroys_items(grd[you.x_pos][you.y_pos])) { - move_item_to_grid( &thing_created, you.x_pos, you.y_pos ); - origin_acquired(mitm[thing_created], you.religion); - - simple_god_message(" grants you a gift!"); - more(); - canned_msg(MSG_SOMETHING_APPEARS); + int thing_created = NON_ITEM; + unsigned char gift_type = MISC_DECK_OF_TRICKS; - you.attribute[ATTR_CARD_COUNTDOWN] = 10; - inc_gift_timeout(5 + random2avg(9, 2)); - } - } + if (!you.attribute[ATTR_CARD_TABLE]) + { + thing_created = items( 1, OBJ_MISCELLANY, + MISC_PORTABLE_ALTAR_OF_NEMELEX, + true, 1, 250 ); - if ((you.religion == GOD_OKAWARU || you.religion == GOD_TROG) - && you.piety > 130 - && random2(you.piety) > 120 - && grd[you.x_pos][you.y_pos] != DNGN_LAVA - && grd[you.x_pos][you.y_pos] != DNGN_DEEP_WATER - && one_chance_in(4)) - { - if (you.religion == GOD_TROG - || (you.religion == GOD_OKAWARU && coinflip())) - { - success = acquirement(OBJ_WEAPONS, you.religion); - } - else - { - success = acquirement(OBJ_ARMOUR, you.religion); - } + if (thing_created != NON_ITEM) + you.attribute[ATTR_CARD_TABLE] = 1; + } + else + { + if (random2(200) <= you.piety && one_chance_in(4)) + gift_type = MISC_DECK_OF_SUMMONINGS; + if (random2(200) <= you.piety && coinflip()) + gift_type = MISC_DECK_OF_WONDERS; + if (random2(200) <= you.piety && one_chance_in(4)) + gift_type = MISC_DECK_OF_POWER; + + thing_created = items( 1, OBJ_MISCELLANY, gift_type, + true, 1, 250 ); + } - if (success) - { - simple_god_message(" has granted you a gift!"); - more(); + if (thing_created != NON_ITEM) + { + move_item_to_grid( &thing_created, you.x_pos, you.y_pos ); + origin_acquired(mitm[thing_created], you.religion); + + simple_god_message(" grants you a gift!"); + more(); + canned_msg(MSG_SOMETHING_APPEARS); - inc_gift_timeout(30 + random2avg(19, 2)); + you.attribute[ATTR_CARD_COUNTDOWN] = 10; + inc_gift_timeout(5 + random2avg(9, 2)); + you.num_gifts[you.religion]++; + take_note(Note(NOTE_GOD_GIFT, you.religion)); + } } - } - - if (you.religion == GOD_YREDELEMNUL - && random2(you.piety) > 80 && one_chance_in(5)) - { - int thing_called = MONS_PROGRAM_BUG; // error trapping {dlb} - - temp_rand = random2(100); - thing_called = ((temp_rand > 66) ? MONS_WRAITH : // 33% - (temp_rand > 52) ? MONS_WIGHT : // 12% - (temp_rand > 40) ? MONS_SPECTRAL_WARRIOR : // 16% - (temp_rand > 31) ? MONS_ROTTING_HULK : // 9% - (temp_rand > 23) ? MONS_SKELETAL_WARRIOR : // 8% - (temp_rand > 16) ? MONS_VAMPIRE : // 7% - (temp_rand > 10) ? MONS_GHOUL : // 6% - (temp_rand > 4) ? MONS_MUMMY // 6% - : MONS_FLAYED_GHOST); // 5% - - if (create_monster( thing_called, 0, BEH_FRIENDLY, - you.x_pos, you.y_pos, - you.pet_target, 250 ) != -1) + break; + + case GOD_OKAWARU: + case GOD_TROG: + if (you.piety > 130 + && random2(you.piety) > 120 + && !grid_destroys_items(grd[you.x_pos][you.y_pos]) + && one_chance_in(4)) { - simple_god_message(" grants you an undead servant!"); - more(); - inc_gift_timeout(4 + random2avg(7, 2)); - } - } - - if ((you.religion == GOD_KIKUBAAQUDGHA - || you.religion == GOD_SIF_MUNA - || you.religion == GOD_VEHUMET) - && you.piety > 160 && random2(you.piety) > 100) - { - unsigned int gift = NUM_BOOKS; + if (you.religion == GOD_TROG + || (you.religion == GOD_OKAWARU && coinflip())) + { + success = acquirement(OBJ_WEAPONS, you.religion); + } + else + { + success = acquirement(OBJ_ARMOUR, you.religion); + } - switch (you.religion) - { - case GOD_KIKUBAAQUDGHA: // gives death books - if (!you.had_book[BOOK_NECROMANCY]) - gift = BOOK_NECROMANCY; - else if (!you.had_book[BOOK_DEATH]) - gift = BOOK_DEATH; - else if (!you.had_book[BOOK_UNLIFE]) - gift = BOOK_UNLIFE; - else if (!you.had_book[BOOK_NECRONOMICON]) - gift = BOOK_NECRONOMICON; - break; + if (success) + { + simple_god_message(" has granted you a gift!"); + more(); - case GOD_SIF_MUNA: - gift = OBJ_RANDOM; // Sif Muna - gives any + inc_gift_timeout(30 + random2avg(19, 2)); + you.num_gifts[ you.religion ]++; + take_note(Note(NOTE_GOD_GIFT, you.religion)); + } break; + } - // Vehumet - gives conj/summ. books (higher skill first) - case GOD_VEHUMET: - if (!you.had_book[BOOK_CONJURATIONS_I]) - gift = give_first_conjuration_book(); - else if (!you.had_book[BOOK_POWER]) - gift = BOOK_POWER; - else if (!you.had_book[BOOK_ANNIHILATIONS]) - gift = BOOK_ANNIHILATIONS; // conj books - - if (you.skills[SK_CONJURATIONS] < you.skills[SK_SUMMONINGS] - || gift == NUM_BOOKS) + if (you.religion == GOD_OKAWARU + && you.piety > 80 + && random2( you.piety ) > 70 + && !grid_destroys_items( grd[you.x_pos][you.y_pos] ) + && one_chance_in(8) + && you.skills[ best_skill(SK_SLINGS, SK_RANGED_COMBAT) ] >= 9) + { + success = acquirement( OBJ_MISSILES, you.religion ); + if (success) { - if (!you.had_book[BOOK_CALLINGS]) - gift = BOOK_CALLINGS; - else if (!you.had_book[BOOK_SUMMONINGS]) - gift = BOOK_SUMMONINGS; - else if (!you.had_book[BOOK_DEMONOLOGY]) - gift = BOOK_DEMONOLOGY; // summoning bks + simple_god_message( " has granted you a gift!" ); + more(); + + inc_gift_timeout( 4 + roll_dice(2,4) ); + you.num_gifts[ you.religion ]++; + take_note(Note(NOTE_GOD_GIFT, you.religion)); } break; } + break; - if (gift != NUM_BOOKS - && (grd[you.x_pos][you.y_pos] != DNGN_LAVA - && grd[you.x_pos][you.y_pos] != DNGN_DEEP_WATER)) + case GOD_YREDELEMNUL: + if (random2(you.piety) > 80 && one_chance_in(5)) { - if (gift == OBJ_RANDOM) - success = acquirement(OBJ_BOOKS, you.religion); - else + int thing_called = random_undead_servant(GOD_YREDELEMNUL); + if (create_monster( thing_called, 0, BEH_FRIENDLY, + you.x_pos, you.y_pos, + you.pet_target, 250 ) != -1) { - int thing_created = items(1, OBJ_BOOKS, gift, true, 1, 250); - if (thing_created == NON_ITEM) - return; + simple_god_message(" grants you an undead servant!"); + more(); + inc_gift_timeout(4 + random2avg(7, 2)); + you.num_gifts[you.religion]++; + take_note(Note(NOTE_GOD_GIFT, you.religion)); + } + } + break; - move_item_to_grid( &thing_created, you.x_pos, you.y_pos ); + case GOD_KIKUBAAQUDGHA: + case GOD_SIF_MUNA: + case GOD_VEHUMET: + if (you.piety > 160 && random2(you.piety) > 100) + { + unsigned int gift = NUM_BOOKS; - if (thing_created != NON_ITEM) + switch (you.religion) + { + case GOD_KIKUBAAQUDGHA: // gives death books + if (!you.had_book[BOOK_NECROMANCY]) + gift = BOOK_NECROMANCY; + else if (!you.had_book[BOOK_DEATH]) + gift = BOOK_DEATH; + else if (!you.had_book[BOOK_UNLIFE]) + gift = BOOK_UNLIFE; + else if (!you.had_book[BOOK_NECRONOMICON]) + gift = BOOK_NECRONOMICON; + break; + + case GOD_SIF_MUNA: + gift = OBJ_RANDOM; // Sif Muna - gives any + break; + + // Vehumet - gives conj/summ. books (higher skill first) + case GOD_VEHUMET: + if (!you.had_book[BOOK_CONJURATIONS_I]) + gift = give_first_conjuration_book(); + else if (!you.had_book[BOOK_POWER]) + gift = BOOK_POWER; + else if (!you.had_book[BOOK_ANNIHILATIONS]) + gift = BOOK_ANNIHILATIONS; // conj books + + if (you.skills[SK_CONJURATIONS] < + you.skills[SK_SUMMONINGS] + || gift == NUM_BOOKS) { - success = true; - origin_acquired(mitm[thing_created], you.religion); + if (!you.had_book[BOOK_CALLINGS]) + gift = BOOK_CALLINGS; + else if (!you.had_book[BOOK_SUMMONINGS]) + gift = BOOK_SUMMONINGS; + else if (!you.had_book[BOOK_DEMONOLOGY]) + gift = BOOK_DEMONOLOGY; // summoning bks } + break; } - if (success) + if (gift != NUM_BOOKS + && !(grid_destroys_items(grd[you.x_pos][you.y_pos]))) { - simple_god_message(" has granted you a gift!"); - more(); + if (gift == OBJ_RANDOM) + success = acquirement(OBJ_BOOKS, you.religion); + else + { + int thing_created = items(1, OBJ_BOOKS, gift, true, 1, 250); + if (thing_created == NON_ITEM) + return; - inc_gift_timeout(40 + random2avg(19, 2)); - } + move_item_to_grid( &thing_created, you.x_pos, you.y_pos ); + + if (thing_created != NON_ITEM) + { + success = true; + origin_acquired(mitm[thing_created], you.religion); + } + } + + if (success) + { + simple_god_message(" has granted you a gift!"); + more(); + inc_gift_timeout(40 + random2avg(19, 2)); + you.num_gifts[ you.religion ]++; + take_note(Note(NOTE_GOD_GIFT, you.religion)); + } - // Vehumet gives books less readily - if (you.religion == GOD_VEHUMET && success) - inc_gift_timeout(10 + random2(10)); - } // end of giving book - } // end of book gods + // Vehumet gives books less readily + if (you.religion == GOD_VEHUMET && success) + inc_gift_timeout(10 + random2(10)); + } // end of giving book + } // end of book gods + break; + } } // end of gift giving } // end pray() @@ -683,7 +733,7 @@ void Xom_acts(bool niceness, int sever, bool force_sever) (temp_rand == 2) ? "\"Let's see if it's strong enough to survive yet.\"" : "You hear Xom's maniacal laughter."); - if (one_chance_in(4)) + if (one_chance_in(4) && (you.equip[EQ_WEAPON] != -1) ) dancing_weapon(100, true); // nasty, but fun else { @@ -823,11 +873,10 @@ void Xom_acts(bool niceness, int sever, bool force_sever) (temp_rand == 1) ? "Xom grants you a gift!" : "Xom's generous nature manifests itself."); - if (grd[you.x_pos][you.y_pos] == DNGN_LAVA - || grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER) - { + if (grid_destroys_items(grd[you.x_pos][you.y_pos])) { // How unfortunate. I'll bet Xom feels sorry for you. - mpr("You hear a splash."); + mprf(MSGCH_SOUND, + grid_item_destruction_message(grd[you.x_pos][you.y_pos])); } else { @@ -862,6 +911,10 @@ void Xom_acts(bool niceness, int sever, bool force_sever) (temp_rand == 1) ? "Xom grants you a demonic servitor." : "Xom opens a gate."); } + else + { + god_speaks(GOD_XOM, "You hear Xom cackling."); + } done_good = true; // well, for Xom, trying == doing {dlb} } @@ -914,12 +967,13 @@ void Xom_acts(bool niceness, int sever, bool force_sever) beam.flavour = BEAM_ELECTRICITY; beam.target_x = you.x_pos; beam.target_y = you.y_pos; - strcpy(beam.beam_name, "blast of lightning"); + beam.name = "blast of lightning"; beam.colour = LIGHTCYAN; - beam.thrower = KILL_YOU; // your explosion + beam.thrower = KILL_MISC; beam.aux_source = "Xom's lightning strike"; beam.ex_size = 2; - beam.isTracer = false; + beam.is_tracer = false; + beam.is_explosion = true; explosion(beam); @@ -933,160 +987,375 @@ void Xom_acts(bool niceness, int sever, bool force_sever) } } // end "Good Things" - if (done_bad || done_good || one_chance_in(4)) - return; - else - goto okay_try_again; + if (done_bad || done_good ) + return; + if ( one_chance_in(4) ) { + god_speaks(GOD_XOM, "Xom's attention is distracted from you."); + return; + } + goto okay_try_again; } // end Xom_acts() -void done_good(char thing_done, int pgain) +// This function is the merger of done_good() and naughty(). +// Returns true if god was interested (good or bad) in conduct. +bool did_god_conduct( int thing_done, int level ) { - if (you.religion == GOD_NO_GOD) - return; + bool ret = false; + int piety_change = 0; + int penance = 0; + + if (you.religion == GOD_NO_GOD || you.religion == GOD_XOM) + return (false); switch (thing_done) { - case GOOD_KILLED_LIVING: + case DID_NECROMANCY: + case DID_UNHOLY: + case DID_ATTACK_HOLY: + switch (you.religion) + { + case GOD_ZIN: + case GOD_SHINING_ONE: + case GOD_ELYVILON: + piety_change = -level; + penance = level * ((you.religion == GOD_ZIN) ? 2 : 1); + ret = true; + break; + } + break; + + case DID_STABBING: + case DID_POISON: + if (you.religion == GOD_SHINING_ONE) + { + ret = true; + piety_change = -level; + penance = level * 2; + } + break; + + case DID_ATTACK_FRIEND: + switch (you.religion) + { + case GOD_ZIN: + case GOD_SHINING_ONE: + case GOD_ELYVILON: + case GOD_OKAWARU: + piety_change = -level; + penance = level * 3; + ret = true; + break; + } + break; + + case DID_FRIEND_DIES: + switch (you.religion) + { + case GOD_ELYVILON: + penance = level; // healer god cares more about this + // fall through + case GOD_ZIN: + case GOD_SHINING_ONE: + case GOD_OKAWARU: + piety_change = -level; + ret = true; + break; + } + break; + + case DID_DEDICATED_BUTCHERY: // aka field sacrifice switch (you.religion) { case GOD_ELYVILON: simple_god_message(" did not appreciate that!"); - naughty(NAUGHTY_KILLING, 10); + ret = true; + piety_change = -10; + penance = 10; break; - case GOD_KIKUBAAQUDGHA: - case GOD_YREDELEMNUL: - case GOD_VEHUMET: + case GOD_OKAWARU: case GOD_MAKHLEB: case GOD_TROG: - simple_god_message(" accepts your kill."); - if (random2(18 + pgain) > 5) - gain_piety(1); + simple_god_message(" accepts your offering."); + ret = true; + if (random2(level + 10) > 5) + piety_change = 1; break; } break; - case GOOD_KILLED_UNDEAD: + case DID_DEDICATED_KILL_LIVING: switch (you.religion) { - case GOD_ZIN: - case GOD_SHINING_ONE: + case GOD_ELYVILON: + simple_god_message(" did not appreciate that!"); + ret = true; + piety_change = -level; + penance = level * 2; + break; + + case GOD_KIKUBAAQUDGHA: + case GOD_YREDELEMNUL: + case GOD_OKAWARU: case GOD_VEHUMET: case GOD_MAKHLEB: - case GOD_OKAWARU: + case GOD_TROG: simple_god_message(" accepts your kill."); - if (random2(18 + pgain) > 4) - gain_piety(1); + ret = true; + if (random2(level + 18) > 5) + piety_change = 1; break; } break; - case GOOD_KILLED_DEMON: + case DID_DEDICATED_KILL_UNDEAD: switch (you.religion) { case GOD_ZIN: case GOD_SHINING_ONE: + case GOD_OKAWARU: case GOD_VEHUMET: case GOD_MAKHLEB: - case GOD_OKAWARU: simple_god_message(" accepts your kill."); - if (random2(18 + pgain) > 3) - gain_piety(1); + ret = true; + if (random2(level + 18) > 4) + piety_change = 1; break; } break; - case GOOD_KILLED_ANGEL_I: - case GOOD_KILLED_ANGEL_II: + case DID_DEDICATED_KILL_DEMON: switch (you.religion) { case GOD_ZIN: case GOD_SHINING_ONE: - case GOD_ELYVILON: - simple_god_message(" did not appreciate that!"); - naughty(NAUGHTY_ATTACK_HOLY, (you.conf ? 3 : pgain * 3)); + case GOD_OKAWARU: + simple_god_message(" accepts your kill."); + ret = true; + if (random2(level + 18) > 3) + piety_change = 1; break; } break; - case GOOD_KILLED_WIZARD: - // hooking this up, but is it too good? - // enjoy it while you can -- bwr + case DID_DEDICATED_KILL_WIZARD: if (you.religion == GOD_TROG) { - simple_god_message( " appreciates your killing of a magic user." ); - - if (random2( 5 + pgain ) > 5) - gain_piety(1); + // hooking this up, but is it too good? + // enjoy it while you can -- bwr + simple_god_message(" appreciates your killing of a magic user."); + ret = true; + if (random2(level + 10) > 5) + piety_change = 1; } break; - case GOOD_HACKED_CORPSE: // NB - pgain is you.experience_level (maybe) + // Note that Angel deaths are special, they are always noticed... + // if you or any friendly kills one you'll get the credit or the blame. + case DID_ANGEL_KILLED_BY_SERVANT: + case DID_KILL_ANGEL: switch (you.religion) { - // case GOD_KIKUBAAQUDGHA: - case GOD_OKAWARU: - case GOD_MAKHLEB: - case GOD_TROG: - simple_god_message(" accepts your offering."); - if (random2(10 + pgain) > 5) - gain_piety(1); + case GOD_ZIN: + case GOD_SHINING_ONE: + case GOD_ELYVILON: + level *= 3; + piety_change = -level; + penance = level * ((you.religion == GOD_ZIN) ? 2 : 1); + ret = true; break; - // case GOD_ZIN: - // case GOD_SHINING_ONE: - case GOD_ELYVILON: - simple_god_message(" did not appreciate that!"); + case GOD_KIKUBAAQUDGHA: + case GOD_YREDELEMNUL: + case GOD_MAKHLEB: + snprintf( info, INFO_SIZE, " accepts your %skill.", + (thing_done == DID_KILL_ANGEL) ? "" : "collateral " ); + + simple_god_message( info ); - naughty(NAUGHTY_BUTCHER, 8); + ret = true; + if (random2(level + 18) > 2) + piety_change = 1; break; } break; - case GOOD_OFFER_STUFF: - simple_god_message(" is pleased with your offering."); - - gain_piety(1); - break; - - case GOOD_SLAVES_KILL_LIVING: + // Undead slave is any friendly undead... Kiku and Yred pay attention + // to the undead and both like the death of living things. + case DID_LIVING_KILLED_BY_UNDEAD_SLAVE: switch (you.religion) { case GOD_KIKUBAAQUDGHA: case GOD_YREDELEMNUL: - case GOD_VEHUMET: simple_god_message(" accepts your slave's kill."); - - if (random2(pgain + 18) > 5) - gain_piety(1); + ret = true; + if (random2(level + 10) > 5) + piety_change = 1; break; } break; - case GOOD_SERVANTS_KILL: + // Servants are currently any friendly monster under Vehumet, or + // any god given pet for everyone else (excluding undead which are + // handled above). + case DID_LIVING_KILLED_BY_SERVANT: switch (you.religion) { + case GOD_KIKUBAAQUDGHA: // note: reapers aren't undead case GOD_VEHUMET: case GOD_MAKHLEB: simple_god_message(" accepts your collateral kill."); + ret = true; + if (random2(level + 10) > 5) + piety_change = 1; + break; + } + break; - if (random2(pgain + 18) > 5) - gain_piety(1); + case DID_UNDEAD_KILLED_BY_SERVANT: + switch (you.religion) + { + case GOD_ZIN: + case GOD_SHINING_ONE: + case GOD_VEHUMET: + case GOD_MAKHLEB: + simple_god_message(" accepts your collateral kill."); + ret = true; + if (random2(level + 10) > 5) + piety_change = 1; break; } break; - case GOOD_CARDS: + case DID_DEMON_KILLED_BY_SERVANT: switch (you.religion) { - case GOD_NEMELEX_XOBEH: - gain_piety(pgain); + case GOD_ZIN: + case GOD_SHINING_ONE: + simple_god_message(" accepts your collateral kill."); + ret = true; + if (random2(level + 10) > 5) + piety_change = 1; break; } break; - // Offering at altars is covered in another function. + + case DID_SPELL_MEMORISE: + if (you.religion == GOD_TROG) + { + penance = level * 10; + piety_change = -penance; + ret = true; + } + break; + + case DID_SPELL_CASTING: + if (you.religion == GOD_TROG) + { + piety_change = -level; + penance = level * 5; + ret = true; + } + break; + + case DID_SPELL_PRACTISE: + // Like CAST, but for skill advancement. + // Level is number of skill points gained... typically 10 * exerise, + // but may be more/less if the skill is at 0 (INT adjustment), or + // if the PC's pool is low and makes change. + if (you.religion == GOD_SIF_MUNA) + { + // Old curve: random2(12) <= spell-level, this is similar, + // but faster at low levels (to help ease things for low level + // Power averages about (level * 20 / 3) + 10 / 3 now. Also + // note that spell skill practise comes just after XP gain, so + // magical kills tend to do both at the same time (unlike melee). + // This means high level spells probably work pretty much like + // they used to (use spell, get piety). + piety_change = div_rand_round( level + 10, 80 ); +#ifdef DEBUG_DIAGNOSTICS + mprf(MSGCH_DIAGNOSTICS, "Spell practise, level: %d, dpiety: %d", + level, piety_change); +#endif + ret = true; + } + break; + + case DID_CARDS: + if (you.religion == GOD_NEMELEX_XOBEH) + { + piety_change = level; + ret = true; + } + break; + + case DID_STIMULANTS: // unused + case DID_EAT_MEAT: // unused + case DID_CREATED_LIFE: // unused + case DID_DEDICATED_KILL_NATURAL_EVIL: // unused + case DID_NATURAL_EVIL_KILLED_BY_SERVANT: // unused + case DID_SPELL_NONUTILITY: // unused + default: + break; + } + + 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 ); + } + } + +#if DEBUG_DIAGNOSTICS + if (ret) + { + static const char *conducts[] = + { + "", + "Necromancy", "Unholy", "Attack Holy", "Attack Friend", + "Friend Died", "Stab", "Poison", "Field Sacrifice", + "Kill Living", "Kill Undead", "Kill Demon", "Kill Natural Evil", + "Kill Wizard", + "Kill Priest", "Kill Angel", "Undead Slave Kill Living", + "Servant Kill Living", "Servant Kill Undead", + "Servant Kill Demon", "Servant Kill Natural Evil", + "Servant Kill Angel", + "Spell Memorise", "Spell Cast", "Spell Practise", "Spell Nonutility", + "Cards", "Stimulants", "Eat Meat", "Create Life" + }; + + mprf( MSGCH_DIAGNOSTICS, + "conduct: %s; piety: %d (%+d); penance: %d (%+d)", + conducts[thing_done], + you.piety, piety_change, you.penance[you.religion], penance ); + } -} // end done_good() +#endif + + return (ret); +} void gain_piety(char pgn) { @@ -1110,10 +1379,20 @@ void gain_piety(char pgn) } // slow down gain at upper levels of piety - if (you.piety > 199 - || (you.piety > 150 && one_chance_in(3)) - || (you.piety > 100 && one_chance_in(3))) - return; + if (you.religion != GOD_SIF_MUNA) + { + if (you.piety > 199 + || (you.piety > 150 && one_chance_in(3)) + || (you.piety > 100 && one_chance_in(3))) + return; + } + else + { + // Sif Muna has a gentler taper off because training because + // naturally slower as the player gains in spell skills. + if (you.piety > 150 && one_chance_in(5)) + return; + } int old_piety = you.piety; @@ -1121,19 +1400,20 @@ void gain_piety(char pgn) if (you.piety >= 30 && old_piety < 30) { + take_note(Note(NOTE_GOD_POWER, you.religion, 0)); switch (you.religion) { case GOD_NO_GOD: case GOD_XOM: case GOD_NEMELEX_XOBEH: - case GOD_SIF_MUNA: break; default: strcpy(info, "You can now "); strcat(info, (you.religion == GOD_ZIN || you.religion == GOD_SHINING_ONE) ? "repel the undead" : - + (you.religion == GOD_SIF_MUNA) + ? "tap ambient magical fields" : (you.religion == GOD_KIKUBAAQUDGHA) ? "recall your undead slaves" : (you.religion == GOD_YREDELEMNUL) @@ -1159,6 +1439,7 @@ void gain_piety(char pgn) if (you.piety >= 50 && old_piety < 50) { + take_note(Note(NOTE_GOD_POWER, you.religion, 1)); switch (you.religion) { case GOD_NO_GOD: @@ -1204,6 +1485,7 @@ void gain_piety(char pgn) if (you.piety >= 75 && old_piety < 75) { + take_note(Note(NOTE_GOD_POWER, you.religion, 2)); switch (you.religion) { case GOD_NO_GOD: @@ -1242,6 +1524,7 @@ void gain_piety(char pgn) if (you.piety >= 100 && old_piety < 100) { + take_note(Note(NOTE_GOD_POWER, you.religion, 3)); switch (you.religion) { case GOD_NO_GOD: @@ -1249,6 +1532,7 @@ void gain_piety(char pgn) case GOD_OKAWARU: case GOD_NEMELEX_XOBEH: case GOD_KIKUBAAQUDGHA: + case GOD_VEHUMET: break; case GOD_SIF_MUNA: simple_god_message @@ -1265,8 +1549,6 @@ void gain_piety(char pgn) ? "hurl bolts of divine anger" : (you.religion == GOD_YREDELEMNUL) ? "drain ambient lifeforce" : - (you.religion == GOD_VEHUMET) - ? "tap ambient magical fields" : (you.religion == GOD_MAKHLEB) ? "hurl Makhleb's greater destruction" : (you.religion == GOD_TROG) @@ -1284,6 +1566,7 @@ void gain_piety(char pgn) if (you.piety >= 120 && old_piety < 120) { + take_note(Note(NOTE_GOD_POWER, you.religion, 4)); switch (you.religion) { case GOD_NO_GOD: @@ -1319,159 +1602,13 @@ void gain_piety(char pgn) break; } } -} // end gain_piety() - -void naughty(char type_naughty, int naughtiness) -{ - int penance = 0; - int piety_loss = 0; - - // if you currently worship no deity in particular, exit function {dlb} - if (you.religion == GOD_NO_GOD) - return; - - switch (you.religion) - { - case GOD_ZIN: - switch (type_naughty) - { - case NAUGHTY_NECROMANCY: - case NAUGHTY_UNHOLY: - case NAUGHTY_ATTACK_HOLY: - piety_loss = naughtiness; - penance = piety_loss * 2; - break; - case NAUGHTY_ATTACK_FRIEND: - piety_loss = naughtiness; - penance = piety_loss * 3; - break; - case NAUGHTY_FRIEND_DIES: - piety_loss = naughtiness; - break; - case NAUGHTY_BUTCHER: - piety_loss = naughtiness; - if (one_chance_in(3)) - penance = piety_loss; - break; - } - break; - - case GOD_SHINING_ONE: - switch (type_naughty) - { - case NAUGHTY_NECROMANCY: - case NAUGHTY_UNHOLY: - case NAUGHTY_ATTACK_HOLY: - piety_loss = naughtiness; - penance = piety_loss; - break; - case NAUGHTY_ATTACK_FRIEND: - piety_loss = naughtiness; - penance = piety_loss * 3; - break; - case NAUGHTY_FRIEND_DIES: - piety_loss = naughtiness; - break; - case NAUGHTY_BUTCHER: - piety_loss = naughtiness; - if (one_chance_in(3)) - penance = piety_loss; - break; - case NAUGHTY_STABBING: - piety_loss = naughtiness; - if (one_chance_in(5)) // can be accidental so we're nice here - penance = piety_loss; - break; - case NAUGHTY_POISON: - piety_loss = naughtiness; - penance = piety_loss * 2; - break; - } - break; - - case GOD_ELYVILON: - switch (type_naughty) - { - case NAUGHTY_NECROMANCY: - case NAUGHTY_UNHOLY: - case NAUGHTY_ATTACK_HOLY: - piety_loss = naughtiness; - penance = piety_loss; - break; - case NAUGHTY_KILLING: - piety_loss = naughtiness; - penance = piety_loss * 2; - break; - case NAUGHTY_ATTACK_FRIEND: - piety_loss = naughtiness; - penance = piety_loss * 3; - break; - // Healer god gets a bit more upset since you should have - // used your healing powers to save them. - case NAUGHTY_FRIEND_DIES: - piety_loss = naughtiness; - penance = piety_loss; - break; - case NAUGHTY_BUTCHER: - piety_loss = naughtiness; - if (one_chance_in(3)) - penance = piety_loss; - break; - } - break; - - case GOD_OKAWARU: - switch (type_naughty) - { - case NAUGHTY_ATTACK_FRIEND: - piety_loss = naughtiness; - penance = piety_loss * 3; - break; - case NAUGHTY_FRIEND_DIES: - piety_loss = naughtiness; - break; - } - break; - - case GOD_TROG: - switch (type_naughty) - { - case NAUGHTY_SPELLCASTING: - piety_loss = naughtiness; - // This penance isn't so bad since its much easier to - // gain piety with Trog than the other gods in this function. - penance = piety_loss * 10; - break; - } - break; - } - - // exit function early iff piety loss is zero: - if (piety_loss < 1) - return; - // output guilt message: - strcpy(info, "You feel"); + if ( you.piety > 160 && old_piety <= 160 && + (you.religion == GOD_SHINING_ONE || you.religion == GOD_ZIN) && + you.num_gifts[you.religion] == 0 ) + simple_god_message( " will now bless your weapon at an altar...once."); - strcat(info, (piety_loss == 1) ? " a little " : - (piety_loss < 5) ? " " : - (piety_loss < 10) ? " very " - : " extremely "); - - strcat(info, "guilty."); - mpr(info); - - lose_piety(piety_loss); - - if (you.piety < 1) - excommunication(); - else if (penance) // Don't bother unless we're not kicking them out - { - //jmf: FIXME: add randomness to following message: - god_speaks(you.religion, "\"You will pay for your transgression, mortal!\""); - inc_penance(penance); - } -} // end naughty() +} // end gain_piety() void lose_piety(char pgn) { @@ -1487,6 +1624,11 @@ void lose_piety(char pgn) // are withheld. if (!player_under_penance() && you.piety != old_piety) { + if (you.piety <= 160 && old_piety > 160 && + (you.religion == GOD_SHINING_ONE || you.religion == GOD_ZIN) && + you.num_gifts[you.religion] == 0) + simple_god_message(" is no longer ready to bless your weapon."); + if (you.piety < 120 && old_piety >= 120) { switch (you.religion) @@ -1534,6 +1676,7 @@ void lose_piety(char pgn) case GOD_OKAWARU: case GOD_NEMELEX_XOBEH: case GOD_KIKUBAAQUDGHA: + case GOD_VEHUMET: break; case GOD_SIF_MUNA: god_speaks(you.religion,"Sif Muna is no longer protecting you from miscast magic."); @@ -1549,8 +1692,6 @@ void lose_piety(char pgn) ? "hurl bolts of divine anger" : (you.religion == GOD_YREDELEMNUL) ? "drain ambient life force" : - (you.religion == GOD_VEHUMET) - ? "tap ambient magical fields" : (you.religion == GOD_MAKHLEB) ? "direct Makhleb's greater destructive powers" : (you.religion == GOD_TROG) @@ -1576,7 +1717,7 @@ void lose_piety(char pgn) case GOD_TROG: break; case GOD_VEHUMET: - simple_god_message(" will longer shield you from summoned creatures."); + simple_god_message(" will no longer shield you from summoned creatures."); break; default: strcpy(info, "You can no longer "); @@ -1654,7 +1795,6 @@ void lose_piety(char pgn) case GOD_NO_GOD: case GOD_XOM: case GOD_NEMELEX_XOBEH: - case GOD_SIF_MUNA: break; default: strcpy(info, "You can no longer "); @@ -1666,6 +1806,8 @@ void lose_piety(char pgn) ? "recall your undead slaves" : (you.religion == GOD_YREDELEMNUL) ? "animate corpses" : + (you.religion == GOD_SIF_MUNA) + ? "tap ambient magical fields" : (you.religion == GOD_VEHUMET) ? "gain power from killing in Vehumet's name" : (you.religion == GOD_MAKHLEB) @@ -1747,6 +1889,10 @@ void divine_retribution( int god ) { simple_god_message( " sends the divine host to punish you for your evil ways!", god ); } + else + { + simple_god_message("'s divine host fails to appear.", god); + } } else { @@ -1768,8 +1914,9 @@ void divine_retribution( int god ) dec_penance( GOD_SHINING_ONE, 1 ); } } + break; } - break; + return; case GOD_ZIN: // angels/creeping doom theme: @@ -1795,6 +1942,10 @@ void divine_retribution( int god ) { simple_god_message(" sends the divine host to punish you for your evil ways!", god); } + else + { + simple_god_message("'s divine host fails to appear.", god); + } } else { @@ -1802,8 +1953,9 @@ void divine_retribution( int god ) summon_swarm( you.experience_level * 20, true, false ); simple_god_message(" sends a plague down upon you!", god); } + break; } - break; + return; case GOD_MAKHLEB: // demonic servant theme @@ -1816,6 +1968,10 @@ void divine_retribution( int god ) simple_god_message(" sends a greater servant after you!", god); } + else + { + simple_god_message("'s greater servant is unavoidably detained.", god); + } } else { @@ -1833,6 +1989,8 @@ void divine_retribution( int god ) if (success) simple_god_message(" sends minions to punish you.", god); + else + simple_god_message("'s minions fail to arrive.", god); } break; @@ -1854,6 +2012,8 @@ void divine_retribution( int god ) if (success) simple_god_message(" unleashes Death upon you!", god); + else + god_speaks(god, "Death has been delayed...for now."); } else { @@ -1895,6 +2055,8 @@ void divine_retribution( int god ) if (success) simple_god_message(" sends a servant to punish you.", god); + else + simple_god_message("'s servant fails to arrive.", god); } else { @@ -1978,6 +2140,8 @@ void divine_retribution( int god ) if (success) simple_god_message(" sends monsters to punish you.", god); + else + simple_god_message(" has no time to punish you...now.", god); } break; @@ -2064,20 +2228,22 @@ void divine_retribution( int god ) if (success) simple_god_message(" sends forces against you!", god); + else + simple_god_message("'s forces are busy with other wars.", god); } break; case GOD_VEHUMET: // conjuration and summoning theme - simple_god_message("'s vengence finds you.", god); + simple_god_message("'s vengeance finds you.", god); miscast_effect( coinflip() ? SPTYP_CONJURATION : SPTYP_SUMMONING, 8 + you.experience_level, random2avg(98, 3), 100, "the wrath of Vehumet" ); break; case GOD_NEMELEX_XOBEH: - // like Xom, this might actually help the player -- bwr` - simple_god_message(" makes you to draw from the Deck of Punishment.", + // like Xom, this might actually help the player -- bwr + simple_god_message(" makes you draw from the Deck of Punishment.", god); deck_of_cards(DECK_OF_PUNISHMENT); break; @@ -2102,7 +2268,7 @@ void divine_retribution( int god ) case 5: case 6: - miscast_effect(SK_DIVINATIONS, 9, 90, 100, "the will of Sif Muna"); + miscast_effect(SPTYP_DIVINATION, 9, 90, 100, "the will of Sif Muna"); break; case 7: @@ -2130,11 +2296,13 @@ void divine_retribution( int god ) return; } - // Sometimes divine experiences are overwelming... + // Sometimes divine experiences are overwhelming... if (one_chance_in(5) && you.experience_level < random2(37)) { - if (coinflip()) + if (coinflip()) { + mpr( "The divine experience confuses you!", MSGCH_WARN); confuse_player( 3 + random2(10) ); + } else { if (you.slow < 90) @@ -2154,6 +2322,8 @@ void excommunication(void) { const int old_god = you.religion; + take_note(Note(NOTE_LOSE_GOD, old_god)); + you.duration[DUR_PRAYER] = 0; you.religion = GOD_NO_GOD; you.piety = 0; @@ -2222,6 +2392,44 @@ void excommunication(void) } } // end excommunication() +static bool bless_weapon( int god, int brand, int colour ) +{ + const int wpn = get_player_wielded_weapon(); + + // Assuming the type of weapon is correct, we only need to check + // to see if it's an artefact we can successfully clobber: + if (!is_fixed_artefact( you.inv[wpn] ) + && !is_random_artefact( you.inv[wpn] )) + { + you.duration[DUR_WEAPON_BRAND] = 0; // just in case + + set_equip_desc( you.inv[wpn], ISFLAG_GLOWING ); + set_item_ego_type( you.inv[wpn], OBJ_WEAPONS, brand ); + you.inv[wpn].colour = colour; + + do_uncurse_item( you.inv[wpn] ); + enchant_weapon( ENCHANT_TO_HIT, true ); + enchant_weapon( ENCHANT_TO_DAM, true ); + + you.wield_change = true; + you.num_gifts[god]++; + take_note(Note(NOTE_GOD_GIFT, you.religion)); + + you.flash_colour = colour; + viewwindow( true, false ); + + mprf( MSGCH_GOD, "Your weapon shines brightly!" ); + simple_god_message( " booms: Use this gift wisely!" ); + + // as currently only Zin and TSO do this is our permabrand effect: + holy_word( 100, true ); + delay(1000); + + return (true); + } + + return (false); +} void altar_prayer(void) { @@ -2239,9 +2447,48 @@ void altar_prayer(void) mpr( "You kneel at the altar and pray." ); - if (you.religion == GOD_SHINING_ONE || you.religion == GOD_XOM) + if (you.religion == GOD_XOM) return; + // TSO blesses long swords with holy wrath + if (you.religion == GOD_SHINING_ONE + && !you.num_gifts[GOD_SHINING_ONE] + && !player_under_penance() + && you.piety > 160) + { + const int wpn = get_player_wielded_weapon(); + + if (wpn != -1 + && weapon_skill( you.inv[wpn] ) == SK_LONG_SWORDS + && get_weapon_brand( you.inv[wpn] ) != SPWPN_HOLY_WRATH) + { + if (bless_weapon( GOD_SHINING_ONE, SPWPN_HOLY_WRATH, YELLOW )) + { + // convert those demon blades if blessed: + if (you.inv[wpn].sub_type == WPN_DEMON_BLADE) + you.inv[wpn].sub_type = WPN_BLESSED_BLADE; + } + } + } + + // Zin blesses maces with disruption + if (you.religion == GOD_ZIN + && !you.num_gifts[GOD_ZIN] + && !player_under_penance() + && you.piety > 160) + { + const int wpn = get_player_wielded_weapon(); + + if (wpn != -1 + && (you.inv[wpn].base_type == OBJ_WEAPONS + && (you.inv[wpn].sub_type == WPN_MACE + || you.inv[wpn].sub_type == WPN_GREAT_MACE)) + && get_weapon_brand( you.inv[wpn] ) != SPWPN_DISRUPTION) + { + bless_weapon( GOD_ZIN, SPWPN_DISRUPTION, WHITE ); + } + } + i = igrd[you.x_pos][you.y_pos]; while (i != NON_ITEM) { @@ -2263,8 +2510,12 @@ void altar_prayer(void) strcat(info, sacrifice[you.religion - 1]); mpr(info); +#ifdef DEBUG_DIAGNOSTICS + mprf(MSGCH_DIAGNOSTICS, "Sacrifice item value: %d", value); +#endif if (mitm[i].base_type == OBJ_CORPSES || random2(value) >= 50 + || (you.religion == GOD_NEMELEX_XOBEH && one_chance_in(50)) || player_under_penance()) { gain_piety(1); @@ -2385,6 +2636,8 @@ void god_pitch(unsigned char which_god) if (you.worshipped[you.religion] < 100) you.worshipped[you.religion]++; + take_note(Note(NOTE_GET_GOD, you.religion)); + // Currently penance is just zeroed, this could be much more interesting. you.penance[you.religion] = 0; @@ -2410,7 +2663,7 @@ void offer_corpse(int corpse) strcat(info, sacrifice[you.religion - 1]); mpr(info); - done_good(GOOD_HACKED_CORPSE, 10); + did_god_conduct(DID_DEDICATED_BUTCHERY, 10); } // end offer_corpse() //jmf: moved stuff from items::handle_time() @@ -2507,8 +2760,17 @@ void handle_god_time(void) break; case GOD_SIF_MUNA: - if (one_chance_in(20)) + // [dshaligram] Sif Muna is now very patient - has to be + // to make up for the new spell training requirements, else + // it's practically impossible to get Master of Arcane status. + if (one_chance_in(100)) + { lose_piety(1); +#ifdef DEBUG_DIAGNOSTICS + mprf(MSGCH_DIAGNOSTICS, + "Sif Muna piety decay (new piety = %d)", you.piety); +#endif + } if (you.piety < 1) excommunication(); break; |