OSDN Git Service

[Refactor] #40392 Separated player-personalities-table.h
[hengbandforosx/hengbandosx.git] / src / birth / inventory-initializer.c
1 #include "system/angband.h"
2 #include "birth/inventory-initializer.h"
3 #include "monster/monsterrace-hook.h"
4 #include "player/player-personalities-table.h"
5 #include "birth/initial-equipments-table.h"
6 #include "object/object-ego.h"
7 #include "object/object-kind.h"
8 #include "autopick/autopick.h"
9 #include "player/player-races-table.h"
10
11 /*!
12  * @brief 所持状態にあるアイテムの中から一部枠の装備可能なものを装備させる。
13  * @return なし
14  */
15 void wield_all(player_type *creature_ptr)
16 {
17     object_type object_type_body;
18     for (INVENTORY_IDX item = INVEN_PACK - 1; item >= 0; item--) {
19         object_type *o_ptr;
20         o_ptr = &creature_ptr->inventory_list[item];
21         if (!o_ptr->k_idx)
22             continue;
23
24         int slot = wield_slot(creature_ptr, o_ptr);
25         if (slot < INVEN_RARM)
26             continue;
27         if (slot == INVEN_LITE)
28             continue;
29         if (creature_ptr->inventory_list[slot].k_idx)
30             continue;
31
32         object_type *i_ptr;
33         i_ptr = &object_type_body;
34         object_copy(i_ptr, o_ptr);
35         i_ptr->number = 1;
36
37         if (item >= 0) {
38             inven_item_increase(creature_ptr, item, -1);
39             inven_item_optimize(creature_ptr, item);
40         } else {
41             floor_item_increase(creature_ptr->current_floor_ptr, 0 - item, -1);
42             floor_item_optimize(creature_ptr, 0 - item);
43         }
44
45         o_ptr = &creature_ptr->inventory_list[slot];
46         object_copy(o_ptr, i_ptr);
47         creature_ptr->total_weight += i_ptr->weight;
48         creature_ptr->equip_cnt++;
49     }
50 }
51
52 /*!
53  * @brief 初期所持アイテムの処理 / Add an outfit object
54  * @details アイテムを既知のものとした上でwield_all()関数により装備させる。
55  * @param o_ptr 処理したいオブジェクト構造体の参照ポインタ
56  * @return なし
57  */
58 void add_outfit(player_type *creature_ptr, object_type *o_ptr)
59 {
60     object_aware(creature_ptr, o_ptr);
61     object_known(o_ptr);
62     s16b slot = inven_carry(creature_ptr, o_ptr);
63     autopick_alter_item(creature_ptr, slot, FALSE);
64     wield_all(creature_ptr);
65 }
66
67 static void decide_initial_items(player_type *creature_ptr, object_type *q_ptr)
68 {
69     switch (creature_ptr->prace) {
70     case RACE_VAMPIRE:
71         /* Nothing! */
72         /* Vampires can drain blood of creatures */
73         break;
74     case RACE_BALROG:
75         /* Demon can drain vitality from humanoid corpse */
76         get_mon_num_prep(creature_ptr, monster_hook_human, NULL);
77         for (int i = rand_range(3, 4); i > 0; i--) {
78             object_prep(q_ptr, lookup_kind(TV_CORPSE, SV_CORPSE));
79             q_ptr->pval = get_mon_num(creature_ptr, 2, 0);
80             if (q_ptr->pval) {
81                 q_ptr->number = 1;
82                 add_outfit(creature_ptr, q_ptr);
83             }
84         }
85
86         break;
87     case RACE_SKELETON:
88     case RACE_GOLEM:
89     case RACE_ZOMBIE:
90     case RACE_SPECTRE:
91         /* Staff (of Nothing) */
92         object_prep(q_ptr, lookup_kind(TV_STAFF, SV_STAFF_NOTHING));
93         q_ptr->number = 1;
94         add_outfit(creature_ptr, q_ptr);
95         break;
96     case RACE_ENT:
97         /* Potions of Water */
98         object_prep(q_ptr, lookup_kind(TV_POTION, SV_POTION_WATER));
99         q_ptr->number = (ITEM_NUMBER)rand_range(15, 23);
100         add_outfit(creature_ptr, q_ptr);
101         break;
102     case RACE_ANDROID:
103         /* Flasks of oil */
104         object_prep(q_ptr, lookup_kind(TV_FLASK, SV_ANY));
105         apply_magic(creature_ptr, q_ptr, 1, AM_NO_FIXED_ART);
106         q_ptr->number = (ITEM_NUMBER)rand_range(7, 12);
107         add_outfit(creature_ptr, q_ptr);
108         break;
109     default:
110         /* Food rations */
111         object_prep(q_ptr, lookup_kind(TV_FOOD, SV_FOOD_RATION));
112         q_ptr->number = (ITEM_NUMBER)rand_range(3, 7);
113         add_outfit(creature_ptr, q_ptr);
114     }
115 }
116
117 /*!
118  * @brief 種族/職業/性格などに基づき初期所持アイテムを設定するメインセット関数。 / Init players with some belongings
119  * @details Having an item makes the player "aware" of its purpose.
120  * @return なし
121  */
122 void player_outfit(player_type *creature_ptr)
123 {
124     object_type *q_ptr;
125     object_type forge;
126     q_ptr = &forge;
127
128     decide_initial_items(creature_ptr, q_ptr);
129     q_ptr = &forge;
130
131     if ((creature_ptr->prace == RACE_VAMPIRE) && (creature_ptr->pclass != CLASS_NINJA)) {
132         object_prep(q_ptr, lookup_kind(TV_SCROLL, SV_SCROLL_DARKNESS));
133         q_ptr->number = (ITEM_NUMBER)rand_range(2, 5);
134         add_outfit(creature_ptr, q_ptr);
135     } else if (creature_ptr->pclass != CLASS_NINJA) {
136         object_prep(q_ptr, lookup_kind(TV_LITE, SV_LITE_TORCH));
137         q_ptr->number = (ITEM_NUMBER)rand_range(3, 7);
138         q_ptr->xtra4 = rand_range(3, 7) * 500;
139
140         add_outfit(creature_ptr, q_ptr);
141     }
142
143     q_ptr = &forge;
144     if (creature_ptr->prace == RACE_MERFOLK) {
145         object_prep(q_ptr, lookup_kind(TV_RING, SV_RING_LEVITATION_FALL));
146         q_ptr->number = 1;
147         add_outfit(creature_ptr, q_ptr);
148     }
149
150     if ((creature_ptr->pclass == CLASS_RANGER) || (creature_ptr->pclass == CLASS_CAVALRY)) {
151         object_prep(q_ptr, lookup_kind(TV_ARROW, SV_AMMO_NORMAL));
152         q_ptr->number = (byte)rand_range(15, 20);
153         add_outfit(creature_ptr, q_ptr);
154     }
155
156     if (creature_ptr->pclass == CLASS_RANGER) {
157         object_prep(q_ptr, lookup_kind(TV_BOW, SV_SHORT_BOW));
158         add_outfit(creature_ptr, q_ptr);
159     } else if (creature_ptr->pclass == CLASS_ARCHER) {
160         object_prep(q_ptr, lookup_kind(TV_ARROW, SV_AMMO_NORMAL));
161         q_ptr->number = (ITEM_NUMBER)rand_range(15, 20);
162         add_outfit(creature_ptr, q_ptr);
163     } else if (creature_ptr->pclass == CLASS_HIGH_MAGE) {
164         object_prep(q_ptr, lookup_kind(TV_WAND, SV_WAND_MAGIC_MISSILE));
165         q_ptr->number = 1;
166         q_ptr->pval = (PARAMETER_VALUE)rand_range(25, 30);
167         add_outfit(creature_ptr, q_ptr);
168     } else if (creature_ptr->pclass == CLASS_SORCERER) {
169         OBJECT_TYPE_VALUE book_tval;
170         for (book_tval = TV_LIFE_BOOK; book_tval <= TV_LIFE_BOOK + MAX_MAGIC - 1; book_tval++) {
171             object_prep(q_ptr, lookup_kind(book_tval, 0));
172             q_ptr->number = 1;
173             add_outfit(creature_ptr, q_ptr);
174         }
175     } else if (creature_ptr->pclass == CLASS_TOURIST) {
176         if (creature_ptr->pseikaku != SEIKAKU_SEXY) {
177             object_prep(q_ptr, lookup_kind(TV_SHOT, SV_AMMO_LIGHT));
178             q_ptr->number = rand_range(15, 20);
179             add_outfit(creature_ptr, q_ptr);
180         }
181
182         object_prep(q_ptr, lookup_kind(TV_FOOD, SV_FOOD_BISCUIT));
183         q_ptr->number = rand_range(2, 4);
184
185         add_outfit(creature_ptr, q_ptr);
186
187         object_prep(q_ptr, lookup_kind(TV_FOOD, SV_FOOD_WAYBREAD));
188         q_ptr->number = rand_range(2, 4);
189
190         add_outfit(creature_ptr, q_ptr);
191
192         object_prep(q_ptr, lookup_kind(TV_FOOD, SV_FOOD_JERKY));
193         q_ptr->number = rand_range(1, 3);
194
195         add_outfit(creature_ptr, q_ptr);
196
197         object_prep(q_ptr, lookup_kind(TV_FOOD, SV_FOOD_PINT_OF_ALE));
198         q_ptr->number = rand_range(2, 4);
199
200         add_outfit(creature_ptr, q_ptr);
201
202         object_prep(q_ptr, lookup_kind(TV_FOOD, SV_FOOD_PINT_OF_WINE));
203         q_ptr->number = rand_range(2, 4);
204
205         add_outfit(creature_ptr, q_ptr);
206     } else if (creature_ptr->pclass == CLASS_NINJA) {
207         object_prep(q_ptr, lookup_kind(TV_SPIKE, 0));
208         q_ptr->number = rand_range(15, 20);
209         add_outfit(creature_ptr, q_ptr);
210     } else if (creature_ptr->pclass == CLASS_SNIPER) {
211         object_prep(q_ptr, lookup_kind(TV_BOLT, SV_AMMO_NORMAL));
212         q_ptr->number = rand_range(15, 20);
213         add_outfit(creature_ptr, q_ptr);
214     }
215
216     if (creature_ptr->pseikaku == SEIKAKU_SEXY) {
217         player_init[creature_ptr->pclass][2][0] = TV_HAFTED;
218         player_init[creature_ptr->pclass][2][1] = SV_WHIP;
219     }
220
221     for (int i = 0; i < 3; i++) {
222         OBJECT_TYPE_VALUE tv = player_init[creature_ptr->pclass][i][0];
223         OBJECT_SUBTYPE_VALUE sv = player_init[creature_ptr->pclass][i][1];
224         if ((creature_ptr->prace == RACE_ANDROID) && ((tv == TV_SOFT_ARMOR) || (tv == TV_HARD_ARMOR)))
225             continue;
226
227         if (tv == TV_SORCERY_BOOK)
228             tv = TV_LIFE_BOOK + creature_ptr->realm1 - 1;
229         else if (tv == TV_DEATH_BOOK)
230             tv = TV_LIFE_BOOK + creature_ptr->realm2 - 1;
231         else if (tv == TV_RING && sv == SV_RING_RES_FEAR && creature_ptr->prace == RACE_BARBARIAN)
232             sv = SV_RING_SUSTAIN_STR;
233         else if (tv == TV_RING && sv == SV_RING_SUSTAIN_INT && creature_ptr->prace == RACE_MIND_FLAYER) {
234             tv = TV_POTION;
235             sv = SV_POTION_RESTORE_MANA;
236         }
237
238         q_ptr = &forge;
239         object_prep(q_ptr, lookup_kind(tv, sv));
240         if ((tv == TV_SWORD || tv == TV_HAFTED) && (creature_ptr->pclass == CLASS_ROGUE && creature_ptr->realm1 == REALM_DEATH)) /* Only assassins get a poisoned weapon */
241             q_ptr->name2 = EGO_BRAND_POIS;
242
243         add_outfit(creature_ptr, q_ptr);
244     }
245
246     k_info[lookup_kind(TV_POTION, SV_POTION_WATER)].aware = TRUE;
247 }