OSDN Git Service

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