diff options
-rw-r--r-- | crawl-ref/source/effects.cc | 43 | ||||
-rw-r--r-- | crawl-ref/source/effects.h | 4 | ||||
-rw-r--r-- | crawl-ref/source/invent.cc | 18 | ||||
-rw-r--r-- | crawl-ref/source/invent.h | 10 | ||||
-rw-r--r-- | crawl-ref/source/religion.cc | 31 | ||||
-rw-r--r-- | crawl-ref/source/spells2.cc | 232 | ||||
-rw-r--r-- | crawl-ref/source/view.cc | 3 |
7 files changed, 189 insertions, 152 deletions
diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index 951a37e139..22710a3139 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -2944,7 +2944,7 @@ void change_labyrinth(bool msg) if (is_terrain_seen(*ri)) count_known++; - if (tries > 1 && count_known > size*size/6) + if (tries > 1 && count_known > size * size / 6) continue; // Fill a vector with wall grids that are potential targets for @@ -4341,7 +4341,7 @@ int spawn_corpse_mushrooms(item_def &corpse, { seen_targets = 0; if (target_count == 0) - return 0; + return (0); int c_size = 8; int permutation[] = {0, 1, 2, 3, 4, 5, 6, 7}; @@ -4365,7 +4365,7 @@ int spawn_corpse_mushrooms(item_def &corpse, corpse.special = 0; if (see_grid(corpse.pos)) - mpr("A ring of toadstools grow before your very eyes."); + mpr("A ring of toadstools grows before your very eyes."); else if (ring_seen > 1) mpr("Some toadstools grow in a peculiar arc."); else if (ring_seen > 0) @@ -4413,10 +4413,10 @@ int spawn_corpse_mushrooms(item_def &corpse, if (mushroom != -1) { - // Going to expliclty override the die-off timer in this case - // (this condition means we got called from fungal_bloom or - // similar and are creating a lot of toadstools at once that - // should die off quickly). + // Going to explicitly override the die-off timer in + // this case (this condition means we got called from + // fungal_bloom() or similar, and are creating a lot of + // toadstools at once that should die off quickly). if (distance_as_time) { coord_def offset = corpse.pos - current; @@ -4496,6 +4496,24 @@ int mushroom_prob(item_def & corpse) return (trial_prob); } +bool mushroom_spawn_message(int seen_targets, int seen_corpses) +{ + if (seen_targets > 0) + { + std::string what = seen_targets > 1 ? "Some toadstools" + : "A toadstool"; + std::string where = seen_corpses > 1 ? "nearby corpses" : + seen_corpses == 1 ? "a nearby corpse" + : "the ground"; + mprf("%s grow%s from %s.", + what.c_str(), seen_targets > 1 ? "" : "s", where.c_str()); + + return (true); + } + + return (false); +} + // Randomly decide whether or not to spawn a mushroom over the given // corpse. Assumption: this is called before the rotting away logic in // update_corpses. Some conditions in this function may set the corpse @@ -4526,16 +4544,7 @@ static void _maybe_spawn_mushroom(item_def & corpse, int rot_time) int seen_spawns; spawn_corpse_mushrooms(corpse, success_count, seen_spawns); - - if (seen_spawns > 0) - { - std::string base = seen_spawns > 1 ? "Some toadstools" : "A toadstool"; - - if (see_grid(corpse.pos)) - mprf("%s grows from a nearby corpse.", base.c_str()); - else - mprf("%s springs up from the ground.", base.c_str()); - } + mushroom_spawn_message(seen_spawns, see_grid(corpse.pos) ? 1 : 0); } //--------------------------------------------------------------- diff --git a/crawl-ref/source/effects.h b/crawl-ref/source/effects.h index 3580839ed0..f80f1bc4dd 100644 --- a/crawl-ref/source/effects.h +++ b/crawl-ref/source/effects.h @@ -51,9 +51,11 @@ bool lose_stat(unsigned char which_stat, unsigned char stat_loss, // called from spells2 -cao int mushroom_prob(item_def & corpse); +bool mushroom_spawn_message(int seen_targets, int seen_corpses); + int spawn_corpse_mushrooms(item_def &corpse, int target_count, - int & seen_targers, + int & seen_targets, bool distance_as_time = false); struct mgen_data; diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc index ac3e7e8dd8..ee7ca7dae4 100644 --- a/crawl-ref/source/invent.cc +++ b/crawl-ref/source/invent.cc @@ -1000,13 +1000,6 @@ static bool _item_class_selected(const item_def &i, int selector) case OSEL_FRUIT: return is_fruit(i); - // This is really dumb. I don't want to talk about it. -cao - case OSEL_SOME_FRUIT: - - return is_fruit(i) && i.quantity >= 2; - - - case OSEL_WORN_ARMOUR: return (itype == OBJ_ARMOUR && item_is_equipped(i)); @@ -1186,8 +1179,8 @@ static unsigned char _get_invent_quant( unsigned char keyin, int &quant ) // This function prompts the user for an item, handles the '?' and '*' // listings, and returns the inventory slot to the caller (which if -// must_exist is true (the default) will be an assigned item, with -// a positive quantity. +// must_exist is true, as it is by default, will be an assigned item, +// with a positive quantity. // // It returns PROMPT_ABORT if the player hits escape. // It returns PROMPT_GOT_SPECIAL if the player hits the "other_valid_char". @@ -1636,7 +1629,9 @@ int prompt_invent_item( const char *prompt, need_getch = false; // Don't redraw if we're just going to display another listing - need_redraw = (keyin != '?' && keyin != '*'); + need_redraw = (keyin != '?' && keyin != '*') + && !(count && auto_list && isdigit(keyin)); + need_prompt = need_redraw; if (items.size()) @@ -1658,6 +1653,9 @@ int prompt_invent_item( const char *prompt, need_prompt = false; need_getch = false; + + if (auto_list) + need_redraw = true; } else if (count == NULL && isdigit( keyin )) { diff --git a/crawl-ref/source/invent.h b/crawl-ref/source/invent.h index 8eab5f2310..e0999fe520 100644 --- a/crawl-ref/source/invent.h +++ b/crawl-ref/source/invent.h @@ -30,13 +30,13 @@ enum object_selector OSEL_BUTCHERY = -10, OSEL_EVOKABLE = -11, OSEL_WORN_ARMOUR = -12, - OSEL_FRUIT = -13, - OSEL_SOME_FRUIT = -14 + OSEL_FRUIT = -13 }; -#define PROMPT_ABORT -1 -#define PROMPT_GOT_SPECIAL -2 -#define PROMPT_NOTHING -3 +#define PROMPT_ABORT -1 +#define PROMPT_GOT_SPECIAL -2 +#define PROMPT_NOTHING -3 +#define PROMPT_INAPPROPRIATE -4 struct SelItem { diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index 6297122b59..7dbcb3fd8b 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -6048,29 +6048,6 @@ static bool _feawn_plants_hostile() return (false); } -static bool _feawn_plants_on_level_neutral() -{ - for (int i = 0; i < MAX_MONSTERS; ++i) - { - monsters *monster = &menv[i]; - - feawn_neutralise_plant(monster); - } - - return (true); -} - -static bool _feawn_plants_neutral() -{ - if (apply_to_all_dungeons(_feawn_plants_on_level_neutral)) - { - mpr("The plants of the dungeon cease their hostilities." , MSGCH_GOD); - return (true); - } - - return (false); -} - // Upon excommunication, ex-Beoghites lose all their orcish followers, // plus all monsters created by their priestly orcish followers. When // under penance, Beoghites can lose all orcish followers in sight, @@ -6493,9 +6470,9 @@ void beogh_convert_orc(monsters *orc, bool emergency, void feawn_neutralise_plant(monsters *plant) { - if (plant->type != MONS_OKLOB_PLANT - && plant->type != MONS_WANDERING_MUSHROOM - && !testbits(plant->flags, MF_ATT_CHANGE_ATTEMPT)) + if ((plant->type != MONS_OKLOB_PLANT + && plant->type != MONS_WANDERING_MUSHROOM) + || testbits(plant->flags, MF_ATT_CHANGE_ATTEMPT)) { return; } @@ -7439,7 +7416,7 @@ void god_pitch(god_type which_god) { mpr("You can call upon Feawn to speed up the decay of corpses.", MSGCH_GOD); - _feawn_plants_neutral(); + mpr("The plants of the dungeon cease their hostilities.", MSGCH_GOD); } if (you.worshipped[you.religion] < 100) diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc index e2ce66c038..c93aa41ad2 100644 --- a/crawl-ref/source/spells2.cc +++ b/crawl-ref/source/spells2.cc @@ -1738,11 +1738,10 @@ int fungal_bloom() int processed_count = 0; for (radius_iterator i(you.position, LOS_RADIUS); i; ++i) { - // going to ignore squares that are already occupied by non-fungi + // Ignore squares that are already occupied by non-fungi. if (actor_at(*i) && !actor_at(*i)->mons_species() == MONS_TOADSTOOL) continue; - for (stack_iterator j(*i); j; ++j) { bool corpse_on_pos = false; @@ -1773,16 +1772,11 @@ int fungal_bloom() if (seen_mushrooms > 0) { - // We obviously saw some corpses since we only processed squares + // We obviously saw some corpses, since we only processed squares // in LOS. ASSERT(seen_corpses > 0); - mprf("%s grow%s from %snearby corpse%s.", - (seen_mushrooms > 1 ? "Some toadstools" - : "A toadstool"), - (seen_mushrooms > 1 ? "s" : ""), - (seen_corpses > 1) ? "" : "a ", - (seen_corpses > 1) ? "s" : ""); + mushroom_spawn_message(seen_mushrooms, seen_corpses); } return (processed_count); @@ -1791,7 +1785,7 @@ int fungal_bloom() int create_plant(coord_def & target) { if (actor_at(target) || !mons_class_can_pass(MONS_PLANT, grd(target))) - return 0; + return (0); const int plant = create_monster(mgen_data (MONS_PLANT, @@ -2092,15 +2086,14 @@ bool prioritise_adjacent(coord_def & target, std::vector<coord_def> & candidates return (true); } -// Create a ring or partial ring around the caster. -// User is prompted to select a stack of fruit then plants are placed on open -// squares adjacent to the caster, of course 1 piece of fruit is consumed per -// plant so a complete ring may not be formed. -bool plant_ring_from_fruit() +// Prompt the user to select a stack of fruit from their inventory. The +// user can optionally select only a partial stack of fruit (the count +// variable will store the number of fruit the user wants). Return the +// index of the item selected in the user's inventory, or a negative +// number if the prompt failed (user canceled or had no fruit). +int _prompt_for_fruit(int & count, const char * prompt_string) { - int possible_count; - int created_count = 0; - int rc = prompt_invent_item("Use which fruit?", + int rc = prompt_invent_item(prompt_string, MT_INVLIST, OSEL_FRUIT, true, @@ -2108,10 +2101,36 @@ bool plant_ring_from_fruit() true, '\0', -1, - &possible_count); + &count); if (prompt_failed(rc)) - return 0; + return (rc); + + // Return PROMPT_INAPPROPRIATE if the 'object selected isn't + // actually fruit. + if (!is_fruit(you.inv[rc])) + return (PROMPT_INAPPROPRIATE); + + // Handle it if the user lies about the amount of fruit available. + if (count > you.inv[rc].quantity) + count = you.inv[rc].quantity; + + return (rc); +} + +// Create a ring or partial ring around the caster. The user is +// prompted to select a stack of fruit, and then plants are placed on open +// squares adjacent to the user. Of course, one piece of fruit is +// consumed per plant, so a complete ring may not be formed. +bool plant_ring_from_fruit() +{ + int possible_count; + int created_count = 0; + int rc = _prompt_for_fruit(possible_count, "Use which fruit?"); + + // Prompt failed? + if (rc < 0) + return (false); std::vector<coord_def> adjacent; @@ -2124,39 +2143,40 @@ bool plant_ring_from_fruit() } } - if ((int) adjacent.size() > possible_count) + if ((int)adjacent.size() > possible_count) { prioritise_adjacent(you.pos(), adjacent); } unsigned target_count = - (possible_count < (int) adjacent.size()) ? possible_count - : adjacent.size(); + (possible_count < (int)adjacent.size()) ? possible_count + : adjacent.size(); for (unsigned i = 0; i < target_count; ++i) + { if (create_plant(adjacent[i])) created_count++; + } dec_inv_item_quantity(rc, created_count); return (created_count); } - -// Creates a circle of water around the target (radius is approximately 2) -// Turns normal floor tiles into shallow water and turns (unoccupied) shallow -// water into deep water. -// Chance of spawning plants or fungus on unoccupied dry floor tiles outside -// of the rainfall area -// Returns the number of plants/fungus created +// Create a circle of water around the target, with a radius of +// approximately 2. This turns normal floor tiles into shallow water +// and turns (unoccupied) shallow water into deep water. There is a +// chance of spawning plants or fungus on unoccupied dry floor tiles +// outside of the rainfall area. Return the number of plants/fungi +// created. int rain(coord_def & target) { int spawned_count = 0; for (radius_iterator rad(target, LOS_RADIUS, true, true, true); rad; ++rad) { - // Adjusting the shape of the rainfall slightly to make it look nicer. - // I want a threshold of 2.5 on the euclidean distance so a threshold - // of 6 prior to the sqrt is close enough. + // Adjust the shape of the rainfall slightly to make it look + // nicer. I want a threshold of 2.5 on the euclidean distance, + // so a threshold of 6 prior to the sqrt is close enough. int rain_thresh = 6; coord_def local = *rad - target; @@ -2164,12 +2184,12 @@ int rain(coord_def & target) if (local.abs() > rain_thresh) { - // Maybe spawn a plant on (dry, open) squares that are in LOS but - // outside the rainfall area. - // In open space there are 213 squares in LOS, and we are - // going to drop water on (25-4) of those, so if we want x plants - // to spawn on average in open space the trial probability should - // be x/192 + // Maybe spawn a plant on (dry, open) squares that are in + // LOS but outside the rainfall area. In open space, there + // are 213 squares in LOS, and we are going to drop water on + // (25-4) of those, so if we want x plants to spawn on + // average in open space, the trial probability should be + // x/192. if (x_chance_in_y(5, 192) && !actor_at(*rad) && ftype >= DNGN_FLOOR_MIN @@ -2187,24 +2207,25 @@ int rain(coord_def & target) if (plant != -1) spawned_count++; } + continue; } - // Turn regular floor squares only into shallow water + // Turn regular floor squares only into shallow water. if (ftype >= DNGN_FLOOR_MIN && ftype <= DNGN_FLOOR_MAX) { grd(*rad) = DNGN_SHALLOW_WATER; - // Remove blood stains as well + // Remove blood stains as well. env.map(*rad).property &= ~(FPROP_BLOODY); monsters *mon = monster_at(*rad); if (mon && mon->has_ench(ENCH_AQUATIC_LAND)) mon->del_ench(ENCH_AQUATIC_LAND); } - // We can also turn shallow water into deep water, but we're just going - // to skip cases where there is something on the shallow water. - // Destroying items will probably annoy people and insta-killing - // monsters is clearly out of the question. + // We can also turn shallow water into deep water, but we're + // just going to skip cases where there is something on the + // shallow water. Destroying items will probably be annoying, + // and insta-killing monsters is clearly out of the question. else if (!actor_at(*rad) && igrd(*rad) == NON_ITEM && ftype == DNGN_SHALLOW_WATER) @@ -2213,7 +2234,7 @@ int rain(coord_def & target) } } - if (spawned_count>0) + if (spawned_count > 0) { mprf("%s grow%s in the rain.", (spawned_count > 1 ? "Some plants" : "A plant"), @@ -2272,17 +2293,18 @@ struct monster_conversion bool operator<(const monster_conversion & left, const monster_conversion & right) { - if(left.cost == right.cost) - return coinflip(); - return left.cost < right.cost; + if (left.cost == right.cost) + return (coinflip()); + + return (left.cost < right.cost); } -// Given a monster (well it should be a plant/fungus) see if evolve_flora can -// upgrade it, and set up a monster_conversion structure for it. Returns true -// (and fills in possible_monster) if input an be upgraded, and returns false -// otherwise. +// Given a monster (which should be a plant/fungus), see if +// evolve_flora() can upgrade it, and set up a monster_conversion +// structure for it. Return true (and fill in possible_monster) if the +// monster can be upgraded, and return false otherwise. bool _possible_evolution(monsters * input, - monster_conversion & possible_monster) + monster_conversion & possible_monster) { int plant_cost = 10; int toadstool_cost = 1; @@ -2307,27 +2329,45 @@ bool _possible_evolution(monsters * input, break; default: - return false; - + return (false); } - return true; + return (true); } bool evolve_flora() { - int needed_fruit = 2; + int rc; + int available_count; + + int points_per_fruit = 8; + int oklob_cost = 10; - std::priority_queue<monster_conversion, std::vector<monster_conversion> > - available_targets; + float approx_oklob_rate = float(points_per_fruit)/float(oklob_cost); + + char prompt_string[100]; + memset(prompt_string,0,100); + sprintf(prompt_string,"Use which fruit (%1.1f oklob plants per fruit)?", + approx_oklob_rate); + + rc = _prompt_for_fruit(available_count, prompt_string); + + // Prompt failed? + if (rc < 0) + return (false); + + int points = points_per_fruit * available_count; + int starting_points = points; + + std::priority_queue<monster_conversion> available_targets; - int points = 15; monster_conversion temp_conversion; for (radius_iterator rad(you.pos(), LOS_RADIUS, true, true, true); rad; ++rad) { monsters * target = monster_at(*rad); + if (!target) continue; @@ -2335,20 +2375,12 @@ bool evolve_flora() available_targets.push(temp_conversion); } + // Nothing available to upgrade. if (available_targets.empty()) + { + mpr("No flora in sight can be evolved."); return (false); - - int rc; - int available_count; - - rc = prompt_invent_item("Use which fruit (must have at least 2)?", - MT_INVLIST, OSEL_SOME_FRUIT, true, true, true, '\0', -1, - &available_count); - - if (prompt_failed(rc)) - return (false); - - dec_inv_item_quantity(rc, needed_fruit); + } int plants_evolved = 0; int toadstools_evolved = 0; @@ -2387,7 +2419,8 @@ bool evolve_flora() current_plant->attitude = ATT_FRIENDLY; current_plant->flags |= MF_CREATED_FRIENDLY; - // Try to remove slowly dying in case we are upgrading a toadstool. + // Try to remove slowly dying in case we are upgrading a + // toadstool. current_plant->del_ench(ENCH_SLOWLY_DYING); // Maybe we can upgrade it again? @@ -2398,29 +2431,46 @@ bool evolve_flora() } } - // messaging... - if (plants_evolved > 0) - { - mprf("%s can now spit acid.", - (plants_evolved > 1 ? "Some plants" : "A plant")); - } + // How many pieces of fruit did we use up? + int points_used = starting_points - points; + int fruit_used = points_used / points_per_fruit; + if (points_used % points_per_fruit) + fruit_used++; - if (toadstools_evolved > 0) + // The player didn't have enough points to upgrade anything (probably + // supplied only one fruit). + if (!fruit_used) { - const bool plural = toadstools_evolved > 1; - mprf("%s toadstool%s gain%s stability.", - (plural ? "Some" : "A"), - (plural ? "s" : ""), - (plural ? "" : "s")); + mpr("Not enough fruit to cause evolution."); + return (false); } - if (fungi_evolved > 0) + dec_inv_item_quantity(rc, fruit_used); + + // Mention how many plants were used. + if (fruit_used > 1) + mprf("%d pieces of fruit are consumed!", fruit_used); + else + mpr("A piece of fruit is consumed!"); + + // Messaging for generated plants. + if (plants_evolved > 1) + mprf("%d plants can now spit acid.", plants_evolved); + else if (plants_evolved == 1) + mpr("A plant can now spit acid."); + + if (toadstools_evolved > 1) + mprf("%d toadstools gained stability.", toadstools_evolved); + else if (toadstools_evolved == 1) + mpr("A toadstool gained stability."); + + if (fungi_evolved > 1) { - const bool plural = fungi_evolved > 1; - mprf("The fungal %s can now pick up %s mycelia and move.", - (plural ? "colonies" : "colony"), - (plural ? "their" : "its")); + mprf("%d fungal colonies can now pick up their mycelia and move.", + fungi_evolved); } + else if (fungi_evolved == 1) + mpr("A fungal colony can now pick up its mycelia and move."); return (true); } diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index ef6466d071..3e23813503 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -1036,8 +1036,9 @@ void feawn_neutralise(monsters* monster) // tangled web, etc. remove_auto_exclude(monster, false); - monster->flags |= MF_ATT_CHANGE_ATTEMPT; feawn_neutralise_plant(monster); + monster->flags |= MF_ATT_CHANGE_ATTEMPT; + stop_running(); } } |