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"
23 #include "io/write-diary.h"
24 #include "cmd/cmd-basic.h"
25 #include "cmd/cmd-diary.h"
26 #include "cmd/cmd-draw.h"
27 #include "cmd/cmd-dump.h"
28 #include "cmd/cmd-help.h"
29 #include "cmd/cmd-item.h"
30 #include "cmd/cmd-macro.h"
31 #include "cmd/cmd-smith.h"
32 #include "cmd/cmd-visuals.h"
33 #include "cmd/cmd-zapwand.h"
34 #include "cmd/cmd-magiceat.h"
38 #include "cmd-spell.h"
40 #include "player-status.h"
41 #include "player-class.h"
42 #include "player-inventory.h"
43 #include "object-flavor.h"
44 #include "object-hook.h"
45 #include "floor-events.h"
48 #include "player-effects.h"
49 #include "player-race.h"
52 #include "objectkind.h"
54 #include "floor-town.h"
56 #include "view-mainwindow.h"
61 static int store_top = 0;
62 static int store_bottom = 0;
63 static int xtra_stock = 0;
64 static store_type *st_ptr = NULL;
65 static const owner_type *ot_ptr = NULL;
66 static s16b old_town_num = 0;
67 static s16b inner_town_num = 0;
70 * We store the current "store feat" here so everyone can access it
72 static int cur_store_feat;
75 * @brief 店舗価格を決定する. 無料にはならない /
76 * Determine the price of an item (qty one) in a store.
77 * @param o_ptr 店舗に並べるオブジェクト構造体の参照ポインタ
79 * @param flip TRUEならば店主にとっての買取価格、FALSEなら売出価格を計算
83 * This function takes into account the player's charisma, and the
84 * shop-keepers friendliness, and the shop-keeper's base greed, but
85 * never lets a shop-keeper lose money in a transaction.
86 * The "greed" value should exceed 100 when the player is "buying" the
87 * item, and should be less than 100 when the player is "selling" it.
88 * Hack -- the black market always charges twice as much as it should.
89 * Charisma adjustment runs from 80 to 130
90 * Racial adjustment runs from 95 to 130
91 * Since greed/charisma/racial adjustments are centered at 100, we need
92 * to adjust (by 200) to extract a usable multiplier. Note that the
93 * "greed" value is always something (?).
96 static PRICE price_item(player_type *player_ptr, object_type *o_ptr, int greed, bool flip)
98 PRICE price = object_value(o_ptr);
99 if (price <= 0) return (0L);
101 int factor = rgold_adj[ot_ptr->owner_race][player_ptr->prace];
102 factor += adj_chr_gold[player_ptr->stat_ind[A_CHR]];
106 adjust = 100 + (300 - (greed + factor));
107 if (adjust > 100) adjust = 100;
108 if (cur_store_num == STORE_BLACK)
111 price = (price * adjust + 50L) / 100L;
115 adjust = 100 + ((greed + factor) - 300);
116 if (adjust < 100) adjust = 100;
117 if (cur_store_num == STORE_BLACK)
120 price = (s32b)(((u32b)price * (u32b)adjust + 50UL) / 100UL);
123 if (price <= 0L) return (1L);
129 * @brief 安価な消耗品の販売数を増やし、低確率で割引にする /
130 * Certain "cheap" objects should be created in "piles"
131 * @param o_ptr 店舗に並べるオブジェクト構造体の参照ポインタ
135 * Some objects can be sold at a "discount" (in small piles)
138 static void mass_produce(object_type *o_ptr)
141 PRICE cost = object_value(o_ptr);
148 if (cost <= 5L) size += damroll(3, 5);
149 if (cost <= 20L) size += damroll(3, 5);
150 if (cost <= 50L) size += damroll(2, 2);
156 if (cost <= 60L) size += damroll(3, 5);
157 if (cost <= 240L) size += damroll(1, 5);
158 if (o_ptr->sval == SV_SCROLL_STAR_IDENTIFY) size += damroll(3, 5);
159 if (o_ptr->sval == SV_SCROLL_STAR_REMOVE_CURSE) size += damroll(1, 4);
163 case TV_SORCERY_BOOK:
171 case TV_CRUSADE_BOOK:
173 case TV_HISSATSU_BOOK:
176 if (cost <= 50L) size += damroll(2, 3);
177 if (cost <= 500L) size += damroll(1, 3);
194 if (object_is_artifact(o_ptr)) break;
195 if (object_is_ego(o_ptr)) break;
196 if (cost <= 10L) size += damroll(3, 5);
197 if (cost <= 100L) size += damroll(3, 5);
205 if (cost <= 5L) size += damroll(5, 5);
206 if (cost <= 50L) size += damroll(5, 5);
207 if (cost <= 500L) size += damroll(5, 5);
212 if (cost <= 100L) size += damroll(2, 2);
213 if (cost <= 1000L) size += damroll(2, 2);
225 * Because many rods (and a few wands and staffs) are useful mainly
226 * in quantity, the Black Market will occasionally have a bunch of
233 if ((cur_store_num == STORE_BLACK) && one_in_(3))
235 if (cost < 1601L) size += damroll(1, 5);
236 else if (cost < 3201L) size += damroll(1, 3);
242 DISCOUNT_RATE discount = 0;
247 else if (one_in_(25))
251 else if (one_in_(150))
255 else if (one_in_(300))
259 else if (one_in_(500))
269 o_ptr->discount = discount;
270 o_ptr->number = size - (size * discount / 100);
271 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
273 o_ptr->pval *= (PARAMETER_VALUE)o_ptr->number;
279 * @brief 店舗に並べた品を同一品であるかどうか判定する /
280 * Determine if a store item can "absorb" another item
281 * @param o_ptr 判定するオブジェクト構造体の参照ポインタ1
282 * @param j_ptr 判定するオブジェクト構造体の参照ポインタ2
283 * @return 同一扱いできるならTRUEを返す
286 * See "object_similar()" for the same function for the "player"
289 static bool store_object_similar(object_type *o_ptr, object_type *j_ptr)
291 if (o_ptr == j_ptr) return 0;
292 if (o_ptr->k_idx != j_ptr->k_idx) return 0;
293 if ((o_ptr->pval != j_ptr->pval) && (o_ptr->tval != TV_WAND) && (o_ptr->tval != TV_ROD)) return 0;
294 if (o_ptr->to_h != j_ptr->to_h) return 0;
295 if (o_ptr->to_d != j_ptr->to_d) return 0;
296 if (o_ptr->to_a != j_ptr->to_a) return 0;
297 if (o_ptr->name2 != j_ptr->name2) return 0;
298 if (object_is_artifact(o_ptr) || object_is_artifact(j_ptr)) return 0;
299 for (int i = 0; i < TR_FLAG_SIZE; i++)
300 if (o_ptr->art_flags[i] != j_ptr->art_flags[i]) return 0;
301 if (o_ptr->xtra1 || j_ptr->xtra1) return 0;
302 if (o_ptr->timeout || j_ptr->timeout) return 0;
303 if (o_ptr->ac != j_ptr->ac) return 0;
304 if (o_ptr->dd != j_ptr->dd) return 0;
305 if (o_ptr->ds != j_ptr->ds) return 0;
306 if (o_ptr->tval == TV_CHEST) return 0;
307 if (o_ptr->tval == TV_STATUE) return 0;
308 if (o_ptr->tval == TV_CAPTURE) return 0;
309 if (o_ptr->discount != j_ptr->discount) return 0;
315 * @brief 店舗に並べた品を重ね合わせできるかどうか判定する /
316 * Allow a store item to absorb another item
317 * @param o_ptr 判定するオブジェクト構造体の参照ポインタ1
318 * @param j_ptr 判定するオブジェクト構造体の参照ポインタ2
319 * @return 重ね合わせできるならTRUEを返す
322 * See "object_similar()" for the same function for the "player"
325 static void store_object_absorb(object_type *o_ptr, object_type *j_ptr)
327 int max_num = (o_ptr->tval == TV_ROD) ?
328 MIN(99, MAX_SHORT / k_info[o_ptr->k_idx].pval) : 99;
329 int total = o_ptr->number + j_ptr->number;
330 int diff = (total > max_num) ? total - max_num : 0;
331 o_ptr->number = (total > max_num) ? max_num : total;
332 if (o_ptr->tval == TV_ROD)
334 o_ptr->pval += j_ptr->pval * (j_ptr->number - diff) / j_ptr->number;
337 if (o_ptr->tval == TV_WAND)
339 o_ptr->pval += j_ptr->pval * (j_ptr->number - diff) / j_ptr->number;
345 * @brief 店舗に品を置くスペースがあるかどうかの判定を返す /
346 * Check to see if the shop will be carrying too many objects -RAK-
347 * @param o_ptr 店舗に置きたいオブジェクト構造体の参照ポインタ
348 * @return 置き場がないなら0、重ね合わせできるアイテムがあるなら-1、スペースがあるなら1を返す。
351 * Note that the shop, just like a player, will not accept things
352 * it cannot hold. Before, one could "nuke" potions this way.
353 * Return value is now int:
355 * -1 : Can be combined to existing slot.
356 * 1 : Cannot be combined but there are empty spaces.
359 static int store_check_num(object_type *o_ptr)
362 if ((cur_store_num == STORE_HOME) || (cur_store_num == STORE_MUSEUM))
364 bool old_stack_force_notes = stack_force_notes;
365 bool old_stack_force_costs = stack_force_costs;
367 if (cur_store_num != STORE_HOME)
369 stack_force_notes = FALSE;
370 stack_force_costs = FALSE;
373 for (int i = 0; i < st_ptr->stock_num; i++)
375 j_ptr = &st_ptr->stock[i];
376 if (object_similar(j_ptr, o_ptr))
378 if (cur_store_num != STORE_HOME)
380 stack_force_notes = old_stack_force_notes;
381 stack_force_costs = old_stack_force_costs;
388 if (cur_store_num != STORE_HOME)
390 stack_force_notes = old_stack_force_notes;
391 stack_force_costs = old_stack_force_costs;
396 for (int i = 0; i < st_ptr->stock_num; i++)
398 j_ptr = &st_ptr->stock[i];
399 if (store_object_similar(j_ptr, o_ptr)) return -1;
403 /* Free space is always usable */
405 * オプション powerup_home が設定されていると
408 if ((cur_store_num == STORE_HOME) && (powerup_home == FALSE))
410 if (st_ptr->stock_num < ((st_ptr->stock_size) / 10))
417 if (st_ptr->stock_num < st_ptr->stock_size)
428 * @brief オブジェクトが祝福されているかの判定を返す /
429 * @param o_ptr 判定したいオブジェクト構造体の参照ポインタ
430 * @return アイテムが祝福されたアイテムならばTRUEを返す
432 static bool is_blessed_item(object_type *o_ptr)
434 BIT_FLAGS flgs[TR_FLAG_SIZE];
435 object_flags(o_ptr, flgs);
436 if (have_flag(flgs, TR_BLESSED)) return TRUE;
442 * @brief オブジェクトが所定の店舗で引き取れるかどうかを返す /
443 * Determine if the current store will purchase the given item
444 * @param o_ptr 判定したいオブジェクト構造体の参照ポインタ
445 * @return アイテムが買い取れるならばTRUEを返す
447 * Note that a shop-keeper must refuse to buy "worthless" items
449 static bool store_will_buy(object_type *o_ptr)
451 if ((cur_store_num == STORE_HOME) || (cur_store_num == STORE_MUSEUM)) return TRUE;
452 switch (cur_store_num)
459 if (o_ptr->sval != SV_POTION_WATER) return FALSE;
514 case TV_HISSATSU_BOOK:
518 if (o_ptr->sval == SV_WIZSTAFF) return FALSE;
532 case TV_CRUSADE_BOOK:
542 monster_race *r_ptr = &r_info[o_ptr->pval];
543 if (!(r_ptr->flags3 & RF3_EVIL))
545 if (r_ptr->flags3 & RF3_GOOD) break;
546 if (r_ptr->flags3 & RF3_ANIMAL) break;
547 if (my_strchr("?!", r_ptr->d_char)) break;
553 if (is_blessed_item(o_ptr)) break;
561 case STORE_ALCHEMIST:
578 case TV_SORCERY_BOOK:
599 if (o_ptr->sval == SV_WIZSTAFF) break;
612 case TV_SORCERY_BOOK:
621 case TV_CRUSADE_BOOK:
633 if (object_value(o_ptr) <= 0) return FALSE;
639 * @brief 現在の町の指定された店舗のアイテムを整理する /
640 * Combine and reorder items in store.
641 * @param store_num 店舗ID
642 * @return 実際に整理が行われたならばTRUEを返す。
644 bool combine_and_reorder_home(int store_num)
646 store_type *old_st_ptr = st_ptr;
647 st_ptr = &town_info[1].store[store_num];
649 if (store_num != STORE_HOME)
651 stack_force_notes = FALSE;
652 stack_force_costs = FALSE;
655 bool combined = TRUE;
659 for (int i = st_ptr->stock_num - 1; i > 0; i--)
662 o_ptr = &st_ptr->stock[i];
663 if (!o_ptr->k_idx) continue;
664 for (int j = 0; j < i; j++)
667 j_ptr = &st_ptr->stock[j];
668 if (!j_ptr->k_idx) continue;
671 * Get maximum number of the stack if these
672 * are similar, get zero otherwise.
674 int max_num = object_similar_part(j_ptr, o_ptr);
675 if (max_num == 0 || j_ptr->number >= max_num) continue;
677 if (o_ptr->number + j_ptr->number <= max_num)
679 object_absorb(j_ptr, o_ptr);
682 for (k = i; k < st_ptr->stock_num; k++)
684 st_ptr->stock[k] = st_ptr->stock[k + 1];
687 object_wipe(&st_ptr->stock[k]);
692 ITEM_NUMBER old_num = o_ptr->number;
693 ITEM_NUMBER remain = j_ptr->number + o_ptr->number - max_num;
694 object_absorb(j_ptr, o_ptr);
695 o_ptr->number = remain;
696 if (o_ptr->tval == TV_ROD)
698 o_ptr->pval = o_ptr->pval * remain / old_num;
699 o_ptr->timeout = o_ptr->timeout * remain / old_num;
701 else if (o_ptr->tval == TV_WAND)
703 o_ptr->pval = o_ptr->pval * remain / old_num;
714 for (int i = 0; i < st_ptr->stock_num; i++)
717 o_ptr = &st_ptr->stock[i];
718 if (!o_ptr->k_idx) continue;
720 s32b o_value = object_value(o_ptr);
722 for (j = 0; j < st_ptr->stock_num; j++)
724 if (object_sort_comp(o_ptr, o_value, &st_ptr->stock[j])) break;
727 if (j >= i) continue;
733 object_copy(j_ptr, &st_ptr->stock[i]);
734 for (int k = i; k > j; k--)
736 object_copy(&st_ptr->stock[k], &st_ptr->stock[k - 1]);
739 object_copy(&st_ptr->stock[j], j_ptr);
743 bool old_stack_force_notes = stack_force_notes;
744 bool old_stack_force_costs = stack_force_costs;
745 if (store_num != STORE_HOME)
747 stack_force_notes = old_stack_force_notes;
748 stack_force_costs = old_stack_force_costs;
756 * @brief 我が家にオブジェクトを加える /
757 * Add the item "o_ptr" to the inventory of the "Home"
758 * @param o_ptr 加えたいオブジェクトの構造体参照ポインタ
762 * In all cases, return the slot (or -1) where the object was placed
763 * Note that this is a hacked up version of "inven_carry()".
764 * Also note that it may not correctly "adapt" to "knowledge" bacoming
765 * known, the player may have to pick stuff up and drop it again.
768 static int home_carry(player_type *player_ptr, object_type *o_ptr)
770 if (cur_store_num != STORE_HOME)
772 stack_force_notes = FALSE;
773 stack_force_costs = FALSE;
776 bool old_stack_force_notes = stack_force_notes;
777 bool old_stack_force_costs = stack_force_costs;
778 for (int slot = 0; slot < st_ptr->stock_num; slot++)
781 j_ptr = &st_ptr->stock[slot];
782 if (object_similar(j_ptr, o_ptr))
784 object_absorb(j_ptr, o_ptr);
785 if (cur_store_num != STORE_HOME)
787 stack_force_notes = old_stack_force_notes;
788 stack_force_costs = old_stack_force_costs;
795 if (cur_store_num != STORE_HOME)
797 stack_force_notes = old_stack_force_notes;
798 stack_force_costs = old_stack_force_costs;
803 * 隠し機能: オプション powerup_home が設定されていると
806 if ((cur_store_num != STORE_HOME) || (powerup_home == TRUE))
808 if (st_ptr->stock_num >= st_ptr->stock_size)
815 if (st_ptr->stock_num >= ((st_ptr->stock_size) / 10))
821 PRICE value = object_value(o_ptr);
823 for (slot = 0; slot < st_ptr->stock_num; slot++)
825 if (object_sort_comp(o_ptr, value, &st_ptr->stock[slot])) break;
828 for (int i = st_ptr->stock_num; i > slot; i--)
830 st_ptr->stock[i] = st_ptr->stock[i - 1];
834 st_ptr->stock[slot] = *o_ptr;
835 chg_virtue(player_ptr, V_SACRIFICE, -1);
836 (void)combine_and_reorder_home(cur_store_num);
842 * @brief 店舗にオブジェクトを加える /
843 * Add the item "o_ptr" to a real stores inventory.
844 * @param o_ptr 加えたいオブジェクトの構造体参照ポインタ
848 * In all cases, return the slot (or -1) where the object was placed
849 * Note that this is a hacked up version of "inven_carry()".
850 * Also note that it may not correctly "adapt" to "knowledge" bacoming
851 * known, the player may have to pick stuff up and drop it again.
854 static int store_carry(object_type *o_ptr)
856 PRICE value = object_value(o_ptr);
857 if (value <= 0) return -1;
858 o_ptr->ident |= IDENT_FULL_KNOWN;
859 o_ptr->inscription = 0;
860 o_ptr->feeling = FEEL_NONE;
862 for (slot = 0; slot < st_ptr->stock_num; slot++)
865 j_ptr = &st_ptr->stock[slot];
866 if (store_object_similar(j_ptr, o_ptr))
868 store_object_absorb(j_ptr, o_ptr);
873 if (st_ptr->stock_num >= st_ptr->stock_size) return -1;
875 for (slot = 0; slot < st_ptr->stock_num; slot++)
878 j_ptr = &st_ptr->stock[slot];
879 if (o_ptr->tval > j_ptr->tval) break;
880 if (o_ptr->tval < j_ptr->tval) continue;
881 if (o_ptr->sval < j_ptr->sval) break;
882 if (o_ptr->sval > j_ptr->sval) continue;
883 if (o_ptr->tval == TV_ROD)
885 if (o_ptr->pval < j_ptr->pval) break;
886 if (o_ptr->pval > j_ptr->pval) continue;
889 PRICE j_value = object_value(j_ptr);
890 if (value > j_value) break;
891 if (value < j_value) continue;
894 for (int i = st_ptr->stock_num; i > slot; i--)
896 st_ptr->stock[i] = st_ptr->stock[i - 1];
900 st_ptr->stock[slot] = *o_ptr;
906 * @brief 店舗のオブジェクト数を増やす /
907 * Add the item "o_ptr" to a real stores inventory.
908 * @param item 増やしたいアイテムのID
913 * Increase, by a given amount, the number of a certain item
914 * in a certain store. This can result in zero items.
916 * @todo numは本来ITEM_NUMBER型にしたい。
918 static void store_item_increase(INVENTORY_IDX item, int num)
921 o_ptr = &st_ptr->stock[item];
922 int cnt = o_ptr->number + num;
923 if (cnt > 255) cnt = 255;
924 else if (cnt < 0) cnt = 0;
926 num = cnt - o_ptr->number;
927 o_ptr->number += (ITEM_NUMBER)num;
932 * @brief 店舗のオブジェクト数を削除する /
933 * Remove a slot if it is empty
934 * @param item 削除したいアイテムのID
937 static void store_item_optimize(INVENTORY_IDX item)
940 o_ptr = &st_ptr->stock[item];
941 if (!o_ptr->k_idx) return;
942 if (o_ptr->number) return;
945 for (int j = item; j < st_ptr->stock_num; j++)
947 st_ptr->stock[j] = st_ptr->stock[j + 1];
950 object_wipe(&st_ptr->stock[st_ptr->stock_num]);
955 * @brief ブラックマーケット用の無価値品の排除判定 /
956 * This function will keep 'crap' out of the black market.
957 * @param player_ptr プレーヤーへの参照ポインタ
958 * @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
959 * @return ブラックマーケットにとって無価値な品ならばTRUEを返す
962 * Crap is defined as any item that is "available" elsewhere
963 * Based on a suggestion by "Lee Vogt" <lvogt@cig.mcel.mot.com>
966 static bool black_market_crap(player_type *player_ptr, object_type *o_ptr)
968 if (object_is_ego(o_ptr)) return FALSE;
970 if (o_ptr->to_a > 0) return FALSE;
971 if (o_ptr->to_h > 0) return FALSE;
972 if (o_ptr->to_d > 0) return FALSE;
974 for (int i = 0; i < MAX_STORES; i++)
976 if (i == STORE_HOME) continue;
977 if (i == STORE_MUSEUM) continue;
979 for (int j = 0; j < town_info[player_ptr->town_num].store[i].stock_num; j++)
981 object_type *j_ptr = &town_info[player_ptr->town_num].store[i].stock[j];
982 if (o_ptr->k_idx == j_ptr->k_idx) return TRUE;
991 * @brief 店舗の品揃え変化のためにアイテムを削除する /
992 * Attempt to delete (some of) a random item from the store
996 * Hack -- we attempt to "maintain" piles of items when possible.
999 static void store_delete(void)
1001 INVENTORY_IDX what = (INVENTORY_IDX)randint0(st_ptr->stock_num);
1002 int num = st_ptr->stock[what].number;
1003 if (randint0(100) < 50) num = (num + 1) / 2;
1004 if (randint0(100) < 50) num = 1;
1005 if ((st_ptr->stock[what].tval == TV_ROD) || (st_ptr->stock[what].tval == TV_WAND))
1007 st_ptr->stock[what].pval -= num * st_ptr->stock[what].pval / st_ptr->stock[what].number;
1010 store_item_increase(what, -num);
1011 store_item_optimize(what);
1016 * @brief 店舗の品揃え変化のためにアイテムを追加する /
1017 * Creates a random item and gives it to a store
1018 * @param player_ptr プレーヤーへの参照ポインタ
1022 * This algorithm needs to be rethought. A lot.
1023 * Currently, "normal" stores use a pre-built array.
1024 * Note -- the "level" given to "obj_get_num()" is a "favored"
1025 * level, that is, there is a much higher chance of getting
1026 * items with a level approaching that of the given level...
1027 * Should we check for "permission" to have the given item?
1030 static void store_create(player_type *player_ptr)
1032 if (st_ptr->stock_num >= st_ptr->stock_size) return;
1034 for (int tries = 0; tries < 4; tries++)
1038 if (cur_store_num == STORE_BLACK)
1040 /* Pick a level for object/magic */
1041 level = 25 + randint0(25);
1043 /* Random item (usually of given level) */
1044 i = get_obj_num(player_ptr, level, 0x00000000);
1046 /* Handle failure */
1047 if (i == 0) continue;
1051 i = st_ptr->table[randint0(st_ptr->table_num)];
1052 level = rand_range(1, STORE_OBJ_LEVEL);
1058 object_prep(q_ptr, i);
1059 apply_magic(player_ptr, q_ptr, level, AM_NO_FIXED_ART);
1060 if (!store_will_buy(q_ptr)) continue;
1062 if (q_ptr->tval == TV_LITE)
1064 if (q_ptr->sval == SV_LITE_TORCH) q_ptr->xtra4 = FUEL_TORCH / 2;
1065 if (q_ptr->sval == SV_LITE_LANTERN) q_ptr->xtra4 = FUEL_LAMP / 2;
1068 object_known(q_ptr);
1069 q_ptr->ident |= IDENT_STORE;
1070 if (q_ptr->tval == TV_CHEST) continue;
1072 if (cur_store_num == STORE_BLACK)
1074 if (black_market_crap(player_ptr, q_ptr)) continue;
1075 if (object_value(q_ptr) < 10) continue;
1079 if (object_value(q_ptr) <= 0) continue;
1082 mass_produce(q_ptr);
1083 (void)store_carry(q_ptr);
1090 * @brief 店舗の割引対象外にするかどうかを判定 /
1091 * Eliminate need to bargain if player has haggled well in the past
1092 * @param minprice アイテムの最低販売価格
1093 * @return 割引を禁止するならTRUEを返す。
1095 static bool noneedtobargain(PRICE minprice)
1097 PRICE good = st_ptr->good_buy;
1098 PRICE bad = st_ptr->bad_buy;
1099 if (minprice < 10L) return TRUE;
1100 if (good == MAX_SHORT) return TRUE;
1101 if (good > ((3 * bad) + (5 + (minprice / 50)))) return TRUE;
1108 * @brief 店主の持つプレイヤーに対する売買の良し悪し経験を記憶する /
1109 * Update the bargain info
1110 * @param price 実際の取引価格
1111 * @param minprice 店主の提示した価格
1115 static void updatebargain(PRICE price, PRICE minprice, int num)
1117 if (!manual_haggle) return;
1118 if ((minprice / num) < 10L) return;
1119 if (price == minprice)
1121 if (st_ptr->good_buy < MAX_SHORT)
1128 if (st_ptr->bad_buy < MAX_SHORT)
1137 * @brief 店の商品リストを再表示する /
1138 * Re-displays a single store entry
1139 * @param player_ptr プレーヤーへの参照ポインタ
1143 static void display_entry(player_type *player_ptr, int pos)
1146 o_ptr = &st_ptr->stock[pos];
1147 int i = (pos % store_bottom);
1149 /* Label it, clear the line --(-- */
1151 (void)sprintf(out_val, "%c) ", ((i > 25) ? toupper(I2A(i - 26)) : I2A(i)));
1152 prt(out_val, i + 6, 0);
1155 if (show_item_graph)
1157 TERM_COLOR a = object_attr(o_ptr);
1158 SYMBOL_CODE c = object_char(o_ptr);
1160 Term_queue_bigchar(cur_col, i + 6, a, c, 0, 0);
1161 if (use_bigtile) cur_col++;
1166 /* Describe an item in the home */
1168 if ((cur_store_num == STORE_HOME) || (cur_store_num == STORE_MUSEUM))
1171 if (show_weights) maxwid -= 10;
1173 GAME_TEXT o_name[MAX_NLEN];
1174 object_desc(player_ptr, o_name, o_ptr, 0);
1175 o_name[maxwid] = '\0';
1176 c_put_str(tval_to_attr[o_ptr->tval], o_name, i + 6, cur_col);
1179 WEIGHT wgt = o_ptr->weight;
1180 sprintf(out_val, _("%3d.%1d kg", "%3d.%d lb"), _(lbtokg1(wgt), wgt / 10), _(lbtokg2(wgt), wgt % 10));
1181 put_str(out_val, i + 6, _(67, 68));
1188 if (show_weights) maxwid -= 7;
1190 GAME_TEXT o_name[MAX_NLEN];
1191 object_desc(player_ptr, o_name, o_ptr, 0);
1192 o_name[maxwid] = '\0';
1193 c_put_str(tval_to_attr[o_ptr->tval], o_name, i + 6, cur_col);
1197 int wgt = o_ptr->weight;
1198 sprintf(out_val, "%3d.%1d", _(lbtokg1(wgt), wgt / 10), _(lbtokg2(wgt), wgt % 10));
1199 put_str(out_val, i + 6, _(60, 61));
1203 if (o_ptr->ident & (IDENT_FIXED))
1205 x = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, FALSE);
1206 (void)sprintf(out_val, _("%9ld固", "%9ld F"), (long)x);
1207 put_str(out_val, i + 6, 68);
1213 x = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, FALSE);
1214 if (!noneedtobargain(x)) x += x / 10;
1216 (void)sprintf(out_val, "%9ld ", (long)x);
1217 put_str(out_val, i + 6, 68);
1221 x = price_item(player_ptr, o_ptr, ot_ptr->max_inflate, FALSE);
1222 (void)sprintf(out_val, "%9ld ", (long)x);
1223 put_str(out_val, i + 6, 68);
1228 * @brief 店の商品リストを表示する /
1229 * Displays a store's inventory -RAK-
1230 * @param player_ptr プレーヤーへの参照ポインタ
1233 * All prices are listed as "per individual object". -BEN-
1235 static void display_store_inventory(player_type *player_ptr)
1238 for (k = 0; k < store_bottom; k++)
1240 if (store_top + k >= st_ptr->stock_num) break;
1242 display_entry(player_ptr, store_top + k);
1245 for (int i = k; i < store_bottom + 1; i++)
1248 put_str(_(" ", " "), 5, _(20, 22));
1249 if (st_ptr->stock_num > store_bottom)
1251 prt(_("-続く-", "-more-"), k + 6, 3);
1252 put_str(format(_("(%dページ) ", "(Page %d) "), store_top / store_bottom + 1), 5, _(20, 22));
1255 if (cur_store_num == STORE_HOME || cur_store_num == STORE_MUSEUM)
1257 k = st_ptr->stock_size;
1258 if (cur_store_num == STORE_HOME && !powerup_home) k /= 10;
1260 put_str(format(_("アイテム数: %4d/%4d", "Objects: %4d/%4d"), st_ptr->stock_num, k), 19 + xtra_stock, _(27, 30));
1266 * @brief プレイヤーの所持金を表示する /
1267 * Displays players gold -RAK-
1268 * @param player_ptr プレーヤーへの参照ポインタ
1272 static void store_prt_gold(player_type *player_ptr)
1274 prt(_("手持ちのお金: ", "Gold Remaining: "), 19 + xtra_stock, 53);
1276 sprintf(out_val, "%9ld", (long)player_ptr->au);
1277 prt(out_val, 19 + xtra_stock, 68);
1282 * @brief 店舗情報全体を表示するメインルーチン /
1283 * Displays store (after clearing screen) -RAK-
1284 * @param player_ptr プレーヤーへの参照ポインタ
1288 static void display_store(player_type *player_ptr)
1291 if (cur_store_num == STORE_HOME)
1293 put_str(_("我が家", "Your Home"), 3, 31);
1294 put_str(_("アイテムの一覧", "Item Description"), 5, 4);
1297 put_str(_(" 重さ", "Weight"), 5, 70);
1300 store_prt_gold(player_ptr);
1301 display_store_inventory(player_ptr);
1305 if (cur_store_num == STORE_MUSEUM)
1307 put_str(_("博物館", "Museum"), 3, 31);
1308 put_str(_("アイテムの一覧", "Item Description"), 5, 4);
1311 put_str(_(" 重さ", "Weight"), 5, 70);
1314 store_prt_gold(player_ptr);
1315 display_store_inventory(player_ptr);
1319 concptr store_name = (f_name + f_info[cur_store_feat].name);
1320 concptr owner_name = (ot_ptr->owner_name);
1321 concptr race_name = race_info[ot_ptr->owner_race].title;
1323 sprintf(buf, "%s (%s)", owner_name, race_name);
1324 put_str(buf, 3, 10);
1326 sprintf(buf, "%s (%ld)", store_name, (long)(ot_ptr->max_cost));
1329 put_str(_("商品の一覧", "Item Description"), 5, 5);
1332 put_str(_(" 重さ", "Weight"), 5, 60);
1335 put_str(_(" 価格", "Price"), 5, 72);
1336 store_prt_gold(player_ptr);
1337 display_store_inventory(player_ptr);
1342 * @brief 店舗からアイテムを選択する /
1343 * Get the ID of a store item and return its value -RAK-
1344 * @param com_val 選択IDを返す参照ポインタ
1345 * @param pmt メッセージキャプション
1348 * @return 実際に選択したらTRUE、キャンセルしたらFALSE
1350 static int get_stock(COMMAND_CODE *com_val, concptr pmt, int i, int j)
1352 if (repeat_pull(com_val) && (*com_val >= i) && (*com_val <= j))
1360 char hi = (j > 25) ? toupper(I2A(j - 26)) : I2A(j);
1363 (void)sprintf(out_val, "(%s:%c-%c, ESCで中断) %s",
1364 (((cur_store_num == STORE_HOME) || (cur_store_num == STORE_MUSEUM)) ? "アイテム" : "商品"),
1367 (void)sprintf(out_val, "(Items %c-%c, ESC to exit) %s",
1374 if (!get_com(out_val, &command, FALSE)) break;
1377 if (islower(command))
1379 else if (isupper(command))
1380 k = A2I(tolower(command)) + 26;
1384 if ((k >= i) && (k <= j))
1394 if (command == ESCAPE) return FALSE;
1396 repeat_push(*com_val);
1402 * @brief 店主の不満度を増やし、プレイヤーを締め出す判定と処理を行う /
1403 * Increase the insult counter and get angry if too many -RAK-
1404 * @return プレイヤーを締め出す場合TRUEを返す
1406 static int increase_insults(void)
1408 st_ptr->insult_cur++;
1409 if (st_ptr->insult_cur <= ot_ptr->insult_max) return FALSE;
1413 st_ptr->insult_cur = 0;
1414 st_ptr->good_buy = 0;
1415 st_ptr->bad_buy = 0;
1416 st_ptr->store_open = current_world_ptr->game_turn + TURNS_PER_TICK * TOWN_DAWN / 8 + randint1(TURNS_PER_TICK*TOWN_DAWN / 8);
1423 * @brief 店主の不満度を減らす /
1424 * Decrease insults -RAK-
1425 * @return プレイヤーを締め出す場合TRUEを返す
1427 static void decrease_insults(void)
1429 if (st_ptr->insult_cur) st_ptr->insult_cur--;
1434 * @brief 店主の不満度が増えた場合のみのメッセージを表示する /
1435 * Have insulted while haggling -RAK-
1436 * @return プレイヤーを締め出す場合TRUEを返す
1438 static int haggle_insults(void)
1440 if (increase_insults()) return TRUE;
1447 * Mega-Hack -- Enable "increments"
1449 static bool allow_inc = FALSE;
1452 * Mega-Hack -- Last "increment" during haggling
1454 static s32b last_inc = 0L;
1457 * @brief 交渉価格を確認と認証の是非を行う /
1460 * @param poffer 別途価格提示をした場合の値を返す参照ポインタ
1461 * @param price 現在の交渉価格
1462 * @param final 最終確定価格ならばTRUE
1463 * @return プレイヤーを締め出す場合TRUEを返す
1465 static int get_haggle(concptr pmt, s32b *poffer, PRICE price, int final)
1468 if (!allow_inc) last_inc = 0L;
1472 sprintf(buf, _("%s [承諾] ", "%s [accept] "), pmt);
1474 else if (last_inc < 0)
1476 sprintf(buf, _("%s [-$%ld] ", "%s [-%ld] "), pmt, (long)(ABS(last_inc)));
1478 else if (last_inc > 0)
1480 sprintf(buf, _("%s [+$%ld] ", "%s [+%ld] "), pmt, (long)(ABS(last_inc)));
1484 sprintf(buf, "%s ", pmt);
1488 GAME_TEXT out_val[160];
1493 strcpy(out_val, "");
1496 * Ask the user for a response.
1497 * Don't allow to use numpad as cursor key.
1499 res = askfor_aux(out_val, 32, FALSE);
1501 if (!res) return FALSE;
1504 for (p = out_val; *p == ' '; p++) /* loop */;
1515 if (allow_inc && last_inc)
1517 *poffer += last_inc;
1521 msg_print(_("値がおかしいです。", "Invalid response."));
1526 if ((*p == '+' || *p == '-'))
1548 * @brief 店主がプレイヤーからの交渉価格を判断する /
1549 * Receive an offer (from the player)
1551 * @param poffer 店主からの交渉価格を返す参照ポインタ
1552 * @param last_offer 現在の交渉価格
1553 * @param factor 店主の価格基準倍率
1554 * @param price アイテムの実価値
1555 * @param final 最終価格確定ならばTRUE
1556 * @return プレイヤーの価格に対して不服ならばTRUEを返す /
1557 * Return TRUE if offer is NOT okay
1559 static bool receive_offer(concptr pmt, s32b *poffer, s32b last_offer, int factor, PRICE price, int final)
1563 if (!get_haggle(pmt, poffer, price, final)) return TRUE;
1564 if (((*poffer) * factor) >= (last_offer * factor)) break;
1565 if (haggle_insults()) return TRUE;
1567 (*poffer) = last_offer;
1575 * @brief プレイヤーが購入する時の値切り処理メインルーチン /
1576 * Haggling routine -RAK-
1577 * @param player_ptr プレーヤーへの参照ポインタ
1578 * @param o_ptr オブジェクトの構造体参照ポインタ
1579 * @param price 最終価格を返す参照ポインタ
1580 * @return プレイヤーの価格に対して店主が不服ならばTRUEを返す /
1581 * Return TRUE if purchase is NOT successful
1583 static bool purchase_haggle(player_type *player_ptr, object_type *o_ptr, s32b *price)
1585 s32b cur_ask = price_item(player_ptr, o_ptr, ot_ptr->max_inflate, FALSE);
1586 s32b final_ask = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, FALSE);
1587 int noneed = noneedtobargain(final_ask);
1589 concptr pmt = _("提示価格", "Asking");
1590 if (noneed || !manual_haggle)
1594 msg_print(_("結局この金額にまとまった。", "You eventually agree upon the price."));
1599 msg_print(_("すんなりとこの金額にまとまった。", "You quickly agree upon the price."));
1601 final_ask += final_ask / 10;
1604 cur_ask = final_ask;
1605 pmt = _("最終提示価格", "Final Offer");
1609 cur_ask *= o_ptr->number;
1610 final_ask *= o_ptr->number;
1611 s32b min_per = ot_ptr->haggle_per;
1612 s32b max_per = min_per * 3;
1613 s32b last_offer = object_value(o_ptr) * o_ptr->number;
1614 last_offer = last_offer * (200 - (int)(ot_ptr->max_inflate)) / 100L;
1615 if (last_offer <= 0) last_offer = 1;
1621 bool cancel = FALSE;
1625 bool loop_flag = TRUE;
1627 while (!flag && loop_flag)
1630 (void)sprintf(out_val, "%s : %ld", pmt, (long)cur_ask);
1631 put_str(out_val, 1, 0);
1632 cancel = receive_offer(_("提示する金額? ", "What do you offer? "), &offer, last_offer, 1, cur_ask, final);
1637 else if (offer > cur_ask)
1642 else if (offer == cur_ask)
1655 s32b x1 = 100 * (offer - last_offer) / (cur_ask - last_offer);
1658 if (haggle_insults())
1664 else if (x1 > max_per)
1667 if (x1 < max_per) x1 = max_per;
1670 s32b x2 = rand_range(x1 - 2, x1 + 2);
1671 s32b x3 = ((cur_ask - offer) * x2 / 100L) + 1;
1675 if (cur_ask < final_ask)
1678 cur_ask = final_ask;
1679 pmt = _("最終提示価格", "What do you offer? ");
1683 (void)(increase_insults());
1688 else if (offer >= cur_ask)
1698 (void)sprintf(out_val, _("前回の提示金額: $%ld", "Your last offer: %ld"), (long)last_offer);
1699 put_str(out_val, 1, 39);
1700 say_comment_2(cur_ask, annoyed);
1703 if (cancel) return TRUE;
1705 updatebargain(*price, final_ask, o_ptr->number);
1711 * @brief プレイヤーが売却する時の値切り処理メインルーチン /
1712 * Haggling routine -RAK-
1713 * @param player_ptr プレーヤーへの参照ポインタ
1714 * @param o_ptr オブジェクトの構造体参照ポインタ
1715 * @param price 最終価格を返す参照ポインタ
1716 * @return プレイヤーの価格に対して店主が不服ならばTRUEを返す /
1717 * Return TRUE if purchase is NOT successful
1719 static bool sell_haggle(player_type *player_ptr, object_type *o_ptr, s32b *price)
1721 s32b cur_ask = price_item(player_ptr, o_ptr, ot_ptr->max_inflate, TRUE);
1722 s32b final_ask = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, TRUE);
1723 int noneed = noneedtobargain(final_ask);
1724 s32b purse = (s32b)(ot_ptr->max_cost);
1726 concptr pmt = _("提示金額", "Offer");
1727 if (noneed || !manual_haggle || (final_ask >= purse))
1729 if (!manual_haggle && !noneed)
1731 final_ask -= final_ask / 10;
1734 if (final_ask >= purse)
1736 msg_print(_("即座にこの金額にまとまった。", "You instantly agree upon the price."));
1742 msg_print(_("結局この金額にまとまった。", "You eventually agree upon the price."));
1747 msg_print(_("すんなりとこの金額にまとまった。", "You quickly agree upon the price."));
1751 cur_ask = final_ask;
1753 pmt = _("最終提示金額", "Final Offer");
1756 cur_ask *= o_ptr->number;
1757 final_ask *= o_ptr->number;
1759 s32b min_per = ot_ptr->haggle_per;
1760 s32b max_per = min_per * 3;
1761 s32b last_offer = object_value(o_ptr) * o_ptr->number;
1762 last_offer = last_offer * ot_ptr->max_inflate / 100L;
1768 bool cancel = FALSE;
1777 (void)sprintf(out_val, "%s : %ld", pmt, (long)cur_ask);
1778 put_str(out_val, 1, 0);
1779 cancel = receive_offer(_("提示する価格? ", "What price do you ask? "),
1780 &offer, last_offer, -1, cur_ask, final);
1786 else if (offer < cur_ask)
1791 else if (offer == cur_ask)
1801 if (flag || !loop_flag) break;
1806 s32b x1 = 100 * (last_offer - offer) / (last_offer - cur_ask);
1809 if (haggle_insults())
1815 else if (x1 > max_per)
1818 if (x1 < max_per) x1 = max_per;
1821 s32b x2 = rand_range(x1 - 2, x1 + 2);
1822 s32b x3 = ((offer - cur_ask) * x2 / 100L) + 1;
1826 if (cur_ask > final_ask)
1828 cur_ask = final_ask;
1830 pmt = _("最終提示金額", "Final Offer");
1837 /* 追加 $0 で買い取られてしまうのを防止 By FIRST*/
1840 (void)(increase_insults());
1843 else if (offer <= cur_ask)
1853 (void)sprintf(out_val, _("前回の提示価格 $%ld", "Your last bid %ld"), (long)last_offer);
1854 put_str(out_val, 1, 39);
1855 say_comment_3(cur_ask, annoyed);
1858 if (cancel) return TRUE;
1860 updatebargain(*price, final_ask, o_ptr->number);
1866 * @brief 店からの購入処理のメインルーチン /
1867 * Buy an item from a store -RAK-
1868 * @param player_ptr プレーヤーへの参照ポインタ
1871 static void store_purchase(player_type *player_ptr)
1873 if (cur_store_num == STORE_MUSEUM)
1875 msg_print(_("博物館から取り出すことはできません。", "Museum."));
1879 if (st_ptr->stock_num <= 0)
1881 if (cur_store_num == STORE_HOME)
1882 msg_print(_("我が家には何も置いてありません。", "Your home is empty."));
1884 msg_print(_("現在商品の在庫を切らしています。", "I am currently out of stock."));
1888 int i = (st_ptr->stock_num - store_top);
1889 if (i > store_bottom) i = store_bottom;
1893 /* ブラックマーケットの時は別のメッセージ */
1894 switch (cur_store_num)
1897 sprintf(out_val, "どのアイテムを取りますか? ");
1900 sprintf(out_val, "どれ? ");
1903 sprintf(out_val, "どの品物が欲しいんだい? ");
1907 if (cur_store_num == STORE_HOME)
1909 sprintf(out_val, "Which item do you want to take? ");
1913 sprintf(out_val, "Which item are you interested in? ");
1918 if (!get_stock(&item, out_val, 0, i - 1)) return;
1920 item = item + store_top;
1922 o_ptr = &st_ptr->stock[item];
1923 ITEM_NUMBER amt = 1;
1927 object_copy(j_ptr, o_ptr);
1930 * If a rod or wand, allocate total maximum timeouts or charges
1931 * between those purchased and left on the shelf.
1933 reduce_charges(j_ptr, o_ptr->number - amt);
1934 j_ptr->number = amt;
1935 if (!inven_carry_okay(j_ptr))
1937 msg_print(_("そんなにアイテムを持てない。", "You cannot carry that many different items."));
1941 PRICE best = price_item(player_ptr, j_ptr, ot_ptr->min_inflate, FALSE);
1942 if (o_ptr->number > 1)
1944 if ((cur_store_num != STORE_HOME) &&
1945 (o_ptr->ident & IDENT_FIXED))
1947 msg_format(_("一つにつき $%ldです。", "That costs %ld gold per item."), (long)(best));
1950 amt = get_quantity(NULL, o_ptr->number);
1951 if (amt <= 0) return;
1955 object_copy(j_ptr, o_ptr);
1958 * If a rod or wand, allocate total maximum timeouts or charges
1959 * between those purchased and left on the shelf.
1961 reduce_charges(j_ptr, o_ptr->number - amt);
1962 j_ptr->number = amt;
1963 if (!inven_carry_okay(j_ptr))
1965 msg_print(_("ザックにそのアイテムを入れる隙間がない。", "You cannot carry that many items."));
1970 COMMAND_CODE item_new;
1972 if (cur_store_num == STORE_HOME)
1974 bool combined_or_reordered;
1975 distribute_charges(o_ptr, j_ptr, amt);
1976 item_new = inven_carry(player_ptr, j_ptr);
1977 GAME_TEXT o_name[MAX_NLEN];
1978 object_desc(player_ptr, o_name, &player_ptr->inventory_list[item_new], 0);
1980 msg_format(_("%s(%c)を取った。", "You have %s (%c)."), o_name, index_to_label(item_new));
1981 handle_stuff(player_ptr);
1983 i = st_ptr->stock_num;
1984 store_item_increase(item, -amt);
1985 store_item_optimize(item);
1986 combined_or_reordered = combine_and_reorder_home(STORE_HOME);
1987 if (i == st_ptr->stock_num)
1989 if (combined_or_reordered) display_store_inventory(player_ptr);
1990 else display_entry(player_ptr, item);
1994 if (st_ptr->stock_num == 0) store_top = 0;
1995 else if (store_top >= st_ptr->stock_num) store_top -= store_bottom;
1996 display_store_inventory(player_ptr);
1998 chg_virtue(player_ptr, V_SACRIFICE, 1);
2004 if (o_ptr->ident & (IDENT_FIXED))
2007 price = (best * j_ptr->number);
2011 GAME_TEXT o_name[MAX_NLEN];
2012 object_desc(player_ptr, o_name, j_ptr, 0);
2013 msg_format(_("%s(%c)を購入する。", "Buying %s (%c)."), o_name, I2A(item));
2015 choice = purchase_haggle(player_ptr, j_ptr, &price);
2016 if (st_ptr->store_open >= current_world_ptr->game_turn) return;
2019 if (choice != 0) return;
2020 if (price == (best * j_ptr->number)) o_ptr->ident |= (IDENT_FIXED);
2021 if (player_ptr->au < price)
2023 msg_print(_("お金が足りません。", "You do not have enough gold."));
2027 say_comment_1(player_ptr);
2028 if (cur_store_num == STORE_BLACK)
2029 chg_virtue(player_ptr, V_JUSTICE, -1);
2030 if ((o_ptr->tval == TV_BOTTLE) && (cur_store_num != STORE_HOME))
2031 chg_virtue(player_ptr, V_NATURE, -1);
2035 player_ptr->au -= price;
2036 store_prt_gold(player_ptr);
2037 object_aware(player_ptr, j_ptr);
2038 j_ptr->ident &= ~(IDENT_FIXED);
2039 GAME_TEXT o_name[MAX_NLEN];
2040 object_desc(player_ptr, o_name, j_ptr, 0);
2042 msg_format(_("%sを $%ldで購入しました。", "You bought %s for %ld gold."), o_name, (long)price);
2044 strcpy(record_o_name, o_name);
2045 record_turn = current_world_ptr->game_turn;
2047 if (record_buy) exe_write_diary(player_ptr, DIARY_BUY, 0, o_name);
2048 object_desc(player_ptr, o_name, o_ptr, OD_NAME_ONLY);
2049 if (record_rand_art && o_ptr->art_name)
2050 exe_write_diary(player_ptr, DIARY_ART, 0, o_name);
2052 j_ptr->inscription = 0;
2053 j_ptr->feeling = FEEL_NONE;
2054 j_ptr->ident &= ~(IDENT_STORE);
2055 item_new = inven_carry(player_ptr, j_ptr);
2057 object_desc(player_ptr, o_name, &player_ptr->inventory_list[item_new], 0);
2058 msg_format(_("%s(%c)を手に入れた。", "You have %s (%c)."), o_name, index_to_label(item_new));
2059 autopick_alter_item(player_ptr, item_new, FALSE);
2060 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
2062 o_ptr->pval -= j_ptr->pval;
2065 handle_stuff(player_ptr);
2066 i = st_ptr->stock_num;
2067 store_item_increase(item, -amt);
2068 store_item_optimize(item);
2069 if (st_ptr->stock_num == 0)
2071 if (one_in_(STORE_SHUFFLE))
2074 msg_print(_("店主は引退した。", "The shopkeeper retires."));
2075 store_shuffle(player_ptr, cur_store_num);
2078 sprintf(buf, "%s (%s)",
2079 ot_ptr->owner_name, race_info[ot_ptr->owner_race].title);
2080 put_str(buf, 3, 10);
2081 sprintf(buf, "%s (%ld)",
2082 (f_name + f_info[cur_store_feat].name), (long)(ot_ptr->max_cost));
2087 msg_print(_("店主は新たな在庫を取り出した。", "The shopkeeper brings out some new stock."));
2090 for (i = 0; i < 10; i++)
2092 store_maint(player_ptr, player_ptr->town_num, cur_store_num);
2096 display_store_inventory(player_ptr);
2098 else if (st_ptr->stock_num != i)
2100 if (store_top >= st_ptr->stock_num) store_top -= store_bottom;
2101 display_store_inventory(player_ptr);
2105 display_entry(player_ptr, item);
2111 * @brief 店からの売却処理のメインルーチン /
2112 * Sell an item to the store (or home)
2113 * @param owner_ptr プレーヤーへの参照ポインタ
2116 static void store_sell(player_type *owner_ptr)
2119 if (cur_store_num == STORE_HOME)
2120 q = _("どのアイテムを置きますか? ", "Drop which item? ");
2121 else if (cur_store_num == STORE_MUSEUM)
2122 q = _("どのアイテムを寄贈しますか? ", "Give which item? ");
2124 q = _("どのアイテムを売りますか? ", "Sell which item? ");
2126 item_tester_hook = store_will_buy;
2128 /* 我が家でおかしなメッセージが出るオリジナルのバグを修正 */
2130 if (cur_store_num == STORE_HOME)
2132 s = _("置けるアイテムを持っていません。", "You don't have any item to drop.");
2134 else if (cur_store_num == STORE_MUSEUM)
2136 s = _("寄贈できるアイテムを持っていません。", "You don't have any item to give.");
2140 s = _("欲しい物がないですねえ。", "You have nothing that I want.");
2145 o_ptr = choose_object(owner_ptr, &item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT), 0);
2148 if ((item >= INVEN_RARM) && object_is_cursed(o_ptr))
2150 msg_print(_("ふーむ、どうやらそれは呪われているようだね。", "Hmmm, it seems to be cursed."));
2155 if (o_ptr->number > 1)
2157 amt = get_quantity(NULL, o_ptr->number);
2158 if (amt <= 0) return;
2164 object_copy(q_ptr, o_ptr);
2165 q_ptr->number = amt;
2168 * Hack -- If a rod or wand, allocate total maximum
2169 * timeouts or charges to those being sold. -LM-
2171 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
2173 q_ptr->pval = o_ptr->pval * amt / o_ptr->number;
2176 GAME_TEXT o_name[MAX_NLEN];
2177 object_desc(owner_ptr, o_name, q_ptr, 0);
2179 /* Remove any inscription, feeling for stores */
2180 if ((cur_store_num != STORE_HOME) && (cur_store_num != STORE_MUSEUM))
2182 q_ptr->inscription = 0;
2183 q_ptr->feeling = FEEL_NONE;
2186 /* Is there room in the store (or the home?) */
2187 if (!store_check_num(q_ptr))
2189 if (cur_store_num == STORE_HOME)
2190 msg_print(_("我が家にはもう置く場所がない。", "Your home is full."));
2192 else if (cur_store_num == STORE_MUSEUM)
2193 msg_print(_("博物館はもう満杯だ。", "Museum is full."));
2196 msg_print(_("すいませんが、店にはもう置く場所がありません。", "I have not the room in my store to keep it."));
2202 PRICE price, value, dummy;
2203 if ((cur_store_num != STORE_HOME) && (cur_store_num != STORE_MUSEUM))
2205 msg_format(_("%s(%c)を売却する。", "Selling %s (%c)."), o_name, index_to_label(item));
2208 choice = sell_haggle(owner_ptr, q_ptr, &price);
2209 if (st_ptr->store_open >= current_world_ptr->game_turn) return;
2213 say_comment_1(owner_ptr);
2215 if (cur_store_num == STORE_BLACK)
2216 chg_virtue(owner_ptr, V_JUSTICE, -1);
2218 if ((o_ptr->tval == TV_BOTTLE) && (cur_store_num != STORE_HOME))
2219 chg_virtue(owner_ptr, V_NATURE, 1);
2222 owner_ptr->au += price;
2223 store_prt_gold(owner_ptr);
2224 dummy = object_value(q_ptr) * q_ptr->number;
2226 identify_item(owner_ptr, o_ptr);
2228 object_copy(q_ptr, o_ptr);
2229 q_ptr->number = amt;
2230 q_ptr->ident |= IDENT_STORE;
2233 * Hack -- If a rod or wand, let the shopkeeper know just
2234 * how many charges he really paid for. -LM-
2236 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
2238 q_ptr->pval = o_ptr->pval * amt / o_ptr->number;
2241 value = object_value(q_ptr) * q_ptr->number;
2242 object_desc(owner_ptr, o_name, q_ptr, 0);
2243 msg_format(_("%sを $%ldで売却しました。", "You sold %s for %ld gold."), o_name, (long)price);
2245 if (record_sell) exe_write_diary(owner_ptr, DIARY_SELL, 0, o_name);
2247 if (!((o_ptr->tval == TV_FIGURINE) && (value > 0)))
2249 purchase_analyze(owner_ptr, price, value, dummy);
2253 * Hack -- Allocate charges between those wands or rods sold
2254 * and retained, unless all are being sold. -LM-
2256 distribute_charges(o_ptr, q_ptr, amt);
2258 inven_item_increase(owner_ptr, item, -amt);
2259 inven_item_describe(owner_ptr, item);
2260 if (o_ptr->number > 0)
2261 autopick_alter_item(owner_ptr, item, FALSE);
2263 inven_item_optimize(owner_ptr, item);
2264 handle_stuff(owner_ptr);
2265 int item_pos = store_carry(q_ptr);
2268 store_top = (item_pos / store_bottom) * store_bottom;
2269 display_store_inventory(owner_ptr);
2273 else if (cur_store_num == STORE_MUSEUM)
2275 char o2_name[MAX_NLEN];
2276 object_desc(owner_ptr, o2_name, q_ptr, OD_NAME_ONLY);
2278 if (-1 == store_check_num(q_ptr))
2280 msg_print(_("それと同じ品物は既に博物館にあるようです。", "The Museum already has one of those items."));
2284 msg_print(_("博物館に寄贈したものは取り出すことができません!!", "You cannot take back items which have been donated to the Museum!!"));
2287 if (!get_check(format(_("本当に%sを寄贈しますか?", "Really give %s to the Museum? "), o2_name))) return;
2289 identify_item(owner_ptr, q_ptr);
2290 q_ptr->ident |= IDENT_FULL_KNOWN;
2292 distribute_charges(o_ptr, q_ptr, amt);
2293 msg_format(_("%sを置いた。(%c)", "You drop %s (%c)."), o_name, index_to_label(item));
2296 vary_item(owner_ptr, item, -amt);
2297 handle_stuff(owner_ptr);
2299 int item_pos = home_carry(owner_ptr, q_ptr);
2302 store_top = (item_pos / store_bottom) * store_bottom;
2303 display_store_inventory(owner_ptr);
2308 distribute_charges(o_ptr, q_ptr, amt);
2309 msg_format(_("%sを置いた。(%c)", "You drop %s (%c)."), o_name, index_to_label(item));
2311 vary_item(owner_ptr, item, -amt);
2312 handle_stuff(owner_ptr);
2313 int item_pos = home_carry(owner_ptr, q_ptr);
2316 store_top = (item_pos / store_bottom) * store_bottom;
2317 display_store_inventory(owner_ptr);
2321 if ((choice == 0) && (item >= INVEN_RARM))
2323 calc_android_exp(owner_ptr);
2324 verify_equip_slot(owner_ptr, item);
2330 * @brief 店のアイテムを調べるコマンドのメインルーチン /
2331 * Examine an item in a store -JDL-
2334 static void store_examine(player_type *player_ptr)
2336 if (st_ptr->stock_num <= 0)
2338 if (cur_store_num == STORE_HOME)
2339 msg_print(_("我が家には何も置いてありません。", "Your home is empty."));
2340 else if (cur_store_num == STORE_MUSEUM)
2341 msg_print(_("博物館には何も置いてありません。", "Museum is empty."));
2343 msg_print(_("現在商品の在庫を切らしています。", "I am currently out of stock."));
2347 int i = (st_ptr->stock_num - store_top);
2348 if (i > store_bottom) i = store_bottom;
2351 sprintf(out_val, _("どれを調べますか?", "Which item do you want to examine? "));
2354 if (!get_stock(&item, out_val, 0, i - 1)) return;
2355 item = item + store_top;
2357 o_ptr = &st_ptr->stock[item];
2358 if (!OBJECT_IS_FULL_KNOWN(o_ptr))
2360 msg_print(_("このアイテムについて特に知っていることはない。", "You have no special knowledge about that item."));
2364 GAME_TEXT o_name[MAX_NLEN];
2365 object_desc(player_ptr, o_name, o_ptr, 0);
2366 msg_format(_("%sを調べている...", "Examining %s..."), o_name);
2368 if (!screen_object(player_ptr, o_ptr, SCROBJ_FORCE_DETAIL))
2369 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
2374 * @brief 博物館のアイテムを除去するコマンドのメインルーチン /
2375 * Remove an item from museum (Originally from TOband)
2376 * @param player_ptr プレーヤーへの参照ポインタ
2379 static void museum_remove_object(player_type *player_ptr)
2381 if (st_ptr->stock_num <= 0)
2383 msg_print(_("博物館には何も置いてありません。", "Museum is empty."));
2387 int i = st_ptr->stock_num - store_top;
2388 if (i > store_bottom) i = store_bottom;
2391 sprintf(out_val, _("どのアイテムの展示をやめさせますか?", "Which item do you want to order to remove? "));
2394 if (!get_stock(&item, out_val, 0, i - 1)) return;
2396 item = item + store_top;
2398 o_ptr = &st_ptr->stock[item];
2400 GAME_TEXT o_name[MAX_NLEN];
2401 object_desc(player_ptr, o_name, o_ptr, 0);
2403 msg_print(_("展示をやめさせたアイテムは二度と見ることはできません!", "Once removed from the Museum, an item will be gone forever!"));
2404 if (!get_check(format(_("本当に%sの展示をやめさせますか?", "Really order to remove %s from the Museum? "), o_name))) return;
2406 msg_format(_("%sの展示をやめさせた。", "You ordered to remove %s."), o_name);
2408 store_item_increase(item, -o_ptr->number);
2409 store_item_optimize(item);
2411 (void)combine_and_reorder_home(STORE_MUSEUM);
2412 if (st_ptr->stock_num == 0) store_top = 0;
2414 else if (store_top >= st_ptr->stock_num) store_top -= store_bottom;
2415 display_store_inventory(player_ptr);
2420 * Hack -- set this to leave the store
2422 static bool leave_store = FALSE;
2426 * @brief 店舗処理コマンド選択のメインルーチン /
2427 * Process a command in a store
2428 * @param client_ptr 顧客となるクリーチャーの参照ポインタ
2432 * Note that we must allow the use of a few "special" commands
2433 * in the stores which are not allowed in the dungeon, and we
2434 * must disable some commands which are allowed in the dungeon
2435 * but not in the stores, to prevent chaos.
2438 static void store_process_command(player_type *client_ptr)
2441 if (rogue_like_commands && command_cmd == 'l')
2446 switch (command_cmd)
2456 /* 1 ページ戻るコマンド: 我が家のページ数が多いので重宝するはず By BUG */
2457 if (st_ptr->stock_num <= store_bottom) {
2458 msg_print(_("これで全部です。", "Entire inventory is shown."));
2461 store_top -= store_bottom;
2463 store_top = ((st_ptr->stock_num - 1) / store_bottom) * store_bottom;
2464 if ((cur_store_num == STORE_HOME) && (powerup_home == FALSE))
2465 if (store_top >= store_bottom) store_top = store_bottom;
2466 display_store_inventory(client_ptr);
2473 if (st_ptr->stock_num <= store_bottom)
2475 msg_print(_("これで全部です。", "Entire inventory is shown."));
2479 store_top += store_bottom;
2481 * 隠しオプション(powerup_home)がセットされていないときは
2482 * 我が家では 2 ページまでしか表示しない
2484 if ((cur_store_num == STORE_HOME) &&
2485 (powerup_home == FALSE) &&
2486 (st_ptr->stock_num >= STORE_INVEN_MAX))
2488 if (store_top >= (STORE_INVEN_MAX - 1))
2495 if (store_top >= st_ptr->stock_num) store_top = 0;
2498 display_store_inventory(client_ptr);
2505 do_cmd_redraw(client_ptr);
2506 display_store(client_ptr);
2511 store_purchase(client_ptr);
2516 store_sell(client_ptr);
2521 store_examine(client_ptr);
2530 do_cmd_wield(client_ptr);
2535 do_cmd_takeoff(client_ptr);
2540 do_cmd_destroy(client_ptr);
2545 do_cmd_equip(client_ptr);
2550 do_cmd_inven(client_ptr);
2555 do_cmd_observe(client_ptr);
2560 toggle_inventory_equipment(client_ptr);
2565 if ((client_ptr->pclass == CLASS_MINDCRAFTER) ||
2566 (client_ptr->pclass == CLASS_BERSERKER) ||
2567 (client_ptr->pclass == CLASS_NINJA) ||
2568 (client_ptr->pclass == CLASS_MIRROR_MASTER)
2569 ) do_cmd_mind_browse(client_ptr);
2570 else if (client_ptr->pclass == CLASS_SMITH)
2571 do_cmd_kaji(client_ptr, TRUE);
2572 else if (client_ptr->pclass == CLASS_MAGIC_EATER)
2573 do_cmd_magic_eater(client_ptr, TRUE, FALSE);
2574 else if (client_ptr->pclass == CLASS_SNIPER)
2575 do_cmd_snipe_browse(client_ptr);
2576 else do_cmd_browse(client_ptr);
2581 do_cmd_inscribe(client_ptr);
2586 do_cmd_uninscribe(client_ptr);
2591 do_cmd_help(client_ptr);
2596 do_cmd_query_symbol(client_ptr);
2601 client_ptr->town_num = old_town_num;
2602 do_cmd_player_status(client_ptr);
2603 client_ptr->town_num = inner_town_num;
2604 display_store(client_ptr);
2614 client_ptr->town_num = old_town_num;
2615 do_cmd_pref(client_ptr);
2616 client_ptr->town_num = inner_town_num;
2621 client_ptr->town_num = old_town_num;
2622 do_cmd_macros(client_ptr);
2623 client_ptr->town_num = inner_town_num;
2628 client_ptr->town_num = old_town_num;
2629 do_cmd_visuals(client_ptr);
2630 client_ptr->town_num = inner_town_num;
2635 client_ptr->town_num = old_town_num;
2636 do_cmd_colors(client_ptr);
2637 client_ptr->town_num = inner_town_num;
2643 (void)combine_and_reorder_home(STORE_HOME);
2644 do_cmd_redraw(client_ptr);
2645 display_store(client_ptr);
2660 do_cmd_feeling(client_ptr);
2665 do_cmd_message_one();
2675 do_cmd_diary(client_ptr);
2680 do_cmd_knowledge(client_ptr);
2685 do_cmd_load_screen();
2690 do_cmd_save_screen(client_ptr);
2695 if ((cur_store_num == STORE_MUSEUM) && (command_cmd == 'r'))
2697 museum_remove_object(client_ptr);
2701 msg_print(_("そのコマンドは店の中では使えません。", "That command does not work in stores."));
2711 * @brief 店舗処理全体のメインルーチン /
2712 * Enter a store, and interact with it. *
2713 * @param player_ptr プレーヤーへの参照ポインタ
2717 * Note that we use the standard "request_command()" function
2718 * to get a command, allowing us to use "command_arg" and all
2719 * command macros and other nifty stuff, but we use the special
2720 * "shopping" argument, to force certain commands to be converted
2721 * into other commands, normally, we convert "p" (pray) and "m"
2722 * (cast magic) into "g" (get), and "s" (search) into "d" (drop).
2725 void do_cmd_store(player_type *player_ptr)
2727 if (player_ptr->wild_mode) return;
2729 Term_get_size(&w, &h);
2731 xtra_stock = MIN(14 + 26, ((h > 24) ? (h - 24) : 0));
2732 store_bottom = MIN_STOCK + xtra_stock;
2735 g_ptr = &player_ptr->current_floor_ptr->grid_array[player_ptr->y][player_ptr->x];
2737 if (!cave_have_flag_grid(g_ptr, FF_STORE))
2739 msg_print(_("ここには店がありません。", "You see no store here."));
2743 int which = f_info[g_ptr->feat].subtype;
2744 old_town_num = player_ptr->town_num;
2745 if ((which == STORE_HOME) || (which == STORE_MUSEUM)) player_ptr->town_num = 1;
2746 if (player_ptr->current_floor_ptr->dun_level) player_ptr->town_num = NO_TOWN;
2747 inner_town_num = player_ptr->town_num;
2749 if ((town_info[player_ptr->town_num].store[which].store_open >= current_world_ptr->game_turn) ||
2752 msg_print(_("ドアに鍵がかかっている。", "The doors are locked."));
2753 player_ptr->town_num = old_town_num;
2757 int maintain_num = (current_world_ptr->game_turn - town_info[player_ptr->town_num].store[which].last_visit) / (TURNS_PER_TICK * STORE_TICKS);
2758 if (maintain_num > 10)
2762 for (int i = 0; i < maintain_num; i++)
2763 store_maint(player_ptr, player_ptr->town_num, which);
2765 town_info[player_ptr->town_num].store[which].last_visit = current_world_ptr->game_turn;
2768 forget_lite(player_ptr->current_floor_ptr);
2769 forget_view(player_ptr->current_floor_ptr);
2770 current_world_ptr->character_icky = TRUE;
2774 get_com_no_macros = TRUE;
2775 cur_store_num = which;
2776 cur_store_feat = g_ptr->feat;
2777 st_ptr = &town_info[player_ptr->town_num].store[cur_store_num];
2778 ot_ptr = &owners[cur_store_num][st_ptr->owner];
2780 play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_BUILD);
2781 display_store(player_ptr);
2782 leave_store = FALSE;
2784 while (!leave_store)
2787 clear_from(20 + xtra_stock);
2788 prt(_(" ESC) 建物から出る", " ESC) Exit from Building."), 21 + xtra_stock, 0);
2789 if (st_ptr->stock_num > store_bottom)
2791 prt(_(" -)前ページ", " -) Previous page"), 22 + xtra_stock, 0);
2792 prt(_(" スペース) 次ページ", " SPACE) Next page"), 23 + xtra_stock, 0);
2795 if (cur_store_num == STORE_HOME)
2797 prt(_("g) アイテムを取る", "g) Get an item."), 21 + xtra_stock, 27);
2798 prt(_("d) アイテムを置く", "d) Drop an item."), 22 + xtra_stock, 27);
2799 prt(_("x) 家のアイテムを調べる", "x) eXamine an item in the home."), 23 + xtra_stock, 27);
2801 else if (cur_store_num == STORE_MUSEUM)
2803 prt(_("d) アイテムを置く", "d) Drop an item."), 21 + xtra_stock, 27);
2804 prt(_("r) アイテムの展示をやめる", "r) order to Remove an item."), 22 + xtra_stock, 27);
2805 prt(_("x) 博物館のアイテムを調べる", "x) eXamine an item in the museum."), 23 + xtra_stock, 27);
2809 prt(_("p) 商品を買う", "p) Purchase an item."), 21 + xtra_stock, 30);
2810 prt(_("s) アイテムを売る", "s) Sell an item."), 22 + xtra_stock, 30);
2811 prt(_("x) 商品を調べる", "x) eXamine an item in the shop"), 23 + xtra_stock, 30);
2814 prt(_("i/e) 持ち物/装備の一覧", "i/e) Inventry/Equipment list"), 21 + xtra_stock, 56);
2815 if (rogue_like_commands)
2817 prt(_("w/T) 装備する/はずす", "w/T) Wear/Take off equipment"), 22 + xtra_stock, 56);
2821 prt(_("w/t) 装備する/はずす", "w/t) Wear/Take off equipment"), 22 + xtra_stock, 56);
2824 prt(_("コマンド:", "You may: "), 20 + xtra_stock, 0);
2825 request_command(player_ptr, TRUE);
2826 store_process_command(player_ptr);
2829 * Hack -- To redraw missiles damage and prices in store
2830 * If player's charisma changes, or if player changes a bow, PU_BONUS is set
2832 bool need_redraw_store_inv = (player_ptr->update & PU_BONUS) ? TRUE : FALSE;
2833 current_world_ptr->character_icky = TRUE;
2834 handle_stuff(player_ptr);
2835 if (player_ptr->inventory_list[INVEN_PACK].k_idx)
2837 INVENTORY_IDX item = INVEN_PACK;
2838 object_type *o_ptr = &player_ptr->inventory_list[item];
2839 if (cur_store_num != STORE_HOME)
2841 if (cur_store_num == STORE_MUSEUM)
2842 msg_print(_("ザックからアイテムがあふれそうなので、あわてて博物館から出た...", "Your pack is so full that you flee the Museum..."));
2844 msg_print(_("ザックからアイテムがあふれそうなので、あわてて店から出た...", "Your pack is so full that you flee the store..."));
2848 else if (!store_check_num(o_ptr))
2850 msg_print(_("ザックからアイテムがあふれそうなので、あわてて家から出た...", "Your pack is so full that you flee your home..."));
2858 GAME_TEXT o_name[MAX_NLEN];
2859 msg_print(_("ザックからアイテムがあふれてしまった!", "Your pack overflows!"));
2861 object_copy(q_ptr, o_ptr);
2862 object_desc(player_ptr, o_name, q_ptr, 0);
2863 msg_format(_("%sが落ちた。(%c)", "You drop %s (%c)."), o_name, index_to_label(item));
2864 vary_item(player_ptr, item, -255);
2865 handle_stuff(player_ptr);
2867 item_pos = home_carry(player_ptr, q_ptr);
2870 store_top = (item_pos / store_bottom) * store_bottom;
2871 display_store_inventory(player_ptr);
2876 if (need_redraw_store_inv) display_store_inventory(player_ptr);
2878 if (st_ptr->store_open >= current_world_ptr->game_turn) leave_store = TRUE;
2881 select_floor_music(player_ptr);
2882 player_ptr->town_num = old_town_num;
2883 take_turn(player_ptr, 100);
2884 current_world_ptr->character_icky = FALSE;
2886 command_see = FALSE;
2887 get_com_no_macros = FALSE;
2892 player_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
2893 player_ptr->update |= (PU_MONSTERS);
2894 player_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_EQUIPPY);
2895 player_ptr->redraw |= (PR_MAP);
2896 player_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
2901 * @brief 現在の町の店主を交代させる /
2902 * Shuffle one of the stores.
2903 * @param which 店舗種類のID
2906 void store_shuffle(player_type *player_ptr, int which)
2908 if (which == STORE_HOME) return;
2909 if (which == STORE_MUSEUM) return;
2911 cur_store_num = which;
2912 st_ptr = &town_info[player_ptr->town_num].store[cur_store_num];
2913 int j = st_ptr->owner;
2916 st_ptr->owner = (byte)randint0(MAX_OWNERS);
2917 if (j == st_ptr->owner) continue;
2919 for (i = 1; i < max_towns; i++)
2921 if (i == player_ptr->town_num) continue;
2922 if (st_ptr->owner == town_info[i].store[cur_store_num].owner) break;
2925 if (i == max_towns) break;
2928 ot_ptr = &owners[cur_store_num][st_ptr->owner];
2929 st_ptr->insult_cur = 0;
2930 st_ptr->store_open = 0;
2931 st_ptr->good_buy = 0;
2932 st_ptr->bad_buy = 0;
2933 for (int i = 0; i < st_ptr->stock_num; i++)
2936 o_ptr = &st_ptr->stock[i];
2937 if (object_is_artifact(o_ptr)) continue;
2939 o_ptr->discount = 50;
2940 o_ptr->ident &= ~(IDENT_FIXED);
2941 o_ptr->inscription = quark_add(_("売出中", "on sale"));
2947 * @brief 店の品揃えを変化させる /
2948 * Maintain the inventory at the stores.
2949 * @param player_ptr プレーヤーへの参照ポインタ
2950 * @param town_num 町のID
2951 * @param store_num 店舗種類のID
2954 void store_maint(player_type *player_ptr, int town_num, int store_num)
2956 cur_store_num = store_num;
2957 if (store_num == STORE_HOME) return;
2958 if (store_num == STORE_MUSEUM) return;
2960 st_ptr = &town_info[town_num].store[store_num];
2961 ot_ptr = &owners[store_num][st_ptr->owner];
2962 st_ptr->insult_cur = 0;
2963 if (store_num == STORE_BLACK)
2965 for (INVENTORY_IDX j = st_ptr->stock_num - 1; j >= 0; j--)
2967 object_type *o_ptr = &st_ptr->stock[j];
2968 if (black_market_crap(player_ptr, o_ptr))
2970 store_item_increase(j, 0 - o_ptr->number);
2971 store_item_optimize(j);
2976 INVENTORY_IDX j = st_ptr->stock_num;
2977 j = j - randint1(STORE_TURNOVER);
2978 if (j > STORE_MAX_KEEP) j = STORE_MAX_KEEP;
2979 if (j < STORE_MIN_KEEP) j = STORE_MIN_KEEP;
2982 while (st_ptr->stock_num > j)
2985 j = st_ptr->stock_num;
2986 j = j + randint1(STORE_TURNOVER);
2987 if (j > STORE_MAX_KEEP) j = STORE_MAX_KEEP;
2988 if (j < STORE_MIN_KEEP) j = STORE_MIN_KEEP;
2989 if (j >= st_ptr->stock_size) j = st_ptr->stock_size - 1;
2991 while (st_ptr->stock_num < j) store_create(player_ptr);
2996 * @brief 店舗情報を初期化する /
2997 * Initialize the stores
2998 * @param town_num 町のID
2999 * @param store_num 店舗種類のID
3002 void store_init(int town_num, int store_num)
3004 cur_store_num = store_num;
3005 st_ptr = &town_info[town_num].store[store_num];
3008 st_ptr->owner = (byte)randint0(MAX_OWNERS);
3010 for (i = 1; i < max_towns; i++)
3012 if (i == town_num) continue;
3013 if (st_ptr->owner == town_info[i].store[store_num].owner) break;
3016 if (i == max_towns) break;
3019 ot_ptr = &owners[store_num][st_ptr->owner];
3021 st_ptr->store_open = 0;
3022 st_ptr->insult_cur = 0;
3023 st_ptr->good_buy = 0;
3024 st_ptr->bad_buy = 0;
3025 st_ptr->stock_num = 0;
3026 st_ptr->last_visit = -10L * TURNS_PER_TICK * STORE_TICKS;
3027 for (int k = 0; k < st_ptr->stock_size; k++)
3029 object_wipe(&st_ptr->stock[k]);