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.
13 #include "store/store.h"
14 #include "autopick/autopick-pref-processor.h"
15 #include "autopick/autopick.h"
16 #include "cmd-action/cmd-spell.h"
17 #include "cmd-io/cmd-diary.h"
18 #include "cmd-io/cmd-dump.h"
19 #include "cmd-io/cmd-help.h"
20 #include "cmd-io/cmd-knowledge.h"
21 #include "cmd-io/cmd-macro.h"
22 #include "cmd-io/cmd-process-screen.h"
23 #include "cmd-item/cmd-item.h"
24 #include "cmd-item/cmd-magiceat.h"
25 #include "cmd-item/cmd-smith.h"
26 #include "cmd-item/cmd-zapwand.h"
27 #include "cmd/cmd-basic.h"
28 #include "cmd/cmd-draw.h"
29 #include "cmd/cmd-visuals.h"
30 #include "combat/snipe.h"
31 #include "core/stuff-handler.h"
32 #include "floor/floor-events.h"
33 #include "floor/floor-town.h"
34 #include "floor/floor.h"
35 #include "floor/wild.h"
36 #include "inventory/inventory-object.h"
37 #include "inventory/player-inventory.h"
38 #include "io/files-util.h"
39 #include "io/write-diary.h"
40 #include "locale/japanese.h"
41 #include "main/music-definitions-table.h"
42 #include "main/sound-definitions-table.h"
43 #include "market/gold-magnification-table.h"
44 #include "mind/mind.h"
45 #include "object-enchant/item-feeling.h"
46 #include "object-enchant/special-object-flags.h"
47 #include "object/item-use-flags.h"
48 #include "object/object-flavor.h"
49 #include "object/object-generator.h"
50 #include "object/object-hook.h"
51 #include "object/object-kind.h"
52 #include "object/object-stack.h"
53 #include "object/object-value.h"
54 #include "perception/identification.h"
55 #include "perception/object-perception.h"
56 #include "player/avatar.h"
57 #include "player/player-class.h"
58 #include "player/player-effects.h"
59 #include "player/player-status.h"
60 #include "player/race-info-table.h"
61 #include "spell/spells3.h"
62 #include "store/black-market.h"
63 #include "store/rumor.h"
64 #include "store/say-comments.h"
65 #include "store/store-owners.h"
66 #include "store/store-util.h"
67 #include "system/angband.h"
68 #include "term/gameterm.h"
69 #include "util/object-sort.h"
70 #include "util/util.h"
71 #include "view/display-main-window.h"
72 #include "view/object-describer.h"
73 #include "world/world.h"
77 static int store_top = 0;
78 static int store_bottom = 0;
79 static int xtra_stock = 0;
80 static const owner_type *ot_ptr = NULL;
81 static s16b old_town_num = 0;
82 static s16b inner_town_num = 0;
85 * We store the current "store feat" here so everyone can access it
87 static int cur_store_feat;
90 * @brief 店舗価格を決定する. 無料にはならない /
91 * Determine the price of an item (qty one) in a store.
92 * @param o_ptr 店舗に並べるオブジェクト構造体の参照ポインタ
94 * @param flip TRUEならば店主にとっての買取価格、FALSEなら売出価格を計算
98 * This function takes into account the player's charisma, and the
99 * shop-keepers friendliness, and the shop-keeper's base greed, but
100 * never lets a shop-keeper lose money in a transaction.
101 * The "greed" value should exceed 100 when the player is "buying" the
102 * item, and should be less than 100 when the player is "selling" it.
103 * Hack -- the black market always charges twice as much as it should.
104 * Charisma adjustment runs from 80 to 130
105 * Racial adjustment runs from 95 to 130
106 * Since greed/charisma/racial adjustments are centered at 100, we need
107 * to adjust (by 200) to extract a usable multiplier. Note that the
108 * "greed" value is always something (?).
111 static PRICE price_item(player_type *player_ptr, object_type *o_ptr, int greed, bool flip)
113 PRICE price = object_value(o_ptr);
114 if (price <= 0) return (0L);
116 int factor = rgold_adj[ot_ptr->owner_race][player_ptr->prace];
117 factor += adj_chr_gold[player_ptr->stat_ind[A_CHR]];
121 adjust = 100 + (300 - (greed + factor));
122 if (adjust > 100) adjust = 100;
123 if (cur_store_num == STORE_BLACK)
126 price = (price * adjust + 50L) / 100L;
130 adjust = 100 + ((greed + factor) - 300);
131 if (adjust < 100) adjust = 100;
132 if (cur_store_num == STORE_BLACK)
135 price = (s32b)(((u32b)price * (u32b)adjust + 50UL) / 100UL);
138 if (price <= 0L) return (1L);
144 * @brief 店舗に品を置くスペースがあるかどうかの判定を返す /
145 * Check to see if the shop will be carrying too many objects -RAK-
146 * @param o_ptr 店舗に置きたいオブジェクト構造体の参照ポインタ
147 * @return 置き場がないなら0、重ね合わせできるアイテムがあるなら-1、スペースがあるなら1を返す。
150 * Note that the shop, just like a player, will not accept things
151 * it cannot hold. Before, one could "nuke" potions this way.
152 * Return value is now int:
154 * -1 : Can be combined to existing slot.
155 * 1 : Cannot be combined but there are empty spaces.
158 static int store_check_num(object_type *o_ptr)
161 if ((cur_store_num == STORE_HOME) || (cur_store_num == STORE_MUSEUM))
163 bool old_stack_force_notes = stack_force_notes;
164 bool old_stack_force_costs = stack_force_costs;
166 if (cur_store_num != STORE_HOME)
168 stack_force_notes = FALSE;
169 stack_force_costs = FALSE;
172 for (int i = 0; i < st_ptr->stock_num; i++)
174 j_ptr = &st_ptr->stock[i];
175 if (object_similar(j_ptr, o_ptr))
177 if (cur_store_num != STORE_HOME)
179 stack_force_notes = old_stack_force_notes;
180 stack_force_costs = old_stack_force_costs;
187 if (cur_store_num != STORE_HOME)
189 stack_force_notes = old_stack_force_notes;
190 stack_force_costs = old_stack_force_costs;
195 for (int i = 0; i < st_ptr->stock_num; i++)
197 j_ptr = &st_ptr->stock[i];
198 if (store_object_similar(j_ptr, o_ptr)) return -1;
202 /* Free space is always usable */
204 * オプション powerup_home が設定されていると
207 if ((cur_store_num == STORE_HOME) && (powerup_home == FALSE))
209 if (st_ptr->stock_num < ((st_ptr->stock_size) / 10))
216 if (st_ptr->stock_num < st_ptr->stock_size)
227 * @brief 現在の町の指定された店舗のアイテムを整理する /
228 * Combine and reorder items in store.
229 * @param store_num 店舗ID
230 * @return 実際に整理が行われたならばTRUEを返す。
232 bool combine_and_reorder_home(int store_num)
234 bool old_stack_force_notes = stack_force_notes;
235 bool old_stack_force_costs = stack_force_costs;
236 store_type *old_st_ptr = st_ptr;
237 st_ptr = &town_info[1].store[store_num];
239 if (store_num != STORE_HOME)
241 stack_force_notes = FALSE;
242 stack_force_costs = FALSE;
245 bool combined = TRUE;
249 for (int i = st_ptr->stock_num - 1; i > 0; i--)
252 o_ptr = &st_ptr->stock[i];
253 if (!o_ptr->k_idx) continue;
254 for (int j = 0; j < i; j++)
257 j_ptr = &st_ptr->stock[j];
258 if (!j_ptr->k_idx) continue;
261 * Get maximum number of the stack if these
262 * are similar, get zero otherwise.
264 int max_num = object_similar_part(j_ptr, o_ptr);
265 if (max_num == 0 || j_ptr->number >= max_num) continue;
267 if (o_ptr->number + j_ptr->number <= max_num)
269 object_absorb(j_ptr, o_ptr);
272 for (k = i; k < st_ptr->stock_num; k++)
274 st_ptr->stock[k] = st_ptr->stock[k + 1];
277 object_wipe(&st_ptr->stock[k]);
282 ITEM_NUMBER old_num = o_ptr->number;
283 ITEM_NUMBER remain = j_ptr->number + o_ptr->number - max_num;
284 object_absorb(j_ptr, o_ptr);
285 o_ptr->number = remain;
286 if (o_ptr->tval == TV_ROD)
288 o_ptr->pval = o_ptr->pval * remain / old_num;
289 o_ptr->timeout = o_ptr->timeout * remain / old_num;
291 else if (o_ptr->tval == TV_WAND)
293 o_ptr->pval = o_ptr->pval * remain / old_num;
304 for (int i = 0; i < st_ptr->stock_num; i++)
307 o_ptr = &st_ptr->stock[i];
308 if (!o_ptr->k_idx) continue;
310 s32b o_value = object_value(o_ptr);
312 for (j = 0; j < st_ptr->stock_num; j++)
314 if (object_sort_comp(o_ptr, o_value, &st_ptr->stock[j])) break;
317 if (j >= i) continue;
323 object_copy(j_ptr, &st_ptr->stock[i]);
324 for (int k = i; k > j; k--)
326 object_copy(&st_ptr->stock[k], &st_ptr->stock[k - 1]);
329 object_copy(&st_ptr->stock[j], j_ptr);
333 if (store_num != STORE_HOME)
335 stack_force_notes = old_stack_force_notes;
336 stack_force_costs = old_stack_force_costs;
344 * @brief 我が家にオブジェクトを加える /
345 * Add the item "o_ptr" to the inventory of the "Home"
346 * @param o_ptr 加えたいオブジェクトの構造体参照ポインタ
350 * In all cases, return the slot (or -1) where the object was placed
351 * Note that this is a hacked up version of "store_item_to_inventory()".
352 * Also note that it may not correctly "adapt" to "knowledge" bacoming
353 * known, the player may have to pick stuff up and drop it again.
356 static int home_carry(player_type *player_ptr, object_type *o_ptr)
358 bool old_stack_force_notes = stack_force_notes;
359 bool old_stack_force_costs = stack_force_costs;
360 if (cur_store_num != STORE_HOME)
362 stack_force_notes = FALSE;
363 stack_force_costs = FALSE;
366 for (int slot = 0; slot < st_ptr->stock_num; slot++)
369 j_ptr = &st_ptr->stock[slot];
370 if (object_similar(j_ptr, o_ptr))
372 object_absorb(j_ptr, o_ptr);
373 if (cur_store_num != STORE_HOME)
375 stack_force_notes = old_stack_force_notes;
376 stack_force_costs = old_stack_force_costs;
383 if (cur_store_num != STORE_HOME)
385 stack_force_notes = old_stack_force_notes;
386 stack_force_costs = old_stack_force_costs;
391 * 隠し機能: オプション powerup_home が設定されていると
394 if ((cur_store_num != STORE_HOME) || (powerup_home == TRUE))
396 if (st_ptr->stock_num >= st_ptr->stock_size)
403 if (st_ptr->stock_num >= ((st_ptr->stock_size) / 10))
409 PRICE value = object_value(o_ptr);
411 for (slot = 0; slot < st_ptr->stock_num; slot++)
413 if (object_sort_comp(o_ptr, value, &st_ptr->stock[slot])) break;
416 for (int i = st_ptr->stock_num; i > slot; i--)
418 st_ptr->stock[i] = st_ptr->stock[i - 1];
422 st_ptr->stock[slot] = *o_ptr;
423 chg_virtue(player_ptr, V_SACRIFICE, -1);
424 (void)combine_and_reorder_home(cur_store_num);
430 * @brief 店舗の割引対象外にするかどうかを判定 /
431 * Eliminate need to bargain if player has haggled well in the past
432 * @param minprice アイテムの最低販売価格
433 * @return 割引を禁止するならTRUEを返す。
435 static bool noneedtobargain(PRICE minprice)
437 PRICE good = st_ptr->good_buy;
438 PRICE bad = st_ptr->bad_buy;
439 if (minprice < 10L) return TRUE;
440 if (good == MAX_SHORT) return TRUE;
441 if (good > ((3 * bad) + (5 + (minprice / 50)))) return TRUE;
448 * @brief 店主の持つプレイヤーに対する売買の良し悪し経験を記憶する /
449 * Update the bargain info
450 * @param price 実際の取引価格
451 * @param minprice 店主の提示した価格
455 static void updatebargain(PRICE price, PRICE minprice, int num)
457 if (!manual_haggle) return;
458 if ((minprice / num) < 10L) return;
459 if (price == minprice)
461 if (st_ptr->good_buy < MAX_SHORT)
468 if (st_ptr->bad_buy < MAX_SHORT)
477 * @brief 店の商品リストを再表示する /
478 * Re-displays a single store entry
479 * @param player_ptr プレーヤーへの参照ポインタ
483 static void display_entry(player_type *player_ptr, int pos)
486 o_ptr = &st_ptr->stock[pos];
487 int i = (pos % store_bottom);
489 /* Label it, clear the line --(-- */
491 (void)sprintf(out_val, "%c) ", ((i > 25) ? toupper(I2A(i - 26)) : I2A(i)));
492 prt(out_val, i + 6, 0);
497 TERM_COLOR a = object_attr(o_ptr);
498 SYMBOL_CODE c = object_char(o_ptr);
500 Term_queue_bigchar(cur_col, i + 6, a, c, 0, 0);
501 if (use_bigtile) cur_col++;
506 /* Describe an item in the home */
508 if ((cur_store_num == STORE_HOME) || (cur_store_num == STORE_MUSEUM))
511 if (show_weights) maxwid -= 10;
513 GAME_TEXT o_name[MAX_NLEN];
514 object_desc(player_ptr, o_name, o_ptr, 0);
515 o_name[maxwid] = '\0';
516 c_put_str(tval_to_attr[o_ptr->tval], o_name, i + 6, cur_col);
519 WEIGHT wgt = o_ptr->weight;
520 sprintf(out_val, _("%3d.%1d kg", "%3d.%d lb"), _(lbtokg1(wgt), wgt / 10), _(lbtokg2(wgt), wgt % 10));
521 put_str(out_val, i + 6, _(67, 68));
528 if (show_weights) maxwid -= 7;
530 GAME_TEXT o_name[MAX_NLEN];
531 object_desc(player_ptr, o_name, o_ptr, 0);
532 o_name[maxwid] = '\0';
533 c_put_str(tval_to_attr[o_ptr->tval], o_name, i + 6, cur_col);
537 int wgt = o_ptr->weight;
538 sprintf(out_val, "%3d.%1d", _(lbtokg1(wgt), wgt / 10), _(lbtokg2(wgt), wgt % 10));
539 put_str(out_val, i + 6, _(60, 61));
543 if (o_ptr->ident & (IDENT_FIXED))
545 x = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, FALSE);
546 (void)sprintf(out_val, _("%9ld固", "%9ld F"), (long)x);
547 put_str(out_val, i + 6, 68);
553 x = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, FALSE);
554 if (!noneedtobargain(x)) x += x / 10;
556 (void)sprintf(out_val, "%9ld ", (long)x);
557 put_str(out_val, i + 6, 68);
561 x = price_item(player_ptr, o_ptr, ot_ptr->max_inflate, FALSE);
562 (void)sprintf(out_val, "%9ld ", (long)x);
563 put_str(out_val, i + 6, 68);
568 * @brief 店の商品リストを表示する /
569 * Displays a store's inventory -RAK-
570 * @param player_ptr プレーヤーへの参照ポインタ
573 * All prices are listed as "per individual object". -BEN-
575 static void display_store_inventory(player_type *player_ptr)
578 for (k = 0; k < store_bottom; k++)
580 if (store_top + k >= st_ptr->stock_num) break;
582 display_entry(player_ptr, store_top + k);
585 for (int i = k; i < store_bottom + 1; i++)
588 put_str(_(" ", " "), 5, _(20, 22));
589 if (st_ptr->stock_num > store_bottom)
591 prt(_("-続く-", "-more-"), k + 6, 3);
592 put_str(format(_("(%dページ) ", "(Page %d) "), store_top / store_bottom + 1), 5, _(20, 22));
595 if (cur_store_num == STORE_HOME || cur_store_num == STORE_MUSEUM)
597 k = st_ptr->stock_size;
598 if (cur_store_num == STORE_HOME && !powerup_home) k /= 10;
600 put_str(format(_("アイテム数: %4d/%4d", "Objects: %4d/%4d"), st_ptr->stock_num, k), 19 + xtra_stock, _(27, 30));
606 * @brief プレイヤーの所持金を表示する /
607 * Displays players gold -RAK-
608 * @param player_ptr プレーヤーへの参照ポインタ
612 static void store_prt_gold(player_type *player_ptr)
614 prt(_("手持ちのお金: ", "Gold Remaining: "), 19 + xtra_stock, 53);
616 sprintf(out_val, "%9ld", (long)player_ptr->au);
617 prt(out_val, 19 + xtra_stock, 68);
622 * @brief 店舗情報全体を表示するメインルーチン /
623 * Displays store (after clearing screen) -RAK-
624 * @param player_ptr プレーヤーへの参照ポインタ
628 static void display_store(player_type *player_ptr)
631 if (cur_store_num == STORE_HOME)
633 put_str(_("我が家", "Your Home"), 3, 31);
634 put_str(_("アイテムの一覧", "Item Description"), 5, 4);
637 put_str(_(" 重さ", "Weight"), 5, 70);
640 store_prt_gold(player_ptr);
641 display_store_inventory(player_ptr);
645 if (cur_store_num == STORE_MUSEUM)
647 put_str(_("博物館", "Museum"), 3, 31);
648 put_str(_("アイテムの一覧", "Item Description"), 5, 4);
651 put_str(_(" 重さ", "Weight"), 5, 70);
654 store_prt_gold(player_ptr);
655 display_store_inventory(player_ptr);
659 concptr store_name = (f_name + f_info[cur_store_feat].name);
660 concptr owner_name = (ot_ptr->owner_name);
661 concptr race_name = race_info[ot_ptr->owner_race].title;
663 sprintf(buf, "%s (%s)", owner_name, race_name);
666 sprintf(buf, "%s (%ld)", store_name, (long)(ot_ptr->max_cost));
669 put_str(_("商品の一覧", "Item Description"), 5, 5);
672 put_str(_(" 重さ", "Weight"), 5, 60);
675 put_str(_(" 価格", "Price"), 5, 72);
676 store_prt_gold(player_ptr);
677 display_store_inventory(player_ptr);
682 * @brief 店舗からアイテムを選択する /
683 * Get the ID of a store item and return its value -RAK-
684 * @param com_val 選択IDを返す参照ポインタ
685 * @param pmt メッセージキャプション
688 * @return 実際に選択したらTRUE、キャンセルしたらFALSE
690 static int get_stock(COMMAND_CODE *com_val, concptr pmt, int i, int j)
692 if (repeat_pull(com_val) && (*com_val >= i) && (*com_val <= j))
700 char hi = (j > 25) ? toupper(I2A(j - 26)) : I2A(j);
703 (void)sprintf(out_val, "(%s:%c-%c, ESCで中断) %s",
704 (((cur_store_num == STORE_HOME) || (cur_store_num == STORE_MUSEUM)) ? "アイテム" : "商品"),
707 (void)sprintf(out_val, "(Items %c-%c, ESC to exit) %s",
714 if (!get_com(out_val, &command, FALSE)) break;
717 if (islower(command))
719 else if (isupper(command))
720 k = A2I(tolower(command)) + 26;
724 if ((k >= i) && (k <= j))
734 if (command == ESCAPE) return FALSE;
736 repeat_push(*com_val);
742 * @brief 店主の不満度を増やし、プレイヤーを締め出す判定と処理を行う /
743 * Increase the insult counter and get angry if too many -RAK-
744 * @return プレイヤーを締め出す場合TRUEを返す
746 static int increase_insults(void)
748 st_ptr->insult_cur++;
749 if (st_ptr->insult_cur <= ot_ptr->insult_max) return FALSE;
753 st_ptr->insult_cur = 0;
754 st_ptr->good_buy = 0;
756 st_ptr->store_open = current_world_ptr->game_turn + TURNS_PER_TICK * TOWN_DAWN / 8 + randint1(TURNS_PER_TICK*TOWN_DAWN / 8);
763 * @brief 店主の不満度を減らす /
764 * Decrease insults -RAK-
765 * @return プレイヤーを締め出す場合TRUEを返す
767 static void decrease_insults(void)
769 if (st_ptr->insult_cur) st_ptr->insult_cur--;
774 * @brief 店主の不満度が増えた場合のみのメッセージを表示する /
775 * Have insulted while haggling -RAK-
776 * @return プレイヤーを締め出す場合TRUEを返す
778 static int haggle_insults(void)
780 if (increase_insults()) return TRUE;
787 * Mega-Hack -- Enable "increments"
789 static bool allow_inc = FALSE;
792 * Mega-Hack -- Last "increment" during haggling
794 static s32b last_inc = 0L;
797 * @brief 交渉価格を確認と認証の是非を行う /
800 * @param poffer 別途価格提示をした場合の値を返す参照ポインタ
801 * @param price 現在の交渉価格
802 * @param final 最終確定価格ならばTRUE
803 * @return プレイヤーを締め出す場合TRUEを返す
805 static int get_haggle(concptr pmt, s32b *poffer, PRICE price, int final)
808 if (!allow_inc) last_inc = 0L;
812 sprintf(buf, _("%s [承諾] ", "%s [accept] "), pmt);
814 else if (last_inc < 0)
816 sprintf(buf, _("%s [-$%ld] ", "%s [-%ld] "), pmt, (long)(ABS(last_inc)));
818 else if (last_inc > 0)
820 sprintf(buf, _("%s [+$%ld] ", "%s [+%ld] "), pmt, (long)(ABS(last_inc)));
824 sprintf(buf, "%s ", pmt);
828 GAME_TEXT out_val[160];
836 * Ask the user for a response.
837 * Don't allow to use numpad as cursor key.
839 res = askfor_aux(out_val, 32, FALSE);
841 if (!res) return FALSE;
844 for (p = out_val; *p == ' '; p++) /* loop */;
855 if (allow_inc && last_inc)
861 msg_print(_("値がおかしいです。", "Invalid response."));
867 if ((*p == '+' || *p == '-'))
889 * @brief 店主がプレイヤーからの交渉価格を判断する /
890 * Receive an offer (from the player)
892 * @param poffer 店主からの交渉価格を返す参照ポインタ
893 * @param last_offer 現在の交渉価格
894 * @param factor 店主の価格基準倍率
895 * @param price アイテムの実価値
896 * @param final 最終価格確定ならばTRUE
897 * @return プレイヤーの価格に対して不服ならばTRUEを返す /
898 * Return TRUE if offer is NOT okay
900 static bool receive_offer(concptr pmt, s32b *poffer, s32b last_offer, int factor, PRICE price, int final)
904 if (!get_haggle(pmt, poffer, price, final)) return TRUE;
905 if (((*poffer) * factor) >= (last_offer * factor)) break;
906 if (haggle_insults()) return TRUE;
908 (*poffer) = last_offer;
916 * @brief プレイヤーが購入する時の値切り処理メインルーチン /
917 * Haggling routine -RAK-
918 * @param player_ptr プレーヤーへの参照ポインタ
919 * @param o_ptr オブジェクトの構造体参照ポインタ
920 * @param price 最終価格を返す参照ポインタ
921 * @return プレイヤーの価格に対して店主が不服ならばTRUEを返す /
922 * Return TRUE if purchase is NOT successful
924 static bool purchase_haggle(player_type *player_ptr, object_type *o_ptr, s32b *price)
926 s32b cur_ask = price_item(player_ptr, o_ptr, ot_ptr->max_inflate, FALSE);
927 s32b final_ask = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, FALSE);
928 int noneed = noneedtobargain(final_ask);
930 concptr pmt = _("提示価格", "Asking");
931 if (noneed || !manual_haggle)
935 msg_print(_("結局この金額にまとまった。", "You eventually agree upon the price."));
940 msg_print(_("すんなりとこの金額にまとまった。", "You quickly agree upon the price."));
942 final_ask += final_ask / 10;
946 pmt = _("最終提示価格", "Final Offer");
950 cur_ask *= o_ptr->number;
951 final_ask *= o_ptr->number;
952 s32b min_per = ot_ptr->haggle_per;
953 s32b max_per = min_per * 3;
954 s32b last_offer = object_value(o_ptr) * o_ptr->number;
955 last_offer = last_offer * (200 - (int)(ot_ptr->max_inflate)) / 100L;
956 if (last_offer <= 0) last_offer = 1;
966 bool loop_flag = TRUE;
968 while (!flag && loop_flag)
971 (void)sprintf(out_val, "%s : %ld", pmt, (long)cur_ask);
972 put_str(out_val, 1, 0);
973 cancel = receive_offer(_("提示する金額? ", "What do you offer? "), &offer, last_offer, 1, cur_ask, final);
978 else if (offer > cur_ask)
983 else if (offer == cur_ask)
996 s32b x1 = 100 * (offer - last_offer) / (cur_ask - last_offer);
999 if (haggle_insults())
1005 else if (x1 > max_per)
1008 if (x1 < max_per) x1 = max_per;
1011 s32b x2 = rand_range(x1 - 2, x1 + 2);
1012 s32b x3 = ((cur_ask - offer) * x2 / 100L) + 1;
1016 if (cur_ask < final_ask)
1019 cur_ask = final_ask;
1020 pmt = _("最終提示価格", "What do you offer? ");
1024 (void)(increase_insults());
1029 else if (offer >= cur_ask)
1041 (void)sprintf(out_val, _("前回の提示金額: $%ld", "Your last offer: %ld"), (long)last_offer);
1042 put_str(out_val, 1, 39);
1043 say_comment_2(cur_ask, annoyed);
1046 if (cancel) return TRUE;
1048 updatebargain(*price, final_ask, o_ptr->number);
1054 * @brief プレイヤーが売却する時の値切り処理メインルーチン /
1055 * Haggling routine -RAK-
1056 * @param player_ptr プレーヤーへの参照ポインタ
1057 * @param o_ptr オブジェクトの構造体参照ポインタ
1058 * @param price 最終価格を返す参照ポインタ
1059 * @return プレイヤーの価格に対して店主が不服ならばTRUEを返す /
1060 * Return TRUE if purchase is NOT successful
1062 static bool sell_haggle(player_type *player_ptr, object_type *o_ptr, s32b *price)
1064 s32b cur_ask = price_item(player_ptr, o_ptr, ot_ptr->max_inflate, TRUE);
1065 s32b final_ask = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, TRUE);
1066 int noneed = noneedtobargain(final_ask);
1067 s32b purse = (s32b)(ot_ptr->max_cost);
1069 concptr pmt = _("提示金額", "Offer");
1070 if (noneed || !manual_haggle || (final_ask >= purse))
1072 if (!manual_haggle && !noneed)
1074 final_ask -= final_ask / 10;
1077 if (final_ask >= purse)
1079 msg_print(_("即座にこの金額にまとまった。", "You instantly agree upon the price."));
1085 msg_print(_("結局この金額にまとまった。", "You eventually agree upon the price."));
1090 msg_print(_("すんなりとこの金額にまとまった。", "You quickly agree upon the price."));
1094 cur_ask = final_ask;
1096 pmt = _("最終提示金額", "Final Offer");
1099 cur_ask *= o_ptr->number;
1100 final_ask *= o_ptr->number;
1102 s32b min_per = ot_ptr->haggle_per;
1103 s32b max_per = min_per * 3;
1104 s32b last_offer = object_value(o_ptr) * o_ptr->number;
1105 last_offer = last_offer * ot_ptr->max_inflate / 100L;
1111 bool cancel = FALSE;
1120 (void)sprintf(out_val, "%s : %ld", pmt, (long)cur_ask);
1121 put_str(out_val, 1, 0);
1122 cancel = receive_offer(_("提示する価格? ", "What price do you ask? "),
1123 &offer, last_offer, -1, cur_ask, final);
1129 else if (offer < cur_ask)
1134 else if (offer == cur_ask)
1144 if (flag || !loop_flag) break;
1149 s32b x1 = 100 * (last_offer - offer) / (last_offer - cur_ask);
1152 if (haggle_insults())
1158 else if (x1 > max_per)
1161 if (x1 < max_per) x1 = max_per;
1164 s32b x2 = rand_range(x1 - 2, x1 + 2);
1165 s32b x3 = ((offer - cur_ask) * x2 / 100L) + 1;
1169 if (cur_ask > final_ask)
1171 cur_ask = final_ask;
1173 pmt = _("最終提示金額", "Final Offer");
1180 /* 追加 $0 で買い取られてしまうのを防止 By FIRST*/
1183 (void)(increase_insults());
1186 else if (offer <= cur_ask)
1196 (void)sprintf(out_val, _("前回の提示価格 $%ld", "Your last bid %ld"), (long)last_offer);
1197 put_str(out_val, 1, 39);
1198 say_comment_3(cur_ask, annoyed);
1201 if (cancel) return TRUE;
1203 updatebargain(*price, final_ask, o_ptr->number);
1209 * @brief 店からの購入処理のメインルーチン /
1210 * Buy an item from a store -RAK-
1211 * @param player_ptr プレーヤーへの参照ポインタ
1214 static void store_purchase(player_type *player_ptr)
1216 if (cur_store_num == STORE_MUSEUM)
1218 msg_print(_("博物館から取り出すことはできません。", "Museum."));
1222 if (st_ptr->stock_num <= 0)
1224 if (cur_store_num == STORE_HOME)
1225 msg_print(_("我が家には何も置いてありません。", "Your home is empty."));
1227 msg_print(_("現在商品の在庫を切らしています。", "I am currently out of stock."));
1231 int i = (st_ptr->stock_num - store_top);
1232 if (i > store_bottom) i = store_bottom;
1236 /* ブラックマーケットの時は別のメッセージ */
1237 switch (cur_store_num)
1240 sprintf(out_val, "どのアイテムを取りますか? ");
1243 sprintf(out_val, "どれ? ");
1246 sprintf(out_val, "どの品物が欲しいんだい? ");
1250 if (cur_store_num == STORE_HOME)
1252 sprintf(out_val, "Which item do you want to take? ");
1256 sprintf(out_val, "Which item are you interested in? ");
1261 if (!get_stock(&item, out_val, 0, i - 1)) return;
1263 item = item + store_top;
1265 o_ptr = &st_ptr->stock[item];
1266 ITEM_NUMBER amt = 1;
1270 object_copy(j_ptr, o_ptr);
1273 * If a rod or wand, allocate total maximum timeouts or charges
1274 * between those purchased and left on the shelf.
1276 reduce_charges(j_ptr, o_ptr->number - amt);
1277 j_ptr->number = amt;
1278 if (!check_store_item_to_inventory(j_ptr))
1280 msg_print(_("そんなにアイテムを持てない。", "You cannot carry that many different items."));
1284 PRICE best = price_item(player_ptr, j_ptr, ot_ptr->min_inflate, FALSE);
1285 if (o_ptr->number > 1)
1287 if ((cur_store_num != STORE_HOME) &&
1288 (o_ptr->ident & IDENT_FIXED))
1290 msg_format(_("一つにつき $%ldです。", "That costs %ld gold per item."), (long)(best));
1293 amt = get_quantity(NULL, o_ptr->number);
1294 if (amt <= 0) return;
1298 object_copy(j_ptr, o_ptr);
1301 * If a rod or wand, allocate total maximum timeouts or charges
1302 * between those purchased and left on the shelf.
1304 reduce_charges(j_ptr, o_ptr->number - amt);
1305 j_ptr->number = amt;
1306 if (!check_store_item_to_inventory(j_ptr))
1308 msg_print(_("ザックにそのアイテムを入れる隙間がない。", "You cannot carry that many items."));
1313 COMMAND_CODE item_new;
1315 if (cur_store_num == STORE_HOME)
1317 bool combined_or_reordered;
1318 distribute_charges(o_ptr, j_ptr, amt);
1319 item_new = store_item_to_inventory(player_ptr, j_ptr);
1320 GAME_TEXT o_name[MAX_NLEN];
1321 object_desc(player_ptr, o_name, &player_ptr->inventory_list[item_new], 0);
1323 msg_format(_("%s(%c)を取った。", "You have %s (%c)."), o_name, index_to_label(item_new));
1324 handle_stuff(player_ptr);
1326 i = st_ptr->stock_num;
1327 store_item_increase(item, -amt);
1328 store_item_optimize(item);
1329 combined_or_reordered = combine_and_reorder_home(STORE_HOME);
1330 if (i == st_ptr->stock_num)
1332 if (combined_or_reordered) display_store_inventory(player_ptr);
1333 else display_entry(player_ptr, item);
1337 if (st_ptr->stock_num == 0) store_top = 0;
1338 else if (store_top >= st_ptr->stock_num) store_top -= store_bottom;
1339 display_store_inventory(player_ptr);
1341 chg_virtue(player_ptr, V_SACRIFICE, 1);
1347 if (o_ptr->ident & (IDENT_FIXED))
1350 price = (best * j_ptr->number);
1354 GAME_TEXT o_name[MAX_NLEN];
1355 object_desc(player_ptr, o_name, j_ptr, 0);
1356 msg_format(_("%s(%c)を購入する。", "Buying %s (%c)."), o_name, I2A(item));
1358 choice = purchase_haggle(player_ptr, j_ptr, &price);
1359 if (st_ptr->store_open >= current_world_ptr->game_turn) return;
1362 if (choice != 0) return;
1363 if (price == (best * j_ptr->number)) o_ptr->ident |= (IDENT_FIXED);
1364 if (player_ptr->au < price)
1366 msg_print(_("お金が足りません。", "You do not have enough gold."));
1370 say_comment_1(player_ptr);
1371 if (cur_store_num == STORE_BLACK)
1372 chg_virtue(player_ptr, V_JUSTICE, -1);
1373 if ((o_ptr->tval == TV_BOTTLE) && (cur_store_num != STORE_HOME))
1374 chg_virtue(player_ptr, V_NATURE, -1);
1378 player_ptr->au -= price;
1379 store_prt_gold(player_ptr);
1380 object_aware(player_ptr, j_ptr);
1381 j_ptr->ident &= ~(IDENT_FIXED);
1382 GAME_TEXT o_name[MAX_NLEN];
1383 object_desc(player_ptr, o_name, j_ptr, 0);
1385 msg_format(_("%sを $%ldで購入しました。", "You bought %s for %ld gold."), o_name, (long)price);
1387 strcpy(record_o_name, o_name);
1388 record_turn = current_world_ptr->game_turn;
1390 if (record_buy) exe_write_diary(player_ptr, DIARY_BUY, 0, o_name);
1391 object_desc(player_ptr, o_name, o_ptr, OD_NAME_ONLY);
1392 if (record_rand_art && o_ptr->art_name)
1393 exe_write_diary(player_ptr, DIARY_ART, 0, o_name);
1395 j_ptr->inscription = 0;
1396 j_ptr->feeling = FEEL_NONE;
1397 j_ptr->ident &= ~(IDENT_STORE);
1398 item_new = store_item_to_inventory(player_ptr, j_ptr);
1400 object_desc(player_ptr, o_name, &player_ptr->inventory_list[item_new], 0);
1401 msg_format(_("%s(%c)を手に入れた。", "You have %s (%c)."), o_name, index_to_label(item_new));
1402 autopick_alter_item(player_ptr, item_new, FALSE);
1403 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
1405 o_ptr->pval -= j_ptr->pval;
1408 handle_stuff(player_ptr);
1409 i = st_ptr->stock_num;
1410 store_item_increase(item, -amt);
1411 store_item_optimize(item);
1412 if (st_ptr->stock_num == 0)
1414 if (one_in_(STORE_SHUFFLE))
1417 msg_print(_("店主は引退した。", "The shopkeeper retires."));
1418 store_shuffle(player_ptr, cur_store_num);
1421 sprintf(buf, "%s (%s)",
1422 ot_ptr->owner_name, race_info[ot_ptr->owner_race].title);
1423 put_str(buf, 3, 10);
1424 sprintf(buf, "%s (%ld)",
1425 (f_name + f_info[cur_store_feat].name), (long)(ot_ptr->max_cost));
1430 msg_print(_("店主は新たな在庫を取り出した。", "The shopkeeper brings out some new stock."));
1433 for (i = 0; i < 10; i++)
1435 store_maint(player_ptr, player_ptr->town_num, cur_store_num);
1439 display_store_inventory(player_ptr);
1441 else if (st_ptr->stock_num != i)
1443 if (store_top >= st_ptr->stock_num) store_top -= store_bottom;
1444 display_store_inventory(player_ptr);
1448 display_entry(player_ptr, item);
1454 * @brief 店からの売却処理のメインルーチン /
1455 * Sell an item to the store (or home)
1456 * @param owner_ptr プレーヤーへの参照ポインタ
1459 static void store_sell(player_type *owner_ptr)
1462 if (cur_store_num == STORE_HOME)
1463 q = _("どのアイテムを置きますか? ", "Drop which item? ");
1464 else if (cur_store_num == STORE_MUSEUM)
1465 q = _("どのアイテムを寄贈しますか? ", "Give which item? ");
1467 q = _("どのアイテムを売りますか? ", "Sell which item? ");
1469 item_tester_hook = store_will_buy;
1471 /* 我が家でおかしなメッセージが出るオリジナルのバグを修正 */
1473 if (cur_store_num == STORE_HOME)
1475 s = _("置けるアイテムを持っていません。", "You don't have any item to drop.");
1477 else if (cur_store_num == STORE_MUSEUM)
1479 s = _("寄贈できるアイテムを持っていません。", "You don't have any item to give.");
1483 s = _("欲しい物がないですねえ。", "You have nothing that I want.");
1488 o_ptr = choose_object(owner_ptr, &item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT), 0);
1491 if ((item >= INVEN_RARM) && object_is_cursed(o_ptr))
1493 msg_print(_("ふーむ、どうやらそれは呪われているようだね。", "Hmmm, it seems to be cursed."));
1498 if (o_ptr->number > 1)
1500 amt = get_quantity(NULL, o_ptr->number);
1501 if (amt <= 0) return;
1507 object_copy(q_ptr, o_ptr);
1508 q_ptr->number = amt;
1511 * Hack -- If a rod or wand, allocate total maximum
1512 * timeouts or charges to those being sold. -LM-
1514 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
1516 q_ptr->pval = o_ptr->pval * amt / o_ptr->number;
1519 GAME_TEXT o_name[MAX_NLEN];
1520 object_desc(owner_ptr, o_name, q_ptr, 0);
1522 /* Remove any inscription, feeling for stores */
1523 if ((cur_store_num != STORE_HOME) && (cur_store_num != STORE_MUSEUM))
1525 q_ptr->inscription = 0;
1526 q_ptr->feeling = FEEL_NONE;
1529 /* Is there room in the store (or the home?) */
1530 if (!store_check_num(q_ptr))
1532 if (cur_store_num == STORE_HOME)
1533 msg_print(_("我が家にはもう置く場所がない。", "Your home is full."));
1535 else if (cur_store_num == STORE_MUSEUM)
1536 msg_print(_("博物館はもう満杯だ。", "Museum is full."));
1539 msg_print(_("すいませんが、店にはもう置く場所がありません。", "I have not the room in my store to keep it."));
1545 PRICE price, value, dummy;
1546 if ((cur_store_num != STORE_HOME) && (cur_store_num != STORE_MUSEUM))
1548 msg_format(_("%s(%c)を売却する。", "Selling %s (%c)."), o_name, index_to_label(item));
1551 choice = sell_haggle(owner_ptr, q_ptr, &price);
1552 if (st_ptr->store_open >= current_world_ptr->game_turn) return;
1556 say_comment_1(owner_ptr);
1558 if (cur_store_num == STORE_BLACK)
1559 chg_virtue(owner_ptr, V_JUSTICE, -1);
1561 if ((o_ptr->tval == TV_BOTTLE) && (cur_store_num != STORE_HOME))
1562 chg_virtue(owner_ptr, V_NATURE, 1);
1565 owner_ptr->au += price;
1566 store_prt_gold(owner_ptr);
1567 dummy = object_value(q_ptr) * q_ptr->number;
1569 identify_item(owner_ptr, o_ptr);
1571 object_copy(q_ptr, o_ptr);
1572 q_ptr->number = amt;
1573 q_ptr->ident |= IDENT_STORE;
1576 * Hack -- If a rod or wand, let the shopkeeper know just
1577 * how many charges he really paid for. -LM-
1579 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
1581 q_ptr->pval = o_ptr->pval * amt / o_ptr->number;
1584 value = object_value(q_ptr) * q_ptr->number;
1585 object_desc(owner_ptr, o_name, q_ptr, 0);
1586 msg_format(_("%sを $%ldで売却しました。", "You sold %s for %ld gold."), o_name, (long)price);
1588 if (record_sell) exe_write_diary(owner_ptr, DIARY_SELL, 0, o_name);
1590 if (!((o_ptr->tval == TV_FIGURINE) && (value > 0)))
1592 purchase_analyze(owner_ptr, price, value, dummy);
1596 * Hack -- Allocate charges between those wands or rods sold
1597 * and retained, unless all are being sold. -LM-
1599 distribute_charges(o_ptr, q_ptr, amt);
1601 inven_item_increase(owner_ptr, item, -amt);
1602 inven_item_describe(owner_ptr, item);
1603 if (o_ptr->number > 0)
1604 autopick_alter_item(owner_ptr, item, FALSE);
1606 inven_item_optimize(owner_ptr, item);
1607 handle_stuff(owner_ptr);
1608 int item_pos = store_carry(q_ptr);
1611 store_top = (item_pos / store_bottom) * store_bottom;
1612 display_store_inventory(owner_ptr);
1616 else if (cur_store_num == STORE_MUSEUM)
1618 char o2_name[MAX_NLEN];
1619 object_desc(owner_ptr, o2_name, q_ptr, OD_NAME_ONLY);
1621 if (-1 == store_check_num(q_ptr))
1623 msg_print(_("それと同じ品物は既に博物館にあるようです。", "The Museum already has one of those items."));
1627 msg_print(_("博物館に寄贈したものは取り出すことができません!!", "You cannot take back items which have been donated to the Museum!!"));
1630 if (!get_check(format(_("本当に%sを寄贈しますか?", "Really give %s to the Museum? "), o2_name))) return;
1632 identify_item(owner_ptr, q_ptr);
1633 q_ptr->ident |= IDENT_FULL_KNOWN;
1635 distribute_charges(o_ptr, q_ptr, amt);
1636 msg_format(_("%sを置いた。(%c)", "You drop %s (%c)."), o_name, index_to_label(item));
1639 vary_item(owner_ptr, item, -amt);
1640 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);
1651 distribute_charges(o_ptr, q_ptr, amt);
1652 msg_format(_("%sを置いた。(%c)", "You drop %s (%c)."), o_name, index_to_label(item));
1654 vary_item(owner_ptr, item, -amt);
1655 handle_stuff(owner_ptr);
1656 int item_pos = home_carry(owner_ptr, q_ptr);
1659 store_top = (item_pos / store_bottom) * store_bottom;
1660 display_store_inventory(owner_ptr);
1664 if ((choice == 0) && (item >= INVEN_RARM))
1666 calc_android_exp(owner_ptr);
1667 verify_equip_slot(owner_ptr, item);
1673 * @brief 店のアイテムを調べるコマンドのメインルーチン /
1674 * Examine an item in a store -JDL-
1677 static void store_examine(player_type *player_ptr)
1679 if (st_ptr->stock_num <= 0)
1681 if (cur_store_num == STORE_HOME)
1682 msg_print(_("我が家には何も置いてありません。", "Your home is empty."));
1683 else if (cur_store_num == STORE_MUSEUM)
1684 msg_print(_("博物館には何も置いてありません。", "Museum is empty."));
1686 msg_print(_("現在商品の在庫を切らしています。", "I am currently out of stock."));
1690 int i = (st_ptr->stock_num - store_top);
1691 if (i > store_bottom) i = store_bottom;
1694 sprintf(out_val, _("どれを調べますか?", "Which item do you want to examine? "));
1697 if (!get_stock(&item, out_val, 0, i - 1)) return;
1698 item = item + store_top;
1700 o_ptr = &st_ptr->stock[item];
1701 if (!object_is_fully_known(o_ptr))
1703 msg_print(_("このアイテムについて特に知っていることはない。", "You have no special knowledge about that item."));
1707 GAME_TEXT o_name[MAX_NLEN];
1708 object_desc(player_ptr, o_name, o_ptr, 0);
1709 msg_format(_("%sを調べている...", "Examining %s..."), o_name);
1711 if (!screen_object(player_ptr, o_ptr, SCROBJ_FORCE_DETAIL))
1712 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
1717 * @brief 博物館のアイテムを除去するコマンドのメインルーチン /
1718 * Remove an item from museum (Originally from TOband)
1719 * @param player_ptr プレーヤーへの参照ポインタ
1722 static void museum_remove_object(player_type *player_ptr)
1724 if (st_ptr->stock_num <= 0)
1726 msg_print(_("博物館には何も置いてありません。", "Museum is empty."));
1730 int i = st_ptr->stock_num - store_top;
1731 if (i > store_bottom) i = store_bottom;
1734 sprintf(out_val, _("どのアイテムの展示をやめさせますか?", "Which item do you want to order to remove? "));
1737 if (!get_stock(&item, out_val, 0, i - 1)) return;
1739 item = item + store_top;
1741 o_ptr = &st_ptr->stock[item];
1743 GAME_TEXT o_name[MAX_NLEN];
1744 object_desc(player_ptr, o_name, o_ptr, 0);
1746 msg_print(_("展示をやめさせたアイテムは二度と見ることはできません!", "Once removed from the Museum, an item will be gone forever!"));
1747 if (!get_check(format(_("本当に%sの展示をやめさせますか?", "Really order to remove %s from the Museum? "), o_name))) return;
1749 msg_format(_("%sの展示をやめさせた。", "You ordered to remove %s."), o_name);
1751 store_item_increase(item, -o_ptr->number);
1752 store_item_optimize(item);
1754 (void)combine_and_reorder_home(STORE_MUSEUM);
1755 if (st_ptr->stock_num == 0) store_top = 0;
1757 else if (store_top >= st_ptr->stock_num) store_top -= store_bottom;
1758 display_store_inventory(player_ptr);
1763 * Hack -- set this to leave the store
1765 static bool leave_store = FALSE;
1769 * @brief 店舗処理コマンド選択のメインルーチン /
1770 * Process a command in a store
1771 * @param client_ptr 顧客となるクリーチャーの参照ポインタ
1775 * Note that we must allow the use of a few "special" commands
1776 * in the stores which are not allowed in the dungeon, and we
1777 * must disable some commands which are allowed in the dungeon
1778 * but not in the stores, to prevent chaos.
1781 static void store_process_command(player_type *client_ptr)
1784 if (rogue_like_commands && command_cmd == 'l')
1789 switch (command_cmd)
1799 /* 1 ページ戻るコマンド: 我が家のページ数が多いので重宝するはず By BUG */
1800 if (st_ptr->stock_num <= store_bottom) {
1801 msg_print(_("これで全部です。", "Entire inventory is shown."));
1805 store_top -= store_bottom;
1807 store_top = ((st_ptr->stock_num - 1) / store_bottom) * store_bottom;
1808 if ((cur_store_num == STORE_HOME) && (powerup_home == FALSE))
1809 if (store_top >= store_bottom) store_top = store_bottom;
1810 display_store_inventory(client_ptr);
1817 if (st_ptr->stock_num <= store_bottom)
1819 msg_print(_("これで全部です。", "Entire inventory is shown."));
1823 store_top += store_bottom;
1825 * 隠しオプション(powerup_home)がセットされていないときは
1826 * 我が家では 2 ページまでしか表示しない
1828 if ((cur_store_num == STORE_HOME) &&
1829 (powerup_home == FALSE) &&
1830 (st_ptr->stock_num >= STORE_INVEN_MAX))
1832 if (store_top >= (STORE_INVEN_MAX - 1))
1839 if (store_top >= st_ptr->stock_num) store_top = 0;
1842 display_store_inventory(client_ptr);
1849 do_cmd_redraw(client_ptr);
1850 display_store(client_ptr);
1855 store_purchase(client_ptr);
1860 store_sell(client_ptr);
1865 store_examine(client_ptr);
1874 do_cmd_wield(client_ptr);
1879 do_cmd_takeoff(client_ptr);
1884 do_cmd_destroy(client_ptr);
1889 do_cmd_equip(client_ptr);
1894 do_cmd_inven(client_ptr);
1899 do_cmd_observe(client_ptr);
1904 toggle_inventory_equipment(client_ptr);
1909 if ((client_ptr->pclass == CLASS_MINDCRAFTER) ||
1910 (client_ptr->pclass == CLASS_BERSERKER) ||
1911 (client_ptr->pclass == CLASS_NINJA) ||
1912 (client_ptr->pclass == CLASS_MIRROR_MASTER)
1913 ) do_cmd_mind_browse(client_ptr);
1914 else if (client_ptr->pclass == CLASS_SMITH)
1915 do_cmd_kaji(client_ptr, TRUE);
1916 else if (client_ptr->pclass == CLASS_MAGIC_EATER)
1917 do_cmd_magic_eater(client_ptr, TRUE, FALSE);
1918 else if (client_ptr->pclass == CLASS_SNIPER)
1919 do_cmd_snipe_browse(client_ptr);
1920 else do_cmd_browse(client_ptr);
1925 do_cmd_inscribe(client_ptr);
1930 do_cmd_uninscribe(client_ptr);
1935 do_cmd_help(client_ptr);
1940 do_cmd_query_symbol(client_ptr);
1945 client_ptr->town_num = old_town_num;
1946 do_cmd_player_status(client_ptr);
1947 client_ptr->town_num = inner_town_num;
1948 display_store(client_ptr);
1958 client_ptr->town_num = old_town_num;
1959 do_cmd_pref(client_ptr);
1960 client_ptr->town_num = inner_town_num;
1965 client_ptr->town_num = old_town_num;
1966 do_cmd_macros(client_ptr, process_autopick_file_command);
1967 client_ptr->town_num = inner_town_num;
1972 client_ptr->town_num = old_town_num;
1973 do_cmd_visuals(client_ptr, process_autopick_file_command);
1974 client_ptr->town_num = inner_town_num;
1979 client_ptr->town_num = old_town_num;
1980 do_cmd_colors(client_ptr, process_autopick_file_command);
1981 client_ptr->town_num = inner_town_num;
1987 (void)combine_and_reorder_home(STORE_HOME);
1988 do_cmd_redraw(client_ptr);
1989 display_store(client_ptr);
2004 do_cmd_feeling(client_ptr);
2009 do_cmd_message_one();
2019 do_cmd_diary(client_ptr);
2024 do_cmd_knowledge(client_ptr);
2029 do_cmd_load_screen();
2034 do_cmd_save_screen(client_ptr, process_autopick_file_command);
2039 if ((cur_store_num == STORE_MUSEUM) && (command_cmd == 'r'))
2041 museum_remove_object(client_ptr);
2045 msg_print(_("そのコマンドは店の中では使えません。", "That command does not work in stores."));
2055 * @brief 店舗処理全体のメインルーチン /
2056 * Enter a store, and interact with it. *
2057 * @param player_ptr プレーヤーへの参照ポインタ
2061 * Note that we use the standard "request_command()" function
2062 * to get a command, allowing us to use "command_arg" and all
2063 * command macros and other nifty stuff, but we use the special
2064 * "shopping" argument, to force certain commands to be converted
2065 * into other commands, normally, we convert "p" (pray) and "m"
2066 * (cast magic) into "g" (get), and "s" (search) into "d" (drop).
2069 void do_cmd_store(player_type *player_ptr)
2071 if (player_ptr->wild_mode) return;
2073 Term_get_size(&w, &h);
2075 xtra_stock = MIN(14 + 26, ((h > 24) ? (h - 24) : 0));
2076 store_bottom = MIN_STOCK + xtra_stock;
2079 g_ptr = &player_ptr->current_floor_ptr->grid_array[player_ptr->y][player_ptr->x];
2081 if (!cave_have_flag_grid(g_ptr, FF_STORE))
2083 msg_print(_("ここには店がありません。", "You see no store here."));
2087 int which = f_info[g_ptr->feat].subtype;
2088 old_town_num = player_ptr->town_num;
2089 if ((which == STORE_HOME) || (which == STORE_MUSEUM)) player_ptr->town_num = 1;
2090 if (player_ptr->current_floor_ptr->dun_level) player_ptr->town_num = NO_TOWN;
2091 inner_town_num = player_ptr->town_num;
2093 if ((town_info[player_ptr->town_num].store[which].store_open >= current_world_ptr->game_turn) ||
2096 msg_print(_("ドアに鍵がかかっている。", "The doors are locked."));
2097 player_ptr->town_num = old_town_num;
2101 int maintain_num = (current_world_ptr->game_turn - town_info[player_ptr->town_num].store[which].last_visit) / (TURNS_PER_TICK * STORE_TICKS);
2102 if (maintain_num > 10)
2106 for (int i = 0; i < maintain_num; i++)
2107 store_maint(player_ptr, player_ptr->town_num, which);
2109 town_info[player_ptr->town_num].store[which].last_visit = current_world_ptr->game_turn;
2112 forget_lite(player_ptr->current_floor_ptr);
2113 forget_view(player_ptr->current_floor_ptr);
2114 current_world_ptr->character_icky = TRUE;
2118 get_com_no_macros = TRUE;
2119 cur_store_num = which;
2120 cur_store_feat = g_ptr->feat;
2121 st_ptr = &town_info[player_ptr->town_num].store[cur_store_num];
2122 ot_ptr = &owners[cur_store_num][st_ptr->owner];
2124 play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_BUILD);
2125 display_store(player_ptr);
2126 leave_store = FALSE;
2128 while (!leave_store)
2131 clear_from(20 + xtra_stock);
2132 prt(_(" ESC) 建物から出る", " ESC) Exit from Building."), 21 + xtra_stock, 0);
2133 if (st_ptr->stock_num > store_bottom)
2135 prt(_(" -)前ページ", " -) Previous page"), 22 + xtra_stock, 0);
2136 prt(_(" スペース) 次ページ", " SPACE) Next page"), 23 + xtra_stock, 0);
2139 if (cur_store_num == STORE_HOME)
2141 prt(_("g) アイテムを取る", "g) Get an item."), 21 + xtra_stock, 27);
2142 prt(_("d) アイテムを置く", "d) Drop an item."), 22 + xtra_stock, 27);
2143 prt(_("x) 家のアイテムを調べる", "x) eXamine an item in the home."), 23 + xtra_stock, 27);
2145 else if (cur_store_num == STORE_MUSEUM)
2147 prt(_("d) アイテムを置く", "d) Drop an item."), 21 + xtra_stock, 27);
2148 prt(_("r) アイテムの展示をやめる", "r) order to Remove an item."), 22 + xtra_stock, 27);
2149 prt(_("x) 博物館のアイテムを調べる", "x) eXamine an item in the museum."), 23 + xtra_stock, 27);
2153 prt(_("p) 商品を買う", "p) Purchase an item."), 21 + xtra_stock, 30);
2154 prt(_("s) アイテムを売る", "s) Sell an item."), 22 + xtra_stock, 30);
2155 prt(_("x) 商品を調べる", "x) eXamine an item in the shop"), 23 + xtra_stock, 30);
2158 prt(_("i/e) 持ち物/装備の一覧", "i/e) Inventry/Equipment list"), 21 + xtra_stock, 56);
2159 if (rogue_like_commands)
2161 prt(_("w/T) 装備する/はずす", "w/T) Wear/Take off equipment"), 22 + xtra_stock, 56);
2165 prt(_("w/t) 装備する/はずす", "w/t) Wear/Take off equipment"), 22 + xtra_stock, 56);
2168 prt(_("コマンド:", "You may: "), 20 + xtra_stock, 0);
2169 request_command(player_ptr, TRUE);
2170 store_process_command(player_ptr);
2173 * Hack -- To redraw missiles damage and prices in store
2174 * If player's charisma changes, or if player changes a bow, PU_BONUS is set
2176 bool need_redraw_store_inv = (player_ptr->update & PU_BONUS) ? TRUE : FALSE;
2177 current_world_ptr->character_icky = TRUE;
2178 handle_stuff(player_ptr);
2179 if (player_ptr->inventory_list[INVEN_PACK].k_idx)
2181 INVENTORY_IDX item = INVEN_PACK;
2182 object_type *o_ptr = &player_ptr->inventory_list[item];
2183 if (cur_store_num != STORE_HOME)
2185 if (cur_store_num == STORE_MUSEUM)
2186 msg_print(_("ザックからアイテムがあふれそうなので、あわてて博物館から出た...", "Your pack is so full that you flee the Museum..."));
2188 msg_print(_("ザックからアイテムがあふれそうなので、あわてて店から出た...", "Your pack is so full that you flee the store..."));
2192 else if (!store_check_num(o_ptr))
2194 msg_print(_("ザックからアイテムがあふれそうなので、あわてて家から出た...", "Your pack is so full that you flee your home..."));
2202 GAME_TEXT o_name[MAX_NLEN];
2203 msg_print(_("ザックからアイテムがあふれてしまった!", "Your pack overflows!"));
2205 object_copy(q_ptr, o_ptr);
2206 object_desc(player_ptr, o_name, q_ptr, 0);
2207 msg_format(_("%sが落ちた。(%c)", "You drop %s (%c)."), o_name, index_to_label(item));
2208 vary_item(player_ptr, item, -255);
2209 handle_stuff(player_ptr);
2211 item_pos = home_carry(player_ptr, q_ptr);
2214 store_top = (item_pos / store_bottom) * store_bottom;
2215 display_store_inventory(player_ptr);
2220 if (need_redraw_store_inv) display_store_inventory(player_ptr);
2222 if (st_ptr->store_open >= current_world_ptr->game_turn) leave_store = TRUE;
2225 select_floor_music(player_ptr);
2226 player_ptr->town_num = old_town_num;
2227 take_turn(player_ptr, 100);
2228 current_world_ptr->character_icky = FALSE;
2230 command_see = FALSE;
2231 get_com_no_macros = FALSE;
2236 player_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
2237 player_ptr->update |= (PU_MONSTERS);
2238 player_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_EQUIPPY);
2239 player_ptr->redraw |= (PR_MAP);
2240 player_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
2245 * @brief 現在の町の店主を交代させる /
2246 * Shuffle one of the stores.
2247 * @param which 店舗種類のID
2250 void store_shuffle(player_type *player_ptr, int which)
2252 if (which == STORE_HOME) return;
2253 if (which == STORE_MUSEUM) return;
2255 cur_store_num = which;
2256 st_ptr = &town_info[player_ptr->town_num].store[cur_store_num];
2257 int j = st_ptr->owner;
2260 st_ptr->owner = (byte)randint0(MAX_OWNERS);
2261 if (j == st_ptr->owner) continue;
2263 for (i = 1; i < max_towns; i++)
2265 if (i == player_ptr->town_num) continue;
2266 if (st_ptr->owner == town_info[i].store[cur_store_num].owner) break;
2269 if (i == max_towns) break;
2272 ot_ptr = &owners[cur_store_num][st_ptr->owner];
2273 st_ptr->insult_cur = 0;
2274 st_ptr->store_open = 0;
2275 st_ptr->good_buy = 0;
2276 st_ptr->bad_buy = 0;
2277 for (int i = 0; i < st_ptr->stock_num; i++)
2280 o_ptr = &st_ptr->stock[i];
2281 if (object_is_artifact(o_ptr)) continue;
2283 o_ptr->discount = 50;
2284 o_ptr->ident &= ~(IDENT_FIXED);
2285 o_ptr->inscription = quark_add(_("売出中", "on sale"));
2291 * @brief 店の品揃えを変化させる /
2292 * Maintain the inventory at the stores.
2293 * @param player_ptr プレーヤーへの参照ポインタ
2294 * @param town_num 町のID
2295 * @param store_num 店舗種類のID
2298 void store_maint(player_type *player_ptr, int town_num, int store_num)
2300 cur_store_num = store_num;
2301 if (store_num == STORE_HOME) return;
2302 if (store_num == STORE_MUSEUM) return;
2304 st_ptr = &town_info[town_num].store[store_num];
2305 ot_ptr = &owners[store_num][st_ptr->owner];
2306 st_ptr->insult_cur = 0;
2307 if (store_num == STORE_BLACK)
2309 for (INVENTORY_IDX j = st_ptr->stock_num - 1; j >= 0; j--)
2311 object_type *o_ptr = &st_ptr->stock[j];
2312 if (black_market_crap(player_ptr, o_ptr))
2314 store_item_increase(j, 0 - o_ptr->number);
2315 store_item_optimize(j);
2320 INVENTORY_IDX j = st_ptr->stock_num;
2321 j = j - randint1(STORE_TURNOVER);
2322 if (j > STORE_MAX_KEEP) j = STORE_MAX_KEEP;
2323 if (j < STORE_MIN_KEEP) j = STORE_MIN_KEEP;
2326 while (st_ptr->stock_num > j)
2329 j = st_ptr->stock_num;
2330 j = j + randint1(STORE_TURNOVER);
2331 if (j > STORE_MAX_KEEP) j = STORE_MAX_KEEP;
2332 if (j < STORE_MIN_KEEP) j = STORE_MIN_KEEP;
2333 if (j >= st_ptr->stock_size) j = st_ptr->stock_size - 1;
2335 while (st_ptr->stock_num < j) store_create(player_ptr, black_market_crap);
2340 * @brief 店舗情報を初期化する /
2341 * Initialize the stores
2342 * @param town_num 町のID
2343 * @param store_num 店舗種類のID
2346 void store_init(int town_num, int store_num)
2348 cur_store_num = store_num;
2349 st_ptr = &town_info[town_num].store[store_num];
2352 st_ptr->owner = (byte)randint0(MAX_OWNERS);
2354 for (i = 1; i < max_towns; i++)
2356 if (i == town_num) continue;
2357 if (st_ptr->owner == town_info[i].store[store_num].owner) break;
2360 if (i == max_towns) break;
2363 ot_ptr = &owners[store_num][st_ptr->owner];
2365 st_ptr->store_open = 0;
2366 st_ptr->insult_cur = 0;
2367 st_ptr->good_buy = 0;
2368 st_ptr->bad_buy = 0;
2369 st_ptr->stock_num = 0;
2370 st_ptr->last_visit = -10L * TURNS_PER_TICK * STORE_TICKS;
2371 for (int k = 0; k < st_ptr->stock_size; k++)
2373 object_wipe(&st_ptr->stock[k]);