OSDN Git Service

Merge pull request #3532 from sikabane-works/release/3.0.0.87-alpha
[hengbandforosx/hengbandosx.git] / src / birth / history-generator.cpp
1 #include "birth/history-generator.h"
2 #include "birth/history.h"
3 #include "player-info/race-types.h"
4 #include "system/player-type-definition.h"
5 #include "util/buffer-shaper.h"
6 #include "util/string-processor.h"
7 #include <algorithm>
8 #include <sstream>
9 #include <string>
10
11 static int get_history_chart(PlayerType *player_ptr)
12 {
13     switch (player_ptr->prace) {
14     case PlayerRaceType::AMBERITE:
15         return 67;
16     case PlayerRaceType::HUMAN:
17     case PlayerRaceType::BARBARIAN:
18     case PlayerRaceType::DUNADAN:
19         return 1;
20     case PlayerRaceType::HALF_ELF:
21         return 4;
22     case PlayerRaceType::ELF:
23     case PlayerRaceType::HIGH_ELF:
24         return 7;
25     case PlayerRaceType::HOBBIT:
26         return 10;
27     case PlayerRaceType::GNOME:
28         return 13;
29     case PlayerRaceType::DWARF:
30         return 16;
31     case PlayerRaceType::HALF_ORC:
32         return 19;
33     case PlayerRaceType::HALF_TROLL:
34         return 22;
35     case PlayerRaceType::DARK_ELF:
36         return 69;
37     case PlayerRaceType::HALF_OGRE:
38         return 74;
39     case PlayerRaceType::HALF_GIANT:
40         return 75;
41     case PlayerRaceType::HALF_TITAN:
42         return 76;
43     case PlayerRaceType::CYCLOPS:
44         return 77;
45     case PlayerRaceType::YEEK:
46         return 78;
47     case PlayerRaceType::KOBOLD:
48         return 82;
49     case PlayerRaceType::KLACKON:
50         return 84;
51     case PlayerRaceType::NIBELUNG:
52         return 87;
53     case PlayerRaceType::DRACONIAN:
54         return 89;
55     case PlayerRaceType::MIND_FLAYER:
56         return 92;
57     case PlayerRaceType::IMP:
58         return 94;
59     case PlayerRaceType::GOLEM:
60         return 98;
61     case PlayerRaceType::SKELETON:
62         return 102;
63     case PlayerRaceType::ZOMBIE:
64         return 107;
65     case PlayerRaceType::VAMPIRE:
66         return 113;
67     case PlayerRaceType::SPECTRE:
68         return 118;
69     case PlayerRaceType::SPRITE:
70         return 124;
71     case PlayerRaceType::BEASTMAN:
72         return 129;
73     case PlayerRaceType::ENT:
74         return 137;
75     case PlayerRaceType::ARCHON:
76         return 142;
77     case PlayerRaceType::BALROG:
78         return 145;
79     case PlayerRaceType::S_FAIRY:
80         return 148;
81     case PlayerRaceType::KUTAR:
82         return 154;
83     case PlayerRaceType::ANDROID:
84         return 155;
85     case PlayerRaceType::MERFOLK:
86         return 170;
87     default:
88         return 0;
89     }
90 }
91
92 /*!
93  * @brief 生い立ちを画面に表示しつつ、種族から社会的地位を決定する
94  * @param player_ptr プレイヤーへの参照ポインタ
95  */
96 static std::string decide_social_class(PlayerType *player_ptr)
97 {
98     short social_class = randint1(4);
99     auto chart = get_history_chart(player_ptr);
100     std::stringstream ss;
101     while (chart != 0) {
102         auto i = 0;
103         auto roll = randint1(100);
104         while ((chart != backgrounds[i].chart) || (roll > backgrounds[i].roll)) {
105             i++;
106         }
107
108         ss << backgrounds[i].info;
109         social_class += static_cast<short>(backgrounds[i].bonus) - 50;
110         chart = backgrounds[i].next;
111     }
112
113     if (social_class > 100) {
114         social_class = 100;
115     } else if (social_class < 1) {
116         social_class = 1;
117     }
118
119     player_ptr->sc = social_class;
120     return ss.str();
121 }
122
123 /*!
124  * @brief プレイヤーの生い立ちの自動生成を行う
125  * @param player_ptr プレイヤーへの参照ポインタ
126  */
127 void get_history(PlayerType *player_ptr)
128 {
129     constexpr auto lines = 4;
130     for (int i = 0; i < lines; i++) {
131         player_ptr->history[i][0] = '\0';
132     }
133
134     auto social_class = decide_social_class(player_ptr);
135     constexpr auto max_line_len = sizeof(player_ptr->history[0]);
136     const auto history_lines = shape_buffer(social_class.data(), max_line_len);
137     const auto max_lines = std::min<int>(lines, history_lines.size());
138     for (auto i = 0; i < max_lines; ++i) {
139         angband_strcpy(player_ptr->history[i], history_lines[i], max_line_len);
140     }
141 }