OSDN Git Service

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