OSDN Git Service

Merge branch 'develop' into macos-develop
[hengbandforosx/hengbandosx.git] / src / info-reader / skill-reader.cpp
1 #include "info-reader/skill-reader.h"
2 #include "info-reader/info-reader-util.h"
3 #include "info-reader/parse-error-types.h"
4 #include "main/angband-headers.h"
5 #include "object/tval-types.h"
6 #include "player/player-skill.h"
7 #include "util/enum-converter.h"
8 #include "util/string-processor.h"
9
10 /*!
11  * @brief 職業技能定義(ClassSkillDefinitions)のパース関数
12  * @param buf テキスト列
13  * @param head ヘッダ構造体
14  * @return エラーコード
15  */
16 errr parse_class_skills_info(std::string_view buf, angband_header *head)
17 {
18     static skill_table *s_ptr = nullptr;
19     const auto &tokens = str_split(buf, ':', false, 5);
20
21     if (tokens[0] == "N") {
22         // N:class-index
23         if (tokens.size() < 2 && tokens[1].size() == 0) {
24             return PARSE_ERROR_GENERIC;
25         }
26
27         auto i = std::stoi(tokens[1]);
28         if (i < error_idx) {
29             return PARSE_ERROR_NON_SEQUENTIAL_RECORDS;
30         }
31         if (i >= head->info_num) {
32             return PARSE_ERROR_OUT_OF_BOUNDS;
33         }
34
35         error_idx = i;
36         s_ptr = &class_skills_info[i];
37     } else if (!s_ptr) {
38         return PARSE_ERROR_MISSING_RECORD_HEADER;
39     } else if (tokens[0] == "W") {
40         if (tokens.size() < 5) {
41             return PARSE_ERROR_TOO_FEW_ARGUMENTS;
42         }
43
44         int tval_offset, sval, start, max;
45         info_set_value(tval_offset, tokens[1]);
46         info_set_value(sval, tokens[2]);
47         info_set_value(start, tokens[3]);
48         info_set_value(max, tokens[4]);
49
50         auto tval = ItemKindType::BOW + tval_offset;
51         s_ptr->w_start[tval][sval] = PlayerSkill::weapon_exp_at(i2enum<PlayerSkillRank>(start));
52         s_ptr->w_max[tval][sval] = PlayerSkill::weapon_exp_at(i2enum<PlayerSkillRank>(max));
53     } else if (tokens[0] == "S") {
54         if (tokens.size() < 4) {
55             return PARSE_ERROR_TOO_FEW_ARGUMENTS;
56         }
57
58         int num, start, max;
59         info_set_value(num, tokens[1]);
60         info_set_value(start, tokens[2]);
61         info_set_value(max, tokens[3]);
62
63         if (!PlayerSkill::valid_weapon_exp(start) || !PlayerSkill::valid_weapon_exp(max) || start > max) {
64             return PARSE_ERROR_INVALID_FLAG;
65         }
66
67         auto skill = PlayerSkillKindType::MARTIAL_ARTS + num;
68         s_ptr->s_start[skill] = static_cast<SUB_EXP>(start);
69         s_ptr->s_max[skill] = static_cast<SUB_EXP>(max);
70     } else {
71         return PARSE_ERROR_UNDEFINED_DIRECTIVE;
72     }
73
74     return PARSE_ERROR_NONE;
75 }