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/stuff-handler.h"
6 #include "flavor/flavor-describer.h"
7 #include "flavor/object-flavor-types.h"
8 #include "floor/floor-object.h"
9 #include "game-option/birth-options.h"
10 #include "game-option/play-record-options.h"
11 #include "inventory/inventory-object.h"
12 #include "inventory/inventory-slot-types.h"
13 #include "io/write-diary.h"
14 #include "main/sound-definitions-table.h"
15 #include "main/sound-of-music.h"
16 #include "object-enchant/item-feeling.h"
17 #include "object-enchant/special-object-flags.h"
18 #include "object-hook/hook-checker.h"
19 #include "object/item-tester-hooker.h"
20 #include "object/item-use-flags.h"
21 #include "object/object-generator.h"
22 #include "object/object-info.h"
23 #include "object/object-stack.h"
24 #include "object/object-value.h"
25 #include "player-info/avatar.h"
26 #include "racial/racial-android.h"
27 #include "spell-kind/spells-perception.h"
28 #include "store/home.h"
29 #include "store/owner-insults.h"
30 #include "store/pricing.h"
31 #include "store/say-comments.h"
32 #include "store/service-checker.h"
33 #include "store/store-util.h"
34 #include "store/store.h"
35 #include "system/object-type-definition.h"
36 #include "term/screen-processor.h"
37 #include "view/display-messages.h"
38 #include "view/display-store.h"
39 #include "view/object-describer.h"
40 #include "world/world.h"
43 * @brief プレイヤーが売却する時の値切り処理メインルーチン /
44 * Haggling routine -RAK-
45 * @param player_ptr プレーヤーへの参照ポインタ
46 * @param o_ptr オブジェクトの構造体参照ポインタ
47 * @param price 最終価格を返す参照ポインタ
48 * @return プレイヤーの価格に対して店主が不服ならばTRUEを返す /
49 * Return TRUE if purchase is NOT successful
51 static bool sell_haggle(player_type *player_ptr, object_type *o_ptr, s32b *price)
53 s32b cur_ask = price_item(player_ptr, o_ptr, ot_ptr->max_inflate, TRUE);
54 s32b final_ask = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, TRUE);
55 int noneed = noneedtobargain(final_ask);
56 s32b purse = (s32b)(ot_ptr->max_cost);
58 concptr pmt = _("提示金額", "Offer");
59 if (noneed || !manual_haggle || (final_ask >= purse)) {
60 if (!manual_haggle && !noneed) {
61 final_ask -= final_ask / 10;
64 if (final_ask >= purse) {
65 msg_print(_("即座にこの金額にまとまった。", "You instantly agree upon the price."));
69 msg_print(_("結局この金額にまとまった。", "You eventually agree upon the price."));
72 msg_print(_("すんなりとこの金額にまとまった。", "You quickly agree upon the price."));
78 pmt = _("最終提示金額", "Final Offer");
81 cur_ask *= o_ptr->number;
82 final_ask *= o_ptr->number;
84 s32b min_per = ot_ptr->haggle_per;
85 s32b max_per = min_per * 3;
86 s32b last_offer = object_value(player_ptr, o_ptr) * o_ptr->number;
87 last_offer = last_offer * ot_ptr->max_inflate / 100L;
100 (void)sprintf(out_val, "%s : %ld", pmt, (long)cur_ask);
101 put_str(out_val, 1, 0);
102 cancel = receive_offer(_("提示する価格? ", "What price do you ask? "), &offer, last_offer, -1, cur_ask, final);
106 } else if (offer < cur_ask) {
109 } else if (offer == cur_ask) {
116 if (flag || !loop_flag)
123 s32b x1 = 100 * (last_offer - offer) / (last_offer - cur_ask);
125 if (haggle_insults()) {
129 } else if (x1 > max_per) {
135 s32b x2 = rand_range(x1 - 2, x1 + 2);
136 s32b x3 = ((offer - cur_ask) * x2 / 100L) + 1;
141 if (cur_ask > final_ask) {
144 pmt = _("最終提示金額", "Final Offer");
150 /* 追加 $0 で買い取られてしまうのを防止 By FIRST*/
153 (void)(increase_insults());
155 } else if (offer <= cur_ask) {
164 (void)sprintf(out_val, _("前回の提示価格 $%ld", "Your last bid %ld"), (long)last_offer);
165 put_str(out_val, 1, 39);
166 say_comment_3(cur_ask, annoyed);
172 updatebargain(*price, final_ask, o_ptr->number);
177 * @brief 店からの売却処理のメインルーチン /
178 * Sell an item to the store (or home)
179 * @param owner_ptr プレーヤーへの参照ポインタ
182 void store_sell(player_type *owner_ptr)
185 if (cur_store_num == STORE_HOME)
186 q = _("どのアイテムを置きますか? ", "Drop which item? ");
187 else if (cur_store_num == STORE_MUSEUM)
188 q = _("どのアイテムを寄贈しますか? ", "Give which item? ");
190 q = _("どのアイテムを売りますか? ", "Sell which item? ");
192 item_tester_hook = store_will_buy;
194 /* 我が家でおかしなメッセージが出るオリジナルのバグを修正 */
196 if (cur_store_num == STORE_HOME) {
197 s = _("置けるアイテムを持っていません。", "You don't have any items to drop.");
198 } else if (cur_store_num == STORE_MUSEUM) {
199 s = _("寄贈できるアイテムを持っていません。", "You don't have any items to give.");
201 s = _("欲しい物がないですねえ。", "You have nothing that I want.");
206 o_ptr = choose_object(owner_ptr, &item, q, s, USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT, 0);
210 if ((item >= INVEN_MAIN_HAND) && object_is_cursed(o_ptr)) {
211 msg_print(_("ふーむ、どうやらそれは呪われているようだね。", "Hmmm, it seems to be cursed."));
216 if (o_ptr->number > 1) {
217 amt = get_quantity(NULL, o_ptr->number);
225 object_copy(q_ptr, o_ptr);
227 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
228 q_ptr->pval = o_ptr->pval * amt / o_ptr->number;
230 GAME_TEXT o_name[MAX_NLEN];
231 describe_flavor(owner_ptr, o_name, q_ptr, 0);
232 if ((cur_store_num != STORE_HOME) && (cur_store_num != STORE_MUSEUM)) {
233 q_ptr->inscription = 0;
234 q_ptr->feeling = FEEL_NONE;
237 if (!store_check_num(q_ptr)) {
238 if (cur_store_num == STORE_HOME)
239 msg_print(_("我が家にはもう置く場所がない。", "Your home is full."));
241 else if (cur_store_num == STORE_MUSEUM)
242 msg_print(_("博物館はもう満杯だ。", "The Museum is full."));
245 msg_print(_("すいませんが、店にはもう置く場所がありません。", "I have not the room in my store to keep it."));
251 PRICE price, value, dummy;
252 if ((cur_store_num != STORE_HOME) && (cur_store_num != STORE_MUSEUM)) {
253 msg_format(_("%s(%c)を売却する。", "Selling %s (%c)."), o_name, index_to_label(item));
256 choice = sell_haggle(owner_ptr, q_ptr, &price);
257 if (st_ptr->store_open >= current_world_ptr->game_turn)
261 say_comment_1(owner_ptr);
263 if (cur_store_num == STORE_BLACK)
264 chg_virtue(owner_ptr, V_JUSTICE, -1);
266 if ((o_ptr->tval == TV_BOTTLE) && (cur_store_num != STORE_HOME))
267 chg_virtue(owner_ptr, V_NATURE, 1);
270 owner_ptr->au += price;
271 store_prt_gold(owner_ptr);
272 dummy = object_value(owner_ptr, q_ptr) * q_ptr->number;
274 identify_item(owner_ptr, o_ptr);
276 object_copy(q_ptr, o_ptr);
278 q_ptr->ident |= IDENT_STORE;
279 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
280 q_ptr->pval = o_ptr->pval * amt / o_ptr->number;
282 value = object_value(owner_ptr, q_ptr) * q_ptr->number;
283 describe_flavor(owner_ptr, o_name, q_ptr, 0);
284 msg_format(_("%sを $%ldで売却しました。", "You sold %s for %ld gold."), o_name, (long)price);
287 exe_write_diary(owner_ptr, DIARY_SELL, 0, o_name);
289 if (!((o_ptr->tval == TV_FIGURINE) && (value > 0)))
290 purchase_analyze(owner_ptr, price, value, dummy);
292 distribute_charges(o_ptr, q_ptr, amt);
294 inven_item_increase(owner_ptr, item, -amt);
295 inven_item_describe(owner_ptr, item);
296 if (o_ptr->number > 0)
297 autopick_alter_item(owner_ptr, item, FALSE);
299 inven_item_optimize(owner_ptr, item);
300 handle_stuff(owner_ptr);
301 int item_pos = store_carry(owner_ptr, q_ptr);
303 store_top = (item_pos / store_bottom) * store_bottom;
304 display_store_inventory(owner_ptr);
307 } else if (cur_store_num == STORE_MUSEUM) {
308 char o2_name[MAX_NLEN];
309 describe_flavor(owner_ptr, o2_name, q_ptr, OD_NAME_ONLY);
311 if (-1 == store_check_num(q_ptr))
312 msg_print(_("それと同じ品物は既に博物館にあるようです。", "The Museum already has one of those items."));
314 msg_print(_("博物館に寄贈したものは取り出すことができません!!", "You cannot take back items which have been donated to the Museum!!"));
316 if (!get_check(format(_("本当に%sを寄贈しますか?", "Really give %s to the Museum? "), o2_name)))
319 identify_item(owner_ptr, q_ptr);
320 q_ptr->ident |= IDENT_FULL_KNOWN;
322 distribute_charges(o_ptr, q_ptr, amt);
323 msg_format(_("%sを置いた。(%c)", "You drop %s (%c)."), o_name, index_to_label(item));
326 vary_item(owner_ptr, item, -amt);
327 handle_stuff(owner_ptr);
329 int item_pos = home_carry(owner_ptr, q_ptr);
331 store_top = (item_pos / store_bottom) * store_bottom;
332 display_store_inventory(owner_ptr);
335 distribute_charges(o_ptr, q_ptr, amt);
336 msg_format(_("%sを置いた。(%c)", "You drop %s (%c)."), o_name, index_to_label(item));
338 vary_item(owner_ptr, item, -amt);
339 handle_stuff(owner_ptr);
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 if ((choice == 0) && (item >= INVEN_MAIN_HAND)) {
348 calc_android_exp(owner_ptr);
349 verify_equip_slot(owner_ptr, item);