OSDN Git Service

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