summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/externs.h1
-rw-r--r--crawl-ref/source/item_use.cc22
-rw-r--r--crawl-ref/source/mon-util.cc22
-rw-r--r--crawl-ref/source/monstuff.cc12
-rw-r--r--crawl-ref/source/monstuff.h1
-rw-r--r--crawl-ref/source/player.cc14
-rw-r--r--crawl-ref/source/religion.cc125
-rw-r--r--crawl-ref/source/skills.cc94
-rw-r--r--crawl-ref/source/spells3.cc32
-rw-r--r--crawl-ref/source/spl-cast.cc139
-rw-r--r--crawl-ref/source/spl-cast.h4
11 files changed, 297 insertions, 169 deletions
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index c157fb7744..c37fc842b6 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -1053,6 +1053,7 @@ public:
bool has_action_energy() const;
void check_redraw(const coord_def &oldpos) const;
void apply_location_effects();
+ bool move_to_pos(const coord_def &newpos);
kill_category kill_alignment() const;
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 63bf8b9c88..82b868ee96 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -484,7 +484,9 @@ void wield_effects(int item_wield_2, bool showMsgs)
item_def &item = you.inv[item_wield_2];
// and here we finally get to the special effects of wielding {dlb}
- if (item.base_type == OBJ_MISCELLANY)
+ switch (item.base_type)
+ {
+ case OBJ_MISCELLANY:
{
if (item.sub_type == MISC_LANTERN_OF_SHADOWS)
{
@@ -495,9 +497,10 @@ void wield_effects(int item_wield_2, bool showMsgs)
setLOSRadius(you.current_vision);
you.special_wield = SPWLD_SHADOW;
}
+ break;
}
- if (item.base_type == OBJ_STAVES)
+ case OBJ_STAVES:
{
if (item.sub_type == STAFF_POWER)
{
@@ -506,15 +509,16 @@ void wield_effects(int item_wield_2, bool showMsgs)
set_ident_flags( item, ISFLAG_EQ_WEAPON_MASK );
mpr("You feel your mana capacity increase.");
}
- else
+ else if (!maybe_identify_staff(item))
{
- // Most staves only give curse status when wielded and
- // right now that's always "uncursed". -- bwr
- set_ident_flags( item, ISFLAG_KNOW_CURSE );
+ // Give curse status when wielded.
+ // Right now that's always "uncursed". -- bwr
+ set_ident_flags( item, ISFLAG_KNOW_CURSE );
}
+ break;
}
- if (item.base_type == OBJ_WEAPONS)
+ case OBJ_WEAPONS:
{
if (is_evil_item(item) && is_good_god(you.religion))
{
@@ -747,7 +751,11 @@ void wield_effects(int item_wield_2, bool showMsgs)
else
xom_is_stimulated(64);
}
+ break;
}
+ default:
+ break;
+ } // switch (base type)
if (showMsgs)
warn_shield_penalties();
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 56e10fdb35..6f901a3c72 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -5480,6 +5480,28 @@ void monsters::apply_location_effects()
}
}
+bool monsters::move_to_pos(const coord_def &newpos)
+{
+ if (mgrd[newpos.x][newpos.y] != NON_MONSTER
+ || you.x_pos == newpos.x && you.y_pos == newpos.y)
+ {
+ return (false);
+ }
+
+ // clear old cell pointer
+ mgrd[x][y] = NON_MONSTER;
+
+ // set monster x,y to new value
+ x = newpos.x;
+ y = newpos.y;
+
+ // set new monster grid pointer to this monster.
+ mgrd[x][y] = monster_index(this);
+
+ return (true);
+}
+
+
// returns true if the trap should be revealed to the player
bool monsters::do_shaft()
{
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index d49fe0a7f1..0b44a9eb7b 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -2594,29 +2594,29 @@ bool choose_any_monster(const monsters* mon)
// likely to get chosen compared with non-named ones.
int choose_random_nearby_monster(int weight,
bool (*suitable)(const monsters* mon),
- bool prefer_named)
+ bool in_sight, bool prefer_named)
{
int mons_count = weight;
int result = NON_MONSTER;
int mon;
int ystart = you.y_pos - 9, xstart = you.x_pos - 9;
- int yend = you.y_pos + 9, xend = you.x_pos + 9;
+ int yend = you.y_pos + 9, xend = you.x_pos + 9;
if ( xstart < 0 ) xstart = 0;
if ( ystart < 0 ) ystart = 0;
- if ( xend >= GXM ) xend = GXM;
- if ( yend >= GYM ) yend = GYM;
+ if ( xend >= GXM ) xend = GXM;
+ if ( yend >= GYM ) yend = GYM;
// monster check
for ( int y = ystart; y < yend; ++y )
for ( int x = xstart; x < xend; ++x )
- if ( see_grid(x,y) && mgrd[x][y] != NON_MONSTER )
+ if ( mgrd[x][y] != NON_MONSTER && (!in_sight || see_grid(x,y)) )
{
mon = mgrd[x][y];
if (suitable(&menv[mon]))
{
if (prefer_named
- && !get_unique_monster_name(&menv[mon]).empty())
+ && !(get_unique_monster_name(&menv[mon]).empty()))
{
mons_count += 2;
// named monsters have doubled chances
diff --git a/crawl-ref/source/monstuff.h b/crawl-ref/source/monstuff.h
index 988a793496..50bf95f3d3 100644
--- a/crawl-ref/source/monstuff.h
+++ b/crawl-ref/source/monstuff.h
@@ -126,6 +126,7 @@ bool choose_any_monster(const monsters* mon);
int choose_random_nearby_monster(int weight,
bool (*suitable)(const monsters* mon) =
choose_any_monster,
+ bool in_sight = true,
bool prefer_named = false);
/* ***********************************************************************
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index 74ca17a0fa..4687203d10 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -776,8 +776,8 @@ int player_equip( equipment_type slot, int sub_type, bool calc_unid )
if (you.equip[EQ_WEAPON] != -1
&& you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_STAVES
&& you.inv[you.equip[EQ_WEAPON]].sub_type == sub_type
- && (calc_unid ||
- item_type_known(you.inv[you.equip[EQ_WEAPON]])))
+ && (calc_unid
+ || item_type_known( you.inv[you.equip[EQ_WEAPON]] )))
{
ret++;
}
@@ -786,16 +786,16 @@ int player_equip( equipment_type slot, int sub_type, bool calc_unid )
case EQ_RINGS:
if (you.equip[EQ_LEFT_RING] != -1
&& you.inv[you.equip[EQ_LEFT_RING]].sub_type == sub_type
- && (calc_unid ||
- item_type_known(you.inv[you.equip[EQ_LEFT_RING]])))
+ && (calc_unid
+ || item_type_known( you.inv[you.equip[EQ_LEFT_RING]] )))
{
ret++;
}
if (you.equip[EQ_RIGHT_RING] != -1
&& you.inv[you.equip[EQ_RIGHT_RING]].sub_type == sub_type
- && (calc_unid ||
- item_type_known(you.inv[you.equip[EQ_RIGHT_RING]])))
+ && (calc_unid
+ || item_type_known( you.inv[you.equip[EQ_RIGHT_RING]] )))
{
ret++;
}
@@ -2870,7 +2870,7 @@ void level_change(bool skip_attribute_increase)
you.redraw_experience = true;
while (you.experience_level < 27
- && you.experience > exp_needed(you.experience_level + 2))
+ && you.experience > exp_needed(you.experience_level + 2))
{
bool skip_more = false;
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index c224c73827..a2bf4caab9 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -1015,6 +1015,60 @@ static bool _tso_blessing_friendliness(monsters *mon)
return true;
}
+// If there are no nearby followers, try to recall some on the level.
+static int _beogh_blessing_recalling()
+{
+ std::vector<int> recalled;
+
+ FixedVector < char, 2 > empty;
+ empty[0] = empty[1] = 0;
+
+ monsters *mon;
+ for (int loopy = 0; loopy < MAX_MONSTERS; loopy++)
+ {
+ mon = &menv[loopy];
+
+ if (mon->type == -1)
+ continue;
+
+ if (!is_orcish_follower(mon))
+ continue;
+
+ recalled.push_back(loopy);
+ }
+ if (recalled.empty())
+ return 0;
+
+ int count_recalled = 0;
+ int total = recalled.size();
+ int amount = 1 + random2(4) + random2(4);
+ bool recall_all = (total <= amount);
+
+ for (unsigned int loopy = 0; loopy < recalled.size(); loopy++)
+ {
+ mon = &menv[recalled[loopy]];
+
+ if (!recall_all && total == amount)
+ recall_all = true;
+
+ if (recall_all || random2(total) < amount)
+ {
+ if (empty_surrounds(you.x_pos, you.y_pos, DNGN_FLOOR, 3,
+ false, empty)
+ && mon->move_to_pos( coord_def(empty[0], empty[1])) )
+ {
+ count_recalled++;
+ amount--;
+ }
+ else
+ break; // no more room to place monsters
+ }
+ total--;
+ }
+
+ return (count_recalled);
+}
+
// If you don't currently have any followers, send a small band to help
// you out.
static bool _beogh_blessing_reinforcement()
@@ -1101,43 +1155,54 @@ bool bless_follower(int follower,
// Otherwise, pick a random follower within sight of the player.
if (follower == -1 || (!force && !suitable(&menv[follower])))
{
+ if (god != GOD_BEOGH)
+ return false;
+
// Choose a random follower in LOS, preferably a named one.
- follower = choose_random_nearby_monster(0, suitable, true);
+ follower = choose_random_nearby_monster(0, suitable, true, true);
if (follower == NON_MONSTER)
{
- switch (god)
+ // Try again, without the LOS restriction.
+ follower = choose_random_nearby_monster(0, suitable, false, true);
+ }
+
+ if (follower == NON_MONSTER)
+ {
+ // If no follower was chosen, either send
+ // reinforcement or get out.
+
+ // First, try to recall orcish followers on level.
+ int recalled = _beogh_blessing_recalling();
+ bool reinforced = false;
+
+ if (recalled < 3)
{
- case GOD_BEOGH:
+ reinforced = _beogh_blessing_reinforcement();
+
+ if (!reinforced || !recalled && coinflip())
{
- // If no follower was chosen, either send
- // reinforcement or get out.
- bool reinforced = _beogh_blessing_reinforcement();
+ // Try again, or possibly send more reinforcement.
+ if (_beogh_blessing_reinforcement())
+ reinforced = true;
+ }
+ }
- if (!reinforced || coinflip())
- {
- // Try again, or possibly send more reinforcement.
- if (_beogh_blessing_reinforcement())
- reinforced = true;
- }
+ if (recalled || reinforced)
+ {
+ pronoun = "";
+ blessed = "you";
- if (reinforced)
- {
- pronoun = "";
- blessed = "you";
- result = "reinforcement";
- goto blessing_done;
- }
- break;
- }
+ if (recalled)
+ result = "recalling";
+ else if (reinforced)
+ result = "reinforcement";
+ else
+ result = "recalling and reinforcement";
- default:
- break;
+ goto blessing_done;
}
-
- return false;
}
-
}
mon = &menv[follower];
@@ -1304,8 +1369,14 @@ bool bless_follower(int follower,
blessing_done:
std::string whom = "";
+
if (follower != NON_MONSTER)
- whom = get_unique_monster_name(mon);
+ {
+ if (!mons_near(mon) || !player_monster_visible(mon))
+ whom = "a follower";
+ else
+ whom = get_unique_monster_name(mon);
+ }
if (whom.empty())
whom = pronoun + blessed;
diff --git a/crawl-ref/source/skills.cc b/crawl-ref/source/skills.cc
index 7dea2ef4aa..8aa0ba2b82 100644
--- a/crawl-ref/source/skills.cc
+++ b/crawl-ref/source/skills.cc
@@ -22,11 +22,13 @@
#include "externs.h"
+#include "itemprop.h"
#include "macro.h"
#include "notes.h"
#include "output.h"
#include "player.h"
#include "skills2.h"
+#include "spl-cast.h"
#include "stuff.h"
#include "tutorial.h"
@@ -34,28 +36,28 @@
// MAX_COST_LIMIT is the maximum XP amount it will cost to raise a skill
// by 10 skill points (ie one standard practice).
//
-// MAX_SPENDING_LIMIT is the maximum XP amount we allow the player to
+// MAX_SPENDING_LIMIT is the maximum XP amount we allow the player to
// spend on a skill in a single raise.
//
-// Note that they don't have to be equal, but it is important to make
+// Note that they don't have to be equal, but it is important to make
// sure that they're set so that the spending limit will always allow
// for 1 skill point to be earned.
#define MAX_COST_LIMIT 250
#define MAX_SPENDING_LIMIT 250
-static int exercise2( int exsk );
+static int _exercise2( int exsk );
// These values were calculated by running a simulation of gaining skills.
// The goal is to try and match the old cost system which used the player's
-// experience level (which has a number of problems) so things shouldn't
-// seem too different to the player... but we still try to err on the
+// experience level (which has a number of problems) so things shouldn't
+// seem too different to the player... but we still try to err on the
// high side for the lower levels. -- bwr
int skill_cost_needed( int level )
{
- // The average starting skill total is actually lower, but
- // some classes get about 2200, and they would probably be
+ // The average starting skill total is actually lower, but
+ // some classes get about 2200, and they would probably be
// start around skill cost level 3 if we used the average. -- bwr
- int ret = 2200;
+ int ret = 2200;
switch (level)
{
@@ -87,15 +89,15 @@ void calc_total_skill_points( void )
you.total_skill_points = 0;
for (i = 0; i < NUM_SKILLS; i++)
- {
+ {
you.total_skill_points += you.skill_points[i];
}
- for (i = 1; i <= 27; i++)
+ for (i = 1; i <= 27; i++)
{
- if (you.total_skill_points < skill_cost_needed(i))
+ if (you.total_skill_points < skill_cost_needed(i))
break;
- }
+ }
you.skill_cost_level = i - 1;
@@ -105,10 +107,10 @@ void calc_total_skill_points( void )
}
// skill_cost_level makes skills more expensive for more experienced characters
-// skill_level makes higher skills more expensive
-static int calc_skill_cost( int skill_cost_level, int skill_level )
+// skill_level makes higher skills more expensive
+static int _calc_skill_cost( int skill_cost_level, int skill_level )
{
- int ret = 1 + skill_level;
+ int ret = 1 + skill_level;
// does not yet allow for loss of skill levels.
if (skill_level > 9)
@@ -162,7 +164,7 @@ int exercise(int exsk, int deg)
break;
if (you.practise_skill[exsk] || one_chance_in(4))
- ret += exercise2( exsk );
+ ret += _exercise2( exsk );
deg--;
}
@@ -170,24 +172,21 @@ int exercise(int exsk, int deg)
#ifdef DEBUG_DIAGNOSTICS
if (ret)
{
- mprf(MSGCH_DIAGNOSTICS,
- "Exercised %s (deg: %d) by %d",
- skill_name(exsk),
- deg,
- ret);
+ mprf(MSGCH_DIAGNOSTICS, "Exercised %s (deg: %d) by %d",
+ skill_name(exsk), deg, ret);
}
#endif
return (ret);
} // end exercise()
-static int exercise2( int exsk )
+static int _exercise2( int exsk )
{
int deg = 1;
int bonus = 0;
char old_best_skill = best_skill(SK_FIGHTING, (NUM_SKILLS - 1), 99);
- int skill_change = calc_skill_cost(you.skill_cost_level, you.skills[exsk]);
+ int skill_change = _calc_skill_cost(you.skill_cost_level, you.skills[exsk]);
int i;
// being good at some weapons makes others easier to learn:
@@ -224,7 +223,7 @@ static int exercise2( int exsk )
{
bonus += random2(3);
}
-
+
/* Slings and Throwing */
if ((exsk == SK_SLINGS || exsk == SK_THROWING)
&& (you.skills[SK_SLINGS] > you.skills[exsk]
@@ -285,10 +284,8 @@ static int exercise2( int exsk )
int skill_rank = 1;
for (i = SK_CONJURATIONS; i <= SK_DIVINATIONS; i++)
- {
if (you.skills[exsk] < you.skills[i])
skill_rank++;
- }
// Things get progressively harder, but not harder than
// the Fire-Air or Ice-Earth level.
@@ -297,7 +294,7 @@ static int exercise2( int exsk )
}
int fraction = 0;
- int spending_limit = (you.exp_available < MAX_SPENDING_LIMIT)
+ int spending_limit = (you.exp_available < MAX_SPENDING_LIMIT)
? you.exp_available : MAX_SPENDING_LIMIT;
// handle fractional learning
@@ -308,8 +305,8 @@ static int exercise2( int exsk )
// Increasing the "deg"ree of exercise would make missile
// weapons too easy earlier on, so instead we're giving them
// a special case here.
- if ((exsk != SK_DARTS && exsk != SK_BOWS && exsk != SK_CROSSBOWS)
- || skill_change > you.exp_available)
+ if (exsk != SK_DARTS && exsk != SK_BOWS && exsk != SK_CROSSBOWS
+ || skill_change > you.exp_available)
{
fraction = (spending_limit * 10) / skill_change;
skill_change = (skill_change * fraction) / 10;
@@ -382,10 +379,11 @@ static int exercise2( int exsk )
you.total_skill_points += skill_inc;
if (you.skill_cost_level < 27
- && you.total_skill_points >= skill_cost_needed(you.skill_cost_level + 1))
+ && you.total_skill_points
+ >= skill_cost_needed(you.skill_cost_level + 1))
{
you.skill_cost_level++;
- }
+ }
if (you.exp_available < 0)
you.exp_available = 0;
@@ -394,21 +392,21 @@ static int exercise2( int exsk )
/*
New (LH): debugging bit: when you exercise a skill, displays the skill
- exercised and how much you spent on it. Too irritating to be a regular
+ exercised and how much you spent on it. Too irritating to be a regular
WIZARD feature.
#if DEBUG_DIAGNOSTICS
- mprf( MSGCH_DIAGNOSTICS, "Exercised %s * %d for %d xp.",
+ mprf( MSGCH_DIAGNOSTICS, "Exercised %s * %d for %d xp.",
skill_name(exsk), skill_inc, skill_change );
#endif
*/
if (you.skill_points[exsk] >
- (skill_exp_needed(you.skills[exsk] + 2)
- * species_skills(exsk, you.species) / 100))
+ (skill_exp_needed(you.skills[exsk] + 2)
+ * species_skills(exsk, you.species) / 100))
{
-
+
you.skills[exsk]++;
take_note(Note(NOTE_GAIN_SKILL, exsk, you.skills[exsk]));
@@ -430,7 +428,7 @@ static int exercise2( int exsk )
learned_something_new(TUT_SKILL_RAISE);
- // Recalculate this skill's order for tie breaking skills
+ // Recalculate this skill's order for tie breaking skills
// at its new level. See skills2.cc::init_skill_order()
// for more details. -- bwr
you.skill_order[exsk] = 0;
@@ -447,35 +445,37 @@ static int exercise2( int exsk )
calc_hp();
if (exsk == SK_INVOCATIONS || exsk == SK_SPELLCASTING)
- {
calc_mp();
- }
if (exsk == SK_DODGING || exsk == SK_ARMOUR)
you.redraw_evasion = 1;
- if (exsk == SK_ARMOUR || exsk == SK_SHIELDS
- || exsk == SK_ICE_MAGIC || exsk == SK_EARTH_MAGIC
- || you.duration[ DUR_TRANSFORMATION ] > 0)
+ if (exsk == SK_ARMOUR || exsk == SK_SHIELDS
+ || exsk == SK_ICE_MAGIC || exsk == SK_EARTH_MAGIC
+ || you.duration[ DUR_TRANSFORMATION ] > 0)
{
you.redraw_armour_class = true;
}
- const unsigned char best = best_skill( SK_FIGHTING,
+ const unsigned char best = best_skill( SK_FIGHTING,
(NUM_SKILLS - 1), 99 );
- const unsigned char best_spell = best_skill( SK_SPELLCASTING,
+ const unsigned char best_spell = best_skill( SK_SPELLCASTING,
SK_POISON_MAGIC, 99 );
- if ((exsk == SK_SPELLCASTING)
- && (you.skills[exsk] == 1 && best_spell == SK_SPELLCASTING))
+ if (exsk == SK_SPELLCASTING
+ && you.skills[exsk] == 1 && best_spell == SK_SPELLCASTING)
{
mpr("You're starting to get the hang of this magic thing.");
}
if (best != old_best_skill || old_best_skill == exsk)
- {
redraw_skill( you.your_name, player_title() );
+
+ if (you.equip[EQ_WEAPON] != -1
+ && item_is_staff( you.inv[you.equip[EQ_WEAPON]] ))
+ {
+ maybe_identify_staff(you.inv[you.equip[EQ_WEAPON]]);
}
}
return (skill_inc);
diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc
index 49b5086eef..4956ef00e1 100644
--- a/crawl-ref/source/spells3.cc
+++ b/crawl-ref/source/spells3.cc
@@ -1147,23 +1147,24 @@ bool project_noise(void)
*/
bool recall(char type_recalled)
{
- int loopy = 0; // general purpose looping variable {dlb}
- bool success = false; // more accurately: "apparent success" {dlb}
- int start_count = 0;
- int step_value = 1;
- int end_count = (MAX_MONSTERS - 1);
+ int loopy = 0; // general purpose looping variable {dlb}
+ bool success = false; // more accurately: "apparent success" {dlb}
+ int start_count = 0;
+ int step_value = 1;
+ int end_count = (MAX_MONSTERS - 1);
+
FixedVector < char, 2 > empty;
struct monsters *monster = 0; // NULL {dlb}
empty[0] = empty[1] = 0;
-// someone really had to make life difficult {dlb}:
-// sometimes goes through monster list backwards
+ // someone really had to make life difficult {dlb}:
+ // sometimes goes through monster list backwards
if (coinflip())
{
start_count = (MAX_MONSTERS - 1);
- end_count = 0;
- step_value = -1;
+ end_count = 0;
+ step_value = -1;
}
for (loopy = start_count; loopy != end_count; loopy += step_value)
@@ -1193,24 +1194,15 @@ bool recall(char type_recalled)
continue;
}
- if (empty_surrounds(you.x_pos, you.y_pos, DNGN_FLOOR, 3, false, empty))
+ if (empty_surrounds(you.x_pos, you.y_pos, DNGN_FLOOR, 3, false, empty)
+ && monster->move_to_pos( coord_def(empty[0], empty[1])) )
{
- // clear old cell pointer -- why isn't there a function for moving a monster?
- mgrd[monster->x][monster->y] = NON_MONSTER;
- // set monster x,y to new value
- monster->x = empty[0];
- monster->y = empty[1];
- // set new monster grid pointer to this monster.
- mgrd[monster->x][monster->y] = monster_index(monster);
-
// only informed if monsters recalled are visible {dlb}:
if (simple_monster_message(monster, " is recalled."))
success = true;
}
else
- {
break; // no more room to place monsters {dlb}
- }
}
if (!success)
diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc
index 5c09d2c00e..1f53d27ce7 100644
--- a/crawl-ref/source/spl-cast.cc
+++ b/crawl-ref/source/spl-cast.cc
@@ -100,9 +100,9 @@ static bool _surge_identify_boosters(spell_type spell)
if ( you.equip[i] != -1 )
{
item_def& ring = you.inv[you.equip[i]];
- if (!item_ident(ring, ISFLAG_KNOW_PROPERTIES) &&
- (ring.sub_type == RING_FIRE ||
- ring.sub_type == RING_ICE))
+ if (!item_ident(ring, ISFLAG_KNOW_PROPERTIES)
+ && (ring.sub_type == RING_FIRE
+ || ring.sub_type == RING_ICE))
{
set_ident_type( ring.base_type, ring.sub_type,
ID_KNOWN_TYPE );
@@ -704,101 +704,132 @@ bool cast_a_spell()
// "Utility" spells for the sake of simplicity are currently ones with
// enchantments, translocations, or divinations.
-bool spell_is_utility_spell( spell_type spell_id )
+static bool _spell_is_utility_spell( spell_type spell_id )
{
return (spell_typematch( spell_id,
SPTYP_ENCHANTMENT | SPTYP_TRANSLOCATION | SPTYP_DIVINATION ));
}
-bool spell_is_unholy( spell_type spell_id )
+static bool _spell_is_unholy( spell_type spell_id )
{
return (testbits( get_spell_flags( spell_id ), SPFLAG_UNHOLY ));
}
-void spellcasting_side_effects(spell_type spell, bool idonly = false)
+bool maybe_identify_staff(item_def &item, spell_type spell)
{
- int total_skill = 0;
+ if (item_type_known(item))
+ return (true);
- if (you.equip[EQ_WEAPON] != -1
- && item_is_staff( you.inv[you.equip[EQ_WEAPON]] )
- && !item_type_known( you.inv[you.equip[EQ_WEAPON]] ))
+ int relevant_skill = 0;
+ const bool chance = (spell != SPELL_NO_SPELL);
+
+ switch (item.sub_type)
{
- switch (you.inv[you.equip[EQ_WEAPON]].sub_type)
- {
case STAFF_ENERGY:
+ if (!chance) // The staff of energy only autoIDs by chance.
+ return (false);
+ // intentional fall-through
case STAFF_WIZARDRY:
- total_skill = you.skills[SK_SPELLCASTING];
+ relevant_skill = you.skills[SK_SPELLCASTING];
break;
+
case STAFF_FIRE:
- if (spell_typematch(spell, SPTYP_FIRE))
- total_skill = you.skills[SK_FIRE_MAGIC];
+ if (!chance || spell_typematch(spell, SPTYP_FIRE))
+ relevant_skill = you.skills[SK_FIRE_MAGIC];
else if (spell_typematch(spell, SPTYP_ICE))
- total_skill = you.skills[SK_ICE_MAGIC];
+ relevant_skill = you.skills[SK_ICE_MAGIC];
break;
+
case STAFF_COLD:
- if (spell_typematch(spell, SPTYP_ICE))
- total_skill = you.skills[SK_ICE_MAGIC];
+ if (!chance || spell_typematch(spell, SPTYP_ICE))
+ relevant_skill = you.skills[SK_ICE_MAGIC];
else if (spell_typematch(spell, SPTYP_FIRE))
- total_skill = you.skills[SK_FIRE_MAGIC];
+ relevant_skill = you.skills[SK_FIRE_MAGIC];
break;
+
case STAFF_AIR:
- if (spell_typematch(spell, SPTYP_AIR))
- total_skill = you.skills[SK_AIR_MAGIC];
+ if (!chance || spell_typematch(spell, SPTYP_AIR))
+ relevant_skill = you.skills[SK_AIR_MAGIC];
else if (spell_typematch(spell, SPTYP_EARTH))
- total_skill = you.skills[SK_EARTH_MAGIC];
+ relevant_skill = you.skills[SK_EARTH_MAGIC];
break;
+
case STAFF_EARTH:
- if (spell_typematch(spell, SPTYP_EARTH))
- total_skill = you.skills[SK_EARTH_MAGIC];
+ if (!chance || spell_typematch(spell, SPTYP_EARTH))
+ relevant_skill = you.skills[SK_EARTH_MAGIC];
else if (spell_typematch(spell, SPTYP_AIR))
- total_skill = you.skills[SK_AIR_MAGIC];
+ relevant_skill = you.skills[SK_AIR_MAGIC];
break;
+
case STAFF_POISON:
- if (spell_typematch(spell, SPTYP_POISON))
- total_skill = you.skills[SK_POISON_MAGIC];
+ if (!chance || spell_typematch(spell, SPTYP_POISON))
+ relevant_skill = you.skills[SK_POISON_MAGIC];
break;
+
case STAFF_DEATH:
- if (spell_typematch(spell, SPTYP_NECROMANCY))
- total_skill = you.skills[SK_NECROMANCY];
+ if (!chance || spell_typematch(spell, SPTYP_NECROMANCY))
+ relevant_skill = you.skills[SK_NECROMANCY];
break;
+
case STAFF_CONJURATION:
- if (spell_typematch(spell, SPTYP_CONJURATION))
- total_skill = you.skills[SK_CONJURATIONS];
+ if (!chance || spell_typematch(spell, SPTYP_CONJURATION))
+ relevant_skill = you.skills[SK_CONJURATIONS];
break;
+
case STAFF_ENCHANTMENT:
- if (spell_typematch(spell, SPTYP_ENCHANTMENT))
- total_skill = you.skills[SK_ENCHANTMENTS];
+ if (!chance || spell_typematch(spell, SPTYP_ENCHANTMENT))
+ relevant_skill = you.skills[SK_ENCHANTMENTS];
break;
+
case STAFF_SUMMONING:
- if (spell_typematch(spell, SPTYP_SUMMONING))
- total_skill = you.skills[SK_SUMMONINGS];
+ if (!chance || spell_typematch(spell, SPTYP_SUMMONING))
+ relevant_skill = you.skills[SK_SUMMONINGS];
break;
- }
+ }
- if (you.skills[SK_SPELLCASTING] > total_skill)
- total_skill = you.skills[SK_SPELLCASTING];
+ bool id_staff = false;
- if (random2(100) < total_skill)
- {
- item_def& wpn = you.inv[you.equip[EQ_WEAPON]];
- // changed from ISFLAG_KNOW_TYPE
- set_ident_flags( wpn, ISFLAG_IDENT_MASK);
- mprf("You are wielding %s.", wpn.name(DESC_NOCAP_A).c_str());
- more();
+ if (chance)
+ {
+ if (you.skills[SK_SPELLCASTING] > relevant_skill)
+ relevant_skill = you.skills[SK_SPELLCASTING];
- you.wield_change = true;
- }
+ if (random2(100) < relevant_skill)
+ id_staff = true;
+ }
+ else if (relevant_skill >= 4)
+ id_staff = true;
+
+ if (id_staff)
+ {
+ item_def& wpn = you.inv[you.equip[EQ_WEAPON]];
+ // changed from ISFLAG_KNOW_TYPE
+ set_ident_flags( wpn, ISFLAG_IDENT_MASK);
+ mprf("You are wielding %s.", wpn.name(DESC_NOCAP_A).c_str());
+ more();
+
+ you.wield_change = true;
+ }
+ return (id_staff);
+}
+
+static void _spellcasting_side_effects(spell_type spell, bool idonly = false)
+{
+ if (you.equip[EQ_WEAPON] != -1
+ && item_is_staff( you.inv[you.equip[EQ_WEAPON]] ))
+ {
+ maybe_identify_staff(you.inv[you.equip[EQ_WEAPON]], spell);
}
if (idonly)
return;
- if (!spell_is_utility_spell(spell))
+ if (!_spell_is_utility_spell(spell))
did_god_conduct( DID_SPELL_NONUTILITY, 10 + spell_difficulty(spell) );
// Self-banishment gets a special exemption - you're there to spread light
- if (spell_is_unholy(spell) &&
- (spell != SPELL_BANISHMENT || !you.banished))
+ if (_spell_is_unholy(spell)
+ && (spell != SPELL_BANISHMENT || !you.banished))
{
did_god_conduct( DID_UNHOLY, 10 + spell_difficulty(spell) );
}
@@ -1010,14 +1041,14 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail )
if (spfl < spfail_chance)
{
- spellcasting_side_effects(spell, true);
+ _spellcasting_side_effects(spell, true);
mpr( "You miscast the spell." );
flush_input_buffer( FLUSH_ON_FAILURE );
if (you.religion == GOD_SIF_MUNA
- && (!player_under_penance()
- && you.piety >= 100 && random2(150) <= you.piety))
+ && !player_under_penance()
+ && you.piety >= 100 && random2(150) <= you.piety)
{
canned_msg(MSG_NOTHING_HAPPENS);
return SPRET_FAIL;
@@ -1951,7 +1982,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail )
break;
} // end switch
- spellcasting_side_effects(spell);
+ _spellcasting_side_effects(spell);
return (SPRET_SUCCESS);
} // end you_spells()
diff --git a/crawl-ref/source/spl-cast.h b/crawl-ref/source/spl-cast.h
index d6c73d053f..6e07fb32bc 100644
--- a/crawl-ref/source/spl-cast.h
+++ b/crawl-ref/source/spl-cast.h
@@ -56,6 +56,8 @@ void exercise_spell( spell_type spell_ex, bool spc, bool divide );
* *********************************************************************** */
bool cast_a_spell( void );
+bool maybe_identify_staff( item_def &item, spell_type spell = SPELL_NO_SPELL );
+
void inspect_spells();
@@ -71,7 +73,7 @@ spret_type your_spells( spell_type spell, int powc = 0,
* called from: acr - decks - fight - it_use2 - it_use3 - item_use - items -
* misc - mstuff2 - religion - spell - spl-book - spells4
* *********************************************************************** */
-void miscast_effect( unsigned int sp_type, int mag_pow, int mag_fail,
+void miscast_effect( unsigned int sp_type, int mag_pow, int mag_fail,
int force_effect, const char *cause = NULL );
const char* failure_rate_to_string( int fail );