diff options
author | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2007-05-28 08:47:30 +0000 |
---|---|---|
committer | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2007-05-28 08:47:30 +0000 |
commit | 20a6609453ee2b51c388c296516c1abc1beab1d2 (patch) | |
tree | 201d735a3a4d66471005cb763078a6c05056752c /crawl-ref/source/religion.cc | |
parent | 7aed4c41d7fa0f9d70df56a82abbe69061e56269 (diff) | |
download | crawl-ref-20a6609453ee2b51c388c296516c1abc1beab1d2.tar.gz crawl-ref-20a6609453ee2b51c388c296516c1abc1beab1d2.zip |
Preliminary integration of Zooko's Xom patch (untested).
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1489 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/religion.cc')
-rw-r--r-- | crawl-ref/source/religion.cc | 531 |
1 files changed, 84 insertions, 447 deletions
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index 8701400c2a..a88c6081b0 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -50,6 +50,7 @@ #include "makeitem.h" #include "misc.h" #include "monplace.h" +#include "monstuff.h" #include "mutation.h" #include "newgame.h" #include "notes.h" @@ -66,7 +67,8 @@ #include "tutorial.h" #include "view.h" -const char *sacrifice[] = { +const char *sacrifice[] = +{ // Zin " glows silver and disappears.", // TSO @@ -257,7 +259,7 @@ const char* god_lose_power_messages[MAX_NUM_GODS][MAX_GOD_ABILITIES] = void altar_prayer(void); void dec_penance(int god, int val); -void divine_retribution(int god); +void divine_retribution(god_type god); void inc_penance(int god, int val); void inc_penance(int val); @@ -279,7 +281,7 @@ static bool is_good_god(god_type god) god == GOD_ELYVILON; } -void dec_penance(int god, int val) +void dec_penance(god_type god, int val) { if (you.penance[god] > 0) { @@ -419,7 +421,7 @@ static void do_god_gift() && !grid_destroys_items(grd[you.x_pos][you.y_pos])) { int thing_created = NON_ITEM; - unsigned char gift_type = MISC_DECK_OF_TRICKS; + int gift_type = MISC_DECK_OF_TRICKS; if (random2(200) <= you.piety && one_chance_in(4)) gift_type = MISC_DECK_OF_SUMMONINGS; @@ -429,7 +431,7 @@ static void do_god_gift() gift_type = MISC_DECK_OF_POWER; thing_created = items( 1, OBJ_MISCELLANY, gift_type, - true, 1, 250 ); + true, 1, MAKE_ITEM_RANDOM_RACE ); if (thing_created != NON_ITEM) { @@ -500,7 +502,7 @@ static void do_god_gift() 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) + you.pet_target, MAKE_ITEM_RANDOM_RACE ) != -1) { simple_god_message(" grants you an undead servant!"); more(); @@ -567,7 +569,8 @@ static void do_god_gift() success = acquirement(OBJ_BOOKS, you.religion); else { - int thing_created = items(1, OBJ_BOOKS, gift, true, 1, 250); + int thing_created = items(1, OBJ_BOOKS, gift, true, 1, + MAKE_ITEM_RANDOM_RACE); if (thing_created == NON_ITEM) return; @@ -684,26 +687,7 @@ void pray() } else if (you.religion == GOD_XOM) { - if (one_chance_in(100)) - { - // Every now and then, Xom listens - // This is for flavour, not effect, so praying should not be - // encouraged. - - // Xom is nicer to experienced players - bool nice = (27 <= random2( 27 + you.experience_level )); - - // and he's not very nice even then - int sever = (nice) ? random2( random2( you.experience_level ) ) - : you.experience_level; - - // bad results are enforced, good are not - bool force = !nice; - - Xom_acts( nice, 1 + sever, force ); - } - else - mpr("Xom ignores you."); + mpr("Xom ignores you."); return; } @@ -743,7 +727,7 @@ void pray() do_god_gift(); } // end pray() -char *god_name( int which_god, bool long_name ) // mv - rewritten +const char *god_name( god_type which_god, bool long_name ) // mv - rewritten { static char godname_buff[80]; @@ -873,405 +857,11 @@ char *god_name( int which_god, bool long_name ) // mv - rewritten return (godname_buff); } // end god_name() -void god_speaks( int god, const char *mesg ) +void god_speaks( god_type god, const char *mesg ) { mpr( mesg, MSGCH_GOD, god ); } // end god_speaks() -void Xom_acts(bool niceness, int sever, bool force_sever) -{ - // niceness = false - bad, true - nice - int temp_rand; // probability determination {dlb} - bool done_bad = false; // flag to clarify logic {dlb} - bool done_good = false; // flag to clarify logic {dlb} - - struct bolt beam; - - if (sever < 1) - sever = 1; - - if (!force_sever) - sever = random2(sever); - - if (sever == 0) - return; - - okay_try_again: - - if (!niceness || one_chance_in(3)) - { - // begin "Bad Things" - done_bad = false; - - // this should always be first - it will often be called - // deliberately, with a low sever value - if (random2(sever) <= 2) - { - temp_rand = random2(4); - - god_speaks(GOD_XOM, - (temp_rand == 0) ? "Xom notices you." : - (temp_rand == 1) ? "Xom's attention turns to you for a moment.": - (temp_rand == 2) ? "Xom's power touches on you for a moment." - : "You hear Xom's maniacal laughter."); - - miscast_effect( SPTYP_RANDOM, 5 + random2(10), random2(100), 0, - "the capriciousness of Xom" ); - - done_bad = true; - } - else if (random2(sever) <= 2) - { - temp_rand = random2(4); - - god_speaks(GOD_XOM, - (temp_rand == 0) ? "\"Suffer!\"" : - (temp_rand == 1) ? "Xom's malign attention turns to you for a moment." : - (temp_rand == 2) ? "Xom's power touches on you for a moment." - : "You hear Xom's maniacal laughter."); - - lose_stat(STAT_RANDOM, 1 + random2(3), true); - - done_bad = true; - } - else if (random2(sever) <= 2) - { - temp_rand = random2(4); - - god_speaks(GOD_XOM, - (temp_rand == 0) ? "Xom notices you." : - (temp_rand == 1) ? "Xom's attention turns to you for a moment.": - (temp_rand == 2) ? "Xom's power touches on you for a moment." - : "You hear Xom's maniacal laughter."); - - miscast_effect( SPTYP_RANDOM, 5 + random2(15), random2(250), 0, - "the capriciousness of Xom" ); - - done_bad = true; - } - else if (!you.is_undead && random2(sever) <= 3) - { - temp_rand = random2(4); - - god_speaks(GOD_XOM, - (temp_rand == 0) ? "\"You need some minor adjustments, mortal!\"" : - (temp_rand == 1) ? "\"Let me alter your pitiful body.\"" : - (temp_rand == 2) ? "Xom's power touches on you for a moment." - : "You hear Xom's maniacal laughter."); - - mpr("Your body is suffused with distortional energy."); - - set_hp(1 + random2(you.hp), false); - deflate_hp(you.hp_max / 2, true); - - bool failMsg = true; - for (int i = 0; i < 4; i++) - { - if (!mutate(100, failMsg)) - failMsg = false; - } - - done_bad = true; - } - else if (!you.is_undead && random2(sever) <= 3) - { - temp_rand = random2(4); - - god_speaks(GOD_XOM, - (temp_rand == 0) ? "\"You have displeased me, mortal.\"" : - (temp_rand == 1) ? "\"You have grown too confident for your meagre worth.\"" : - (temp_rand == 2) ? "Xom's power touches on you for a moment." - : "You hear Xom's maniacal laughter."); - - if (one_chance_in(4)) - { - drain_exp(); - if (random2(sever) > 3) - drain_exp(); - if (random2(sever) > 3) - drain_exp(); - } - else - { - mpr("A wave of agony tears through your body!"); - set_hp(1 + (you.hp / 2), false); - } - - done_bad = true; - } - else if (random2(sever) <= 3) - { - temp_rand = random2(4); - - god_speaks(GOD_XOM, - (temp_rand == 0) ? "\"Time to have some fun!\"" : - (temp_rand == 1) ? "\"Fight to survive, mortal.\"" : - (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) && (you.equip[EQ_WEAPON] != -1) ) - dancing_weapon(100, true); // nasty, but fun - else - { - create_monster(MONS_NEQOXEC + random2(5), 3, - BEH_HOSTILE, you.x_pos, you.y_pos, MHITNOT, 250); - - if (one_chance_in(3)) - create_monster(MONS_NEQOXEC + random2(5), 3, - BEH_HOSTILE, you.x_pos, you.y_pos, MHITNOT, 250); - - if (one_chance_in(4)) - create_monster(MONS_NEQOXEC + random2(5), 3, - BEH_HOSTILE, you.x_pos, you.y_pos, MHITNOT, 250); - - if (one_chance_in(3)) - create_monster(MONS_HELLION + random2(10), 3, - BEH_HOSTILE, you.x_pos, you.y_pos, MHITNOT, 250); - - if (one_chance_in(4)) - create_monster(MONS_HELLION + random2(10), 3, - BEH_HOSTILE, you.x_pos, you.y_pos, MHITNOT, 250); - } - - done_bad = true; - } - else if (you.your_level == 0) - { - // this should remain the last possible outcome {dlb} - temp_rand = random2(3); - - god_speaks(GOD_XOM, - (temp_rand == 0) ? "\"You have grown too comfortable in your little world, mortal!\"" : - (temp_rand == 1) ? "Xom casts you into the Abyss!" - : "The world seems to spin as Xom's maniacal laughter rings in your ears."); - - banished(DNGN_ENTER_ABYSS, "Xom"); - - done_bad = true; - } - } // end "Bad Things" - else - { - // begin "Good Things" - done_good = false; - -// Okay, now for the nicer stuff (note: these things are not necessarily nice): - if (random2(sever) <= 2) - { - temp_rand = random2(4); - - god_speaks(GOD_XOM, - (temp_rand == 0) ? "\"Go forth and destroy!\"" : - (temp_rand == 1) ? "\"Go forth and destroy, mortal!\"" : - (temp_rand == 2) ? "Xom grants you a minor favour." - : "Xom smiles on you."); - - switch (random2(7)) - { - case 0: - potion_effect(POT_HEALING, 150); - break; - case 1: - potion_effect(POT_HEAL_WOUNDS, 150); - break; - case 2: - potion_effect(POT_SPEED, 150); - break; - case 3: - potion_effect(POT_MIGHT, 150); - break; - case 4: - potion_effect(POT_INVISIBILITY, 150); - break; - case 5: - if (one_chance_in(6)) - potion_effect(POT_EXPERIENCE, 150); - else - { - you.berserk_penalty = NO_BERSERK_PENALTY; - potion_effect(POT_BERSERK_RAGE, 150); - } - break; - case 6: - you.berserk_penalty = NO_BERSERK_PENALTY; - potion_effect(POT_BERSERK_RAGE, 150); - break; - } - - done_good = true; - } - else if (random2(sever) <= 4) - { - temp_rand = random2(3); - - god_speaks(GOD_XOM, - (temp_rand == 0) ? "\"Serve the mortal, my children!\"" : - (temp_rand == 1) ? "Xom grants you some temporary aid." - : "Xom opens a gate."); - - create_monster( MONS_NEQOXEC + random2(5), 3, - BEH_FRIENDLY, you.x_pos, you.y_pos, - you.pet_target, 250 ); - - create_monster( MONS_NEQOXEC + random2(5), 3, - BEH_FRIENDLY, you.x_pos, you.y_pos, - you.pet_target, 250 ); - - if (random2( you.experience_level ) >= 8) - { - create_monster( MONS_NEQOXEC + random2(5), 3, - BEH_FRIENDLY, you.x_pos, you.y_pos, - you.pet_target, 250 ); - } - - if (random2( you.experience_level ) >= 8) - { - create_monster( MONS_HELLION + random2(10), 3, - BEH_FRIENDLY, you.x_pos, you.y_pos, - you.pet_target, 250 ); - } - - if (random2( you.experience_level ) >= 8) - { - create_monster( MONS_HELLION + random2(10), 3, - BEH_FRIENDLY, you.x_pos, you.y_pos, - you.pet_target, 250 ); - } - - done_good = true; - } - else if (random2(sever) <= 3) - { - temp_rand = random2(3); - - god_speaks(GOD_XOM, - (temp_rand == 0) ? "\"Take this token of my esteem.\"" : - (temp_rand == 1) ? "Xom grants you a gift!" - : "Xom's generous nature manifests itself."); - - if (grid_destroys_items(grd[you.x_pos][you.y_pos])) { - // How unfortunate. I'll bet Xom feels sorry for you. - mprf(MSGCH_SOUND, - grid_item_destruction_message(grd[you.x_pos][you.y_pos])); - } - else - { - int thing_created = items(1, OBJ_RANDOM, OBJ_RANDOM, true, - you.experience_level * 3, 250); - - move_item_to_grid( &thing_created, you.x_pos, you.y_pos ); - - if (thing_created != NON_ITEM) - { - origin_acquired(mitm[thing_created], GOD_XOM); - canned_msg(MSG_SOMETHING_APPEARS); - more(); - } - } - - done_good = true; - } - else if (random2(sever) <= 4) - { - const int demon = (random2(you.experience_level) < 6) - ? MONS_WHITE_IMP + random2(5) - : MONS_NEQOXEC + random2(5); - - if (create_monster( demon, 0, BEH_FRIENDLY, you.x_pos, you.y_pos, - you.pet_target, 250 ) != -1) - { - temp_rand = random2(3); - - god_speaks(GOD_XOM, - (temp_rand == 0) ? "\"Serve the mortal, my child!\"" : - (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} - } - else if (random2(sever) <= 4) - { - temp_rand = random2(4); - - god_speaks(GOD_XOM, - (temp_rand == 0) ? "\"Take this instrument of destruction!\"" : - (temp_rand == 1) ? "\"You have earned yourself a gift.\"" : - (temp_rand == 2) ? "Xom grants you an implement of death." - : "Xom smiles on you."); - - if (acquirement(OBJ_WEAPONS, GOD_XOM)) - more(); - - done_good = true; - } - else if (!you.is_undead && random2(sever) <= 5) - { - temp_rand = random2(4); - - god_speaks(GOD_XOM, - (temp_rand == 0) ? "\"You need some minor adjustments, mortal!\"" : - (temp_rand == 1) ? "\"Let me alter your pitiful body.\"" : - (temp_rand == 2) ? "Xom's power touches on you for a moment." - : "You hear Xom's maniacal chuckling."); - - mpr("Your body is suffused with distortional energy."); - - set_hp(1 + random2(you.hp), false); - deflate_hp(you.hp_max / 2, true); - - if (coinflip() || !give_cosmetic_mutation()) - give_good_mutation(); - - done_good = true; - } - else if (random2(sever) <= 2) - { - // this should remain the last possible outcome {dlb} - if (!one_chance_in(8)) - you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] = 1; - - god_speaks(GOD_XOM, "The area is suffused with divine lightning!"); - - beam.beam_source = NON_MONSTER; - beam.type = SYM_BURST; - beam.damage = dice_def( 3, 30 ); - beam.flavour = BEAM_ELECTRICITY; - beam.target_x = you.x_pos; - beam.target_y = you.y_pos; - beam.name = "blast of lightning"; - beam.colour = LIGHTCYAN; - beam.thrower = KILL_MISC; - beam.aux_source = "Xom's lightning strike"; - beam.ex_size = 2; - beam.is_tracer = false; - beam.is_explosion = true; - - explosion(beam); - - if (you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] == 1) - { - mpr("Your divine protection wanes."); - you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] = 0; - } - - done_good = true; - } - } // end "Good Things" - - 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() - // 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 ) @@ -1674,8 +1264,12 @@ bool did_god_conduct( int thing_done, int level ) return (ret); } -void gain_piety(char pgn) +void gain_piety(int pgn) { + // Xom uses piety differently... + if (you.religion == GOD_XOM) + return; + // check to see if we owe anything first if (you.penance[you.religion] > 0) { @@ -1750,7 +1344,7 @@ void gain_piety(char pgn) do_god_gift(); } -void lose_piety(char pgn) +void lose_piety(int pgn) { int old_piety = you.piety; @@ -1791,7 +1385,7 @@ void lose_piety(char pgn) } } -static void lugonu_retribution(int god) +static void lugonu_retribution(god_type god) { if (coinflip()) { @@ -1806,7 +1400,7 @@ static void lugonu_retribution(int god) simple_god_message("'s wrath finds you!", god); mpr("Space warps around you!"); if (!one_chance_in(3)) - you_teleport2(false); + you_teleport_now(false); else random_blink(false); @@ -1848,7 +1442,7 @@ static void lugonu_retribution(int god) } } -void divine_retribution( int god ) +void divine_retribution( god_type god ) { ASSERT(god != GOD_NO_GOD); @@ -1874,14 +1468,8 @@ void divine_retribution( int god ) switch (god) { case GOD_XOM: - { - // One in ten chance that Xom might do something good... - // but that isn't forced, bad things are though - bool nice = one_chance_in(10); - bool force = !nice; - - Xom_acts(nice, you.experience_level, force); - } + // One in ten chance that Xom might do something good... + xom_acts(one_chance_in(10), abs(you.piety - 100)); break; case GOD_SHINING_ONE: @@ -2343,7 +1931,7 @@ void divine_retribution( int god ) void excommunication(void) { - const int old_god = you.religion; + const god_type old_god = you.religion; take_note(Note(NOTE_LOSE_GOD, old_god)); @@ -2358,7 +1946,7 @@ void excommunication(void) switch (old_god) { case GOD_XOM: - Xom_acts( false, (you.experience_level * 2), true ); + xom_acts( false, abs(you.piety - 100) * 2); inc_penance( old_god, 50 ); break; @@ -2613,7 +2201,7 @@ void offer_items() } } -void god_pitch(unsigned char which_god) +void god_pitch(god_type which_god) { mprf("You kneel at the altar of %s.", god_name(which_god)); more(); @@ -2660,8 +2248,19 @@ void god_pitch(unsigned char which_god) //jmf: moved up so god_speaks gives right colour you.religion = static_cast<god_type>(which_god); - you.piety = 15; // to prevent near instant excommunication - you.gift_timeout = 0; + + if (you.religion == GOD_XOM) + { + // Xom uses piety and gift_timeout differently. + you.piety = 100; + you.gift_timeout = random2(40) + random2(40); + } + else + { + you.piety = 15; // to prevent near instant excommunication + you.gift_timeout = 0; + } + set_god_ability_slots(); // remove old god's slots, reserve new god's #ifdef DGL_WHEREIS whereis_record(); @@ -2742,7 +2341,7 @@ void handle_god_time(void) // why we do it this way... it requires only one pass and doesn't // require an array. - int which_god = GOD_NO_GOD; + god_type which_god = GOD_NO_GOD; unsigned int count = 0; for (int i = GOD_NO_GOD; i < NUM_GODS; i++) @@ -2751,7 +2350,7 @@ void handle_god_time(void) { count++; if (one_chance_in(count)) - which_god = i; + which_god = static_cast<god_type>(i); } } @@ -2765,9 +2364,47 @@ void handle_god_time(void) switch (you.religion) { case GOD_XOM: - if (one_chance_in(75)) - Xom_acts(true, you.experience_level + random2(15), true); + { + // Xom semi-randomly drifts your piety. + int delta; + const char *origfavour = describe_xom_favour(); + const bool good = you.piety >= 100; + int size = abs(you.piety - 100); + delta = (random2(1000) < 511) ? 1 : -1; + size += delta; + you.piety = 100 + (good ? size : -size); + const char *newfavour = describe_xom_favour(); + if (strcmp(origfavour, newfavour)) + { + // Dampen oscillation across announcement boundaries: + size += delta * 2; + you.piety = 100 + (good ? size : -size); + } + + // ... but he gets bored... (I re-use gift_timeout for + // this instead of making a separate field because I don't + // want to learn how to save and restore a new field). In + // this usage, the "gift" is the gift you give to Xom of + // something interesting happening. + if (you.gift_timeout == 1) + { + mpr("Xom is getting BORED."); + you.gift_timeout = 0; + } + else if (you.gift_timeout > 1) + { + you.gift_timeout -= random2(2); + } + + if (one_chance_in(20)) + { + // If you.gift_timeout was == 0, then Xom was BORED. + // He HATES that. + xom_acts(you.gift_timeout > 0 && you.piety > 100, + abs(you.piety - 100)); + } break; + } case GOD_ZIN: // These gods like long-standing worshippers case GOD_ELYVILON: @@ -2831,7 +2468,7 @@ void handle_god_time(void) } // end handle_god_time() // yet another wrapper for mpr() {dlb}: -void simple_god_message(const char *event, int which_deity) +void simple_god_message(const char *event, god_type which_deity) { char buff[ INFO_SIZE ]; @@ -2843,7 +2480,7 @@ void simple_god_message(const char *event, int which_deity) god_speaks( which_deity, buff ); } -char god_colour( char god ) //mv - added +int god_colour( god_type god ) //mv - added { switch (god) { |