diff options
-rw-r--r-- | crawl-ref/source/externs.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/item_use.cc | 22 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 22 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 12 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/player.cc | 14 | ||||
-rw-r--r-- | crawl-ref/source/religion.cc | 125 | ||||
-rw-r--r-- | crawl-ref/source/skills.cc | 94 | ||||
-rw-r--r-- | crawl-ref/source/spells3.cc | 32 | ||||
-rw-r--r-- | crawl-ref/source/spl-cast.cc | 139 | ||||
-rw-r--r-- | crawl-ref/source/spl-cast.h | 4 |
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 ); |