3 * @brief 店の処理 / Store commands
6 * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke\n
7 * This software may be copied and distributed for educational, research, and\n
8 * not for profit purposes provided that this copyright and statement are\n
9 * included in all such copies.\n
10 * 2014 Deskull rearranged comment for Doxygen.
14 #include "market/say-comments.h"
15 #include "market/store-owners.h"
16 #include "market/store-util.h"
17 #include "market/gold-magnification-table.h"
18 #include "market/store-util.h"
19 #include "market/black-market.h"
22 #include "main/music-definitions-table.h"
23 #include "main/sound-definitions-table.h"
27 #include "io/write-diary.h"
28 #include "cmd/cmd-basic.h"
29 #include "cmd/cmd-diary.h"
30 #include "cmd/cmd-draw.h"
31 #include "cmd/cmd-dump.h"
32 #include "cmd/cmd-help.h"
33 #include "cmd/cmd-item.h"
34 #include "cmd/cmd-macro.h"
35 #include "cmd/cmd-process-screen.h"
36 #include "cmd/cmd-smith.h"
37 #include "cmd/cmd-visuals.h"
38 #include "cmd/cmd-zapwand.h"
39 #include "cmd/cmd-magiceat.h"
41 #include "market/store.h"
43 #include "cmd-spell.h"
45 #include "player-status.h"
46 #include "player-class.h"
47 #include "player-inventory.h"
48 #include "object-flavor.h"
49 #include "object-hook.h"
50 #include "floor-events.h"
53 #include "player-effects.h"
54 #include "player/race-info-table.h"
57 #include "objectkind.h"
59 #include "floor-town.h"
61 #include "view-mainwindow.h"
66 static int store_top = 0;
67 static int store_bottom = 0;
68 static int xtra_stock = 0;
69 static const owner_type *ot_ptr = NULL;
70 static s16b old_town_num = 0;
71 static s16b inner_town_num = 0;
74 * We store the current "store feat" here so everyone can access it
76 static int cur_store_feat;
79 * @brief 店舗価格を決定する. 無料にはならない /
80 * Determine the price of an item (qty one) in a store.
81 * @param o_ptr 店舗に並べるオブジェクト構造体の参照ポインタ
83 * @param flip TRUEならば店主にとっての買取価格、FALSEなら売出価格を計算
87 * This function takes into account the player's charisma, and the
88 * shop-keepers friendliness, and the shop-keeper's base greed, but
89 * never lets a shop-keeper lose money in a transaction.
90 * The "greed" value should exceed 100 when the player is "buying" the
91 * item, and should be less than 100 when the player is "selling" it.
92 * Hack -- the black market always charges twice as much as it should.
93 * Charisma adjustment runs from 80 to 130
94 * Racial adjustment runs from 95 to 130
95 * Since greed/charisma/racial adjustments are centered at 100, we need
96 * to adjust (by 200) to extract a usable multiplier. Note that the
97 * "greed" value is always something (?).
100 static PRICE price_item(player_type *player_ptr, object_type *o_ptr, int greed, bool flip)
102 PRICE price = object_value(o_ptr);
103 if (price <= 0) return (0L);
105 int factor = rgold_adj[ot_ptr->owner_race][player_ptr->prace];
106 factor += adj_chr_gold[player_ptr->stat_ind[A_CHR]];
110 adjust = 100 + (300 - (greed + factor));
111 if (adjust > 100) adjust = 100;
112 if (cur_store_num == STORE_BLACK)
115 price = (price * adjust + 50L) / 100L;
119 adjust = 100 + ((greed + factor) - 300);
120 if (adjust < 100) adjust = 100;
121 if (cur_store_num == STORE_BLACK)
124 price = (s32b)(((u32b)price * (u32b)adjust + 50UL) / 100UL);
127 if (price <= 0L) return (1L);
133 * @brief 店舗に品を置くスペースがあるかどうかの判定を返す /
134 * Check to see if the shop will be carrying too many objects -RAK-
135 * @param o_ptr 店舗に置きたいオブジェクト構造体の参照ポインタ
136 * @return 置き場がないなら0、重ね合わせできるアイテムがあるなら-1、スペースがあるなら1を返す。
139 * Note that the shop, just like a player, will not accept things
140 * it cannot hold. Before, one could "nuke" potions this way.
141 * Return value is now int:
143 * -1 : Can be combined to existing slot.
144 * 1 : Cannot be combined but there are empty spaces.
147 static int store_check_num(object_type *o_ptr)
150 if ((cur_store_num == STORE_HOME) || (cur_store_num == STORE_MUSEUM))
152 bool old_stack_force_notes = stack_force_notes;
153 bool old_stack_force_costs = stack_force_costs;
155 if (cur_store_num != STORE_HOME)
157 stack_force_notes = FALSE;
158 stack_force_costs = FALSE;
161 for (int i = 0; i < st_ptr->stock_num; i++)
163 j_ptr = &st_ptr->stock[i];
164 if (object_similar(j_ptr, o_ptr))
166 if (cur_store_num != STORE_HOME)
168 stack_force_notes = old_stack_force_notes;
169 stack_force_costs = old_stack_force_costs;
176 if (cur_store_num != STORE_HOME)
178 stack_force_notes = old_stack_force_notes;
179 stack_force_costs = old_stack_force_costs;
184 for (int i = 0; i < st_ptr->stock_num; i++)
186 j_ptr = &st_ptr->stock[i];
187 if (store_object_similar(j_ptr, o_ptr)) return -1;
191 /* Free space is always usable */
193 * オプション powerup_home が設定されていると
196 if ((cur_store_num == STORE_HOME) && (powerup_home == FALSE))
198 if (st_ptr->stock_num < ((st_ptr->stock_size) / 10))
205 if (st_ptr->stock_num < st_ptr->stock_size)
216 * @brief 現在の町の指定された店舗のアイテムを整理する /
217 * Combine and reorder items in store.
218 * @param store_num 店舗ID
219 * @return 実際に整理が行われたならばTRUEを返す。
221 bool combine_and_reorder_home(int store_num)
223 store_type *old_st_ptr = st_ptr;
224 st_ptr = &town_info[1].store[store_num];
226 if (store_num != STORE_HOME)
228 stack_force_notes = FALSE;
229 stack_force_costs = FALSE;
232 bool combined = TRUE;
236 for (int i = st_ptr->stock_num - 1; i > 0; i--)
239 o_ptr = &st_ptr->stock[i];
240 if (!o_ptr->k_idx) continue;
241 for (int j = 0; j < i; j++)
244 j_ptr = &st_ptr->stock[j];
245 if (!j_ptr->k_idx) continue;
248 * Get maximum number of the stack if these
249 * are similar, get zero otherwise.
251 int max_num = object_similar_part(j_ptr, o_ptr);
252 if (max_num == 0 || j_ptr->number >= max_num) continue;
254 if (o_ptr->number + j_ptr->number <= max_num)
256 object_absorb(j_ptr, o_ptr);
259 for (k = i; k < st_ptr->stock_num; k++)
261 st_ptr->stock[k] = st_ptr->stock[k + 1];
264 object_wipe(&st_ptr->stock[k]);
269 ITEM_NUMBER old_num = o_ptr->number;
270 ITEM_NUMBER remain = j_ptr->number + o_ptr->number - max_num;
271 object_absorb(j_ptr, o_ptr);
272 o_ptr->number = remain;
273 if (o_ptr->tval == TV_ROD)
275 o_ptr->pval = o_ptr->pval * remain / old_num;
276 o_ptr->timeout = o_ptr->timeout * remain / old_num;
278 else if (o_ptr->tval == TV_WAND)
280 o_ptr->pval = o_ptr->pval * remain / old_num;
291 for (int i = 0; i < st_ptr->stock_num; i++)
294 o_ptr = &st_ptr->stock[i];
295 if (!o_ptr->k_idx) continue;
297 s32b o_value = object_value(o_ptr);
299 for (j = 0; j < st_ptr->stock_num; j++)
301 if (object_sort_comp(o_ptr, o_value, &st_ptr->stock[j])) break;
304 if (j >= i) continue;
310 object_copy(j_ptr, &st_ptr->stock[i]);
311 for (int k = i; k > j; k--)
313 object_copy(&st_ptr->stock[k], &st_ptr->stock[k - 1]);
316 object_copy(&st_ptr->stock[j], j_ptr);
320 bool old_stack_force_notes = stack_force_notes;
321 bool old_stack_force_costs = stack_force_costs;
322 if (store_num != STORE_HOME)
324 stack_force_notes = old_stack_force_notes;
325 stack_force_costs = old_stack_force_costs;
333 * @brief 我が家にオブジェクトを加える /
334 * Add the item "o_ptr" to the inventory of the "Home"
335 * @param o_ptr 加えたいオブジェクトの構造体参照ポインタ
339 * In all cases, return the slot (or -1) where the object was placed
340 * Note that this is a hacked up version of "inven_carry()".
341 * Also note that it may not correctly "adapt" to "knowledge" bacoming
342 * known, the player may have to pick stuff up and drop it again.
345 static int home_carry(player_type *player_ptr, object_type *o_ptr)
347 if (cur_store_num != STORE_HOME)
349 stack_force_notes = FALSE;
350 stack_force_costs = FALSE;
353 bool old_stack_force_notes = stack_force_notes;
354 bool old_stack_force_costs = stack_force_costs;
355 for (int slot = 0; slot < st_ptr->stock_num; slot++)
358 j_ptr = &st_ptr->stock[slot];
359 if (object_similar(j_ptr, o_ptr))
361 object_absorb(j_ptr, o_ptr);
362 if (cur_store_num != STORE_HOME)
364 stack_force_notes = old_stack_force_notes;
365 stack_force_costs = old_stack_force_costs;
372 if (cur_store_num != STORE_HOME)
374 stack_force_notes = old_stack_force_notes;
375 stack_force_costs = old_stack_force_costs;
380 * 隠し機能: オプション powerup_home が設定されていると
383 if ((cur_store_num != STORE_HOME) || (powerup_home == TRUE))
385 if (st_ptr->stock_num >= st_ptr->stock_size)
392 if (st_ptr->stock_num >= ((st_ptr->stock_size) / 10))
398 PRICE value = object_value(o_ptr);
400 for (slot = 0; slot < st_ptr->stock_num; slot++)
402 if (object_sort_comp(o_ptr, value, &st_ptr->stock[slot])) break;
405 for (int i = st_ptr->stock_num; i > slot; i--)
407 st_ptr->stock[i] = st_ptr->stock[i - 1];
411 st_ptr->stock[slot] = *o_ptr;
412 chg_virtue(player_ptr, V_SACRIFICE, -1);
413 (void)combine_and_reorder_home(cur_store_num);
419 * @brief 店舗の割引対象外にするかどうかを判定 /
420 * Eliminate need to bargain if player has haggled well in the past
421 * @param minprice アイテムの最低販売価格
422 * @return 割引を禁止するならTRUEを返す。
424 static bool noneedtobargain(PRICE minprice)
426 PRICE good = st_ptr->good_buy;
427 PRICE bad = st_ptr->bad_buy;
428 if (minprice < 10L) return TRUE;
429 if (good == MAX_SHORT) return TRUE;
430 if (good > ((3 * bad) + (5 + (minprice / 50)))) return TRUE;
437 * @brief 店主の持つプレイヤーに対する売買の良し悪し経験を記憶する /
438 * Update the bargain info
439 * @param price 実際の取引価格
440 * @param minprice 店主の提示した価格
444 static void updatebargain(PRICE price, PRICE minprice, int num)
446 if (!manual_haggle) return;
447 if ((minprice / num) < 10L) return;
448 if (price == minprice)
450 if (st_ptr->good_buy < MAX_SHORT)
457 if (st_ptr->bad_buy < MAX_SHORT)
466 * @brief 店の商品リストを再表示する /
467 * Re-displays a single store entry
468 * @param player_ptr プレーヤーへの参照ポインタ
472 static void display_entry(player_type *player_ptr, int pos)
475 o_ptr = &st_ptr->stock[pos];
476 int i = (pos % store_bottom);
478 /* Label it, clear the line --(-- */
480 (void)sprintf(out_val, "%c) ", ((i > 25) ? toupper(I2A(i - 26)) : I2A(i)));
481 prt(out_val, i + 6, 0);
486 TERM_COLOR a = object_attr(o_ptr);
487 SYMBOL_CODE c = object_char(o_ptr);
489 Term_queue_bigchar(cur_col, i + 6, a, c, 0, 0);
490 if (use_bigtile) cur_col++;
495 /* Describe an item in the home */
497 if ((cur_store_num == STORE_HOME) || (cur_store_num == STORE_MUSEUM))
500 if (show_weights) maxwid -= 10;
502 GAME_TEXT o_name[MAX_NLEN];
503 object_desc(player_ptr, o_name, o_ptr, 0);
504 o_name[maxwid] = '\0';
505 c_put_str(tval_to_attr[o_ptr->tval], o_name, i + 6, cur_col);
508 WEIGHT wgt = o_ptr->weight;
509 sprintf(out_val, _("%3d.%1d kg", "%3d.%d lb"), _(lbtokg1(wgt), wgt / 10), _(lbtokg2(wgt), wgt % 10));
510 put_str(out_val, i + 6, _(67, 68));
517 if (show_weights) maxwid -= 7;
519 GAME_TEXT o_name[MAX_NLEN];
520 object_desc(player_ptr, o_name, o_ptr, 0);
521 o_name[maxwid] = '\0';
522 c_put_str(tval_to_attr[o_ptr->tval], o_name, i + 6, cur_col);
526 int wgt = o_ptr->weight;
527 sprintf(out_val, "%3d.%1d", _(lbtokg1(wgt), wgt / 10), _(lbtokg2(wgt), wgt % 10));
528 put_str(out_val, i + 6, _(60, 61));
532 if (o_ptr->ident & (IDENT_FIXED))
534 x = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, FALSE);
535 (void)sprintf(out_val, _("%9ld固", "%9ld F"), (long)x);
536 put_str(out_val, i + 6, 68);
542 x = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, FALSE);
543 if (!noneedtobargain(x)) x += x / 10;
545 (void)sprintf(out_val, "%9ld ", (long)x);
546 put_str(out_val, i + 6, 68);
550 x = price_item(player_ptr, o_ptr, ot_ptr->max_inflate, FALSE);
551 (void)sprintf(out_val, "%9ld ", (long)x);
552 put_str(out_val, i + 6, 68);
557 * @brief 店の商品リストを表示する /
558 * Displays a store's inventory -RAK-
559 * @param player_ptr プレーヤーへの参照ポインタ
562 * All prices are listed as "per individual object". -BEN-
564 static void display_store_inventory(player_type *player_ptr)
567 for (k = 0; k < store_bottom; k++)
569 if (store_top + k >= st_ptr->stock_num) break;
571 display_entry(player_ptr, store_top + k);
574 for (int i = k; i < store_bottom + 1; i++)
577 put_str(_(" ", " "), 5, _(20, 22));
578 if (st_ptr->stock_num > store_bottom)
580 prt(_("-続く-", "-more-"), k + 6, 3);
581 put_str(format(_("(%dページ) ", "(Page %d) "), store_top / store_bottom + 1), 5, _(20, 22));
584 if (cur_store_num == STORE_HOME || cur_store_num == STORE_MUSEUM)
586 k = st_ptr->stock_size;
587 if (cur_store_num == STORE_HOME && !powerup_home) k /= 10;
589 put_str(format(_("アイテム数: %4d/%4d", "Objects: %4d/%4d"), st_ptr->stock_num, k), 19 + xtra_stock, _(27, 30));
595 * @brief プレイヤーの所持金を表示する /
596 * Displays players gold -RAK-
597 * @param player_ptr プレーヤーへの参照ポインタ
601 static void store_prt_gold(player_type *player_ptr)
603 prt(_("手持ちのお金: ", "Gold Remaining: "), 19 + xtra_stock, 53);
605 sprintf(out_val, "%9ld", (long)player_ptr->au);
606 prt(out_val, 19 + xtra_stock, 68);
611 * @brief 店舗情報全体を表示するメインルーチン /
612 * Displays store (after clearing screen) -RAK-
613 * @param player_ptr プレーヤーへの参照ポインタ
617 static void display_store(player_type *player_ptr)
620 if (cur_store_num == STORE_HOME)
622 put_str(_("我が家", "Your Home"), 3, 31);
623 put_str(_("アイテムの一覧", "Item Description"), 5, 4);
626 put_str(_(" 重さ", "Weight"), 5, 70);
629 store_prt_gold(player_ptr);
630 display_store_inventory(player_ptr);
634 if (cur_store_num == STORE_MUSEUM)
636 put_str(_("博物館", "Museum"), 3, 31);
637 put_str(_("アイテムの一覧", "Item Description"), 5, 4);
640 put_str(_(" 重さ", "Weight"), 5, 70);
643 store_prt_gold(player_ptr);
644 display_store_inventory(player_ptr);
648 concptr store_name = (f_name + f_info[cur_store_feat].name);
649 concptr owner_name = (ot_ptr->owner_name);
650 concptr race_name = race_info[ot_ptr->owner_race].title;
652 sprintf(buf, "%s (%s)", owner_name, race_name);
655 sprintf(buf, "%s (%ld)", store_name, (long)(ot_ptr->max_cost));
658 put_str(_("商品の一覧", "Item Description"), 5, 5);
661 put_str(_(" 重さ", "Weight"), 5, 60);
664 put_str(_(" 価格", "Price"), 5, 72);
665 store_prt_gold(player_ptr);
666 display_store_inventory(player_ptr);
671 * @brief 店舗からアイテムを選択する /
672 * Get the ID of a store item and return its value -RAK-
673 * @param com_val 選択IDを返す参照ポインタ
674 * @param pmt メッセージキャプション
677 * @return 実際に選択したらTRUE、キャンセルしたらFALSE
679 static int get_stock(COMMAND_CODE *com_val, concptr pmt, int i, int j)
681 if (repeat_pull(com_val) && (*com_val >= i) && (*com_val <= j))
689 char hi = (j > 25) ? toupper(I2A(j - 26)) : I2A(j);
692 (void)sprintf(out_val, "(%s:%c-%c, ESCで中断) %s",
693 (((cur_store_num == STORE_HOME) || (cur_store_num == STORE_MUSEUM)) ? "アイテム" : "商品"),
696 (void)sprintf(out_val, "(Items %c-%c, ESC to exit) %s",
703 if (!get_com(out_val, &command, FALSE)) break;
706 if (islower(command))
708 else if (isupper(command))
709 k = A2I(tolower(command)) + 26;
713 if ((k >= i) && (k <= j))
723 if (command == ESCAPE) return FALSE;
725 repeat_push(*com_val);
731 * @brief 店主の不満度を増やし、プレイヤーを締め出す判定と処理を行う /
732 * Increase the insult counter and get angry if too many -RAK-
733 * @return プレイヤーを締め出す場合TRUEを返す
735 static int increase_insults(void)
737 st_ptr->insult_cur++;
738 if (st_ptr->insult_cur <= ot_ptr->insult_max) return FALSE;
742 st_ptr->insult_cur = 0;
743 st_ptr->good_buy = 0;
745 st_ptr->store_open = current_world_ptr->game_turn + TURNS_PER_TICK * TOWN_DAWN / 8 + randint1(TURNS_PER_TICK*TOWN_DAWN / 8);
752 * @brief 店主の不満度を減らす /
753 * Decrease insults -RAK-
754 * @return プレイヤーを締め出す場合TRUEを返す
756 static void decrease_insults(void)
758 if (st_ptr->insult_cur) st_ptr->insult_cur--;
763 * @brief 店主の不満度が増えた場合のみのメッセージを表示する /
764 * Have insulted while haggling -RAK-
765 * @return プレイヤーを締め出す場合TRUEを返す
767 static int haggle_insults(void)
769 if (increase_insults()) return TRUE;
776 * Mega-Hack -- Enable "increments"
778 static bool allow_inc = FALSE;
781 * Mega-Hack -- Last "increment" during haggling
783 static s32b last_inc = 0L;
786 * @brief 交渉価格を確認と認証の是非を行う /
789 * @param poffer 別途価格提示をした場合の値を返す参照ポインタ
790 * @param price 現在の交渉価格
791 * @param final 最終確定価格ならばTRUE
792 * @return プレイヤーを締め出す場合TRUEを返す
794 static int get_haggle(concptr pmt, s32b *poffer, PRICE price, int final)
797 if (!allow_inc) last_inc = 0L;
801 sprintf(buf, _("%s [承諾] ", "%s [accept] "), pmt);
803 else if (last_inc < 0)
805 sprintf(buf, _("%s [-$%ld] ", "%s [-%ld] "), pmt, (long)(ABS(last_inc)));
807 else if (last_inc > 0)
809 sprintf(buf, _("%s [+$%ld] ", "%s [+%ld] "), pmt, (long)(ABS(last_inc)));
813 sprintf(buf, "%s ", pmt);
817 GAME_TEXT out_val[160];
825 * Ask the user for a response.
826 * Don't allow to use numpad as cursor key.
828 res = askfor_aux(out_val, 32, FALSE);
830 if (!res) return FALSE;
833 for (p = out_val; *p == ' '; p++) /* loop */;
844 if (allow_inc && last_inc)
850 msg_print(_("値がおかしいです。", "Invalid response."));
855 if ((*p == '+' || *p == '-'))
877 * @brief 店主がプレイヤーからの交渉価格を判断する /
878 * Receive an offer (from the player)
880 * @param poffer 店主からの交渉価格を返す参照ポインタ
881 * @param last_offer 現在の交渉価格
882 * @param factor 店主の価格基準倍率
883 * @param price アイテムの実価値
884 * @param final 最終価格確定ならばTRUE
885 * @return プレイヤーの価格に対して不服ならばTRUEを返す /
886 * Return TRUE if offer is NOT okay
888 static bool receive_offer(concptr pmt, s32b *poffer, s32b last_offer, int factor, PRICE price, int final)
892 if (!get_haggle(pmt, poffer, price, final)) return TRUE;
893 if (((*poffer) * factor) >= (last_offer * factor)) break;
894 if (haggle_insults()) return TRUE;
896 (*poffer) = last_offer;
904 * @brief プレイヤーが購入する時の値切り処理メインルーチン /
905 * Haggling routine -RAK-
906 * @param player_ptr プレーヤーへの参照ポインタ
907 * @param o_ptr オブジェクトの構造体参照ポインタ
908 * @param price 最終価格を返す参照ポインタ
909 * @return プレイヤーの価格に対して店主が不服ならばTRUEを返す /
910 * Return TRUE if purchase is NOT successful
912 static bool purchase_haggle(player_type *player_ptr, object_type *o_ptr, s32b *price)
914 s32b cur_ask = price_item(player_ptr, o_ptr, ot_ptr->max_inflate, FALSE);
915 s32b final_ask = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, FALSE);
916 int noneed = noneedtobargain(final_ask);
918 concptr pmt = _("提示価格", "Asking");
919 if (noneed || !manual_haggle)
923 msg_print(_("結局この金額にまとまった。", "You eventually agree upon the price."));
928 msg_print(_("すんなりとこの金額にまとまった。", "You quickly agree upon the price."));
930 final_ask += final_ask / 10;
934 pmt = _("最終提示価格", "Final Offer");
938 cur_ask *= o_ptr->number;
939 final_ask *= o_ptr->number;
940 s32b min_per = ot_ptr->haggle_per;
941 s32b max_per = min_per * 3;
942 s32b last_offer = object_value(o_ptr) * o_ptr->number;
943 last_offer = last_offer * (200 - (int)(ot_ptr->max_inflate)) / 100L;
944 if (last_offer <= 0) last_offer = 1;
954 bool loop_flag = TRUE;
956 while (!flag && loop_flag)
959 (void)sprintf(out_val, "%s : %ld", pmt, (long)cur_ask);
960 put_str(out_val, 1, 0);
961 cancel = receive_offer(_("提示する金額? ", "What do you offer? "), &offer, last_offer, 1, cur_ask, final);
966 else if (offer > cur_ask)
971 else if (offer == cur_ask)
984 s32b x1 = 100 * (offer - last_offer) / (cur_ask - last_offer);
987 if (haggle_insults())
993 else if (x1 > max_per)
996 if (x1 < max_per) x1 = max_per;
999 s32b x2 = rand_range(x1 - 2, x1 + 2);
1000 s32b x3 = ((cur_ask - offer) * x2 / 100L) + 1;
1004 if (cur_ask < final_ask)
1007 cur_ask = final_ask;
1008 pmt = _("最終提示価格", "What do you offer? ");
1012 (void)(increase_insults());
1017 else if (offer >= cur_ask)
1027 (void)sprintf(out_val, _("前回の提示金額: $%ld", "Your last offer: %ld"), (long)last_offer);
1028 put_str(out_val, 1, 39);
1029 say_comment_2(cur_ask, annoyed);
1032 if (cancel) return TRUE;
1034 updatebargain(*price, final_ask, o_ptr->number);
1040 * @brief プレイヤーが売却する時の値切り処理メインルーチン /
1041 * Haggling routine -RAK-
1042 * @param player_ptr プレーヤーへの参照ポインタ
1043 * @param o_ptr オブジェクトの構造体参照ポインタ
1044 * @param price 最終価格を返す参照ポインタ
1045 * @return プレイヤーの価格に対して店主が不服ならばTRUEを返す /
1046 * Return TRUE if purchase is NOT successful
1048 static bool sell_haggle(player_type *player_ptr, object_type *o_ptr, s32b *price)
1050 s32b cur_ask = price_item(player_ptr, o_ptr, ot_ptr->max_inflate, TRUE);
1051 s32b final_ask = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, TRUE);
1052 int noneed = noneedtobargain(final_ask);
1053 s32b purse = (s32b)(ot_ptr->max_cost);
1055 concptr pmt = _("提示金額", "Offer");
1056 if (noneed || !manual_haggle || (final_ask >= purse))
1058 if (!manual_haggle && !noneed)
1060 final_ask -= final_ask / 10;
1063 if (final_ask >= purse)
1065 msg_print(_("即座にこの金額にまとまった。", "You instantly agree upon the price."));
1071 msg_print(_("結局この金額にまとまった。", "You eventually agree upon the price."));
1076 msg_print(_("すんなりとこの金額にまとまった。", "You quickly agree upon the price."));
1080 cur_ask = final_ask;
1082 pmt = _("最終提示金額", "Final Offer");
1085 cur_ask *= o_ptr->number;
1086 final_ask *= o_ptr->number;
1088 s32b min_per = ot_ptr->haggle_per;
1089 s32b max_per = min_per * 3;
1090 s32b last_offer = object_value(o_ptr) * o_ptr->number;
1091 last_offer = last_offer * ot_ptr->max_inflate / 100L;
1097 bool cancel = FALSE;
1106 (void)sprintf(out_val, "%s : %ld", pmt, (long)cur_ask);
1107 put_str(out_val, 1, 0);
1108 cancel = receive_offer(_("提示する価格? ", "What price do you ask? "),
1109 &offer, last_offer, -1, cur_ask, final);
1115 else if (offer < cur_ask)
1120 else if (offer == cur_ask)
1130 if (flag || !loop_flag) break;
1135 s32b x1 = 100 * (last_offer - offer) / (last_offer - cur_ask);
1138 if (haggle_insults())
1144 else if (x1 > max_per)
1147 if (x1 < max_per) x1 = max_per;
1150 s32b x2 = rand_range(x1 - 2, x1 + 2);
1151 s32b x3 = ((offer - cur_ask) * x2 / 100L) + 1;
1155 if (cur_ask > final_ask)
1157 cur_ask = final_ask;
1159 pmt = _("最終提示金額", "Final Offer");
1166 /* 追加 $0 で買い取られてしまうのを防止 By FIRST*/
1169 (void)(increase_insults());
1172 else if (offer <= cur_ask)
1182 (void)sprintf(out_val, _("前回の提示価格 $%ld", "Your last bid %ld"), (long)last_offer);
1183 put_str(out_val, 1, 39);
1184 say_comment_3(cur_ask, annoyed);
1187 if (cancel) return TRUE;
1189 updatebargain(*price, final_ask, o_ptr->number);
1195 * @brief 店からの購入処理のメインルーチン /
1196 * Buy an item from a store -RAK-
1197 * @param player_ptr プレーヤーへの参照ポインタ
1200 static void store_purchase(player_type *player_ptr)
1202 if (cur_store_num == STORE_MUSEUM)
1204 msg_print(_("博物館から取り出すことはできません。", "Museum."));
1208 if (st_ptr->stock_num <= 0)
1210 if (cur_store_num == STORE_HOME)
1211 msg_print(_("我が家には何も置いてありません。", "Your home is empty."));
1213 msg_print(_("現在商品の在庫を切らしています。", "I am currently out of stock."));
1217 int i = (st_ptr->stock_num - store_top);
1218 if (i > store_bottom) i = store_bottom;
1222 /* ブラックマーケットの時は別のメッセージ */
1223 switch (cur_store_num)
1226 sprintf(out_val, "どのアイテムを取りますか? ");
1229 sprintf(out_val, "どれ? ");
1232 sprintf(out_val, "どの品物が欲しいんだい? ");
1236 if (cur_store_num == STORE_HOME)
1238 sprintf(out_val, "Which item do you want to take? ");
1242 sprintf(out_val, "Which item are you interested in? ");
1247 if (!get_stock(&item, out_val, 0, i - 1)) return;
1249 item = item + store_top;
1251 o_ptr = &st_ptr->stock[item];
1252 ITEM_NUMBER amt = 1;
1256 object_copy(j_ptr, o_ptr);
1259 * If a rod or wand, allocate total maximum timeouts or charges
1260 * between those purchased and left on the shelf.
1262 reduce_charges(j_ptr, o_ptr->number - amt);
1263 j_ptr->number = amt;
1264 if (!inven_carry_okay(j_ptr))
1266 msg_print(_("そんなにアイテムを持てない。", "You cannot carry that many different items."));
1270 PRICE best = price_item(player_ptr, j_ptr, ot_ptr->min_inflate, FALSE);
1271 if (o_ptr->number > 1)
1273 if ((cur_store_num != STORE_HOME) &&
1274 (o_ptr->ident & IDENT_FIXED))
1276 msg_format(_("一つにつき $%ldです。", "That costs %ld gold per item."), (long)(best));
1279 amt = get_quantity(NULL, o_ptr->number);
1280 if (amt <= 0) return;
1284 object_copy(j_ptr, o_ptr);
1287 * If a rod or wand, allocate total maximum timeouts or charges
1288 * between those purchased and left on the shelf.
1290 reduce_charges(j_ptr, o_ptr->number - amt);
1291 j_ptr->number = amt;
1292 if (!inven_carry_okay(j_ptr))
1294 msg_print(_("ザックにそのアイテムを入れる隙間がない。", "You cannot carry that many items."));
1299 COMMAND_CODE item_new;
1301 if (cur_store_num == STORE_HOME)
1303 bool combined_or_reordered;
1304 distribute_charges(o_ptr, j_ptr, amt);
1305 item_new = inven_carry(player_ptr, j_ptr);
1306 GAME_TEXT o_name[MAX_NLEN];
1307 object_desc(player_ptr, o_name, &player_ptr->inventory_list[item_new], 0);
1309 msg_format(_("%s(%c)を取った。", "You have %s (%c)."), o_name, index_to_label(item_new));
1310 handle_stuff(player_ptr);
1312 i = st_ptr->stock_num;
1313 store_item_increase(item, -amt);
1314 store_item_optimize(item);
1315 combined_or_reordered = combine_and_reorder_home(STORE_HOME);
1316 if (i == st_ptr->stock_num)
1318 if (combined_or_reordered) display_store_inventory(player_ptr);
1319 else display_entry(player_ptr, item);
1323 if (st_ptr->stock_num == 0) store_top = 0;
1324 else if (store_top >= st_ptr->stock_num) store_top -= store_bottom;
1325 display_store_inventory(player_ptr);
1327 chg_virtue(player_ptr, V_SACRIFICE, 1);
1333 if (o_ptr->ident & (IDENT_FIXED))
1336 price = (best * j_ptr->number);
1340 GAME_TEXT o_name[MAX_NLEN];
1341 object_desc(player_ptr, o_name, j_ptr, 0);
1342 msg_format(_("%s(%c)を購入する。", "Buying %s (%c)."), o_name, I2A(item));
1344 choice = purchase_haggle(player_ptr, j_ptr, &price);
1345 if (st_ptr->store_open >= current_world_ptr->game_turn) return;
1348 if (choice != 0) return;
1349 if (price == (best * j_ptr->number)) o_ptr->ident |= (IDENT_FIXED);
1350 if (player_ptr->au < price)
1352 msg_print(_("お金が足りません。", "You do not have enough gold."));
1356 say_comment_1(player_ptr);
1357 if (cur_store_num == STORE_BLACK)
1358 chg_virtue(player_ptr, V_JUSTICE, -1);
1359 if ((o_ptr->tval == TV_BOTTLE) && (cur_store_num != STORE_HOME))
1360 chg_virtue(player_ptr, V_NATURE, -1);
1364 player_ptr->au -= price;
1365 store_prt_gold(player_ptr);
1366 object_aware(player_ptr, j_ptr);
1367 j_ptr->ident &= ~(IDENT_FIXED);
1368 GAME_TEXT o_name[MAX_NLEN];
1369 object_desc(player_ptr, o_name, j_ptr, 0);
1371 msg_format(_("%sを $%ldで購入しました。", "You bought %s for %ld gold."), o_name, (long)price);
1373 strcpy(record_o_name, o_name);
1374 record_turn = current_world_ptr->game_turn;
1376 if (record_buy) exe_write_diary(player_ptr, DIARY_BUY, 0, o_name);
1377 object_desc(player_ptr, o_name, o_ptr, OD_NAME_ONLY);
1378 if (record_rand_art && o_ptr->art_name)
1379 exe_write_diary(player_ptr, DIARY_ART, 0, o_name);
1381 j_ptr->inscription = 0;
1382 j_ptr->feeling = FEEL_NONE;
1383 j_ptr->ident &= ~(IDENT_STORE);
1384 item_new = inven_carry(player_ptr, j_ptr);
1386 object_desc(player_ptr, o_name, &player_ptr->inventory_list[item_new], 0);
1387 msg_format(_("%s(%c)を手に入れた。", "You have %s (%c)."), o_name, index_to_label(item_new));
1388 autopick_alter_item(player_ptr, item_new, FALSE);
1389 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
1391 o_ptr->pval -= j_ptr->pval;
1394 handle_stuff(player_ptr);
1395 i = st_ptr->stock_num;
1396 store_item_increase(item, -amt);
1397 store_item_optimize(item);
1398 if (st_ptr->stock_num == 0)
1400 if (one_in_(STORE_SHUFFLE))
1403 msg_print(_("店主は引退した。", "The shopkeeper retires."));
1404 store_shuffle(player_ptr, cur_store_num);
1407 sprintf(buf, "%s (%s)",
1408 ot_ptr->owner_name, race_info[ot_ptr->owner_race].title);
1409 put_str(buf, 3, 10);
1410 sprintf(buf, "%s (%ld)",
1411 (f_name + f_info[cur_store_feat].name), (long)(ot_ptr->max_cost));
1416 msg_print(_("店主は新たな在庫を取り出した。", "The shopkeeper brings out some new stock."));
1419 for (i = 0; i < 10; i++)
1421 store_maint(player_ptr, player_ptr->town_num, cur_store_num);
1425 display_store_inventory(player_ptr);
1427 else if (st_ptr->stock_num != i)
1429 if (store_top >= st_ptr->stock_num) store_top -= store_bottom;
1430 display_store_inventory(player_ptr);
1434 display_entry(player_ptr, item);
1440 * @brief 店からの売却処理のメインルーチン /
1441 * Sell an item to the store (or home)
1442 * @param owner_ptr プレーヤーへの参照ポインタ
1445 static void store_sell(player_type *owner_ptr)
1448 if (cur_store_num == STORE_HOME)
1449 q = _("どのアイテムを置きますか? ", "Drop which item? ");
1450 else if (cur_store_num == STORE_MUSEUM)
1451 q = _("どのアイテムを寄贈しますか? ", "Give which item? ");
1453 q = _("どのアイテムを売りますか? ", "Sell which item? ");
1455 item_tester_hook = store_will_buy;
1457 /* 我が家でおかしなメッセージが出るオリジナルのバグを修正 */
1459 if (cur_store_num == STORE_HOME)
1461 s = _("置けるアイテムを持っていません。", "You don't have any item to drop.");
1463 else if (cur_store_num == STORE_MUSEUM)
1465 s = _("寄贈できるアイテムを持っていません。", "You don't have any item to give.");
1469 s = _("欲しい物がないですねえ。", "You have nothing that I want.");
1474 o_ptr = choose_object(owner_ptr, &item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT), 0);
1477 if ((item >= INVEN_RARM) && object_is_cursed(o_ptr))
1479 msg_print(_("ふーむ、どうやらそれは呪われているようだね。", "Hmmm, it seems to be cursed."));
1484 if (o_ptr->number > 1)
1486 amt = get_quantity(NULL, o_ptr->number);
1487 if (amt <= 0) return;
1493 object_copy(q_ptr, o_ptr);
1494 q_ptr->number = amt;
1497 * Hack -- If a rod or wand, allocate total maximum
1498 * timeouts or charges to those being sold. -LM-
1500 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
1502 q_ptr->pval = o_ptr->pval * amt / o_ptr->number;
1505 GAME_TEXT o_name[MAX_NLEN];
1506 object_desc(owner_ptr, o_name, q_ptr, 0);
1508 /* Remove any inscription, feeling for stores */
1509 if ((cur_store_num != STORE_HOME) && (cur_store_num != STORE_MUSEUM))
1511 q_ptr->inscription = 0;
1512 q_ptr->feeling = FEEL_NONE;
1515 /* Is there room in the store (or the home?) */
1516 if (!store_check_num(q_ptr))
1518 if (cur_store_num == STORE_HOME)
1519 msg_print(_("我が家にはもう置く場所がない。", "Your home is full."));
1521 else if (cur_store_num == STORE_MUSEUM)
1522 msg_print(_("博物館はもう満杯だ。", "Museum is full."));
1525 msg_print(_("すいませんが、店にはもう置く場所がありません。", "I have not the room in my store to keep it."));
1531 PRICE price, value, dummy;
1532 if ((cur_store_num != STORE_HOME) && (cur_store_num != STORE_MUSEUM))
1534 msg_format(_("%s(%c)を売却する。", "Selling %s (%c)."), o_name, index_to_label(item));
1537 choice = sell_haggle(owner_ptr, q_ptr, &price);
1538 if (st_ptr->store_open >= current_world_ptr->game_turn) return;
1542 say_comment_1(owner_ptr);
1544 if (cur_store_num == STORE_BLACK)
1545 chg_virtue(owner_ptr, V_JUSTICE, -1);
1547 if ((o_ptr->tval == TV_BOTTLE) && (cur_store_num != STORE_HOME))
1548 chg_virtue(owner_ptr, V_NATURE, 1);
1551 owner_ptr->au += price;
1552 store_prt_gold(owner_ptr);
1553 dummy = object_value(q_ptr) * q_ptr->number;
1555 identify_item(owner_ptr, o_ptr);
1557 object_copy(q_ptr, o_ptr);
1558 q_ptr->number = amt;
1559 q_ptr->ident |= IDENT_STORE;
1562 * Hack -- If a rod or wand, let the shopkeeper know just
1563 * how many charges he really paid for. -LM-
1565 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
1567 q_ptr->pval = o_ptr->pval * amt / o_ptr->number;
1570 value = object_value(q_ptr) * q_ptr->number;
1571 object_desc(owner_ptr, o_name, q_ptr, 0);
1572 msg_format(_("%sを $%ldで売却しました。", "You sold %s for %ld gold."), o_name, (long)price);
1574 if (record_sell) exe_write_diary(owner_ptr, DIARY_SELL, 0, o_name);
1576 if (!((o_ptr->tval == TV_FIGURINE) && (value > 0)))
1578 purchase_analyze(owner_ptr, price, value, dummy);
1582 * Hack -- Allocate charges between those wands or rods sold
1583 * and retained, unless all are being sold. -LM-
1585 distribute_charges(o_ptr, q_ptr, amt);
1587 inven_item_increase(owner_ptr, item, -amt);
1588 inven_item_describe(owner_ptr, item);
1589 if (o_ptr->number > 0)
1590 autopick_alter_item(owner_ptr, item, FALSE);
1592 inven_item_optimize(owner_ptr, item);
1593 handle_stuff(owner_ptr);
1594 int item_pos = store_carry(q_ptr);
1597 store_top = (item_pos / store_bottom) * store_bottom;
1598 display_store_inventory(owner_ptr);
1602 else if (cur_store_num == STORE_MUSEUM)
1604 char o2_name[MAX_NLEN];
1605 object_desc(owner_ptr, o2_name, q_ptr, OD_NAME_ONLY);
1607 if (-1 == store_check_num(q_ptr))
1609 msg_print(_("それと同じ品物は既に博物館にあるようです。", "The Museum already has one of those items."));
1613 msg_print(_("博物館に寄贈したものは取り出すことができません!!", "You cannot take back items which have been donated to the Museum!!"));
1616 if (!get_check(format(_("本当に%sを寄贈しますか?", "Really give %s to the Museum? "), o2_name))) return;
1618 identify_item(owner_ptr, q_ptr);
1619 q_ptr->ident |= IDENT_FULL_KNOWN;
1621 distribute_charges(o_ptr, q_ptr, amt);
1622 msg_format(_("%sを置いた。(%c)", "You drop %s (%c)."), o_name, index_to_label(item));
1625 vary_item(owner_ptr, item, -amt);
1626 handle_stuff(owner_ptr);
1628 int item_pos = home_carry(owner_ptr, q_ptr);
1631 store_top = (item_pos / store_bottom) * store_bottom;
1632 display_store_inventory(owner_ptr);
1637 distribute_charges(o_ptr, q_ptr, amt);
1638 msg_format(_("%sを置いた。(%c)", "You drop %s (%c)."), o_name, index_to_label(item));
1640 vary_item(owner_ptr, item, -amt);
1641 handle_stuff(owner_ptr);
1642 int item_pos = home_carry(owner_ptr, q_ptr);
1645 store_top = (item_pos / store_bottom) * store_bottom;
1646 display_store_inventory(owner_ptr);
1650 if ((choice == 0) && (item >= INVEN_RARM))
1652 calc_android_exp(owner_ptr);
1653 verify_equip_slot(owner_ptr, item);
1659 * @brief 店のアイテムを調べるコマンドのメインルーチン /
1660 * Examine an item in a store -JDL-
1663 static void store_examine(player_type *player_ptr)
1665 if (st_ptr->stock_num <= 0)
1667 if (cur_store_num == STORE_HOME)
1668 msg_print(_("我が家には何も置いてありません。", "Your home is empty."));
1669 else if (cur_store_num == STORE_MUSEUM)
1670 msg_print(_("博物館には何も置いてありません。", "Museum is empty."));
1672 msg_print(_("現在商品の在庫を切らしています。", "I am currently out of stock."));
1676 int i = (st_ptr->stock_num - store_top);
1677 if (i > store_bottom) i = store_bottom;
1680 sprintf(out_val, _("どれを調べますか?", "Which item do you want to examine? "));
1683 if (!get_stock(&item, out_val, 0, i - 1)) return;
1684 item = item + store_top;
1686 o_ptr = &st_ptr->stock[item];
1687 if (!OBJECT_IS_FULL_KNOWN(o_ptr))
1689 msg_print(_("このアイテムについて特に知っていることはない。", "You have no special knowledge about that item."));
1693 GAME_TEXT o_name[MAX_NLEN];
1694 object_desc(player_ptr, o_name, o_ptr, 0);
1695 msg_format(_("%sを調べている...", "Examining %s..."), o_name);
1697 if (!screen_object(player_ptr, o_ptr, SCROBJ_FORCE_DETAIL))
1698 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
1703 * @brief 博物館のアイテムを除去するコマンドのメインルーチン /
1704 * Remove an item from museum (Originally from TOband)
1705 * @param player_ptr プレーヤーへの参照ポインタ
1708 static void museum_remove_object(player_type *player_ptr)
1710 if (st_ptr->stock_num <= 0)
1712 msg_print(_("博物館には何も置いてありません。", "Museum is empty."));
1716 int i = st_ptr->stock_num - store_top;
1717 if (i > store_bottom) i = store_bottom;
1720 sprintf(out_val, _("どのアイテムの展示をやめさせますか?", "Which item do you want to order to remove? "));
1723 if (!get_stock(&item, out_val, 0, i - 1)) return;
1725 item = item + store_top;
1727 o_ptr = &st_ptr->stock[item];
1729 GAME_TEXT o_name[MAX_NLEN];
1730 object_desc(player_ptr, o_name, o_ptr, 0);
1732 msg_print(_("展示をやめさせたアイテムは二度と見ることはできません!", "Once removed from the Museum, an item will be gone forever!"));
1733 if (!get_check(format(_("本当に%sの展示をやめさせますか?", "Really order to remove %s from the Museum? "), o_name))) return;
1735 msg_format(_("%sの展示をやめさせた。", "You ordered to remove %s."), o_name);
1737 store_item_increase(item, -o_ptr->number);
1738 store_item_optimize(item);
1740 (void)combine_and_reorder_home(STORE_MUSEUM);
1741 if (st_ptr->stock_num == 0) store_top = 0;
1743 else if (store_top >= st_ptr->stock_num) store_top -= store_bottom;
1744 display_store_inventory(player_ptr);
1749 * Hack -- set this to leave the store
1751 static bool leave_store = FALSE;
1755 * @brief 店舗処理コマンド選択のメインルーチン /
1756 * Process a command in a store
1757 * @param client_ptr 顧客となるクリーチャーの参照ポインタ
1761 * Note that we must allow the use of a few "special" commands
1762 * in the stores which are not allowed in the dungeon, and we
1763 * must disable some commands which are allowed in the dungeon
1764 * but not in the stores, to prevent chaos.
1767 static void store_process_command(player_type *client_ptr)
1770 if (rogue_like_commands && command_cmd == 'l')
1775 switch (command_cmd)
1785 /* 1 ページ戻るコマンド: 我が家のページ数が多いので重宝するはず By BUG */
1786 if (st_ptr->stock_num <= store_bottom) {
1787 msg_print(_("これで全部です。", "Entire inventory is shown."));
1791 store_top -= store_bottom;
1793 store_top = ((st_ptr->stock_num - 1) / store_bottom) * store_bottom;
1794 if ((cur_store_num == STORE_HOME) && (powerup_home == FALSE))
1795 if (store_top >= store_bottom) store_top = store_bottom;
1796 display_store_inventory(client_ptr);
1803 if (st_ptr->stock_num <= store_bottom)
1805 msg_print(_("これで全部です。", "Entire inventory is shown."));
1809 store_top += store_bottom;
1811 * 隠しオプション(powerup_home)がセットされていないときは
1812 * 我が家では 2 ページまでしか表示しない
1814 if ((cur_store_num == STORE_HOME) &&
1815 (powerup_home == FALSE) &&
1816 (st_ptr->stock_num >= STORE_INVEN_MAX))
1818 if (store_top >= (STORE_INVEN_MAX - 1))
1825 if (store_top >= st_ptr->stock_num) store_top = 0;
1828 display_store_inventory(client_ptr);
1835 do_cmd_redraw(client_ptr);
1836 display_store(client_ptr);
1841 store_purchase(client_ptr);
1846 store_sell(client_ptr);
1851 store_examine(client_ptr);
1860 do_cmd_wield(client_ptr);
1865 do_cmd_takeoff(client_ptr);
1870 do_cmd_destroy(client_ptr);
1875 do_cmd_equip(client_ptr);
1880 do_cmd_inven(client_ptr);
1885 do_cmd_observe(client_ptr);
1890 toggle_inventory_equipment(client_ptr);
1895 if ((client_ptr->pclass == CLASS_MINDCRAFTER) ||
1896 (client_ptr->pclass == CLASS_BERSERKER) ||
1897 (client_ptr->pclass == CLASS_NINJA) ||
1898 (client_ptr->pclass == CLASS_MIRROR_MASTER)
1899 ) do_cmd_mind_browse(client_ptr);
1900 else if (client_ptr->pclass == CLASS_SMITH)
1901 do_cmd_kaji(client_ptr, TRUE);
1902 else if (client_ptr->pclass == CLASS_MAGIC_EATER)
1903 do_cmd_magic_eater(client_ptr, TRUE, FALSE);
1904 else if (client_ptr->pclass == CLASS_SNIPER)
1905 do_cmd_snipe_browse(client_ptr);
1906 else do_cmd_browse(client_ptr);
1911 do_cmd_inscribe(client_ptr);
1916 do_cmd_uninscribe(client_ptr);
1921 do_cmd_help(client_ptr);
1926 do_cmd_query_symbol(client_ptr);
1931 client_ptr->town_num = old_town_num;
1932 do_cmd_player_status(client_ptr);
1933 client_ptr->town_num = inner_town_num;
1934 display_store(client_ptr);
1944 client_ptr->town_num = old_town_num;
1945 do_cmd_pref(client_ptr);
1946 client_ptr->town_num = inner_town_num;
1951 client_ptr->town_num = old_town_num;
1952 do_cmd_macros(client_ptr);
1953 client_ptr->town_num = inner_town_num;
1958 client_ptr->town_num = old_town_num;
1959 do_cmd_visuals(client_ptr);
1960 client_ptr->town_num = inner_town_num;
1965 client_ptr->town_num = old_town_num;
1966 do_cmd_colors(client_ptr);
1967 client_ptr->town_num = inner_town_num;
1973 (void)combine_and_reorder_home(STORE_HOME);
1974 do_cmd_redraw(client_ptr);
1975 display_store(client_ptr);
1990 do_cmd_feeling(client_ptr);
1995 do_cmd_message_one();
2005 do_cmd_diary(client_ptr);
2010 do_cmd_knowledge(client_ptr);
2015 do_cmd_load_screen();
2020 do_cmd_save_screen(client_ptr);
2025 if ((cur_store_num == STORE_MUSEUM) && (command_cmd == 'r'))
2027 museum_remove_object(client_ptr);
2031 msg_print(_("そのコマンドは店の中では使えません。", "That command does not work in stores."));
2041 * @brief 店舗処理全体のメインルーチン /
2042 * Enter a store, and interact with it. *
2043 * @param player_ptr プレーヤーへの参照ポインタ
2047 * Note that we use the standard "request_command()" function
2048 * to get a command, allowing us to use "command_arg" and all
2049 * command macros and other nifty stuff, but we use the special
2050 * "shopping" argument, to force certain commands to be converted
2051 * into other commands, normally, we convert "p" (pray) and "m"
2052 * (cast magic) into "g" (get), and "s" (search) into "d" (drop).
2055 void do_cmd_store(player_type *player_ptr)
2057 if (player_ptr->wild_mode) return;
2059 Term_get_size(&w, &h);
2061 xtra_stock = MIN(14 + 26, ((h > 24) ? (h - 24) : 0));
2062 store_bottom = MIN_STOCK + xtra_stock;
2065 g_ptr = &player_ptr->current_floor_ptr->grid_array[player_ptr->y][player_ptr->x];
2067 if (!cave_have_flag_grid(g_ptr, FF_STORE))
2069 msg_print(_("ここには店がありません。", "You see no store here."));
2073 int which = f_info[g_ptr->feat].subtype;
2074 old_town_num = player_ptr->town_num;
2075 if ((which == STORE_HOME) || (which == STORE_MUSEUM)) player_ptr->town_num = 1;
2076 if (player_ptr->current_floor_ptr->dun_level) player_ptr->town_num = NO_TOWN;
2077 inner_town_num = player_ptr->town_num;
2079 if ((town_info[player_ptr->town_num].store[which].store_open >= current_world_ptr->game_turn) ||
2082 msg_print(_("ドアに鍵がかかっている。", "The doors are locked."));
2083 player_ptr->town_num = old_town_num;
2087 int maintain_num = (current_world_ptr->game_turn - town_info[player_ptr->town_num].store[which].last_visit) / (TURNS_PER_TICK * STORE_TICKS);
2088 if (maintain_num > 10)
2092 for (int i = 0; i < maintain_num; i++)
2093 store_maint(player_ptr, player_ptr->town_num, which);
2095 town_info[player_ptr->town_num].store[which].last_visit = current_world_ptr->game_turn;
2098 forget_lite(player_ptr->current_floor_ptr);
2099 forget_view(player_ptr->current_floor_ptr);
2100 current_world_ptr->character_icky = TRUE;
2104 get_com_no_macros = TRUE;
2105 cur_store_num = which;
2106 cur_store_feat = g_ptr->feat;
2107 st_ptr = &town_info[player_ptr->town_num].store[cur_store_num];
2108 ot_ptr = &owners[cur_store_num][st_ptr->owner];
2110 play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_BUILD);
2111 display_store(player_ptr);
2112 leave_store = FALSE;
2114 while (!leave_store)
2117 clear_from(20 + xtra_stock);
2118 prt(_(" ESC) 建物から出る", " ESC) Exit from Building."), 21 + xtra_stock, 0);
2119 if (st_ptr->stock_num > store_bottom)
2121 prt(_(" -)前ページ", " -) Previous page"), 22 + xtra_stock, 0);
2122 prt(_(" スペース) 次ページ", " SPACE) Next page"), 23 + xtra_stock, 0);
2125 if (cur_store_num == STORE_HOME)
2127 prt(_("g) アイテムを取る", "g) Get an item."), 21 + xtra_stock, 27);
2128 prt(_("d) アイテムを置く", "d) Drop an item."), 22 + xtra_stock, 27);
2129 prt(_("x) 家のアイテムを調べる", "x) eXamine an item in the home."), 23 + xtra_stock, 27);
2131 else if (cur_store_num == STORE_MUSEUM)
2133 prt(_("d) アイテムを置く", "d) Drop an item."), 21 + xtra_stock, 27);
2134 prt(_("r) アイテムの展示をやめる", "r) order to Remove an item."), 22 + xtra_stock, 27);
2135 prt(_("x) 博物館のアイテムを調べる", "x) eXamine an item in the museum."), 23 + xtra_stock, 27);
2139 prt(_("p) 商品を買う", "p) Purchase an item."), 21 + xtra_stock, 30);
2140 prt(_("s) アイテムを売る", "s) Sell an item."), 22 + xtra_stock, 30);
2141 prt(_("x) 商品を調べる", "x) eXamine an item in the shop"), 23 + xtra_stock, 30);
2144 prt(_("i/e) 持ち物/装備の一覧", "i/e) Inventry/Equipment list"), 21 + xtra_stock, 56);
2145 if (rogue_like_commands)
2147 prt(_("w/T) 装備する/はずす", "w/T) Wear/Take off equipment"), 22 + xtra_stock, 56);
2151 prt(_("w/t) 装備する/はずす", "w/t) Wear/Take off equipment"), 22 + xtra_stock, 56);
2154 prt(_("コマンド:", "You may: "), 20 + xtra_stock, 0);
2155 request_command(player_ptr, TRUE);
2156 store_process_command(player_ptr);
2159 * Hack -- To redraw missiles damage and prices in store
2160 * If player's charisma changes, or if player changes a bow, PU_BONUS is set
2162 bool need_redraw_store_inv = (player_ptr->update & PU_BONUS) ? TRUE : FALSE;
2163 current_world_ptr->character_icky = TRUE;
2164 handle_stuff(player_ptr);
2165 if (player_ptr->inventory_list[INVEN_PACK].k_idx)
2167 INVENTORY_IDX item = INVEN_PACK;
2168 object_type *o_ptr = &player_ptr->inventory_list[item];
2169 if (cur_store_num != STORE_HOME)
2171 if (cur_store_num == STORE_MUSEUM)
2172 msg_print(_("ザックからアイテムがあふれそうなので、あわてて博物館から出た...", "Your pack is so full that you flee the Museum..."));
2174 msg_print(_("ザックからアイテムがあふれそうなので、あわてて店から出た...", "Your pack is so full that you flee the store..."));
2178 else if (!store_check_num(o_ptr))
2180 msg_print(_("ザックからアイテムがあふれそうなので、あわてて家から出た...", "Your pack is so full that you flee your home..."));
2188 GAME_TEXT o_name[MAX_NLEN];
2189 msg_print(_("ザックからアイテムがあふれてしまった!", "Your pack overflows!"));
2191 object_copy(q_ptr, o_ptr);
2192 object_desc(player_ptr, o_name, q_ptr, 0);
2193 msg_format(_("%sが落ちた。(%c)", "You drop %s (%c)."), o_name, index_to_label(item));
2194 vary_item(player_ptr, item, -255);
2195 handle_stuff(player_ptr);
2197 item_pos = home_carry(player_ptr, q_ptr);
2200 store_top = (item_pos / store_bottom) * store_bottom;
2201 display_store_inventory(player_ptr);
2206 if (need_redraw_store_inv) display_store_inventory(player_ptr);
2208 if (st_ptr->store_open >= current_world_ptr->game_turn) leave_store = TRUE;
2211 select_floor_music(player_ptr);
2212 player_ptr->town_num = old_town_num;
2213 take_turn(player_ptr, 100);
2214 current_world_ptr->character_icky = FALSE;
2216 command_see = FALSE;
2217 get_com_no_macros = FALSE;
2222 player_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
2223 player_ptr->update |= (PU_MONSTERS);
2224 player_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_EQUIPPY);
2225 player_ptr->redraw |= (PR_MAP);
2226 player_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
2231 * @brief 現在の町の店主を交代させる /
2232 * Shuffle one of the stores.
2233 * @param which 店舗種類のID
2236 void store_shuffle(player_type *player_ptr, int which)
2238 if (which == STORE_HOME) return;
2239 if (which == STORE_MUSEUM) return;
2241 cur_store_num = which;
2242 st_ptr = &town_info[player_ptr->town_num].store[cur_store_num];
2243 int j = st_ptr->owner;
2246 st_ptr->owner = (byte)randint0(MAX_OWNERS);
2247 if (j == st_ptr->owner) continue;
2249 for (i = 1; i < max_towns; i++)
2251 if (i == player_ptr->town_num) continue;
2252 if (st_ptr->owner == town_info[i].store[cur_store_num].owner) break;
2255 if (i == max_towns) break;
2258 ot_ptr = &owners[cur_store_num][st_ptr->owner];
2259 st_ptr->insult_cur = 0;
2260 st_ptr->store_open = 0;
2261 st_ptr->good_buy = 0;
2262 st_ptr->bad_buy = 0;
2263 for (int i = 0; i < st_ptr->stock_num; i++)
2266 o_ptr = &st_ptr->stock[i];
2267 if (object_is_artifact(o_ptr)) continue;
2269 o_ptr->discount = 50;
2270 o_ptr->ident &= ~(IDENT_FIXED);
2271 o_ptr->inscription = quark_add(_("売出中", "on sale"));
2277 * @brief 店の品揃えを変化させる /
2278 * Maintain the inventory at the stores.
2279 * @param player_ptr プレーヤーへの参照ポインタ
2280 * @param town_num 町のID
2281 * @param store_num 店舗種類のID
2284 void store_maint(player_type *player_ptr, int town_num, int store_num)
2286 cur_store_num = store_num;
2287 if (store_num == STORE_HOME) return;
2288 if (store_num == STORE_MUSEUM) return;
2290 st_ptr = &town_info[town_num].store[store_num];
2291 ot_ptr = &owners[store_num][st_ptr->owner];
2292 st_ptr->insult_cur = 0;
2293 if (store_num == STORE_BLACK)
2295 for (INVENTORY_IDX j = st_ptr->stock_num - 1; j >= 0; j--)
2297 object_type *o_ptr = &st_ptr->stock[j];
2298 if (black_market_crap(player_ptr, o_ptr))
2300 store_item_increase(j, 0 - o_ptr->number);
2301 store_item_optimize(j);
2306 INVENTORY_IDX j = st_ptr->stock_num;
2307 j = j - randint1(STORE_TURNOVER);
2308 if (j > STORE_MAX_KEEP) j = STORE_MAX_KEEP;
2309 if (j < STORE_MIN_KEEP) j = STORE_MIN_KEEP;
2312 while (st_ptr->stock_num > j)
2315 j = st_ptr->stock_num;
2316 j = j + randint1(STORE_TURNOVER);
2317 if (j > STORE_MAX_KEEP) j = STORE_MAX_KEEP;
2318 if (j < STORE_MIN_KEEP) j = STORE_MIN_KEEP;
2319 if (j >= st_ptr->stock_size) j = st_ptr->stock_size - 1;
2321 while (st_ptr->stock_num < j) store_create(player_ptr, black_market_crap);
2326 * @brief 店舗情報を初期化する /
2327 * Initialize the stores
2328 * @param town_num 町のID
2329 * @param store_num 店舗種類のID
2332 void store_init(int town_num, int store_num)
2334 cur_store_num = store_num;
2335 st_ptr = &town_info[town_num].store[store_num];
2338 st_ptr->owner = (byte)randint0(MAX_OWNERS);
2340 for (i = 1; i < max_towns; i++)
2342 if (i == town_num) continue;
2343 if (st_ptr->owner == town_info[i].store[store_num].owner) break;
2346 if (i == max_towns) break;
2349 ot_ptr = &owners[store_num][st_ptr->owner];
2351 st_ptr->store_open = 0;
2352 st_ptr->insult_cur = 0;
2353 st_ptr->good_buy = 0;
2354 st_ptr->bad_buy = 0;
2355 st_ptr->stock_num = 0;
2356 st_ptr->last_visit = -10L * TURNS_PER_TICK * STORE_TICKS;
2357 for (int k = 0; k < st_ptr->stock_size; k++)
2359 object_wipe(&st_ptr->stock[k]);