summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/effects.cc43
-rw-r--r--crawl-ref/source/effects.h4
-rw-r--r--crawl-ref/source/invent.cc18
-rw-r--r--crawl-ref/source/invent.h10
-rw-r--r--crawl-ref/source/religion.cc31
-rw-r--r--crawl-ref/source/spells2.cc232
-rw-r--r--crawl-ref/source/view.cc3
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();
}
}