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/abl-show.cc | 5 ++- crawl-ref/source/player.cc | 82 +++++++++++++++++++++++++++++++++----------- crawl-ref/source/player.h | 51 +++------------------------ crawl-ref/source/skills2.cc | 63 +++++----------------------------- crawl-ref/source/skills2.h | 60 +++----------------------------- 5 files changed, 84 insertions(+), 177 deletions(-) diff --git a/crawl-ref/source/abl-show.cc b/crawl-ref/source/abl-show.cc index 0c1ada0d03..2e5bbab3d5 100644 --- a/crawl-ref/source/abl-show.cc +++ b/crawl-ref/source/abl-show.cc @@ -988,7 +988,10 @@ static bool _activate_talent(const talent& tal) const ability_def& abil = get_ability_def(tal.which); // Check that we can afford to pay the costs. - if (!enough_mp( abil.mp_cost, false )) + // Note that mutation shenanigans might leave us with negative MP, + // so don't fail in that case if there's no MP cost. + if (abil.mp_cost > 0 + && !enough_mp(abil.mp_cost, false, !(abil.flags & ABFLAG_PERMANENT_MP))) { crawl_state.zero_turns_taken(); return (false); 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; diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index bdc557bc09..bc214b322a 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -348,45 +348,18 @@ bool player_wearing_slot( int eq ); bool you_tran_can_wear(const item_def &item); bool you_tran_can_wear( int eq, bool check_mutation = false ); -/* *********************************************************************** - * called from: ability - effects - fight - it_use3 - ouch - spell - - * spells - spells2 - spells3 - spells4 - * *********************************************************************** */ -void dec_hp(int hp_loss, bool fatal, const char *aux = NULL); - - -/* *********************************************************************** - * called from: ability - it_use3 - spell - spells3 - * *********************************************************************** */ -bool enough_hp (int minimum, bool suppress_msg); - +bool enough_hp(int minimum, bool suppress_msg); +bool enough_mp(int minimum, bool suppress_msg, bool include_items = true); -/* *********************************************************************** - * called from: ability - it_use3 - * *********************************************************************** */ -bool enough_mp (int minimum, bool suppress_msg); - - -/* *********************************************************************** - * called from: ability - fight - it_use3 - monstuff - ouch - spell - * *********************************************************************** */ +void dec_hp(int hp_loss, bool fatal, const char *aux = NULL); void dec_mp(int mp_loss); - -/* *********************************************************************** - * called from: ability - acr - fight - it_use2 - it_use3 - spells3 - * *********************************************************************** */ void inc_mp(int mp_gain, bool max_too); - - -/* *********************************************************************** - * called from: acr - fight - food - spells1 - spells2 - * *********************************************************************** */ void inc_hp(int hp_gain, bool max_too); void rot_hp( int hp_loss ); void unrot_hp( int hp_recovered ); -int player_rotted( void ); +int player_rotted(); void rot_mp( int mp_loss ); void inc_max_hp( int hp_gain ); @@ -395,28 +368,14 @@ void dec_max_hp( int hp_loss ); void inc_max_mp( int mp_gain ); void dec_max_mp( int mp_loss ); -/* *********************************************************************** - * called from: acr - misc - religion - skills2 - spells1 - transfor - * *********************************************************************** */ void deflate_hp(int new_level, bool floor); - - -/* *********************************************************************** - * called from: acr - it_use2 - newgame - ouch - religion - spell - spells1 - * *********************************************************************** */ void set_hp(int new_amount, bool max_too); int get_real_hp(bool trans, bool rotted = false); +int get_real_mp(bool include_items); -/* *********************************************************************** - * called from: it_use3 - newgame - * *********************************************************************** */ void set_mp(int new_amount, bool max_too); -// last updated 19apr2001 {gdl} -/* *********************************************************************** - * called from: - * *********************************************************************** */ void contaminate_player(int change, bool controlled = false, bool status_only = false); diff --git a/crawl-ref/source/skills2.cc b/crawl-ref/source/skills2.cc index aacb6c817a..dc2fa7680e 100644 --- a/crawl-ref/source/skills2.cc +++ b/crawl-ref/source/skills2.cc @@ -2108,65 +2108,18 @@ void init_skill_order( void ) } } -int calc_hp(bool real_hp) +void calc_hp() { - int hitp = get_real_hp(!real_hp, false); - - you.hp_max = hitp; - - deflate_hp( you.hp_max, false ); - - return (hitp); -} // end calc_hp() + you.hp_max = get_real_hp(true, false); + deflate_hp(you.hp_max, false); +} -int calc_mp(bool real_mp) +void calc_mp() { - int enp; - - // base_magic_points2 accounts for species and magic potions - 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; - - if (spell_extra > invoc_extra) - enp += spell_extra; - else - enp += invoc_extra; - - you.max_magic_points = stepdown_value( enp, 9, 18, 45, 100 ); - - // this is our "rotted" base (applied after scaling): - you.max_magic_points += (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 - if (you.max_magic_points > 50) - you.max_magic_points = 50; - - // now applied after scaling so that power items are more useful -- bwr - if (!real_mp) - you.max_magic_points += player_magical_power(); - - // analogous to ROBUST/FRAIL - you.max_magic_points *= (10 + player_mutation_level(MUT_HIGH_MAGIC) - - player_mutation_level(MUT_LOW_MAGIC)); - you.max_magic_points /= 10; - - if (you.max_magic_points > 50) - you.max_magic_points = 50 + ((you.max_magic_points - 50) / 2); - - if (you.max_magic_points < 0) - you.max_magic_points = 0; - - if (you.magic_points > you.max_magic_points) - you.magic_points = you.max_magic_points; - + you.max_magic_points = get_real_mp(true); + you.magic_points = std::min(you.magic_points, you.max_magic_points); you.redraw_magic_points = true; - - return (you.max_magic_points); -} // end calc_mp() +} unsigned int skill_exp_needed(int lev) { diff --git a/crawl-ref/source/skills2.h b/crawl-ref/source/skills2.h index 97ac2d92a1..93e3464ec7 100644 --- a/crawl-ref/source/skills2.h +++ b/crawl-ref/source/skills2.h @@ -10,80 +10,30 @@ #ifndef SKILLS2_H #define SKILLS2_H -#define MAX_SKILL_ORDER 100 +const int MAX_SKILL_ORDER = 100; #include "enum.h" -// last_updated 24may2000 {dlb} -/* *********************************************************************** - * called from: chardump - it_use3 - itemname - skills - * *********************************************************************** */ const char *skill_name(int which_skill); int str_to_skill(const std::string &skill); -// last_updated 24may2000 {dlb} -/* *********************************************************************** - * called from: describe - * *********************************************************************** */ std::string skill_title( unsigned char best_skill, unsigned char skill_lev, // these used for ghosts and hiscores: int species = -1, int str = -1, int dex = -1, int god = -1 ); -// last_updated Sept 20 -- bwr -/* *********************************************************************** - * called from: acr - chardump - player - skills - stuff - * *********************************************************************** */ -std::string player_title( void ); - +std::string player_title(); skill_type best_skill(int min_skill, int max_skill, int excl_skill = -1); +void init_skill_order(); -void init_skill_order( void ); - - -// last_updated 24may2000 {dlb} -/* *********************************************************************** - * called from: acr - it_use2 - item_use - newgame - ouch - player - skills - * *********************************************************************** */ -int calc_mp(bool real_mp = false); - +void calc_mp(); +void calc_hp(); -// last_updated 24may2000 {dlb} -/* *********************************************************************** - * called from: ability - acr - food - it_use2 - misc - mutation - - * newgame - ouch - player - skills - spells1 - transfor - * *********************************************************************** */ -int calc_hp(bool real_hp = false); - - -// last_updated 24may2000 {dlb} -/* *********************************************************************** - * called from: newgame - skills - skills2 - * *********************************************************************** */ int species_skills(int skill, species_type species); - - -// last_updated 24may2000 {dlb} -/* *********************************************************************** - * called from: newgame - skills - skills2 - * *********************************************************************** */ unsigned int skill_exp_needed(int lev); - - -// last_updated 24may2000 {dlb} -/* *********************************************************************** - * called from: acr - * *********************************************************************** */ void show_skills(); - - -// last_updated 14jan2001 {gdl} -/* *********************************************************************** - * called from: item_use - * *********************************************************************** */ void wield_warning(bool newWeapon = true); - bool is_invalid_skill(int skill); #endif -- cgit v1.2.3-54-g00ecf