1 #include "store/sell-order.h"
2 #include "action/weapon-shield.h"
3 #include "autopick/autopick.h"
4 #include "core/asking-player.h"
5 #include "core/player-update-types.h"
6 #include "core/stuff-handler.h"
7 #include "core/window-redrawer.h"
8 #include "flavor/flavor-describer.h"
9 #include "flavor/object-flavor-types.h"
10 #include "floor/floor-object.h"
11 #include "game-option/birth-options.h"
12 #include "game-option/play-record-options.h"
13 #include "inventory/inventory-object.h"
14 #include "inventory/inventory-slot-types.h"
15 #include "io/write-diary.h"
16 #include "main/sound-definitions-table.h"
17 #include "main/sound-of-music.h"
18 #include "object-enchant/item-feeling.h"
19 #include "object-enchant/special-object-flags.h"
20 #include "object-hook/hook-checker.h"
21 #include "object/item-tester-hooker.h"
22 #include "object/item-use-flags.h"
23 #include "object/object-generator.h"
24 #include "object/object-info.h"
25 #include "object/object-stack.h"
26 #include "object/object-value.h"
27 #include "player-info/avatar.h"
28 #include "racial/racial-android.h"
29 #include "spell-kind/spells-perception.h"
30 #include "store/home.h"
31 #include "store/owner-insults.h"
32 #include "store/pricing.h"
33 #include "store/say-comments.h"
34 #include "store/service-checker.h"
35 #include "store/store-util.h"
36 #include "store/store.h"
37 #include "system/object-type-definition.h"
38 #include "term/screen-processor.h"
39 #include "view/display-messages.h"
40 #include "view/display-store.h"
41 #include "view/object-describer.h"
42 #include "util/bit-flags-calculator.h"
43 #include "world/world.h"
46 * @brief プレイヤーが売却する時の値切り処理メインルーチン /
47 * Haggling routine -RAK-
48 * @param player_ptr プレーヤーへの参照ポインタ
49 * @param o_ptr オブジェクトの構造体参照ポインタ
50 * @param price 最終価格を返す参照ポインタ
51 * @return プレイヤーの価格に対して店主が不服ならばTRUEを返す /
52 * Return TRUE if purchase is NOT successful
54 static bool sell_haggle(player_type *player_ptr, object_type *o_ptr, s32b *price)
56 s32b cur_ask = price_item(player_ptr, o_ptr, ot_ptr->max_inflate, TRUE);
57 s32b final_ask = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, TRUE);
58 int noneed = noneedtobargain(final_ask);
59 s32b purse = (s32b)(ot_ptr->max_cost);
61 concptr pmt = _("提示金額", "Offer");
62 if (noneed || !manual_haggle || (final_ask >= purse)) {
63 if (!manual_haggle && !noneed) {
64 final_ask -= final_ask / 10;
67 if (final_ask >= purse) {
68 msg_print(_("即座にこの金額にまとまった。", "You instantly agree upon the price."));
72 msg_print(_("結局この金額にまとまった。", "You eventually agree upon the price."));
75 msg_print(_("すんなりとこの金額にまとまった。", "You quickly agree upon the price."));
81 pmt = _("最終提示金額", "Final Offer");
84 cur_ask *= o_ptr->number;
85 final_ask *= o_ptr->number;
87 s32b min_per = ot_ptr->haggle_per;
88 s32b max_per = min_per * 3;
89 s32b last_offer = object_value(player_ptr, o_ptr) * o_ptr->number;
90 last_offer = last_offer * ot_ptr->max_inflate / 100L;
103 (void)sprintf(out_val, "%s : %ld", pmt, (long)cur_ask);
104 put_str(out_val, 1, 0);
105 cancel = receive_offer(_("提示する価格? ", "What price do you ask? "), &offer, last_offer, -1, cur_ask, final);
109 } else if (offer < cur_ask) {
112 } else if (offer == cur_ask) {
119 if (flag || !loop_flag)
126 s32b x1 = 100 * (last_offer - offer) / (last_offer - cur_ask);
128 if (haggle_insults()) {
132 } else if (x1 > max_per) {
138 s32b x2 = rand_range(x1 - 2, x1 + 2);
139 s32b x3 = ((offer - cur_ask) * x2 / 100L) + 1;
144 if (cur_ask > final_ask) {
147 pmt = _("最終提示金額", "Final Offer");
153 /* 追加 $0 で買い取られてしまうのを防止 By FIRST*/
156 (void)(increase_insults());
158 } else if (offer <= cur_ask) {
167 (void)sprintf(out_val, _("前回の提示価格 $%ld", "Your last bid %ld"), (long)last_offer);
168 put_str(out_val, 1, 39);
169 say_comment_3(cur_ask, annoyed);
175 updatebargain(*price, final_ask, o_ptr->number);
180 * @brief 店からの売却処理のメインルーチン /
181 * Sell an item to the store (or home)
182 * @param owner_ptr プレーヤーへの参照ポインタ
185 void store_sell(player_type *owner_ptr)
188 if (cur_store_num == STORE_HOME)
189 q = _("どのアイテムを置きますか? ", "Drop which item? ");
190 else if (cur_store_num == STORE_MUSEUM)
191 q = _("どのアイテムを寄贈しますか? ", "Give which item? ");
193 q = _("どのアイテムを売りますか? ", "Sell which item? ");
195 item_tester_hook = store_will_buy;
197 /* 我が家でおかしなメッセージが出るオリジナルのバグを修正 */
199 if (cur_store_num == STORE_HOME) {
200 s = _("置けるアイテムを持っていません。", "You don't have any items to drop.");
201 } else if (cur_store_num == STORE_MUSEUM) {
202 s = _("寄贈できるアイテムを持っていません。", "You don't have any items to give.");
204 s = _("欲しい物がないですねえ。", "You have nothing that I want.");
209 o_ptr = choose_object(owner_ptr, &item, q, s, USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT, TV_NONE);
213 if ((item >= INVEN_MAIN_HAND) && object_is_cursed(o_ptr)) {
214 msg_print(_("ふーむ、どうやらそれは呪われているようだね。", "Hmmm, it seems to be cursed."));
219 if (o_ptr->number > 1) {
220 amt = get_quantity(NULL, o_ptr->number);
228 object_copy(q_ptr, o_ptr);
230 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
231 q_ptr->pval = o_ptr->pval * amt / o_ptr->number;
233 GAME_TEXT o_name[MAX_NLEN];
234 describe_flavor(owner_ptr, o_name, q_ptr, 0);
235 if ((cur_store_num != STORE_HOME) && (cur_store_num != STORE_MUSEUM)) {
236 q_ptr->inscription = 0;
237 q_ptr->feeling = FEEL_NONE;
240 if (!store_check_num(q_ptr)) {
241 if (cur_store_num == STORE_HOME)
242 msg_print(_("我が家にはもう置く場所がない。", "Your home is full."));
244 else if (cur_store_num == STORE_MUSEUM)
245 msg_print(_("博物館はもう満杯だ。", "The Museum is full."));
248 msg_print(_("すいませんが、店にはもう置く場所がありません。", "I have not the room in my store to keep it."));
254 PRICE price, value, dummy;
255 if ((cur_store_num != STORE_HOME) && (cur_store_num != STORE_MUSEUM)) {
256 msg_format(_("%s(%c)を売却する。", "Selling %s (%c)."), o_name, index_to_label(item));
259 choice = sell_haggle(owner_ptr, q_ptr, &price);
260 if (st_ptr->store_open >= current_world_ptr->game_turn)
264 say_comment_1(owner_ptr);
266 if (cur_store_num == STORE_BLACK)
267 chg_virtue(owner_ptr, V_JUSTICE, -1);
269 if ((o_ptr->tval == TV_BOTTLE) && (cur_store_num != STORE_HOME))
270 chg_virtue(owner_ptr, V_NATURE, 1);
273 owner_ptr->au += price;
274 store_prt_gold(owner_ptr);
275 dummy = object_value(owner_ptr, q_ptr) * q_ptr->number;
277 identify_item(owner_ptr, o_ptr);
279 object_copy(q_ptr, o_ptr);
281 q_ptr->ident |= IDENT_STORE;
282 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
283 q_ptr->pval = o_ptr->pval * amt / o_ptr->number;
285 value = object_value(owner_ptr, q_ptr) * q_ptr->number;
286 describe_flavor(owner_ptr, o_name, q_ptr, 0);
287 msg_format(_("%sを $%ldで売却しました。", "You sold %s for %ld gold."), o_name, (long)price);
290 exe_write_diary(owner_ptr, DIARY_SELL, 0, o_name);
292 if (!((o_ptr->tval == TV_FIGURINE) && (value > 0)))
293 purchase_analyze(owner_ptr, price, value, dummy);
295 distribute_charges(o_ptr, q_ptr, amt);
297 inven_item_increase(owner_ptr, item, -amt);
298 inven_item_describe(owner_ptr, item);
299 if (o_ptr->number > 0)
300 autopick_alter_item(owner_ptr, item, FALSE);
302 inven_item_optimize(owner_ptr, item);
303 int item_pos = store_carry(owner_ptr, q_ptr);
305 store_top = (item_pos / store_bottom) * store_bottom;
306 display_store_inventory(owner_ptr);
309 } else if (cur_store_num == STORE_MUSEUM) {
310 char o2_name[MAX_NLEN];
311 describe_flavor(owner_ptr, o2_name, q_ptr, OD_NAME_ONLY);
313 if (-1 == store_check_num(q_ptr))
314 msg_print(_("それと同じ品物は既に博物館にあるようです。", "The Museum already has one of those items."));
316 msg_print(_("博物館に寄贈したものは取り出すことができません!!", "You cannot take back items which have been donated to the Museum!!"));
318 if (!get_check(format(_("本当に%sを寄贈しますか?", "Really give %s to the Museum? "), o2_name)))
321 identify_item(owner_ptr, q_ptr);
322 q_ptr->ident |= IDENT_FULL_KNOWN;
324 distribute_charges(o_ptr, q_ptr, amt);
325 msg_format(_("%sを置いた。(%c)", "You drop %s (%c)."), o_name, index_to_label(item));
328 vary_item(owner_ptr, item, -amt);
330 int item_pos = home_carry(owner_ptr, q_ptr);
332 store_top = (item_pos / store_bottom) * store_bottom;
333 display_store_inventory(owner_ptr);
336 distribute_charges(o_ptr, q_ptr, amt);
337 msg_format(_("%sを置いた。(%c)", "You drop %s (%c)."), o_name, index_to_label(item));
339 vary_item(owner_ptr, item, -amt);
340 int item_pos = home_carry(owner_ptr, q_ptr);
342 store_top = (item_pos / store_bottom) * store_bottom;
343 display_store_inventory(owner_ptr);
347 set_bits(owner_ptr->update, PU_BONUS);
348 set_bits(owner_ptr->window_flags, PW_PLAYER);
349 handle_stuff(owner_ptr);
351 if ((choice == 0) && (item >= INVEN_MAIN_HAND)) {
352 calc_android_exp(owner_ptr);
353 verify_equip_slot(owner_ptr, item);