OSDN Git Service

47504e5c76b4aac4347b9175984376adb5899665
[hengbandforosx/hengbandosx.git] / src / load / store-loader.cpp
1 #include "load/store-loader.h"
2 #include "object/object-generator.h"
3 #include "floor/floor-town.h"
4 #include "load/angband-version-comparer.h"
5 #include "load/item-loader.h"
6 #include "load/load-util.h"
7 #include "object/object-stack.h"
8 #include "object/object-value.h"
9 #include "player-info/avatar.h"
10 #include "store/store.h"
11 #include "system/object-type-definition.h"
12 #include "system/player-type-definition.h"
13 #include "util/object-sort.h"
14
15 /*!
16  * @brief 店置きのアイテムオブジェクトを読み込む / Add the item "o_ptr" to the inventory of the "Home"
17  * @param player_ptr プレーヤーへの参照ポインタ
18  * @param store_ptr 店舗の参照ポインタ
19  * @param o_ptr アイテムオブジェクト参照ポインタ
20  * @return なし
21  * @details
22  * In all cases, return the slot (or -1) where the object was placed
23  *
24  * Note that this is a hacked up version of "store_item_to_inventory()".
25  *
26  * Also note that it may not correctly "adapt" to "knowledge" bacoming
27  * known, the player may have to pick stuff up and drop it again.
28  */
29 static void home_carry_load(player_type *player_ptr, store_type *store_ptr, object_type *o_ptr)
30 {
31     for (int i = 0; i < store_ptr->stock_num; i++) {
32         object_type *j_ptr;
33         j_ptr = &store_ptr->stock[i];
34         if (!object_similar(j_ptr, o_ptr))
35             continue;
36
37         object_absorb(j_ptr, o_ptr);
38         return;
39     }
40
41     if (store_ptr->stock_num >= store_get_stock_max(STORE_HOME))
42         return;
43
44     s32b value = object_value(player_ptr, o_ptr);
45     int slot;
46     for (slot = 0; slot < store_ptr->stock_num; slot++) {
47         if (object_sort_comp(player_ptr, o_ptr, value, &store_ptr->stock[slot]))
48             break;
49     }
50
51     for (int i = store_ptr->stock_num; i > slot; i--) {
52         store_ptr->stock[i] = store_ptr->stock[i - 1];
53     }
54
55     store_ptr->stock_num++;
56     store_ptr->stock[slot] = *o_ptr;
57     chg_virtue(player_ptr, V_SACRIFICE, -1);
58 }
59
60 /*!
61  * @brief 店舗情報を読み込む / Read a store
62  * @param player_ptr プレーヤーへの参照ポインタ
63  * @param town_number 街ID
64  * @param store_number 店舗ID
65  * @return エラーID
66  */
67 static errr rd_store(player_type *player_ptr, int town_number, int store_number)
68 {
69     store_type *store_ptr;
70     bool sort = FALSE;
71     if (h_older_than(0, 3, 3) && (store_number == STORE_HOME)) {
72         store_ptr = &town_info[1].store[store_number];
73         if (store_ptr->stock_num)
74             sort = TRUE;
75     } else {
76         store_ptr = &town_info[town_number].store[store_number];
77     }
78
79     byte owner_idx;
80     byte tmp8u;
81     s16b inven_num;
82     rd_s32b(&store_ptr->store_open);
83     rd_s16b(&store_ptr->insult_cur);
84     rd_byte(&owner_idx);
85     if (h_older_than(1, 0, 4)) {
86         rd_byte(&tmp8u);
87         inven_num = tmp8u;
88     } else {
89         rd_s16b(&inven_num);
90     }
91
92     rd_s16b(&store_ptr->good_buy);
93     rd_s16b(&store_ptr->bad_buy);
94
95     rd_s32b(&store_ptr->last_visit);
96     store_ptr->owner = owner_idx;
97
98     for (int j = 0; j < inven_num; j++) {
99         object_type forge;
100         object_type *q_ptr;
101         q_ptr = &forge;
102         object_wipe(q_ptr);
103
104         rd_item(player_ptr, q_ptr);
105
106         auto stock_max = store_get_stock_max(static_cast<STORE_TYPE_IDX>(store_number));
107         if (store_ptr->stock_num >= stock_max)
108             continue;
109
110         if (sort) {
111             home_carry_load(player_ptr, store_ptr, q_ptr);
112         } else {
113             int k = store_ptr->stock_num++;
114             object_copy(&store_ptr->stock[k], q_ptr);
115         }
116     }
117
118     return 0;
119 }
120
121 /*!
122  * @brief 店舗情報を読み込む
123  * @param creature_ptr プレイヤー情報への参照ポインタ(未使用)
124  * @return 読み込み終わったら0、失敗したら22
125  */
126 errr load_store(player_type *creature_ptr)
127 {
128     (void)creature_ptr;
129
130     u16b tmp16u;
131     rd_u16b(&tmp16u);
132     auto town_count = (int)tmp16u;
133
134     rd_u16b(&tmp16u);
135     auto store_count = (int)tmp16u;
136
137     for (int town_idx = 1; town_idx < town_count; town_idx++)
138         for (int store_idx = 0; store_idx < store_count; store_idx++)
139             if (rd_store(creature_ptr, town_idx, store_idx))
140                 return 22;
141
142     return 0;
143 }