OSDN Git Service

Merge pull request #2122 from sikabane-works/release/3.0.0Alpha52
[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/item/item-loader-factory.h"
6 #include "load/load-util.h"
7 #include "load/old/item-loader-savefile50.h"
8 #include "object/object-stack.h"
9 #include "object/object-value.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 #include <stdint.h>
15
16 /*!
17  * @brief 店置きのアイテムオブジェクトを読み込む / Add the item "o_ptr" to the inventory of the "Home"
18  * @param player_ptr プレイヤーへの参照ポインタ
19  * @param store_ptr 店舗の参照ポインタ
20  * @param o_ptr アイテムオブジェクト参照ポインタ
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(PlayerType *player_ptr, store_type *store_ptr, object_type *o_ptr)
30 {
31     for (auto i = 0; i < store_ptr->stock_num; i++) {
32         auto *j_ptr = &store_ptr->stock[i];
33         if (!object_similar(j_ptr, o_ptr)) {
34             continue;
35         }
36
37         object_absorb(j_ptr, o_ptr);
38         return;
39     }
40
41     if (store_ptr->stock_num >= store_get_stock_max(StoreSaleType::HOME)) {
42         return;
43     }
44
45     auto value = object_value(o_ptr);
46     int slot;
47     for (slot = 0; slot < store_ptr->stock_num; slot++) {
48         if (object_sort_comp(player_ptr, o_ptr, value, &store_ptr->stock[slot]))
49             break;
50     }
51
52     for (auto i = store_ptr->stock_num; i > slot; i--) {
53         store_ptr->stock[i] = store_ptr->stock[i - 1];
54     }
55
56     store_ptr->stock_num++;
57     store_ptr->stock[slot] = *o_ptr;
58     chg_virtue(player_ptr, V_SACRIFICE, -1);
59 }
60
61 /*!
62  * @brief 店舗情報を読み込む / Read a store
63  * @param player_ptr プレイヤーへの参照ポインタ
64  * @param town_number 街ID
65  * @param store_number 店舗ID
66  * @return エラーID
67  */
68 static void rd_store(PlayerType *player_ptr, int town_number, int store_number)
69 {
70     store_type *store_ptr;
71     auto sort = false;
72     if (h_older_than(0, 3, 3) && (i2enum<StoreSaleType>(store_number) == StoreSaleType::HOME)) {
73         store_ptr = &town_info[1].store[store_number];
74         if (store_ptr->stock_num) {
75             sort = true;
76         }
77     } else {
78         store_ptr = &town_info[town_number].store[store_number];
79     }
80
81     store_ptr->store_open = rd_s32b();
82     store_ptr->insult_cur = rd_s16b();
83     store_ptr->owner = rd_byte();
84
85     int16_t inven_num;
86     if (h_older_than(1, 0, 4)) {
87         inven_num = rd_byte();
88     } else {
89         inven_num = rd_s16b();
90     }
91
92     store_ptr->good_buy = rd_s16b();
93     store_ptr->bad_buy = rd_s16b();
94     store_ptr->last_visit = rd_s32b();
95
96     auto item_loader = ItemLoaderFactory::create_loader();
97     for (int j = 0; j < inven_num; j++) {
98         object_type item;
99         item_loader->rd_item(&item);
100         auto stock_max = store_get_stock_max(i2enum<StoreSaleType>(store_number));
101         if (store_ptr->stock_num >= stock_max) {
102             continue;
103         }
104
105         if (sort) {
106             home_carry_load(player_ptr, store_ptr, &item);
107         } else {
108             int k = store_ptr->stock_num++;
109             store_ptr->stock[k].copy_from(&item);
110         }
111     }
112 }
113
114 /*!
115  * @brief 店舗情報を読み込む
116  * @param player_ptr プレイヤー情報への参照ポインタ(未使用)
117  * @return 読み込み終わったら0、失敗したら22
118  */
119 void load_store(PlayerType *player_ptr)
120 {
121     int16_t town_count = rd_u16b();
122     int16_t store_count = rd_u16b();
123     for (int16_t town_idx = 1; town_idx < town_count; town_idx++) {
124         for (int16_t store_idx = 0; store_idx < store_count; store_idx++) {
125             rd_store(player_ptr, town_idx, store_idx);
126         }
127     }
128 }