OSDN Git Service

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