summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-04-25 23:35:17 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-04-25 23:35:17 +0000
commit4a746253d5b490b74bf195038b943583fe4c1017 (patch)
tree8630c8f492d66e6183507ba346e7a85f4d5036fe
parent3285cab37e38320a6fd566a035d96939e4fb9b3e (diff)
downloadcrawl-ref-4a746253d5b490b74bf195038b943583fe4c1017.tar.gz
crawl-ref-4a746253d5b490b74bf195038b943583fe4c1017.zip
Two changes:
1.) If Beogh can't find a nearby follower in LOS to bless, try again without the LOS restriction (but still nearby). If this also fails, recall a small amount of followers (1 + rnd(4) + rnd(4)) on the level. I don't think there's much harm in Beogh actively doing something you already have as an invocation as long as it doesn't make the invocation superfluous (and this doesn't). In this case, the chance of this happening should probably be lowered, and actual reinforcement should be rarer still. 2.) Identify magical staves if you have at least 4 skill levels in the corresponding spell school when wielding it, or gain the 4th level while wielding it. (I decided on 4 because that is what most mages start out with in their special school, and it seems a good enough treshold.) Prior to that, there's still the random identification chance at casting an appropriate spell, as before. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@4639 c06c8d41-db1a-0410-9941-cceddc491573
-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 );