From 2772e5117bba390bc735af3dd9e0853f93a8306d Mon Sep 17 00:00:00 2001 From: haranp Date: Fri, 6 Mar 2009 14:35:34 +0000 Subject: Fix permanent-MP abilities being usable when only temporary MP (e.g. from a ring of magical power) is available. [2664906] This does not apply to HP costs because there's no way to abuse that. In theory it might still be possible to get negative real MP with the high/low magic mutations. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@9347 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/player.cc | 82 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 20 deletions(-) (limited to 'crawl-ref/source/player.cc') diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index e86bc5a5cb..5ff67c0139 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -3493,25 +3493,20 @@ void level_change(bool skip_attribute_increase) inc_max_hp( hp_adjust ); inc_max_mp( mp_adjust ); - deflate_hp( you.hp_max, false ); + deflate_hp(you.hp_max, false); you.magic_points = std::max(0, you.magic_points); - { - unwind_var hpmax(you.hp_max); - unwind_var hp(you.hp); - unwind_var mpmax(you.max_magic_points); - unwind_var mp(you.magic_points); - // calculate "real" values for note-taking, i.e. ignore Berserk, - // transformations or equipped items - calc_hp(true); - calc_mp(true); - - char buf[200]; - sprintf(buf, "HP: %d/%d MP: %d/%d", - you.hp, you.hp_max, you.magic_points, you.max_magic_points); - take_note(Note(NOTE_XP_LEVEL_CHANGE, you.experience_level, 0, buf)); - } + // Get "real" values for note-taking, i.e. ignore Berserk, + // transformations or equipped items. + const int note_maxhp = get_real_hp(false, false); + const int note_maxmp = get_real_mp(false); + + char buf[200]; + sprintf(buf, "HP: %d/%d MP: %d/%d", + std::min(you.hp, note_maxhp), note_maxhp, + std::min(you.magic_points, note_maxmp), note_maxmp); + take_note(Note(NOTE_XP_LEVEL_CHANGE, you.experience_level, 0, buf)); // recalculate for game calc_hp(); @@ -4780,21 +4775,32 @@ bool enough_hp(int minimum, bool suppress_msg) return (true); } -bool enough_mp(int minimum, bool suppress_msg) +bool enough_mp(int minimum, bool suppress_msg, bool include_items) { ASSERT(!crawl_state.arena); - if (you.magic_points < minimum) + bool rc = false; + + if (get_real_mp(include_items) < minimum) + { + if (!suppress_msg) + mpr("You haven't enough magic capacity."); + } + else if (you.magic_points < minimum) { if (!suppress_msg) mpr("You haven't enough magic at the moment."); + } + else + rc = true; + if (!rc) + { crawl_state.cancel_cmd_again(); crawl_state.cancel_cmd_repeat(); - return (false); } - return (true); + return (rc); } // Note that "max_too" refers to the base potential, the actual @@ -5033,6 +5039,42 @@ int get_real_hp(bool trans, bool rotted) return (hitp); } +int get_real_mp(bool include_items) +{ + // base_magic_points2 accounts for species + int enp = (you.base_magic_points2 - 5000); + + int spell_extra = (you.experience_level * you.skills[SK_SPELLCASTING]) / 4; + int invoc_extra = (you.experience_level * you.skills[SK_INVOCATIONS]) / 6; + + enp += std::max(spell_extra, invoc_extra); + enp = stepdown_value(enp, 9, 18, 45, 100); + + // this is our "rotted" base (applied after scaling): + enp += (you.base_magic_points - 5000); + + // Yes, we really do want this duplication... this is so the stepdown + // doesn't truncate before we apply the rotted base. We're doing this + // the nice way. -- bwr + enp = std::min(enp, 50); + + // Now applied after scaling so that power items are more useful -- bwr + if (include_items) + enp += player_magical_power(); + + // Analogous to ROBUST/FRAIL + enp *= (10 + player_mutation_level(MUT_HIGH_MAGIC) + - player_mutation_level(MUT_LOW_MAGIC)); + enp /= 10; + + if (enp > 50) + enp = 50 + ((enp - 50) / 2); + + enp = std::max(enp, 0); + + return enp; +} + static int _get_contamination_level() { const int glow = you.magic_contamination; -- cgit v1.2.3-54-g00ecf