diff options
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/ability_type.hpp | 2 | ||||
-rw-r--r-- | src/birth.cc | 5 | ||||
-rw-r--r-- | src/cmd1.cc | 4 | ||||
-rw-r--r-- | src/cmd4.cc | 2 | ||||
-rw-r--r-- | src/cmd6.cc | 2 | ||||
-rw-r--r-- | src/dungeon.cc | 4 | ||||
-rw-r--r-- | src/init1.cc | 1 | ||||
-rw-r--r-- | src/loadsave.cc | 17 | ||||
-rw-r--r-- | src/lua_bind.cc | 2 | ||||
-rw-r--r-- | src/player_type.cc | 28 | ||||
-rw-r--r-- | src/player_type.hpp | 20 | ||||
-rw-r--r-- | src/skills.cc | 55 | ||||
-rw-r--r-- | src/skills.hpp | 1 | ||||
-rw-r--r-- | src/spells1.cc | 2 | ||||
-rw-r--r-- | src/spells2.cc | 2 | ||||
-rw-r--r-- | src/squelch/condition.cc | 2 | ||||
-rw-r--r-- | src/xtra1.cc | 4 |
18 files changed, 95 insertions, 59 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7b4d025b..8ac5e097 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -57,6 +57,7 @@ SET(SRCS_COMMON object_filter.cc object_flag_meta.cc options.cc + player_type.cc powers.cc q_betwen.cc q_bounty.cc diff --git a/src/ability_type.hpp b/src/ability_type.hpp index ea8a921d..3a2a51ee 100644 --- a/src/ability_type.hpp +++ b/src/ability_type.hpp @@ -16,8 +16,6 @@ struct ability_type s16b cost; /* Skill points cost */ - bool_ acquired; /* Do the player actualylg ot it ? */ - /* Prereqs */ s16b skills[10]; /* List of prereq skills(10 max) */ s16b skill_levels[10]; /* List of prereq skills(10 max) */ diff --git a/src/birth.cc b/src/birth.cc index 1fc5d515..f426fca9 100644 --- a/src/birth.cc +++ b/src/birth.cc @@ -1142,7 +1142,7 @@ static void player_outfit(void) } /* Rogues have a better knowledge of traps */ - if (has_ability(AB_TRAPPING)) + if (p_ptr->has_ability(AB_TRAPPING)) { t_info[TRAP_OF_DAGGER_I].known = randint(50) + 50; t_info[TRAP_OF_POISON_NEEDLE].known = randint(50) + 50; @@ -3083,8 +3083,7 @@ void player_birth(void) recalc_skills(FALSE); /* grab level 1 abilities */ - for (i = 0; i < max_ab_idx; i++) - ab_info[i].acquired = FALSE; + p_ptr->abilities.clear(); apply_level_abilities(1); /* Complete the god */ diff --git a/src/cmd1.cc b/src/cmd1.cc index c54e3dbd..f8e064c2 100644 --- a/src/cmd1.cc +++ b/src/cmd1.cc @@ -2369,7 +2369,7 @@ void py_attack(int y, int x, int max_blow) /* Hack -- High-level warriors can spread their attacks out * among weaker foes. */ - if ((has_ability(AB_SPREAD_BLOWS)) && (num < num_blow) && + if ((p_ptr->has_ability(AB_SPREAD_BLOWS)) && (num < num_blow) && (energy_use)) { energy_use = energy_use * num / num_blow; @@ -2587,7 +2587,7 @@ bool_ player_can_enter(byte feature) { if (p_ptr->fly || pass_wall || - (has_ability(AB_TREE_WALK)) || + p_ptr->has_ability(AB_TREE_WALK) || (p_ptr->mimic_form == resolve_mimic_name("Ent")) || ((p_ptr->grace >= 9000) && praying_to(GOD_YAVANNA))) return (TRUE); diff --git a/src/cmd4.cc b/src/cmd4.cc index 01452090..724d5a1f 100644 --- a/src/cmd4.cc +++ b/src/cmd4.cc @@ -3457,7 +3457,7 @@ static void do_cmd_knowledge_pets(void) // Calculate upkeep int show_upkeep = 0; - int upkeep_divider = has_ability(AB_PERFECT_CASTING) ? 15 : 20; + int upkeep_divider = p_ptr->has_ability(AB_PERFECT_CASTING) ? 15 : 20; if (t_friends > 1 + (p_ptr->lev / (upkeep_divider))) { diff --git a/src/cmd6.cc b/src/cmd6.cc index 4490b5de..1663b5c1 100644 --- a/src/cmd6.cc +++ b/src/cmd6.cc @@ -5318,7 +5318,7 @@ const char *activation_aux(object_type * o_ptr, bool_ doit, int item) msg_print("The stone reveals hidden mysteries..."); if (!ident_spell()) break; - if (has_ability(AB_PERFECT_CASTING)) + if (p_ptr->has_ability(AB_PERFECT_CASTING)) { /* Sufficient mana */ if (20 <= p_ptr->csp) diff --git a/src/dungeon.cc b/src/dungeon.cc index b02b2a87..00bee6f4 100644 --- a/src/dungeon.cc +++ b/src/dungeon.cc @@ -1489,7 +1489,7 @@ static void process_world(void) int feature = cave[p_ptr->py][p_ptr->px].feat; /* Player can walk through or fly over trees */ - if ((has_ability(AB_TREE_WALK) || p_ptr->fly) && (feature == FEAT_TREES)) + if ((p_ptr->has_ability(AB_TREE_WALK) || p_ptr->fly) && (feature == FEAT_TREES)) { /* Do nothing */ } @@ -1673,7 +1673,7 @@ static void process_world(void) { int upkeep_divider = 20; - if (has_ability(AB_PERFECT_CASTING)) + if (p_ptr->has_ability(AB_PERFECT_CASTING)) upkeep_divider = 15; if (total_friends > 1 + (p_ptr->lev / (upkeep_divider))) diff --git a/src/init1.cc b/src/init1.cc index de92ae90..3f803fbe 100644 --- a/src/init1.cc +++ b/src/init1.cc @@ -3419,7 +3419,6 @@ errr init_ab_info_txt(FILE *fp) /* Init */ ab_ptr->action_mkey = 0; - ab_ptr->acquired = FALSE; for (z = 0; z < 10; z++) { ab_ptr->skills[z] = -1; diff --git a/src/loadsave.cc b/src/loadsave.cc index 2e3ac33f..e6f4cefa 100644 --- a/src/loadsave.cc +++ b/src/loadsave.cc @@ -1,7 +1,6 @@ #include "loadsave.hpp" #include "loadsave.h" -#include "ability_type.hpp" #include "artifact_type.hpp" #include "birth.hpp" #include "cave_type.hpp" @@ -619,21 +618,7 @@ static bool_ do_extra(ls_flag_t flag) } // Abilities - { - u16b tmp16u = max_ab_idx; - - do_u16b(&tmp16u, flag); - - if ((flag == ls_flag_t::LOAD) && (tmp16u > max_ab_idx)) - { - quit("Too many abilities"); - } - - for (std::size_t i = 0; i < tmp16u; ++i) - { - do_bool(&ab_info[i].acquired, flag); - } - } + do_vector(flag, p_ptr->abilities, do_u16b); // Miscellaneous do_s16b(&p_ptr->luck_base, flag); diff --git a/src/lua_bind.cc b/src/lua_bind.cc index 151ba3b8..1612fb29 100644 --- a/src/lua_bind.cc +++ b/src/lua_bind.cc @@ -146,7 +146,7 @@ static s32b spell_chance_school(s32b s) minfail = adj_mag_fail[stat_ind]; /* Must have Perfect Casting to get below 5% */ - if (!(has_ability(AB_PERFECT_CASTING))) + if (!(p_ptr->has_ability(AB_PERFECT_CASTING))) { if (minfail < 5) minfail = 5; } diff --git a/src/player_type.cc b/src/player_type.cc new file mode 100644 index 00000000..0cc66de7 --- /dev/null +++ b/src/player_type.cc @@ -0,0 +1,28 @@ +#include "player_type.hpp" + +#include <algorithm> + +bool player_type::has_ability(u16b ability_idx) const +{ + return std::find( + abilities.begin(), + abilities.end(), + ability_idx) != abilities.end(); +} + +void player_type::gain_ability(u16b ability_idx) +{ + // Duplicates don't really matter, so let's just + // accept whatever value we get without checking + // anything. + abilities.push_back(ability_idx); +} + +void player_type::lose_ability(u16b ability_idx) +{ + abilities.erase( + std::remove( + abilities.begin(), + abilities.end(), + ability_idx)); +} diff --git a/src/player_type.hpp b/src/player_type.hpp index 1285e018..8f3c06dc 100644 --- a/src/player_type.hpp +++ b/src/player_type.hpp @@ -378,6 +378,9 @@ struct player_type bool_ powers[POWER_MAX] = { FALSE }; /* Actual powers */ bool_ powers_mod[POWER_MAX] = { FALSE }; /* Intrinsinc powers */ + /* Acquired abilities; indexes into ab_info[] */ + std::vector<u16b> abilities; + /* Skills */ s16b skill_points = 0; s16b skill_last_level = 0; /* Prevents gaining skills by losing level and regaining them */ @@ -400,5 +403,20 @@ struct player_type bool_ did_nothing = FALSE; /* True if the last action wasnt a real action */ bool_ leaving = FALSE; /* True if player is leaving */ -}; + /** + * Does the player have the given ability? + */ + bool has_ability(u16b ability_idx) const; + + /** + * Gain the given ability. + */ + void gain_ability(u16b ability_idx); + + /** + * Lose the given ability. + */ + void lose_ability(u16b ability_idx); + +}; diff --git a/src/skills.cc b/src/skills.cc index 70665a49..fc5b068c 100644 --- a/src/skills.cc +++ b/src/skills.cc @@ -839,7 +839,7 @@ static int do_cmd_activate_skill_aux() for (size_t i = 0; i < max_ab_idx; i++) { - if (ab_info[i].action_mkey && ab_info[i].acquired) + if (ab_info[i].action_mkey && p_ptr->has_ability(i)) { bool_ next = FALSE; @@ -970,7 +970,7 @@ void do_cmd_activate_skill() } for (j = 0; j < max_ab_idx; j++) { - if (ab_info[j].acquired && (ab_info[j].action_mkey == x_idx)) + if (p_ptr->has_ability(j) && (ab_info[j].action_mkey == x_idx)) break; } @@ -1436,21 +1436,13 @@ s16b find_ability(cptr name) return ( -1); } -/* - * Do the player have the ability - */ -bool_ has_ability(int ab) -{ - return ab_info[ab].acquired; -} - /* Do we meet the requirements */ static bool_ can_learn_ability(int ab) { ability_type *ab_ptr = &ab_info[ab]; int i; - if (ab_ptr->acquired) + if (p_ptr->has_ability(ab)) return FALSE; if (p_ptr->skill_points < ab_info[ab].cost) @@ -1468,15 +1460,19 @@ static bool_ can_learn_ability(int ab) /* Must have ability */ if (ab_ptr->need_abilities[i] > -1) { - if (!ab_info[ab_ptr->need_abilities[i]].acquired) + if (!p_ptr->has_ability(ab_ptr->need_abilities[i])) + { return FALSE; + } } /* Must not have ability */ if (ab_ptr->forbid_abilities[i] > -1) { - if (ab_info[ab_ptr->forbid_abilities[i]].acquired) + if (p_ptr->has_ability(ab_ptr->forbid_abilities[i])) + { return FALSE; + } } } @@ -1509,12 +1505,12 @@ static void gain_ability(int ab) flush(); /* Ask we can commit the change */ - if (msg_box("Learn this ability(this is permanent)? (y/n)", hgt / 2, wid / 2) != 'y') + if (msg_box("Learn this ability (this is permanent)? (y/n)", hgt / 2, wid / 2) != 'y') { return; } - ab_info[ab].acquired = TRUE; + p_ptr->gain_ability(ab); p_ptr->skill_points -= ab_info[ab].cost; } @@ -1534,7 +1530,7 @@ void dump_abilities(FILE *fff) std::vector<int> table; for (i = 0; i < max_ab_idx; i++) { - if (ab_info[i].name && has_ability(i)) + if (ab_info[i].name && p_ptr->has_ability(i)) { table.push_back(i); } @@ -1592,12 +1588,18 @@ static void print_abilities(const std::vector<int> &table, int sel, int start) i = table[j]; - if (ab_info[i].acquired) + if (p_ptr->has_ability(i)) + { color = TERM_L_BLUE; + } else if (can_learn_ability(i)) + { color = TERM_WHITE; + } else + { color = TERM_L_DARK; + } if (j == sel) @@ -1610,7 +1612,7 @@ static void print_abilities(const std::vector<int> &table, int sel, int start) c_prt(color, format("%c.%c%s", deb, end, ab_info[i].name), j + 7 - start, 0); - if (!ab_info[i].acquired) + if (!p_ptr->has_ability(i)) { c_prt(color, format("%d", ab_info[i].cost), j + 7 - start, 60); } @@ -1702,10 +1704,16 @@ void do_cmd_ability() /* gain ability */ if (dir == 6) gain_ability(table[sel]); - /* XXX XXX XXX Wizard mode commands outside of wizard2.c */ + /* Wizard mode allows any ability */ + if (wizard && (c == '+')) + { + p_ptr->gain_ability(table[sel]); + } - if (wizard && (c == '+')) ab_info[table[sel]].acquired = TRUE; - if (wizard && (c == '-')) ab_info[table[sel]].acquired = FALSE; + if (wizard && (c == '-')) + { + p_ptr->lose_ability(table[sel]); + } /* Contextual help */ if (c == '?') @@ -1755,11 +1763,12 @@ void apply_level_abilities(int level) { if (a.level == level) { - if ((level > 1) && (!ab_info[a.ability].acquired)) + if ((level > 1) && (!p_ptr->has_ability(a.ability))) { cmsg_format(TERM_L_GREEN, "You have learned the ability '%s'.", ab_info[a.ability].name); } - ab_info[a.ability].acquired = TRUE; + + p_ptr->gain_ability(a.ability); } } }; diff --git a/src/skills.hpp b/src/skills.hpp index 6c1880a6..4cd63358 100644 --- a/src/skills.hpp +++ b/src/skills.hpp @@ -22,6 +22,5 @@ extern void init_skill(s32b value, s32b mod, int i); extern s16b find_ability(cptr name); extern void dump_abilities(FILE *fff); extern void do_cmd_ability(void); -extern bool_ has_ability(int ab); extern void apply_level_abilities(int level); extern void recalc_skills(bool_ init); diff --git a/src/spells1.cc b/src/spells1.cc index 1fe14c5a..0054a1d6 100644 --- a/src/spells1.cc +++ b/src/spells1.cc @@ -1322,7 +1322,7 @@ void take_hit(int damage, cptr hit_from) if (p_ptr->chp < 0) { /* Necromancers get a special treatment */ - if (((!has_ability(AB_UNDEAD_FORM)) || ((p_ptr->necro_extra & CLASS_UNDEAD)))) + if (((!p_ptr->has_ability(AB_UNDEAD_FORM)) || ((p_ptr->necro_extra & CLASS_UNDEAD)))) { /* Hack -- Note death */ if (!options->last_words) diff --git a/src/spells2.cc b/src/spells2.cc index 0cdf08ed..bc5b8642 100644 --- a/src/spells2.cc +++ b/src/spells2.cc @@ -3623,7 +3623,7 @@ bool_ recharge(int power) /*** Determine Seriousness of Failure ***/ /* Mages recharge objects more safely. */ - if (has_ability(AB_PERFECT_CASTING)) + if (p_ptr->has_ability(AB_PERFECT_CASTING)) { /* 10% chance to blow up one rod, otherwise draining. */ if (o_ptr->tval == TV_ROD_MAIN) diff --git a/src/squelch/condition.cc b/src/squelch/condition.cc index c3b8c3f5..41806feb 100644 --- a/src/squelch/condition.cc +++ b/src/squelch/condition.cc @@ -891,7 +891,7 @@ void SymbolCondition::to_json(json_t *j) const bool AbilityCondition::is_match(object_type *) const { - return has_ability(m_ability_idx); + return p_ptr->has_ability(m_ability_idx); } std::shared_ptr<Condition> AbilityCondition::from_json(json_t *j) diff --git a/src/xtra1.cc b/src/xtra1.cc index 16edf4bf..280cc61a 100644 --- a/src/xtra1.cc +++ b/src/xtra1.cc @@ -2246,8 +2246,8 @@ void calc_body_bonus() static int get_extra_blows_ability() { /* Count bonus abilities */ int num = 0; - if (has_ability(AB_MAX_BLOW1)) num++; - if (has_ability(AB_MAX_BLOW2)) num++; + if (p_ptr->has_ability(AB_MAX_BLOW1)) num++; + if (p_ptr->has_ability(AB_MAX_BLOW2)) num++; return num; } |