OSDN Git Service

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