diff options
author | j-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573> | 2009-03-29 12:43:34 +0000 |
---|---|---|
committer | j-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573> | 2009-03-29 12:43:34 +0000 |
commit | 996361d167065bc29bef5da248e3d18bd0d9cbab (patch) | |
tree | bac3e756a6c0a8d10988563761cdb297652cd9c6 /crawl-ref/source | |
parent | 262fc856ccb0dbc4462aa71cfb7f56d81cd9b03d (diff) | |
download | crawl-ref-996361d167065bc29bef5da248e3d18bd0d9cbab.tar.gz crawl-ref-996361d167065bc29bef5da248e3d18bd0d9cbab.zip |
* When Xom decides to cast Magic Mapping or send you on a teleportation
journey, use a random sample of level grids as a guesstimate of the
explored portion of the level, and reduce chances for mostly explored
levels.
* Don't attempt to cast spells you wouldn't be able to cast (e.g. the
transformations for undead).
* Tweak random uselessness messages as per FR 2595700.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@9565 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/effects.cc | 21 | ||||
-rw-r--r-- | crawl-ref/source/spl-cast.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/view.cc | 25 | ||||
-rw-r--r-- | crawl-ref/source/xom.cc | 146 |
4 files changed, 150 insertions, 44 deletions
diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index 76477d6331..d236f38719 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -806,7 +806,8 @@ void random_uselessness(int scroll_slot) break; case 1: - mpr("The scroll reassembles itself in your hands!"); + mprf("The scroll reassembles itself in your %s!", + your_hand(true).c_str()); inc_inv_item_quantity(scroll_slot, 1); break; @@ -825,12 +826,10 @@ void random_uselessness(int scroll_slot) break; case 3: - if (player_can_smell()) - mprf("You smell %s.", weird_smell().c_str()); - else if (you.species == SP_MUMMY) + if (you.species == SP_MUMMY) mpr("Your bandages flutter."); - else // currently not ever used - canned_msg(MSG_NOTHING_HAPPENS); + else // if (player_can_smell()) + mprf("You smell %s.", weird_smell().c_str()); break; case 4: @@ -839,10 +838,12 @@ void random_uselessness(int scroll_slot) case 5: temp_rand = random2(3); - mprf("Your %s", - (temp_rand == 0) ? "ears itch!" : - (temp_rand == 1) ? "brain hurts!" - : "nose twitches suddenly!"); + if (player_mutation_level(MUT_BEAK) || one_chance_in(3)) + mpr("Your brain hurts!"); + else if (you.species == SP_MUMMY || coinflip()) + mpr("Your ears itch!"); + else + mpr("Your nose twitches suddenly!"); break; case 6: diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc index 085426734a..f8d54c1e02 100644 --- a/crawl-ref/source/spl-cast.cc +++ b/crawl-ref/source/spl-cast.cc @@ -1978,9 +1978,7 @@ spret_type your_spells(spell_type spell, int powc, bool allow_fail) case SPELL_MAGIC_MAPPING: if (you.level_type == LEVEL_PANDEMONIUM) - { mpr("Your Earth magic cannot map Pandemonium."); - } else { powc = stepdown_value( powc, 10, 10, 40, 45 ); diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index 7fedaa0110..d641ac4f02 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -3836,9 +3836,6 @@ bool magic_mapping(int map_radius, int proportion, bool suppress_msg, return (false); } - if (!suppress_msg) - mpr( "You feel aware of your surroundings." ); - if (map_radius > 50 && map_radius != 1000) map_radius = 50; else if (map_radius < 5) @@ -3848,8 +3845,10 @@ bool magic_mapping(int map_radius, int proportion, bool suppress_msg, const int pfar = (map_radius * 7) / 10; const int very_far = (map_radius * 9) / 10; - const bool wizard_map = map_radius == 1000 && you.wizard; - for ( radius_iterator ri(you.pos(), map_radius, true, false); ri; ++ri ) + const bool wizard_map = (you.wizard && map_radius == 1000); + + bool did_map = false; + for (radius_iterator ri(you.pos(), map_radius, true, false); ri; ++ri) { if (proportion < 100 && random2(100) >= proportion) continue; // note that proportion can be over 100 @@ -3875,7 +3874,7 @@ bool magic_mapping(int map_radius, int proportion, bool suppress_msg, } #endif - if (!wizard_map && is_terrain_known(*ri)) + if (!wizard_map && (is_terrain_known(*ri) || is_terrain_seen(*ri))) continue; bool open = true; @@ -3883,7 +3882,7 @@ bool magic_mapping(int map_radius, int proportion, bool suppress_msg, if (grid_is_solid(grd(*ri)) && grd(*ri) != DNGN_CLOSED_DOOR) { open = false; - for ( adjacent_iterator ai(*ri); ai; ++ai ) + for (adjacent_iterator ai(*ri); ai; ++ai) { if (map_bounds(*ai) && (!grid_is_opaque(grd(*ai)) || grd(*ai) == DNGN_CLOSED_DOOR)) @@ -3894,7 +3893,7 @@ bool magic_mapping(int map_radius, int proportion, bool suppress_msg, } } - if (open > 0) + if (open) { if (wizard_map || !get_envmap_obj(*ri)) set_envmap_obj(*ri, grd(*ri)); @@ -3903,10 +3902,18 @@ bool magic_mapping(int map_radius, int proportion, bool suppress_msg, set_terrain_seen(*ri); else set_terrain_mapped(*ri); + + did_map = true; } } - return (true); + if (!suppress_msg) + { + mpr(did_map ? "You feel aware of your surroundings." + : "You feel momentarily disoriented."); + } + + return (did_map); } // Realize that this is simply a repackaged version of diff --git a/crawl-ref/source/xom.cc b/crawl-ref/source/xom.cc index 673630344b..0626b35b5f 100644 --- a/crawl-ref/source/xom.cc +++ b/crawl-ref/source/xom.cc @@ -33,6 +33,7 @@ REVISION("$Rev$"); #include "spells1.h" #include "spells2.h" #include "spells3.h" +#include "spl-book.h" #include "spl-cast.h" #include "spl-mis.h" #include "spl-util.h" @@ -209,6 +210,20 @@ void xom_is_stimulated(int maxinterestingness, xom_message_type message_type, force_message); } +void xom_is_stimulated(int maxinterestingness, const std::string& message, + bool force_message) +{ + if (you.religion != GOD_XOM) + return; + + const char *message_array[6]; + + for (int i = 0; i < 6; ++i) + message_array[i] = message.c_str(); + + _xom_is_stimulated(maxinterestingness, message_array, force_message); +} + void xom_tick() { // Xom semi-randomly drifts your piety. @@ -249,15 +264,30 @@ void xom_tick() tension <= 20 ? 4 : 5); - // During tension, Xom may briefly forget about being bored. - if (_xom_is_bored() && x_chance_in_y(chance-1, 4)) + // If Xom is bored the chances for Xom acting are reversed. + if (you.gift_timeout == 0 && x_chance_in_y(5-chance,5)) { - you.gift_timeout += random2(chance*20); + xom_acts(abs(you.piety - MAX_PIETY/2), tension); + return; + } + else if (you.gift_timeout <= 1 && x_chance_in_y(chance-1, 4)) + { + // During tension, Xom may briefly forget about being bored. + const int interest = random2(chance*15); + if (interest > 0) + { + if (interest < 25) + simple_god_message(" is interested."); + else + simple_god_message(" is intrigued."); + + you.gift_timeout += interest; #if defined(DEBUG_RELIGION) || defined(DEBUG_XOM) - mprf(MSGCH_DIAGNOSTICS, - "tension %d (chance: %d) -> increase interest to %d", - tension, chance, you.gift_timeout); + mprf(MSGCH_DIAGNOSTICS, + "tension %d (chance: %d) -> increase interest to %d", + tension, chance, you.gift_timeout); #endif + } } if (x_chance_in_y(chance, 5)) @@ -265,21 +295,63 @@ void xom_tick() } } -void xom_is_stimulated(int maxinterestingness, const std::string& message, - bool force_message) +// Picks 100 random grids from the level and checks whether they've been +// marked as seen (explored) or known (mapped). If seen_only is true +// grids only "seen" via magic mapping don't count. +// Returns the estimated percentage value of exploration. +static int _exploration_estimate(bool seen_only = false) { - if (you.religion != GOD_XOM) - return; + int seen = 0; + int total = 0; + int tries = 0; + do + { + tries++; + coord_def pos = random_in_bounds(); + if (!seen_only && is_terrain_known(pos) || is_terrain_seen(pos)) + { + seen++; + total++; + continue; + } - const char *message_array[6]; + bool open = true; + if (grid_is_solid(grd(pos)) && grd(pos) != DNGN_CLOSED_DOOR) + { + open = false; + for (adjacent_iterator ai(pos); ai; ++ai) + { + if (map_bounds(*ai) && (!grid_is_opaque(grd(*ai)) + || grd(*ai) == DNGN_CLOSED_DOOR)) + { + open = true; + break; + } + } + } + if (open) + total++; + } + while (total < 100 && tries < 1000); - for (int i = 0; i < 6; ++i) - message_array[i] = message.c_str(); +#ifdef DEBUG_XOM + mprf(MSGCH_DIAGNOSTICS, + "exploration estimate (%s): %d out of %d grids seen", + seen_only ? "explored" : "mapped", seen, total); +#endif - _xom_is_stimulated(maxinterestingness, message_array, force_message); + // If we didn't get any qualifying grids, there are probably so few + // of them you've already seen them all. + if (total == 0) + return 100; + + if (total < 100) + seen *= 100/total; + + return (seen); } -static void _xom_makes_you_cast_random_spell(int sever, int tension) +static bool _xom_makes_you_cast_random_spell(int sever, int tension) { int spellenum = sever; @@ -297,7 +369,19 @@ static void _xom_makes_you_cast_random_spell(int sever, int tension) const int nxomspells = ARRAYSZ(_xom_nontension_spells); spellenum = std::min(nxomspells, spellenum); spell = _xom_nontension_spells[random2(spellenum)]; + + if (spell == SPELL_MAGIC_MAPPING) + { + // If the level is already mostly explored, there's + // a chance we might try something else. + const int explored = _exploration_estimate(); + if (explored > 80 && x_chance_in_y(explored, 100)) + return (false); + } } + // Don't attempt to cast spells the undead cannot memorise. + if (you_cannot_memorise(spell)) + return (false); god_speaks(GOD_XOM, _get_xom_speech("spell effect").c_str()); @@ -308,6 +392,7 @@ static void _xom_makes_you_cast_random_spell(int sever, int tension) #endif your_spells(spell, sever, false); + return (true); } static void _try_brand_switch(const int item_index) @@ -1261,10 +1346,7 @@ static bool _xom_is_good(int sever, int tension) // There are a lot less non-tension spells than tension ones, // so use them more rarely. if (tension > 0 || one_chance_in(3)) - { - _xom_makes_you_cast_random_spell(sever, tension); - done = true; - } + done = _xom_makes_you_cast_random_spell(sever, tension); } else if (x_chance_in_y(4, sever)) done = _xom_confuse_monsters(sever); @@ -1288,8 +1370,15 @@ static bool _xom_is_good(int sever, int tension) _xom_give_item(sever); done = true; } - else if (x_chance_in_y(11, sever) && (you.level_type != LEVEL_ABYSS)) + else if (x_chance_in_y(11, sever) && you.level_type != LEVEL_ABYSS) { + // This is not very interesting if the level is already fully + // explored (presumably cleared). Even then, it may occasionally + // happen. + const int explored = _exploration_estimate(true); + if (explored >= 80 && x_chance_in_y(explored, 120)) + return (false); + // The Xom teleportation train takes you on instant teleportation // to a few random areas, stopping randomly but most likely in // an area that is not dangerous to you. @@ -1679,7 +1768,8 @@ static void _get_hand_type(std::string &hand, bool &can_plural) hand_vec.push_back("mandible"); plural_vec.push_back(true); } - else if (you.species != SP_MUMMY || transform_changed_physiology()) + else if (you.species != SP_MUMMY && !player_mutation_level(MUT_BEAK) + || transform_changed_physiology()) { hand_vec.push_back("nose"); plural_vec.push_back(false); @@ -1962,9 +2052,19 @@ static bool _xom_is_bad(int sever, int tension) badness = 2; done = true; } - else if ((!nasty || coinflip()) - && x_chance_in_y(7, sever) && you.level_type != LEVEL_ABYSS) + else if (x_chance_in_y(7, sever) && you.level_type != LEVEL_ABYSS) { + // This is not particularly exciting if the level is already fully + // explored (presumably cleared). If Xom is feeling nasty this + // is likelier to happen if the level is unexplored. + const int explored = _exploration_estimate(true); + if (nasty && explored >= 50 && coinflip() + || explored >= 80 + random2(20)) + { + done = false; + continue; + } + // The Xom teleportation train takes you on instant // teleportation to a few random areas, stopping if either // an area is dangerous to you or randomly. |