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/store-owners.h"
15 #include "market/store-owner-comments.h"
21 #include "io/write-diary.h"
22 #include "cmd/cmd-basic.h"
23 #include "cmd/cmd-diary.h"
24 #include "cmd/cmd-draw.h"
25 #include "cmd/cmd-dump.h"
26 #include "cmd/cmd-help.h"
27 #include "cmd/cmd-item.h"
28 #include "cmd/cmd-macro.h"
29 #include "cmd/cmd-smith.h"
30 #include "cmd/cmd-visuals.h"
31 #include "cmd/cmd-zapwand.h"
32 #include "cmd/cmd-magiceat.h"
36 #include "cmd-spell.h"
38 #include "player-status.h"
39 #include "player-class.h"
40 #include "player-inventory.h"
41 #include "object-flavor.h"
42 #include "object-hook.h"
43 #include "floor-events.h"
46 #include "player-effects.h"
47 #include "player-race.h"
50 #include "objectkind.h"
52 #include "floor-town.h"
54 #include "view-mainwindow.h"
59 static int cur_store_num = 0;
60 static int store_top = 0;
61 static int store_bottom = 0;
62 static int xtra_stock = 0;
63 static store_type *st_ptr = NULL;
64 static const owner_type *ot_ptr = NULL;
65 static s16b old_town_num = 0;
66 static s16b inner_town_num = 0;
67 #define RUMOR_CHANCE 8
69 /*** Initialize others ***/
72 * @brief 取引成功時の店主のメッセージ処理 /
73 * ブラックマーケットのときは別のメッセージを出す
75 * @param player_ptr プレーヤーへの参照ポインタ
78 static void say_comment_1(player_type *player_ptr)
81 if (cur_store_num == STORE_BLACK)
83 msg_print(comment_1_B[randint0(MAX_COMMENT_1)]);
87 msg_print(comment_1[randint0(MAX_COMMENT_1)]);
90 msg_print(comment_1[randint0(MAX_COMMENT_1)]);
93 if (one_in_(RUMOR_CHANCE))
96 msg_print("店主は耳うちした:");
98 msg_print("The shopkeeper whispers something into your ear:");
100 display_rumor(player_ptr, TRUE);
106 * @brief プレイヤーがアイテムを買う時の価格代案メッセージ処理 /
107 * Continue haggling (player is buying)
108 * @param value 店主の提示価格
109 * @param annoyed 店主のいらつき度
112 static void say_comment_2(PRICE value, int annoyed)
114 /* Prepare a string to insert */
116 sprintf(tmp_val, "%ld", (long)value);
120 msg_format(comment_2a[randint0(MAX_COMMENT_2A)], tmp_val);
125 if (cur_store_num == STORE_BLACK)
127 msg_format(comment_2b_B[randint0(MAX_COMMENT_2B)], tmp_val);
131 msg_format(comment_2b[randint0(MAX_COMMENT_2B)], tmp_val);
134 msg_format(comment_2b[randint0(MAX_COMMENT_2B)], tmp_val);
140 * @brief プレイヤーがアイテムを売る時の価格代案メッセージ処理 /
141 * ブラックマーケットのときは別のメッセージを出す
142 * Continue haggling (player is selling)
143 * @param value 店主の提示価格
144 * @param annoyed 店主のいらつき度
147 static void say_comment_3(PRICE value, int annoyed)
150 sprintf(tmp_val, "%ld", (long)value);
153 msg_format(comment_3a[randint0(MAX_COMMENT_3A)], tmp_val);
158 /* ブラックマーケットの時は別のメッセージを出す */
159 if (cur_store_num == STORE_BLACK)
161 msg_format(comment_3b_B[randint0(MAX_COMMENT_3B)], tmp_val);
165 msg_format(comment_3b[randint0(MAX_COMMENT_3B)], tmp_val);
168 msg_format(comment_3b[randint0(MAX_COMMENT_3B)], tmp_val);
175 * @brief 店主がプレイヤーを追い出す時のメッセージ処理 /
176 * ブラックマーケットの時は別のメッセージを出す
177 * Kick 'da bum out. -RAK-
180 static void say_comment_4(void)
183 if (cur_store_num == STORE_BLACK)
185 msg_print(comment_4a_B[randint0(MAX_COMMENT_4A)]);
186 msg_print(comment_4b_B[randint0(MAX_COMMENT_4B)]);
190 msg_print(comment_4a[randint0(MAX_COMMENT_4A)]);
191 msg_print(comment_4b[randint0(MAX_COMMENT_4B)]);
194 msg_print(comment_4a[randint0(MAX_COMMENT_4A)]);
195 msg_print(comment_4b[randint0(MAX_COMMENT_4B)]);
202 * @brief 店主がプレイヤーに取り合わない時のメッセージ処理 /
203 * ブラックマーケットの時は別のメッセージを出す
204 * You are insulting me
207 static void say_comment_5(void)
210 if (cur_store_num == STORE_BLACK)
212 msg_print(comment_5_B[randint0(MAX_COMMENT_5)]);
216 msg_print(comment_5[randint0(MAX_COMMENT_5)]);
219 msg_print(comment_5[randint0(MAX_COMMENT_5)]);
226 * @brief 店主がプレイヤーの提示を理解できなかった時のメッセージ処理 /
227 * That makes no sense.
230 static void say_comment_6(void)
232 msg_print(comment_6[randint0(MAX_COMMENT_6)]);
235 #define MAX_COMMENT_7A 4
237 static concptr comment_7a[MAX_COMMENT_7A] =
242 "誰かがむせび泣く声が聞こえる...。",
247 "You hear someone sobbing...",
248 "The shopkeeper howls in agony!"
253 #define MAX_COMMENT_7B 4
255 static concptr comment_7b[MAX_COMMENT_7B] =
265 "The shopkeeper curses at you.",
266 "The shopkeeper glares at you."
271 #define MAX_COMMENT_7C 4
273 static concptr comment_7c[MAX_COMMENT_7C] =
282 "You've made my day!",
283 "The shopkeeper giggles.",
284 "The shopkeeper laughs loudly."
289 #define MAX_COMMENT_7D 4
291 static concptr comment_7d[MAX_COMMENT_7D] =
295 "こんなおいしい思いをしたら、真面目に働けなくなるなぁ。",
300 "I think I'll retire!",
301 "The shopkeeper jumps for joy.",
302 "The shopkeeper smiles gleefully."
309 * @brief 店主が交渉を終えた際の反応を返す処理 /
310 * Let a shop-keeper React to a purchase
311 * @param price アイテムの取引額
312 * @param value アイテムの実際価値
313 * @param guess 店主が当初予想していた価値
316 * We paid "price", it was worth "value", and we thought it was worth "guess"
318 static void purchase_analyze(player_type *player_ptr, PRICE price, PRICE value, PRICE guess)
320 /* Item was worthless, but we bought it */
321 if ((value <= 0) && (price > value))
323 msg_print(comment_7a[randint0(MAX_COMMENT_7A)]);
324 chg_virtue(player_ptr, V_HONOUR, -1);
325 chg_virtue(player_ptr, V_JUSTICE, -1);
330 /* Item was cheaper than we thought, and we paid more than necessary */
331 if ((value < guess) && (price > value))
333 msg_print(comment_7b[randint0(MAX_COMMENT_7B)]);
334 chg_virtue(player_ptr, V_JUSTICE, -1);
335 if (one_in_(4)) chg_virtue(player_ptr, V_HONOUR, -1);
340 /* Item was a good bargain, and we got away with it */
341 if ((value > guess) && (value < (4 * guess)) && (price < value))
343 msg_print(comment_7c[randint0(MAX_COMMENT_7C)]);
344 if (one_in_(4)) chg_virtue(player_ptr, V_HONOUR, -1);
345 else if (one_in_(4)) chg_virtue(player_ptr, V_HONOUR, 1);
350 /* Item was a great bargain, and we got away with it */
351 if ((value > guess) && (price < value))
353 msg_print(comment_7d[randint0(MAX_COMMENT_7D)]);
354 if (one_in_(2)) chg_virtue(player_ptr, V_HONOUR, -1);
355 if (one_in_(4)) chg_virtue(player_ptr, V_HONOUR, 1);
356 if (10 * price < value) chg_virtue(player_ptr, V_SACRIFICE, 1);
363 * We store the current "store feat" here so everyone can access it
365 static int cur_store_feat;
368 * Buying and selling adjustments for race combinations.
369 * Entry[owner][player] gives the basic "cost inflation".
371 static byte rgold_adj[MAX_RACES][MAX_RACES] =
373 /*Hum, HfE, Elf, Hal, Gno, Dwa, HfO, HfT, Dun, HiE, Barbarian,
374 HfOg, HGn, HTn, Cyc, Yek, Klc, Kbd, Nbl, DkE, Drc, Mind Flayer,
375 Imp, Glm, Skl, Zombie, Vampire, Spectre, Fairy, Beastman, Ent,
376 Angel, Demon, Kutar, Android, Merfolk */
379 { 100, 105, 105, 110, 113, 115, 120, 125, 100, 105, 100,
380 124, 120, 110, 125, 115, 120, 120, 120, 120, 115, 120,
381 115, 105, 125, 125, 125, 125, 105, 120, 105, 95, 140,
382 100, 120, 110, 105, 110 },
385 { 110, 100, 100, 105, 110, 120, 125, 130, 110, 100, 110,
386 120, 115, 108, 115, 110, 110, 120, 120, 115, 115, 110,
387 120, 110, 110, 110, 120, 110, 100, 125, 100, 95, 140,
388 110, 115, 110, 110, 110 },
391 { 110, 105, 100, 105, 110, 120, 125, 130, 110, 100, 110,
392 120, 120, 105, 120, 110, 105, 125, 125, 110, 115, 108,
393 120, 115, 110, 110, 120, 110, 100, 125, 100, 95, 140,
394 110, 110, 105, 110, 110 },
397 { 115, 110, 105, 95, 105, 110, 115, 130, 115, 105, 115,
398 125, 120, 120, 125, 115, 110, 120, 120, 120, 115, 115,
399 120, 110, 120, 120, 130, 110, 110, 130, 110, 95, 140,
400 115, 120, 105, 115, 105 },
403 { 115, 115, 110, 105, 95, 110, 115, 130, 115, 110, 115,
404 120, 125, 110, 120, 110, 105, 120, 110, 110, 105, 110,
405 120, 101, 110, 110, 120, 120, 115, 130, 115, 95, 140,
406 115, 110, 110, 115, 110 },
409 { 115, 120, 120, 110, 110, 95, 125, 135, 115, 120, 115,
410 125, 140, 130, 130, 120, 115, 115, 115, 135, 125, 120,
411 120, 105, 115, 115, 115, 115, 120, 130, 120, 95, 140,
412 115, 110, 115, 115, 120 },
415 { 115, 120, 125, 115, 115, 130, 110, 115, 115, 125, 115,
416 110, 110, 120, 110, 120, 125, 115, 115, 110, 120, 110,
417 115, 125, 120, 120, 115, 120, 125, 115, 125, 95, 140,
418 115, 110, 115, 115, 125 },
421 { 110, 115, 115, 110, 110, 130, 110, 110, 110, 115, 110,
422 110, 115, 120, 110, 120, 120, 110, 110, 110, 115, 110,
423 110, 115, 112, 112, 115, 112, 120, 110, 120, 95, 140,
424 110, 110, 115, 110, 130 },
427 { 100, 105, 105, 110, 113, 115, 120, 125, 100, 105, 100,
428 120, 120, 105, 120, 115, 105, 115, 120, 110, 105, 105,
429 120, 105, 120, 120, 125, 120, 105, 135, 105, 95, 140,
430 100, 110, 110, 100, 110 },
433 { 110, 105, 100, 105, 110, 120, 125, 130, 110, 100, 110,
434 125, 125, 101, 120, 115, 110, 115, 125, 110, 110, 110,
435 125, 115, 120, 120, 125, 120, 100, 125, 100, 95, 140,
436 110, 110, 105, 110, 110 },
438 /* Human / Barbarian (copied from human) */
439 { 100, 105, 105, 110, 113, 115, 120, 125, 100, 105, 100,
440 124, 120, 110, 125, 115, 120, 120, 120, 120, 115, 120,
441 115, 105, 125, 125, 130, 125, 115, 120, 115, 95, 140,
442 100, 120, 110, 100, 110 },
444 /* Half-Ogre: theoretical, copied from half-troll */
445 { 110, 115, 115, 110, 110, 130, 110, 110, 110, 115, 110,
446 110, 115, 120, 110, 120, 120, 110, 110, 110, 115, 110,
447 110, 115, 112, 112, 115, 112, 120, 110, 120, 95, 140,
448 110, 110, 115, 110, 120 },
450 /* Half-Giant: theoretical, copied from half-troll */
451 { 110, 115, 115, 110, 110, 130, 110, 110, 110, 115, 110,
452 110, 115, 120, 110, 120, 120, 110, 110, 110, 115, 110,
453 110, 115, 112, 112, 115, 112, 130, 120, 130, 95, 140,
454 110, 110, 115, 110, 115 },
456 /* Half-Titan: theoretical, copied from High_Elf */
457 { 110, 105, 100, 105, 110, 120, 125, 130, 110, 100, 110,
458 125, 125, 101, 120, 115, 110, 115, 125, 110, 110, 110,
459 125, 115, 120, 120, 120, 120, 130, 130, 130, 95, 140,
460 110, 110, 115, 110, 108 },
462 /* Cyclops: theoretical, copied from half-troll */
463 { 110, 115, 115, 110, 110, 130, 110, 110, 110, 115, 110,
464 110, 115, 120, 110, 120, 120, 110, 110, 110, 115, 110,
465 110, 115, 112, 112, 115, 112, 130, 130, 130, 95, 140,
466 110, 110, 115, 110, 115 },
468 /* Yeek: theoretical, copied from Half-Orc */
469 { 115, 120, 125, 115, 115, 130, 110, 115, 115, 125, 115,
470 110, 110, 120, 110, 120, 125, 115, 115, 110, 120, 110,
471 115, 125, 120, 120, 120, 120, 130, 130, 130, 95, 140,
472 115, 110, 115, 115, 110 },
474 /* Klackon: theoretical, copied from Gnome */
475 { 115, 115, 110, 105, 95, 110, 115, 130, 115, 110, 115,
476 120, 125, 110, 120, 110, 105, 120, 110, 110, 105, 110,
477 120, 101, 110, 110, 120, 120, 130, 130, 130, 95, 140,
478 115, 110, 115, 115, 110 },
480 /* Kobold: theoretical, copied from Half-Orc */
481 { 115, 120, 125, 115, 115, 130, 110, 115, 115, 125, 115,
482 110, 110, 120, 110, 120, 125, 115, 115, 110, 120, 110,
483 115, 125, 120, 120, 120, 120, 130, 130, 130, 95, 140,
484 115, 110, 115, 115, 120 },
486 /* Nibelung: theoretical, copied from Dwarf */
487 { 115, 120, 120, 110, 110, 95, 125, 135, 115, 120, 115,
488 125, 140, 130, 130, 120, 115, 115, 115, 135, 125, 120,
489 120, 105, 115, 115, 120, 120, 130, 130, 130, 95, 140,
490 115, 135, 115, 115, 120 },
493 { 110, 110, 110, 115, 120, 130, 115, 115, 120, 110, 115,
494 115, 115, 116, 115, 120, 120, 115, 115, 101, 110, 110,
495 110, 110, 112, 122, 110, 110, 110, 115, 110, 120, 120,
496 110, 101, 115, 110, 115 },
498 /* Draconian: theoretical, copied from High_Elf */
499 { 110, 105, 100, 105, 110, 120, 125, 130, 110, 100, 110,
500 125, 125, 101, 120, 115, 110, 115, 125, 110, 110, 110,
501 125, 115, 120, 120, 120, 120, 130, 130, 130, 95, 140,
502 110, 110, 115, 110, 115 },
504 /* Mind Flayer: theoretical, copied from High_Elf */
505 { 110, 105, 100, 105, 110, 120, 125, 130, 110, 100, 110,
506 125, 125, 101, 120, 115, 110, 115, 125, 110, 110, 110,
507 125, 115, 120, 120, 120, 120, 130, 130, 130, 95, 140,
508 110, 110, 115, 110, 110 },
510 /* Imp: theoretical, copied from High_Elf */
511 { 110, 105, 100, 105, 110, 120, 125, 130, 110, 100, 110,
512 125, 125, 101, 120, 115, 110, 115, 125, 110, 110, 110,
513 125, 115, 120, 120, 120, 120, 130, 130, 130, 120, 120,
514 110, 110, 115, 110, 120 },
516 /* Golem: theoretical, copied from High_Elf */
517 { 110, 105, 100, 105, 110, 120, 125, 130, 110, 100, 110,
518 125, 125, 101, 120, 115, 110, 115, 125, 110, 110, 110,
519 125, 115, 120, 120, 120, 120, 130, 130, 130, 95, 140,
520 110, 110, 115, 110, 110 },
522 /* Skeleton: theoretical, copied from half-orc */
523 { 115, 120, 125, 115, 115, 130, 110, 115, 115, 125, 115,
524 110, 110, 120, 110, 120, 125, 115, 115, 110, 120, 110,
525 115, 125, 120, 120, 120, 120, 130, 130, 130, 120, 120,
526 115, 110, 125, 115, 110 },
528 /* Zombie: Theoretical, copied from half-orc */
529 { 115, 120, 125, 115, 115, 130, 110, 115, 115, 125, 115,
530 110, 110, 120, 110, 120, 125, 115, 115, 110, 120, 110,
531 115, 125, 120, 120, 120, 120, 130, 130, 130, 120, 120,
532 115, 110, 125, 115, 110 },
534 /* Vampire: Theoretical, copied from half-orc */
535 { 115, 120, 125, 115, 115, 130, 110, 115, 115, 125, 115,
536 110, 110, 120, 110, 120, 125, 115, 115, 110, 120, 110,
537 115, 125, 120, 120, 120, 120, 130, 130, 130, 120, 120,
538 115, 110, 125, 115, 120 },
540 /* Spectre: Theoretical, copied from half-orc */
541 { 115, 120, 125, 115, 115, 130, 110, 115, 115, 125, 115,
542 110, 110, 120, 110, 120, 125, 115, 115, 110, 120, 110,
543 115, 125, 120, 120, 120, 120, 130, 130, 130, 120, 120,
544 115, 110, 125, 115, 110 },
546 /* Sprite: Theoretical, copied from half-orc */
547 { 115, 120, 125, 115, 115, 130, 110, 115, 115, 125, 115,
548 110, 110, 120, 110, 120, 125, 115, 115, 110, 120, 110,
549 115, 125, 120, 120, 120, 120, 130, 130, 130, 95, 140,
550 115, 110, 105, 115, 110 },
552 /* Beastman: Theoretical, copied from half-orc */
553 { 115, 120, 125, 115, 115, 130, 110, 115, 115, 125, 115,
554 110, 110, 120, 110, 120, 125, 115, 115, 110, 120, 110,
555 115, 125, 120, 120, 120, 120, 130, 130, 130, 95, 140,
556 115, 110, 115, 115, 125 },
559 { 110, 105, 100, 105, 110, 120, 125, 130, 110, 100, 110,
560 120, 120, 105, 120, 110, 105, 125, 125, 110, 115, 108,
561 120, 115, 110, 110, 120, 110, 100, 125, 100, 95, 140,
562 110, 110, 105, 110, 110 },
565 { 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
566 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
567 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 160,
568 95, 95, 95, 95, 95 },
571 { 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
572 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
573 140, 140, 140, 140, 140, 140, 140, 140, 140, 160, 120,
574 140, 140, 140, 140, 140 },
577 { 100, 105, 105, 110, 113, 115, 120, 125, 100, 105, 100,
578 124, 120, 110, 125, 115, 120, 120, 120, 120, 115, 120,
579 115, 105, 125, 125, 125, 125, 105, 120, 105, 95, 140,
580 100, 120, 110, 100, 110 },
583 { 110, 110, 110, 115, 120, 130, 115, 115, 120, 110, 115,
584 115, 115, 116, 115, 120, 120, 115, 115, 101, 110, 110,
585 110, 110, 112, 122, 110, 110, 110, 115, 110, 120, 120,
586 110, 101, 115, 110, 115 },
589 { 110, 110, 105, 105, 110, 115, 115, 115, 110, 105, 110,
590 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115,
591 115, 115, 125, 125, 125, 125, 105, 115, 105, 95, 140,
592 110, 115, 100, 110, 110 },
595 { 105, 105, 105, 110, 113, 115, 120, 125, 100, 105, 100,
596 124, 120, 110, 125, 115, 120, 120, 120, 120, 115, 120,
597 115, 105, 125, 125, 125, 125, 105, 120, 105, 95, 140,
598 100, 120, 110, 100, 110 },
601 { 110, 110, 110, 105, 110, 120, 125, 130, 110, 110, 110,
602 120, 115, 108, 115, 110, 110, 120, 120, 115, 115, 110,
603 120, 110, 110, 110, 120, 110, 110, 125, 110, 95, 140,
604 110, 115, 110, 110, 100 },
609 * @brief 店舗価格を決定する. 無料にはならない /
610 * Determine the price of an item (qty one) in a store.
611 * @param o_ptr 店舗に並べるオブジェクト構造体の参照ポインタ
612 * @param greed 店主の強欲度
613 * @param flip TRUEならば店主にとっての買取価格、FALSEなら売出価格を計算
617 * This function takes into account the player's charisma, and the
618 * shop-keepers friendliness, and the shop-keeper's base greed, but
619 * never lets a shop-keeper lose money in a transaction.
620 * The "greed" value should exceed 100 when the player is "buying" the
621 * item, and should be less than 100 when the player is "selling" it.
622 * Hack -- the black market always charges twice as much as it should.
623 * Charisma adjustment runs from 80 to 130
624 * Racial adjustment runs from 95 to 130
625 * Since greed/charisma/racial adjustments are centered at 100, we need
626 * to adjust (by 200) to extract a usable multiplier. Note that the
627 * "greed" value is always something (?).
630 static PRICE price_item(player_type *player_ptr, object_type *o_ptr, int greed, bool flip)
632 PRICE price = object_value(o_ptr);
633 if (price <= 0) return (0L);
635 int factor = rgold_adj[ot_ptr->owner_race][player_ptr->prace];
636 factor += adj_chr_gold[player_ptr->stat_ind[A_CHR]];
640 adjust = 100 + (300 - (greed + factor));
641 if (adjust > 100) adjust = 100;
642 if (cur_store_num == STORE_BLACK)
645 price = (price * adjust + 50L) / 100L;
649 adjust = 100 + ((greed + factor) - 300);
650 if (adjust < 100) adjust = 100;
651 if (cur_store_num == STORE_BLACK)
654 price = (s32b)(((u32b)price * (u32b)adjust + 50UL) / 100UL);
657 if (price <= 0L) return (1L);
663 * @brief 安価な消耗品の販売数を増やし、低確率で割引にする /
664 * Certain "cheap" objects should be created in "piles"
665 * @param o_ptr 店舗に並べるオブジェクト構造体の参照ポインタ
669 * Some objects can be sold at a "discount" (in small piles)
672 static void mass_produce(object_type *o_ptr)
675 PRICE cost = object_value(o_ptr);
682 if (cost <= 5L) size += damroll(3, 5);
683 if (cost <= 20L) size += damroll(3, 5);
684 if (cost <= 50L) size += damroll(2, 2);
690 if (cost <= 60L) size += damroll(3, 5);
691 if (cost <= 240L) size += damroll(1, 5);
692 if (o_ptr->sval == SV_SCROLL_STAR_IDENTIFY) size += damroll(3, 5);
693 if (o_ptr->sval == SV_SCROLL_STAR_REMOVE_CURSE) size += damroll(1, 4);
697 case TV_SORCERY_BOOK:
705 case TV_CRUSADE_BOOK:
707 case TV_HISSATSU_BOOK:
710 if (cost <= 50L) size += damroll(2, 3);
711 if (cost <= 500L) size += damroll(1, 3);
728 if (object_is_artifact(o_ptr)) break;
729 if (object_is_ego(o_ptr)) break;
730 if (cost <= 10L) size += damroll(3, 5);
731 if (cost <= 100L) size += damroll(3, 5);
739 if (cost <= 5L) size += damroll(5, 5);
740 if (cost <= 50L) size += damroll(5, 5);
741 if (cost <= 500L) size += damroll(5, 5);
746 if (cost <= 100L) size += damroll(2, 2);
747 if (cost <= 1000L) size += damroll(2, 2);
759 * Because many rods (and a few wands and staffs) are useful mainly
760 * in quantity, the Black Market will occasionally have a bunch of
767 if ((cur_store_num == STORE_BLACK) && one_in_(3))
769 if (cost < 1601L) size += damroll(1, 5);
770 else if (cost < 3201L) size += damroll(1, 3);
776 DISCOUNT_RATE discount = 0;
781 else if (one_in_(25))
785 else if (one_in_(150))
789 else if (one_in_(300))
793 else if (one_in_(500))
803 o_ptr->discount = discount;
804 o_ptr->number = size - (size * discount / 100);
805 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
807 o_ptr->pval *= (PARAMETER_VALUE)o_ptr->number;
813 * @brief 店舗に並べた品を同一品であるかどうか判定する /
814 * Determine if a store item can "absorb" another item
815 * @param o_ptr 判定するオブジェクト構造体の参照ポインタ1
816 * @param j_ptr 判定するオブジェクト構造体の参照ポインタ2
817 * @return 同一扱いできるならTRUEを返す
820 * See "object_similar()" for the same function for the "player"
823 static bool store_object_similar(object_type *o_ptr, object_type *j_ptr)
825 if (o_ptr == j_ptr) return 0;
826 if (o_ptr->k_idx != j_ptr->k_idx) return 0;
827 if ((o_ptr->pval != j_ptr->pval) && (o_ptr->tval != TV_WAND) && (o_ptr->tval != TV_ROD)) return 0;
828 if (o_ptr->to_h != j_ptr->to_h) return 0;
829 if (o_ptr->to_d != j_ptr->to_d) return 0;
830 if (o_ptr->to_a != j_ptr->to_a) return 0;
831 if (o_ptr->name2 != j_ptr->name2) return 0;
832 if (object_is_artifact(o_ptr) || object_is_artifact(j_ptr)) return 0;
833 for (int i = 0; i < TR_FLAG_SIZE; i++)
834 if (o_ptr->art_flags[i] != j_ptr->art_flags[i]) return 0;
835 if (o_ptr->xtra1 || j_ptr->xtra1) return 0;
836 if (o_ptr->timeout || j_ptr->timeout) return 0;
837 if (o_ptr->ac != j_ptr->ac) return 0;
838 if (o_ptr->dd != j_ptr->dd) return 0;
839 if (o_ptr->ds != j_ptr->ds) return 0;
840 if (o_ptr->tval == TV_CHEST) return 0;
841 if (o_ptr->tval == TV_STATUE) return 0;
842 if (o_ptr->tval == TV_CAPTURE) return 0;
843 if (o_ptr->discount != j_ptr->discount) return 0;
849 * @brief 店舗に並べた品を重ね合わせできるかどうか判定する /
850 * Allow a store item to absorb another item
851 * @param o_ptr 判定するオブジェクト構造体の参照ポインタ1
852 * @param j_ptr 判定するオブジェクト構造体の参照ポインタ2
853 * @return 重ね合わせできるならTRUEを返す
856 * See "object_similar()" for the same function for the "player"
859 static void store_object_absorb(object_type *o_ptr, object_type *j_ptr)
861 int max_num = (o_ptr->tval == TV_ROD) ?
862 MIN(99, MAX_SHORT / k_info[o_ptr->k_idx].pval) : 99;
863 int total = o_ptr->number + j_ptr->number;
864 int diff = (total > max_num) ? total - max_num : 0;
865 o_ptr->number = (total > max_num) ? max_num : total;
866 if (o_ptr->tval == TV_ROD)
868 o_ptr->pval += j_ptr->pval * (j_ptr->number - diff) / j_ptr->number;
871 if (o_ptr->tval == TV_WAND)
873 o_ptr->pval += j_ptr->pval * (j_ptr->number - diff) / j_ptr->number;
879 * @brief 店舗に品を置くスペースがあるかどうかの判定を返す /
880 * Check to see if the shop will be carrying too many objects -RAK-
881 * @param o_ptr 店舗に置きたいオブジェクト構造体の参照ポインタ
882 * @return 置き場がないなら0、重ね合わせできるアイテムがあるなら-1、スペースがあるなら1を返す。
885 * Note that the shop, just like a player, will not accept things
886 * it cannot hold. Before, one could "nuke" potions this way.
887 * Return value is now int:
889 * -1 : Can be combined to existing slot.
890 * 1 : Cannot be combined but there are empty spaces.
893 static int store_check_num(object_type *o_ptr)
896 if ((cur_store_num == STORE_HOME) || (cur_store_num == STORE_MUSEUM))
898 bool old_stack_force_notes = stack_force_notes;
899 bool old_stack_force_costs = stack_force_costs;
901 if (cur_store_num != STORE_HOME)
903 stack_force_notes = FALSE;
904 stack_force_costs = FALSE;
907 for (int i = 0; i < st_ptr->stock_num; i++)
909 j_ptr = &st_ptr->stock[i];
910 if (object_similar(j_ptr, o_ptr))
912 if (cur_store_num != STORE_HOME)
914 stack_force_notes = old_stack_force_notes;
915 stack_force_costs = old_stack_force_costs;
922 if (cur_store_num != STORE_HOME)
924 stack_force_notes = old_stack_force_notes;
925 stack_force_costs = old_stack_force_costs;
930 for (int i = 0; i < st_ptr->stock_num; i++)
932 j_ptr = &st_ptr->stock[i];
933 if (store_object_similar(j_ptr, o_ptr)) return -1;
937 /* Free space is always usable */
939 * オプション powerup_home が設定されていると
942 if ((cur_store_num == STORE_HOME) && (powerup_home == FALSE))
944 if (st_ptr->stock_num < ((st_ptr->stock_size) / 10))
951 if (st_ptr->stock_num < st_ptr->stock_size)
962 * @brief オブジェクトが祝福されているかの判定を返す /
963 * @param o_ptr 判定したいオブジェクト構造体の参照ポインタ
964 * @return アイテムが祝福されたアイテムならばTRUEを返す
966 static bool is_blessed_item(object_type *o_ptr)
968 BIT_FLAGS flgs[TR_FLAG_SIZE];
969 object_flags(o_ptr, flgs);
970 if (have_flag(flgs, TR_BLESSED)) return TRUE;
976 * @brief オブジェクトが所定の店舗で引き取れるかどうかを返す /
977 * Determine if the current store will purchase the given item
978 * @param o_ptr 判定したいオブジェクト構造体の参照ポインタ
979 * @return アイテムが買い取れるならばTRUEを返す
981 * Note that a shop-keeper must refuse to buy "worthless" items
983 static bool store_will_buy(object_type *o_ptr)
985 if ((cur_store_num == STORE_HOME) || (cur_store_num == STORE_MUSEUM)) return TRUE;
986 switch (cur_store_num)
993 if (o_ptr->sval != SV_POTION_WATER) return FALSE;
1019 switch (o_ptr->tval)
1039 switch (o_ptr->tval)
1048 case TV_HISSATSU_BOOK:
1052 if (o_ptr->sval == SV_WIZSTAFF) return FALSE;
1063 switch (o_ptr->tval)
1066 case TV_CRUSADE_BOOK:
1076 monster_race *r_ptr = &r_info[o_ptr->pval];
1077 if (!(r_ptr->flags3 & RF3_EVIL))
1079 if (r_ptr->flags3 & RF3_GOOD) break;
1080 if (r_ptr->flags3 & RF3_ANIMAL) break;
1081 if (my_strchr("?!", r_ptr->d_char)) break;
1087 if (is_blessed_item(o_ptr)) break;
1095 case STORE_ALCHEMIST:
1097 switch (o_ptr->tval)
1110 switch (o_ptr->tval)
1112 case TV_SORCERY_BOOK:
1113 case TV_NATURE_BOOK:
1117 case TV_ARCANE_BOOK:
1119 case TV_DAEMON_BOOK:
1133 if (o_ptr->sval == SV_WIZSTAFF) break;
1144 switch (o_ptr->tval)
1146 case TV_SORCERY_BOOK:
1147 case TV_NATURE_BOOK:
1152 case TV_ARCANE_BOOK:
1154 case TV_DAEMON_BOOK:
1155 case TV_CRUSADE_BOOK:
1167 if (object_value(o_ptr) <= 0) return FALSE;
1173 * @brief 現在の町の指定された店舗のアイテムを整理する /
1174 * Combine and reorder items in store.
1175 * @param store_num 店舗ID
1176 * @return 実際に整理が行われたならばTRUEを返す。
1178 bool combine_and_reorder_home(int store_num)
1180 store_type *old_st_ptr = st_ptr;
1181 st_ptr = &town_info[1].store[store_num];
1183 if (store_num != STORE_HOME)
1185 stack_force_notes = FALSE;
1186 stack_force_costs = FALSE;
1189 bool combined = TRUE;
1193 for (int i = st_ptr->stock_num - 1; i > 0; i--)
1196 o_ptr = &st_ptr->stock[i];
1197 if (!o_ptr->k_idx) continue;
1198 for (int j = 0; j < i; j++)
1201 j_ptr = &st_ptr->stock[j];
1202 if (!j_ptr->k_idx) continue;
1205 * Get maximum number of the stack if these
1206 * are similar, get zero otherwise.
1208 int max_num = object_similar_part(j_ptr, o_ptr);
1209 if (max_num == 0 || j_ptr->number >= max_num) continue;
1211 if (o_ptr->number + j_ptr->number <= max_num)
1213 object_absorb(j_ptr, o_ptr);
1214 st_ptr->stock_num--;
1216 for (k = i; k < st_ptr->stock_num; k++)
1218 st_ptr->stock[k] = st_ptr->stock[k + 1];
1221 object_wipe(&st_ptr->stock[k]);
1226 ITEM_NUMBER old_num = o_ptr->number;
1227 ITEM_NUMBER remain = j_ptr->number + o_ptr->number - max_num;
1228 object_absorb(j_ptr, o_ptr);
1229 o_ptr->number = remain;
1230 if (o_ptr->tval == TV_ROD)
1232 o_ptr->pval = o_ptr->pval * remain / old_num;
1233 o_ptr->timeout = o_ptr->timeout * remain / old_num;
1235 else if (o_ptr->tval == TV_WAND)
1237 o_ptr->pval = o_ptr->pval * remain / old_num;
1248 for (int i = 0; i < st_ptr->stock_num; i++)
1251 o_ptr = &st_ptr->stock[i];
1252 if (!o_ptr->k_idx) continue;
1254 s32b o_value = object_value(o_ptr);
1256 for (j = 0; j < st_ptr->stock_num; j++)
1258 if (object_sort_comp(o_ptr, o_value, &st_ptr->stock[j])) break;
1261 if (j >= i) continue;
1267 object_copy(j_ptr, &st_ptr->stock[i]);
1268 for (int k = i; k > j; k--)
1270 object_copy(&st_ptr->stock[k], &st_ptr->stock[k - 1]);
1273 object_copy(&st_ptr->stock[j], j_ptr);
1276 st_ptr = old_st_ptr;
1277 bool old_stack_force_notes = stack_force_notes;
1278 bool old_stack_force_costs = stack_force_costs;
1279 if (store_num != STORE_HOME)
1281 stack_force_notes = old_stack_force_notes;
1282 stack_force_costs = old_stack_force_costs;
1290 * @brief 我が家にオブジェクトを加える /
1291 * Add the item "o_ptr" to the inventory of the "Home"
1292 * @param o_ptr 加えたいオブジェクトの構造体参照ポインタ
1296 * In all cases, return the slot (or -1) where the object was placed
1297 * Note that this is a hacked up version of "inven_carry()".
1298 * Also note that it may not correctly "adapt" to "knowledge" bacoming
1299 * known, the player may have to pick stuff up and drop it again.
1302 static int home_carry(player_type *player_ptr, object_type *o_ptr)
1304 if (cur_store_num != STORE_HOME)
1306 stack_force_notes = FALSE;
1307 stack_force_costs = FALSE;
1310 bool old_stack_force_notes = stack_force_notes;
1311 bool old_stack_force_costs = stack_force_costs;
1312 for (int slot = 0; slot < st_ptr->stock_num; slot++)
1315 j_ptr = &st_ptr->stock[slot];
1316 if (object_similar(j_ptr, o_ptr))
1318 object_absorb(j_ptr, o_ptr);
1319 if (cur_store_num != STORE_HOME)
1321 stack_force_notes = old_stack_force_notes;
1322 stack_force_costs = old_stack_force_costs;
1329 if (cur_store_num != STORE_HOME)
1331 stack_force_notes = old_stack_force_notes;
1332 stack_force_costs = old_stack_force_costs;
1337 * 隠し機能: オプション powerup_home が設定されていると
1340 if ((cur_store_num != STORE_HOME) || (powerup_home == TRUE))
1342 if (st_ptr->stock_num >= st_ptr->stock_size)
1349 if (st_ptr->stock_num >= ((st_ptr->stock_size) / 10))
1355 PRICE value = object_value(o_ptr);
1357 for (slot = 0; slot < st_ptr->stock_num; slot++)
1359 if (object_sort_comp(o_ptr, value, &st_ptr->stock[slot])) break;
1362 for (int i = st_ptr->stock_num; i > slot; i--)
1364 st_ptr->stock[i] = st_ptr->stock[i - 1];
1367 st_ptr->stock_num++;
1368 st_ptr->stock[slot] = *o_ptr;
1369 chg_virtue(player_ptr, V_SACRIFICE, -1);
1370 (void)combine_and_reorder_home(cur_store_num);
1376 * @brief 店舗にオブジェクトを加える /
1377 * Add the item "o_ptr" to a real stores inventory.
1378 * @param o_ptr 加えたいオブジェクトの構造体参照ポインタ
1382 * In all cases, return the slot (or -1) where the object was placed
1383 * Note that this is a hacked up version of "inven_carry()".
1384 * Also note that it may not correctly "adapt" to "knowledge" bacoming
1385 * known, the player may have to pick stuff up and drop it again.
1388 static int store_carry(object_type *o_ptr)
1390 PRICE value = object_value(o_ptr);
1391 if (value <= 0) return -1;
1392 o_ptr->ident |= IDENT_FULL_KNOWN;
1393 o_ptr->inscription = 0;
1394 o_ptr->feeling = FEEL_NONE;
1396 for (slot = 0; slot < st_ptr->stock_num; slot++)
1399 j_ptr = &st_ptr->stock[slot];
1400 if (store_object_similar(j_ptr, o_ptr))
1402 store_object_absorb(j_ptr, o_ptr);
1407 if (st_ptr->stock_num >= st_ptr->stock_size) return -1;
1409 for (slot = 0; slot < st_ptr->stock_num; slot++)
1412 j_ptr = &st_ptr->stock[slot];
1413 if (o_ptr->tval > j_ptr->tval) break;
1414 if (o_ptr->tval < j_ptr->tval) continue;
1415 if (o_ptr->sval < j_ptr->sval) break;
1416 if (o_ptr->sval > j_ptr->sval) continue;
1417 if (o_ptr->tval == TV_ROD)
1419 if (o_ptr->pval < j_ptr->pval) break;
1420 if (o_ptr->pval > j_ptr->pval) continue;
1423 PRICE j_value = object_value(j_ptr);
1424 if (value > j_value) break;
1425 if (value < j_value) continue;
1428 for (int i = st_ptr->stock_num; i > slot; i--)
1430 st_ptr->stock[i] = st_ptr->stock[i - 1];
1433 st_ptr->stock_num++;
1434 st_ptr->stock[slot] = *o_ptr;
1440 * @brief 店舗のオブジェクト数を増やす /
1441 * Add the item "o_ptr" to a real stores inventory.
1442 * @param item 増やしたいアイテムのID
1447 * Increase, by a given amount, the number of a certain item
1448 * in a certain store. This can result in zero items.
1450 * @todo numは本来ITEM_NUMBER型にしたい。
1452 static void store_item_increase(INVENTORY_IDX item, int num)
1455 o_ptr = &st_ptr->stock[item];
1456 int cnt = o_ptr->number + num;
1457 if (cnt > 255) cnt = 255;
1458 else if (cnt < 0) cnt = 0;
1460 num = cnt - o_ptr->number;
1461 o_ptr->number += (ITEM_NUMBER)num;
1466 * @brief 店舗のオブジェクト数を削除する /
1467 * Remove a slot if it is empty
1468 * @param item 削除したいアイテムのID
1471 static void store_item_optimize(INVENTORY_IDX item)
1474 o_ptr = &st_ptr->stock[item];
1475 if (!o_ptr->k_idx) return;
1476 if (o_ptr->number) return;
1478 st_ptr->stock_num--;
1479 for (int j = item; j < st_ptr->stock_num; j++)
1481 st_ptr->stock[j] = st_ptr->stock[j + 1];
1484 object_wipe(&st_ptr->stock[st_ptr->stock_num]);
1489 * @brief ブラックマーケット用の無価値品の排除判定 /
1490 * This function will keep 'crap' out of the black market.
1491 * @param player_ptr プレーヤーへの参照ポインタ
1492 * @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
1493 * @return ブラックマーケットにとって無価値な品ならばTRUEを返す
1496 * Crap is defined as any item that is "available" elsewhere
1497 * Based on a suggestion by "Lee Vogt" <lvogt@cig.mcel.mot.com>
1500 static bool black_market_crap(player_type *player_ptr, object_type *o_ptr)
1502 if (object_is_ego(o_ptr)) return FALSE;
1504 if (o_ptr->to_a > 0) return FALSE;
1505 if (o_ptr->to_h > 0) return FALSE;
1506 if (o_ptr->to_d > 0) return FALSE;
1508 for (int i = 0; i < MAX_STORES; i++)
1510 if (i == STORE_HOME) continue;
1511 if (i == STORE_MUSEUM) continue;
1513 for (int j = 0; j < town_info[player_ptr->town_num].store[i].stock_num; j++)
1515 object_type *j_ptr = &town_info[player_ptr->town_num].store[i].stock[j];
1516 if (o_ptr->k_idx == j_ptr->k_idx) return TRUE;
1525 * @brief 店舗の品揃え変化のためにアイテムを削除する /
1526 * Attempt to delete (some of) a random item from the store
1530 * Hack -- we attempt to "maintain" piles of items when possible.
1533 static void store_delete(void)
1535 INVENTORY_IDX what = (INVENTORY_IDX)randint0(st_ptr->stock_num);
1536 int num = st_ptr->stock[what].number;
1537 if (randint0(100) < 50) num = (num + 1) / 2;
1538 if (randint0(100) < 50) num = 1;
1539 if ((st_ptr->stock[what].tval == TV_ROD) || (st_ptr->stock[what].tval == TV_WAND))
1541 st_ptr->stock[what].pval -= num * st_ptr->stock[what].pval / st_ptr->stock[what].number;
1544 store_item_increase(what, -num);
1545 store_item_optimize(what);
1550 * @brief 店舗の品揃え変化のためにアイテムを追加する /
1551 * Creates a random item and gives it to a store
1552 * @param player_ptr プレーヤーへの参照ポインタ
1556 * This algorithm needs to be rethought. A lot.
1557 * Currently, "normal" stores use a pre-built array.
1558 * Note -- the "level" given to "obj_get_num()" is a "favored"
1559 * level, that is, there is a much higher chance of getting
1560 * items with a level approaching that of the given level...
1561 * Should we check for "permission" to have the given item?
1564 static void store_create(player_type *player_ptr)
1566 if (st_ptr->stock_num >= st_ptr->stock_size) return;
1568 for (int tries = 0; tries < 4; tries++)
1572 if (cur_store_num == STORE_BLACK)
1574 /* Pick a level for object/magic */
1575 level = 25 + randint0(25);
1577 /* Random item (usually of given level) */
1578 i = get_obj_num(player_ptr, level, 0x00000000);
1580 /* Handle failure */
1581 if (i == 0) continue;
1585 i = st_ptr->table[randint0(st_ptr->table_num)];
1586 level = rand_range(1, STORE_OBJ_LEVEL);
1592 object_prep(q_ptr, i);
1593 apply_magic(player_ptr, q_ptr, level, AM_NO_FIXED_ART);
1594 if (!store_will_buy(q_ptr)) continue;
1596 if (q_ptr->tval == TV_LITE)
1598 if (q_ptr->sval == SV_LITE_TORCH) q_ptr->xtra4 = FUEL_TORCH / 2;
1599 if (q_ptr->sval == SV_LITE_LANTERN) q_ptr->xtra4 = FUEL_LAMP / 2;
1602 object_known(q_ptr);
1603 q_ptr->ident |= IDENT_STORE;
1604 if (q_ptr->tval == TV_CHEST) continue;
1606 if (cur_store_num == STORE_BLACK)
1608 if (black_market_crap(player_ptr, q_ptr)) continue;
1609 if (object_value(q_ptr) < 10) continue;
1613 if (object_value(q_ptr) <= 0) continue;
1616 mass_produce(q_ptr);
1617 (void)store_carry(q_ptr);
1624 * @brief 店舗の割引対象外にするかどうかを判定 /
1625 * Eliminate need to bargain if player has haggled well in the past
1626 * @param minprice アイテムの最低販売価格
1627 * @return 割引を禁止するならTRUEを返す。
1629 static bool noneedtobargain(PRICE minprice)
1631 PRICE good = st_ptr->good_buy;
1632 PRICE bad = st_ptr->bad_buy;
1633 if (minprice < 10L) return TRUE;
1634 if (good == MAX_SHORT) return TRUE;
1635 if (good > ((3 * bad) + (5 + (minprice / 50)))) return TRUE;
1642 * @brief 店主の持つプレイヤーに対する売買の良し悪し経験を記憶する /
1643 * Update the bargain info
1644 * @param price 実際の取引価格
1645 * @param minprice 店主の提示した価格
1649 static void updatebargain(PRICE price, PRICE minprice, int num)
1651 if (!manual_haggle) return;
1652 if ((minprice / num) < 10L) return;
1653 if (price == minprice)
1655 if (st_ptr->good_buy < MAX_SHORT)
1662 if (st_ptr->bad_buy < MAX_SHORT)
1671 * @brief 店の商品リストを再表示する /
1672 * Re-displays a single store entry
1673 * @param player_ptr プレーヤーへの参照ポインタ
1677 static void display_entry(player_type *player_ptr, int pos)
1680 o_ptr = &st_ptr->stock[pos];
1681 int i = (pos % store_bottom);
1683 /* Label it, clear the line --(-- */
1685 (void)sprintf(out_val, "%c) ", ((i > 25) ? toupper(I2A(i - 26)) : I2A(i)));
1686 prt(out_val, i + 6, 0);
1689 if (show_item_graph)
1691 TERM_COLOR a = object_attr(o_ptr);
1692 SYMBOL_CODE c = object_char(o_ptr);
1694 Term_queue_bigchar(cur_col, i + 6, a, c, 0, 0);
1695 if (use_bigtile) cur_col++;
1700 /* Describe an item in the home */
1702 if ((cur_store_num == STORE_HOME) || (cur_store_num == STORE_MUSEUM))
1705 if (show_weights) maxwid -= 10;
1707 GAME_TEXT o_name[MAX_NLEN];
1708 object_desc(player_ptr, o_name, o_ptr, 0);
1709 o_name[maxwid] = '\0';
1710 c_put_str(tval_to_attr[o_ptr->tval], o_name, i + 6, cur_col);
1713 WEIGHT wgt = o_ptr->weight;
1715 sprintf(out_val, "%3d.%1d kg", lbtokg1(wgt), lbtokg2(wgt));
1716 put_str(out_val, i + 6, 67);
1718 (void)sprintf(out_val, "%3d.%d lb", wgt / 10, wgt % 10);
1719 put_str(out_val, i + 6, 68);
1728 if (show_weights) maxwid -= 7;
1730 GAME_TEXT o_name[MAX_NLEN];
1731 object_desc(player_ptr, o_name, o_ptr, 0);
1732 o_name[maxwid] = '\0';
1733 c_put_str(tval_to_attr[o_ptr->tval], o_name, i + 6, cur_col);
1737 int wgt = o_ptr->weight;
1739 sprintf(out_val, "%3d.%1d", lbtokg1(wgt), lbtokg2(wgt));
1740 put_str(out_val, i + 6, 60);
1742 (void)sprintf(out_val, "%3d.%d", wgt / 10, wgt % 10);
1743 put_str(out_val, i + 6, 61);
1749 if (o_ptr->ident & (IDENT_FIXED))
1751 x = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, FALSE);
1753 (void)sprintf(out_val, "%9ld固", (long)x);
1755 (void)sprintf(out_val, "%9ld F", (long)x);
1757 put_str(out_val, i + 6, 68);
1763 x = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, FALSE);
1764 if (!noneedtobargain(x)) x += x / 10;
1766 (void)sprintf(out_val, "%9ld ", (long)x);
1767 put_str(out_val, i + 6, 68);
1771 x = price_item(player_ptr, o_ptr, ot_ptr->max_inflate, FALSE);
1772 (void)sprintf(out_val, "%9ld ", (long)x);
1773 put_str(out_val, i + 6, 68);
1778 * @brief 店の商品リストを表示する /
1779 * Displays a store's inventory -RAK-
1780 * @param player_ptr プレーヤーへの参照ポインタ
1783 * All prices are listed as "per individual object". -BEN-
1785 static void display_store_inventory(player_type *player_ptr)
1788 for (k = 0; k < store_bottom; k++)
1790 if (store_top + k >= st_ptr->stock_num) break;
1792 display_entry(player_ptr, store_top + k);
1795 for (int i = k; i < store_bottom + 1; i++)
1799 put_str(" ", 5, 20);
1801 put_str(" ", 5, 22);
1804 if (st_ptr->stock_num > store_bottom)
1806 prt(_("-続く-", "-more-"), k + 6, 3);
1807 put_str(format(_("(%dページ) ", "(Page %d) "), store_top / store_bottom + 1), 5, _(20, 22));
1810 if (cur_store_num == STORE_HOME || cur_store_num == STORE_MUSEUM)
1812 k = st_ptr->stock_size;
1813 if (cur_store_num == STORE_HOME && !powerup_home) k /= 10;
1815 put_str(format("アイテム数: %4d/%4d", st_ptr->stock_num, k), 19 + xtra_stock, 27);
1817 put_str(format("Objects: %4d/%4d", st_ptr->stock_num, k), 19 + xtra_stock, 30);
1824 * @brief プレイヤーの所持金を表示する /
1825 * Displays players gold -RAK-
1826 * @param player_ptr プレーヤーへの参照ポインタ
1830 static void store_prt_gold(player_type *player_ptr)
1832 prt(_("手持ちのお金: ", "Gold Remaining: "), 19 + xtra_stock, 53);
1834 sprintf(out_val, "%9ld", (long)player_ptr->au);
1835 prt(out_val, 19 + xtra_stock, 68);
1840 * @brief 店舗情報全体を表示するメインルーチン /
1841 * Displays store (after clearing screen) -RAK-
1842 * @param player_ptr プレーヤーへの参照ポインタ
1846 static void display_store(player_type *player_ptr)
1849 if (cur_store_num == STORE_HOME)
1851 put_str(_("我が家", "Your Home"), 3, 31);
1852 put_str(_("アイテムの一覧", "Item Description"), 5, 4);
1855 put_str(_(" 重さ", "Weight"), 5, 70);
1858 store_prt_gold(player_ptr);
1859 display_store_inventory(player_ptr);
1863 if (cur_store_num == STORE_MUSEUM)
1865 put_str(_("博物館", "Museum"), 3, 31);
1866 put_str(_("アイテムの一覧", "Item Description"), 5, 4);
1869 put_str(_(" 重さ", "Weight"), 5, 70);
1872 store_prt_gold(player_ptr);
1873 display_store_inventory(player_ptr);
1877 concptr store_name = (f_name + f_info[cur_store_feat].name);
1878 concptr owner_name = (ot_ptr->owner_name);
1879 concptr race_name = race_info[ot_ptr->owner_race].title;
1881 sprintf(buf, "%s (%s)", owner_name, race_name);
1882 put_str(buf, 3, 10);
1884 sprintf(buf, "%s (%ld)", store_name, (long)(ot_ptr->max_cost));
1887 put_str(_("商品の一覧", "Item Description"), 5, 5);
1890 put_str(_(" 重さ", "Weight"), 5, 60);
1893 put_str(_(" 価格", "Price"), 5, 72);
1894 store_prt_gold(player_ptr);
1895 display_store_inventory(player_ptr);
1900 * @brief 店舗からアイテムを選択する /
1901 * Get the ID of a store item and return its value -RAK-
1902 * @param com_val 選択IDを返す参照ポインタ
1903 * @param pmt メッセージキャプション
1906 * @return 実際に選択したらTRUE、キャンセルしたらFALSE
1908 static int get_stock(COMMAND_CODE *com_val, concptr pmt, int i, int j)
1910 if (repeat_pull(com_val) && (*com_val >= i) && (*com_val <= j))
1918 char hi = (j > 25) ? toupper(I2A(j - 26)) : I2A(j);
1921 (void)sprintf(out_val, "(%s:%c-%c, ESCで中断) %s",
1922 (((cur_store_num == STORE_HOME) || (cur_store_num == STORE_MUSEUM)) ? "アイテム" : "商品"),
1925 (void)sprintf(out_val, "(Items %c-%c, ESC to exit) %s",
1932 if (!get_com(out_val, &command, FALSE)) break;
1935 if (islower(command))
1937 else if (isupper(command))
1938 k = A2I(tolower(command)) + 26;
1942 if ((k >= i) && (k <= j))
1952 if (command == ESCAPE) return FALSE;
1954 repeat_push(*com_val);
1960 * @brief 店主の不満度を増やし、プレイヤーを締め出す判定と処理を行う /
1961 * Increase the insult counter and get angry if too many -RAK-
1962 * @return プレイヤーを締め出す場合TRUEを返す
1964 static int increase_insults(void)
1966 st_ptr->insult_cur++;
1967 if (st_ptr->insult_cur <= ot_ptr->insult_max) return FALSE;
1971 st_ptr->insult_cur = 0;
1972 st_ptr->good_buy = 0;
1973 st_ptr->bad_buy = 0;
1974 st_ptr->store_open = current_world_ptr->game_turn + TURNS_PER_TICK * TOWN_DAWN / 8 + randint1(TURNS_PER_TICK*TOWN_DAWN / 8);
1981 * @brief 店主の不満度を減らす /
1982 * Decrease insults -RAK-
1983 * @return プレイヤーを締め出す場合TRUEを返す
1985 static void decrease_insults(void)
1987 if (st_ptr->insult_cur) st_ptr->insult_cur--;
1992 * @brief 店主の不満度が増えた場合のみのメッセージを表示する /
1993 * Have insulted while haggling -RAK-
1994 * @return プレイヤーを締め出す場合TRUEを返す
1996 static int haggle_insults(void)
1998 if (increase_insults()) return TRUE;
2005 * Mega-Hack -- Enable "increments"
2007 static bool allow_inc = FALSE;
2010 * Mega-Hack -- Last "increment" during haggling
2012 static s32b last_inc = 0L;
2015 * @brief 交渉価格を確認と認証の是非を行う /
2018 * @param poffer 別途価格提示をした場合の値を返す参照ポインタ
2019 * @param price 現在の交渉価格
2020 * @param final 最終確定価格ならばTRUE
2021 * @return プレイヤーを締め出す場合TRUEを返す
2023 static int get_haggle(concptr pmt, s32b *poffer, PRICE price, int final)
2026 if (!allow_inc) last_inc = 0L;
2030 sprintf(buf, _("%s [承諾] ", "%s [accept] "), pmt);
2032 else if (last_inc < 0)
2034 sprintf(buf, _("%s [-$%ld] ", "%s [-%ld] "), pmt, (long)(ABS(last_inc)));
2036 else if (last_inc > 0)
2038 sprintf(buf, _("%s [+$%ld] ", "%s [+%ld] "), pmt, (long)(ABS(last_inc)));
2042 sprintf(buf, "%s ", pmt);
2046 GAME_TEXT out_val[160];
2051 strcpy(out_val, "");
2054 * Ask the user for a response.
2055 * Don't allow to use numpad as cursor key.
2057 res = askfor_aux(out_val, 32, FALSE);
2059 if (!res) return FALSE;
2062 for (p = out_val; *p == ' '; p++) /* loop */;
2073 if (allow_inc && last_inc)
2075 *poffer += last_inc;
2079 msg_print(_("値がおかしいです。", "Invalid response."));
2084 if ((*p == '+' || *p == '-'))
2106 * @brief 店主がプレイヤーからの交渉価格を判断する /
2107 * Receive an offer (from the player)
2109 * @param poffer 店主からの交渉価格を返す参照ポインタ
2110 * @param last_offer 現在の交渉価格
2111 * @param factor 店主の価格基準倍率
2112 * @param price アイテムの実価値
2113 * @param final 最終価格確定ならばTRUE
2114 * @return プレイヤーの価格に対して不服ならばTRUEを返す /
2115 * Return TRUE if offer is NOT okay
2117 static bool receive_offer(concptr pmt, s32b *poffer, s32b last_offer, int factor, PRICE price, int final)
2121 if (!get_haggle(pmt, poffer, price, final)) return TRUE;
2122 if (((*poffer) * factor) >= (last_offer * factor)) break;
2123 if (haggle_insults()) return TRUE;
2125 (*poffer) = last_offer;
2133 * @brief プレイヤーが購入する時の値切り処理メインルーチン /
2134 * Haggling routine -RAK-
2135 * @param player_ptr プレーヤーへの参照ポインタ
2136 * @param o_ptr オブジェクトの構造体参照ポインタ
2137 * @param price 最終価格を返す参照ポインタ
2138 * @return プレイヤーの価格に対して店主が不服ならばTRUEを返す /
2139 * Return TRUE if purchase is NOT successful
2141 static bool purchase_haggle(player_type *player_ptr, object_type *o_ptr, s32b *price)
2143 s32b cur_ask = price_item(player_ptr, o_ptr, ot_ptr->max_inflate, FALSE);
2144 s32b final_ask = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, FALSE);
2145 int noneed = noneedtobargain(final_ask);
2147 concptr pmt = _("提示価格", "Asking");
2148 if (noneed || !manual_haggle)
2152 msg_print(_("結局この金額にまとまった。", "You eventually agree upon the price."));
2157 msg_print(_("すんなりとこの金額にまとまった。", "You quickly agree upon the price."));
2159 final_ask += final_ask / 10;
2162 cur_ask = final_ask;
2163 pmt = _("最終提示価格", "Final Offer");
2167 cur_ask *= o_ptr->number;
2168 final_ask *= o_ptr->number;
2169 s32b min_per = ot_ptr->haggle_per;
2170 s32b max_per = min_per * 3;
2171 s32b last_offer = object_value(o_ptr) * o_ptr->number;
2172 last_offer = last_offer * (200 - (int)(ot_ptr->max_inflate)) / 100L;
2173 if (last_offer <= 0) last_offer = 1;
2179 bool cancel = FALSE;
2183 bool loop_flag = TRUE;
2185 while (!flag && loop_flag)
2188 (void)sprintf(out_val, "%s : %ld", pmt, (long)cur_ask);
2189 put_str(out_val, 1, 0);
2190 cancel = receive_offer(_("提示する金額? ", "What do you offer? "), &offer, last_offer, 1, cur_ask, final);
2195 else if (offer > cur_ask)
2200 else if (offer == cur_ask)
2213 s32b x1 = 100 * (offer - last_offer) / (cur_ask - last_offer);
2216 if (haggle_insults())
2222 else if (x1 > max_per)
2225 if (x1 < max_per) x1 = max_per;
2228 s32b x2 = rand_range(x1 - 2, x1 + 2);
2229 s32b x3 = ((cur_ask - offer) * x2 / 100L) + 1;
2233 if (cur_ask < final_ask)
2236 cur_ask = final_ask;
2237 pmt = _("最終提示価格", "What do you offer? ");
2241 (void)(increase_insults());
2246 else if (offer >= cur_ask)
2256 (void)sprintf(out_val, _("前回の提示金額: $%ld", "Your last offer: %ld"), (long)last_offer);
2257 put_str(out_val, 1, 39);
2258 say_comment_2(cur_ask, annoyed);
2261 if (cancel) return TRUE;
2263 updatebargain(*price, final_ask, o_ptr->number);
2269 * @brief プレイヤーが売却する時の値切り処理メインルーチン /
2270 * Haggling routine -RAK-
2271 * @param player_ptr プレーヤーへの参照ポインタ
2272 * @param o_ptr オブジェクトの構造体参照ポインタ
2273 * @param price 最終価格を返す参照ポインタ
2274 * @return プレイヤーの価格に対して店主が不服ならばTRUEを返す /
2275 * Return TRUE if purchase is NOT successful
2277 static bool sell_haggle(player_type *player_ptr, object_type *o_ptr, s32b *price)
2279 s32b cur_ask = price_item(player_ptr, o_ptr, ot_ptr->max_inflate, TRUE);
2280 s32b final_ask = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, TRUE);
2281 int noneed = noneedtobargain(final_ask);
2282 s32b purse = (s32b)(ot_ptr->max_cost);
2284 concptr pmt = _("提示金額", "Offer");
2285 if (noneed || !manual_haggle || (final_ask >= purse))
2287 if (!manual_haggle && !noneed)
2289 final_ask -= final_ask / 10;
2292 if (final_ask >= purse)
2294 msg_print(_("即座にこの金額にまとまった。", "You instantly agree upon the price."));
2300 msg_print(_("結局この金額にまとまった。", "You eventually agree upon the price."));
2305 msg_print(_("すんなりとこの金額にまとまった。", "You quickly agree upon the price."));
2309 cur_ask = final_ask;
2311 pmt = _("最終提示金額", "Final Offer");
2314 cur_ask *= o_ptr->number;
2315 final_ask *= o_ptr->number;
2317 s32b min_per = ot_ptr->haggle_per;
2318 s32b max_per = min_per * 3;
2319 s32b last_offer = object_value(o_ptr) * o_ptr->number;
2320 last_offer = last_offer * ot_ptr->max_inflate / 100L;
2326 bool cancel = FALSE;
2335 (void)sprintf(out_val, "%s : %ld", pmt, (long)cur_ask);
2336 put_str(out_val, 1, 0);
2337 cancel = receive_offer(_("提示する価格? ", "What price do you ask? "),
2338 &offer, last_offer, -1, cur_ask, final);
2344 else if (offer < cur_ask)
2349 else if (offer == cur_ask)
2359 if (flag || !loop_flag) break;
2364 s32b x1 = 100 * (last_offer - offer) / (last_offer - cur_ask);
2367 if (haggle_insults())
2373 else if (x1 > max_per)
2376 if (x1 < max_per) x1 = max_per;
2379 s32b x2 = rand_range(x1 - 2, x1 + 2);
2380 s32b x3 = ((offer - cur_ask) * x2 / 100L) + 1;
2384 if (cur_ask > final_ask)
2386 cur_ask = final_ask;
2388 pmt = _("最終提示金額", "Final Offer");
2395 /* 追加 $0 で買い取られてしまうのを防止 By FIRST*/
2398 (void)(increase_insults());
2401 else if (offer <= cur_ask)
2411 (void)sprintf(out_val, _("前回の提示価格 $%ld", "Your last bid %ld"), (long)last_offer);
2412 put_str(out_val, 1, 39);
2413 say_comment_3(cur_ask, annoyed);
2416 if (cancel) return TRUE;
2418 updatebargain(*price, final_ask, o_ptr->number);
2424 * @brief 店からの購入処理のメインルーチン /
2425 * Buy an item from a store -RAK-
2426 * @param player_ptr プレーヤーへの参照ポインタ
2429 static void store_purchase(player_type *player_ptr)
2431 if (cur_store_num == STORE_MUSEUM)
2433 msg_print(_("博物館から取り出すことはできません。", "Museum."));
2437 if (st_ptr->stock_num <= 0)
2439 if (cur_store_num == STORE_HOME)
2440 msg_print(_("我が家には何も置いてありません。", "Your home is empty."));
2442 msg_print(_("現在商品の在庫を切らしています。", "I am currently out of stock."));
2446 int i = (st_ptr->stock_num - store_top);
2447 if (i > store_bottom) i = store_bottom;
2451 /* ブラックマーケットの時は別のメッセージ */
2452 switch (cur_store_num) {
2454 sprintf(out_val, "どのアイテムを取りますか? ");
2457 sprintf(out_val, "どれ? ");
2460 sprintf(out_val, "どの品物が欲しいんだい? ");
2464 if (cur_store_num == STORE_HOME)
2466 sprintf(out_val, "Which item do you want to take? ");
2470 sprintf(out_val, "Which item are you interested in? ");
2475 if (!get_stock(&item, out_val, 0, i - 1)) return;
2477 item = item + store_top;
2479 o_ptr = &st_ptr->stock[item];
2480 ITEM_NUMBER amt = 1;
2484 object_copy(j_ptr, o_ptr);
2487 * If a rod or wand, allocate total maximum timeouts or charges
2488 * between those purchased and left on the shelf.
2490 reduce_charges(j_ptr, o_ptr->number - amt);
2491 j_ptr->number = amt;
2492 if (!inven_carry_okay(j_ptr))
2494 msg_print(_("そんなにアイテムを持てない。", "You cannot carry that many different items."));
2498 PRICE best = price_item(player_ptr, j_ptr, ot_ptr->min_inflate, FALSE);
2499 if (o_ptr->number > 1)
2501 if ((cur_store_num != STORE_HOME) &&
2502 (o_ptr->ident & IDENT_FIXED))
2504 msg_format(_("一つにつき $%ldです。", "That costs %ld gold per item."), (long)(best));
2507 amt = get_quantity(NULL, o_ptr->number);
2508 if (amt <= 0) return;
2512 object_copy(j_ptr, o_ptr);
2515 * If a rod or wand, allocate total maximum timeouts or charges
2516 * between those purchased and left on the shelf.
2518 reduce_charges(j_ptr, o_ptr->number - amt);
2519 j_ptr->number = amt;
2520 if (!inven_carry_okay(j_ptr))
2522 msg_print(_("ザックにそのアイテムを入れる隙間がない。", "You cannot carry that many items."));
2527 COMMAND_CODE item_new;
2529 if (cur_store_num == STORE_HOME)
2531 bool combined_or_reordered;
2532 distribute_charges(o_ptr, j_ptr, amt);
2533 item_new = inven_carry(player_ptr, j_ptr);
2534 GAME_TEXT o_name[MAX_NLEN];
2535 object_desc(player_ptr, o_name, &player_ptr->inventory_list[item_new], 0);
2537 msg_format(_("%s(%c)を取った。", "You have %s (%c)."), o_name, index_to_label(item_new));
2538 handle_stuff(player_ptr);
2540 i = st_ptr->stock_num;
2541 store_item_increase(item, -amt);
2542 store_item_optimize(item);
2543 combined_or_reordered = combine_and_reorder_home(STORE_HOME);
2544 if (i == st_ptr->stock_num)
2546 if (combined_or_reordered) display_store_inventory(player_ptr);
2547 else display_entry(player_ptr, item);
2551 if (st_ptr->stock_num == 0) store_top = 0;
2552 else if (store_top >= st_ptr->stock_num) store_top -= store_bottom;
2553 display_store_inventory(player_ptr);
2555 chg_virtue(player_ptr, V_SACRIFICE, 1);
2561 if (o_ptr->ident & (IDENT_FIXED))
2564 price = (best * j_ptr->number);
2568 GAME_TEXT o_name[MAX_NLEN];
2569 object_desc(player_ptr, o_name, j_ptr, 0);
2570 msg_format(_("%s(%c)を購入する。", "Buying %s (%c)."), o_name, I2A(item));
2572 choice = purchase_haggle(player_ptr, j_ptr, &price);
2573 if (st_ptr->store_open >= current_world_ptr->game_turn) return;
2576 if (choice != 0) return;
2577 if (price == (best * j_ptr->number)) o_ptr->ident |= (IDENT_FIXED);
2578 if (player_ptr->au < price)
2580 msg_print(_("お金が足りません。", "You do not have enough gold."));
2584 say_comment_1(player_ptr);
2585 if (cur_store_num == STORE_BLACK)
2586 chg_virtue(player_ptr, V_JUSTICE, -1);
2587 if ((o_ptr->tval == TV_BOTTLE) && (cur_store_num != STORE_HOME))
2588 chg_virtue(player_ptr, V_NATURE, -1);
2592 player_ptr->au -= price;
2593 store_prt_gold(player_ptr);
2594 object_aware(player_ptr, j_ptr);
2595 j_ptr->ident &= ~(IDENT_FIXED);
2596 GAME_TEXT o_name[MAX_NLEN];
2597 object_desc(player_ptr, o_name, j_ptr, 0);
2599 msg_format(_("%sを $%ldで購入しました。", "You bought %s for %ld gold."), o_name, (long)price);
2601 strcpy(record_o_name, o_name);
2602 record_turn = current_world_ptr->game_turn;
2604 if (record_buy) exe_write_diary(player_ptr, DIARY_BUY, 0, o_name);
2605 object_desc(player_ptr, o_name, o_ptr, OD_NAME_ONLY);
2606 if (record_rand_art && o_ptr->art_name)
2607 exe_write_diary(player_ptr, DIARY_ART, 0, o_name);
2609 j_ptr->inscription = 0;
2610 j_ptr->feeling = FEEL_NONE;
2611 j_ptr->ident &= ~(IDENT_STORE);
2612 item_new = inven_carry(player_ptr, j_ptr);
2614 object_desc(player_ptr, o_name, &player_ptr->inventory_list[item_new], 0);
2615 msg_format(_("%s(%c)を手に入れた。", "You have %s (%c)."), o_name, index_to_label(item_new));
2616 autopick_alter_item(player_ptr, item_new, FALSE);
2617 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
2619 o_ptr->pval -= j_ptr->pval;
2622 handle_stuff(player_ptr);
2623 i = st_ptr->stock_num;
2624 store_item_increase(item, -amt);
2625 store_item_optimize(item);
2626 if (st_ptr->stock_num == 0)
2628 if (one_in_(STORE_SHUFFLE))
2631 msg_print(_("店主は引退した。", "The shopkeeper retires."));
2632 store_shuffle(player_ptr, cur_store_num);
2635 sprintf(buf, "%s (%s)",
2636 ot_ptr->owner_name, race_info[ot_ptr->owner_race].title);
2637 put_str(buf, 3, 10);
2638 sprintf(buf, "%s (%ld)",
2639 (f_name + f_info[cur_store_feat].name), (long)(ot_ptr->max_cost));
2644 msg_print(_("店主は新たな在庫を取り出した。", "The shopkeeper brings out some new stock."));
2647 for (i = 0; i < 10; i++)
2649 store_maint(player_ptr, player_ptr->town_num, cur_store_num);
2653 display_store_inventory(player_ptr);
2655 else if (st_ptr->stock_num != i)
2657 if (store_top >= st_ptr->stock_num) store_top -= store_bottom;
2658 display_store_inventory(player_ptr);
2662 display_entry(player_ptr, item);
2668 * @brief 店からの売却処理のメインルーチン /
2669 * Sell an item to the store (or home)
2670 * @param owner_ptr プレーヤーへの参照ポインタ
2673 static void store_sell(player_type *owner_ptr)
2676 if (cur_store_num == STORE_HOME)
2677 q = _("どのアイテムを置きますか? ", "Drop which item? ");
2678 else if (cur_store_num == STORE_MUSEUM)
2679 q = _("どのアイテムを寄贈しますか? ", "Give which item? ");
2681 q = _("どのアイテムを売りますか? ", "Sell which item? ");
2683 item_tester_hook = store_will_buy;
2685 /* 我が家でおかしなメッセージが出るオリジナルのバグを修正 */
2687 if (cur_store_num == STORE_HOME)
2689 s = _("置けるアイテムを持っていません。", "You don't have any item to drop.");
2691 else if (cur_store_num == STORE_MUSEUM)
2693 s = _("寄贈できるアイテムを持っていません。", "You don't have any item to give.");
2697 s = _("欲しい物がないですねえ。", "You have nothing that I want.");
2702 o_ptr = choose_object(owner_ptr, &item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT), 0);
2705 if ((item >= INVEN_RARM) && object_is_cursed(o_ptr))
2707 msg_print(_("ふーむ、どうやらそれは呪われているようだね。", "Hmmm, it seems to be cursed."));
2712 if (o_ptr->number > 1)
2714 amt = get_quantity(NULL, o_ptr->number);
2715 if (amt <= 0) return;
2721 object_copy(q_ptr, o_ptr);
2722 q_ptr->number = amt;
2725 * Hack -- If a rod or wand, allocate total maximum
2726 * timeouts or charges to those being sold. -LM-
2728 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
2730 q_ptr->pval = o_ptr->pval * amt / o_ptr->number;
2733 GAME_TEXT o_name[MAX_NLEN];
2734 object_desc(owner_ptr, o_name, q_ptr, 0);
2736 /* Remove any inscription, feeling for stores */
2737 if ((cur_store_num != STORE_HOME) && (cur_store_num != STORE_MUSEUM))
2739 q_ptr->inscription = 0;
2740 q_ptr->feeling = FEEL_NONE;
2743 /* Is there room in the store (or the home?) */
2744 if (!store_check_num(q_ptr))
2746 if (cur_store_num == STORE_HOME)
2747 msg_print(_("我が家にはもう置く場所がない。", "Your home is full."));
2749 else if (cur_store_num == STORE_MUSEUM)
2750 msg_print(_("博物館はもう満杯だ。", "Museum is full."));
2753 msg_print(_("すいませんが、店にはもう置く場所がありません。", "I have not the room in my store to keep it."));
2759 PRICE price, value, dummy;
2760 if ((cur_store_num != STORE_HOME) && (cur_store_num != STORE_MUSEUM))
2762 msg_format(_("%s(%c)を売却する。", "Selling %s (%c)."), o_name, index_to_label(item));
2765 choice = sell_haggle(owner_ptr, q_ptr, &price);
2766 if (st_ptr->store_open >= current_world_ptr->game_turn) return;
2770 say_comment_1(owner_ptr);
2772 if (cur_store_num == STORE_BLACK)
2773 chg_virtue(owner_ptr, V_JUSTICE, -1);
2775 if ((o_ptr->tval == TV_BOTTLE) && (cur_store_num != STORE_HOME))
2776 chg_virtue(owner_ptr, V_NATURE, 1);
2779 owner_ptr->au += price;
2780 store_prt_gold(owner_ptr);
2781 dummy = object_value(q_ptr) * q_ptr->number;
2783 identify_item(owner_ptr, o_ptr);
2785 object_copy(q_ptr, o_ptr);
2786 q_ptr->number = amt;
2787 q_ptr->ident |= IDENT_STORE;
2790 * Hack -- If a rod or wand, let the shopkeeper know just
2791 * how many charges he really paid for. -LM-
2793 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
2795 q_ptr->pval = o_ptr->pval * amt / o_ptr->number;
2798 value = object_value(q_ptr) * q_ptr->number;
2799 object_desc(owner_ptr, o_name, q_ptr, 0);
2800 msg_format(_("%sを $%ldで売却しました。", "You sold %s for %ld gold."), o_name, (long)price);
2802 if (record_sell) exe_write_diary(owner_ptr, DIARY_SELL, 0, o_name);
2804 if (!((o_ptr->tval == TV_FIGURINE) && (value > 0)))
2806 purchase_analyze(owner_ptr, price, value, dummy);
2810 * Hack -- Allocate charges between those wands or rods sold
2811 * and retained, unless all are being sold. -LM-
2813 distribute_charges(o_ptr, q_ptr, amt);
2815 inven_item_increase(owner_ptr, item, -amt);
2816 inven_item_describe(owner_ptr, item);
2817 if (o_ptr->number > 0)
2818 autopick_alter_item(owner_ptr, item, FALSE);
2820 inven_item_optimize(owner_ptr, item);
2821 handle_stuff(owner_ptr);
2822 int item_pos = store_carry(q_ptr);
2825 store_top = (item_pos / store_bottom) * store_bottom;
2826 display_store_inventory(owner_ptr);
2830 else if (cur_store_num == STORE_MUSEUM)
2832 char o2_name[MAX_NLEN];
2833 object_desc(owner_ptr, o2_name, q_ptr, OD_NAME_ONLY);
2835 if (-1 == store_check_num(q_ptr))
2837 msg_print(_("それと同じ品物は既に博物館にあるようです。", "The Museum already has one of those items."));
2841 msg_print(_("博物館に寄贈したものは取り出すことができません!!", "You cannot take back items which have been donated to the Museum!!"));
2844 if (!get_check(format(_("本当に%sを寄贈しますか?", "Really give %s to the Museum? "), o2_name))) return;
2846 identify_item(owner_ptr, q_ptr);
2847 q_ptr->ident |= IDENT_FULL_KNOWN;
2849 distribute_charges(o_ptr, q_ptr, amt);
2850 msg_format(_("%sを置いた。(%c)", "You drop %s (%c)."), o_name, index_to_label(item));
2853 vary_item(owner_ptr, item, -amt);
2854 handle_stuff(owner_ptr);
2856 int item_pos = home_carry(owner_ptr, q_ptr);
2859 store_top = (item_pos / store_bottom) * store_bottom;
2860 display_store_inventory(owner_ptr);
2865 distribute_charges(o_ptr, q_ptr, amt);
2866 msg_format(_("%sを置いた。(%c)", "You drop %s (%c)."), o_name, index_to_label(item));
2868 vary_item(owner_ptr, item, -amt);
2869 handle_stuff(owner_ptr);
2870 int item_pos = home_carry(owner_ptr, q_ptr);
2873 store_top = (item_pos / store_bottom) * store_bottom;
2874 display_store_inventory(owner_ptr);
2878 if ((choice == 0) && (item >= INVEN_RARM))
2880 calc_android_exp(owner_ptr);
2881 verify_equip_slot(owner_ptr, item);
2887 * @brief 店のアイテムを調べるコマンドのメインルーチン /
2888 * Examine an item in a store -JDL-
2891 static void store_examine(player_type *player_ptr)
2893 if (st_ptr->stock_num <= 0)
2895 if (cur_store_num == STORE_HOME)
2896 msg_print(_("我が家には何も置いてありません。", "Your home is empty."));
2897 else if (cur_store_num == STORE_MUSEUM)
2898 msg_print(_("博物館には何も置いてありません。", "Museum is empty."));
2900 msg_print(_("現在商品の在庫を切らしています。", "I am currently out of stock."));
2904 int i = (st_ptr->stock_num - store_top);
2905 if (i > store_bottom) i = store_bottom;
2908 sprintf(out_val, _("どれを調べますか?", "Which item do you want to examine? "));
2911 if (!get_stock(&item, out_val, 0, i - 1)) return;
2912 item = item + store_top;
2914 o_ptr = &st_ptr->stock[item];
2915 if (!OBJECT_IS_FULL_KNOWN(o_ptr))
2917 msg_print(_("このアイテムについて特に知っていることはない。", "You have no special knowledge about that item."));
2921 GAME_TEXT o_name[MAX_NLEN];
2922 object_desc(player_ptr, o_name, o_ptr, 0);
2923 msg_format(_("%sを調べている...", "Examining %s..."), o_name);
2925 if (!screen_object(player_ptr, o_ptr, SCROBJ_FORCE_DETAIL))
2926 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
2933 * @brief 博物館のアイテムを除去するコマンドのメインルーチン /
2934 * Remove an item from museum (Originally from TOband)
2935 * @param player_ptr プレーヤーへの参照ポインタ
2938 static void museum_remove_object(player_type *player_ptr)
2940 if (st_ptr->stock_num <= 0)
2942 msg_print(_("博物館には何も置いてありません。", "Museum is empty."));
2946 int i = st_ptr->stock_num - store_top;
2947 if (i > store_bottom) i = store_bottom;
2950 sprintf(out_val, _("どのアイテムの展示をやめさせますか?", "Which item do you want to order to remove? "));
2953 if (!get_stock(&item, out_val, 0, i - 1)) return;
2955 item = item + store_top;
2957 o_ptr = &st_ptr->stock[item];
2959 GAME_TEXT o_name[MAX_NLEN];
2960 object_desc(player_ptr, o_name, o_ptr, 0);
2962 msg_print(_("展示をやめさせたアイテムは二度と見ることはできません!", "Once removed from the Museum, an item will be gone forever!"));
2963 if (!get_check(format(_("本当に%sの展示をやめさせますか?", "Really order to remove %s from the Museum? "), o_name))) return;
2965 msg_format(_("%sの展示をやめさせた。", "You ordered to remove %s."), o_name);
2967 store_item_increase(item, -o_ptr->number);
2968 store_item_optimize(item);
2970 (void)combine_and_reorder_home(STORE_MUSEUM);
2971 if (st_ptr->stock_num == 0) store_top = 0;
2973 else if (store_top >= st_ptr->stock_num) store_top -= store_bottom;
2974 display_store_inventory(player_ptr);
2979 * Hack -- set this to leave the store
2981 static bool leave_store = FALSE;
2985 * @brief 店舗処理コマンド選択のメインルーチン /
2986 * Process a command in a store
2987 * @param client_ptr 顧客となるクリーチャーの参照ポインタ
2991 * Note that we must allow the use of a few "special" commands
2992 * in the stores which are not allowed in the dungeon, and we
2993 * must disable some commands which are allowed in the dungeon
2994 * but not in the stores, to prevent chaos.
2997 static void store_process_command(player_type *client_ptr)
3000 if (rogue_like_commands && command_cmd == 'l')
3005 switch (command_cmd)
3015 /* 1 ページ戻るコマンド: 我が家のページ数が多いので重宝するはず By BUG */
3016 if (st_ptr->stock_num <= store_bottom) {
3017 msg_print(_("これで全部です。", "Entire inventory is shown."));
3020 store_top -= store_bottom;
3022 store_top = ((st_ptr->stock_num - 1) / store_bottom) * store_bottom;
3023 if ((cur_store_num == STORE_HOME) && (powerup_home == FALSE))
3024 if (store_top >= store_bottom) store_top = store_bottom;
3025 display_store_inventory(client_ptr);
3032 if (st_ptr->stock_num <= store_bottom)
3034 msg_print(_("これで全部です。", "Entire inventory is shown."));
3038 store_top += store_bottom;
3040 * 隠しオプション(powerup_home)がセットされていないときは
3041 * 我が家では 2 ページまでしか表示しない
3043 if ((cur_store_num == STORE_HOME) &&
3044 (powerup_home == FALSE) &&
3045 (st_ptr->stock_num >= STORE_INVEN_MAX))
3047 if (store_top >= (STORE_INVEN_MAX - 1))
3054 if (store_top >= st_ptr->stock_num) store_top = 0;
3057 display_store_inventory(client_ptr);
3064 do_cmd_redraw(client_ptr);
3065 display_store(client_ptr);
3070 store_purchase(client_ptr);
3075 store_sell(client_ptr);
3080 store_examine(client_ptr);
3089 do_cmd_wield(client_ptr);
3094 do_cmd_takeoff(client_ptr);
3099 do_cmd_destroy(client_ptr);
3104 do_cmd_equip(client_ptr);
3109 do_cmd_inven(client_ptr);
3114 do_cmd_observe(client_ptr);
3119 toggle_inventory_equipment(client_ptr);
3124 if ((client_ptr->pclass == CLASS_MINDCRAFTER) ||
3125 (client_ptr->pclass == CLASS_BERSERKER) ||
3126 (client_ptr->pclass == CLASS_NINJA) ||
3127 (client_ptr->pclass == CLASS_MIRROR_MASTER)
3128 ) do_cmd_mind_browse(client_ptr);
3129 else if (client_ptr->pclass == CLASS_SMITH)
3130 do_cmd_kaji(client_ptr, TRUE);
3131 else if (client_ptr->pclass == CLASS_MAGIC_EATER)
3132 do_cmd_magic_eater(client_ptr, TRUE, FALSE);
3133 else if (client_ptr->pclass == CLASS_SNIPER)
3134 do_cmd_snipe_browse(client_ptr);
3135 else do_cmd_browse(client_ptr);
3140 do_cmd_inscribe(client_ptr);
3145 do_cmd_uninscribe(client_ptr);
3150 do_cmd_help(client_ptr);
3155 do_cmd_query_symbol(client_ptr);
3160 client_ptr->town_num = old_town_num;
3161 do_cmd_player_status(client_ptr);
3162 client_ptr->town_num = inner_town_num;
3163 display_store(client_ptr);
3173 client_ptr->town_num = old_town_num;
3174 do_cmd_pref(client_ptr);
3175 client_ptr->town_num = inner_town_num;
3180 client_ptr->town_num = old_town_num;
3181 do_cmd_macros(client_ptr);
3182 client_ptr->town_num = inner_town_num;
3187 client_ptr->town_num = old_town_num;
3188 do_cmd_visuals(client_ptr);
3189 client_ptr->town_num = inner_town_num;
3194 client_ptr->town_num = old_town_num;
3195 do_cmd_colors(client_ptr);
3196 client_ptr->town_num = inner_town_num;
3202 (void)combine_and_reorder_home(STORE_HOME);
3203 do_cmd_redraw(client_ptr);
3204 display_store(client_ptr);
3219 do_cmd_feeling(client_ptr);
3224 do_cmd_message_one();
3234 do_cmd_diary(client_ptr);
3239 do_cmd_knowledge(client_ptr);
3244 do_cmd_load_screen();
3249 do_cmd_save_screen(client_ptr);
3254 if ((cur_store_num == STORE_MUSEUM) && (command_cmd == 'r'))
3256 museum_remove_object(client_ptr);
3260 msg_print(_("そのコマンドは店の中では使えません。", "That command does not work in stores."));
3270 * @brief 店舗処理全体のメインルーチン /
3271 * Enter a store, and interact with it. *
3272 * @param player_ptr プレーヤーへの参照ポインタ
3276 * Note that we use the standard "request_command()" function
3277 * to get a command, allowing us to use "command_arg" and all
3278 * command macros and other nifty stuff, but we use the special
3279 * "shopping" argument, to force certain commands to be converted
3280 * into other commands, normally, we convert "p" (pray) and "m"
3281 * (cast magic) into "g" (get), and "s" (search) into "d" (drop).
3284 void do_cmd_store(player_type *player_ptr)
3286 if (player_ptr->wild_mode) return;
3288 Term_get_size(&w, &h);
3290 xtra_stock = MIN(14 + 26, ((h > 24) ? (h - 24) : 0));
3291 store_bottom = MIN_STOCK + xtra_stock;
3294 g_ptr = &player_ptr->current_floor_ptr->grid_array[player_ptr->y][player_ptr->x];
3296 if (!cave_have_flag_grid(g_ptr, FF_STORE))
3298 msg_print(_("ここには店がありません。", "You see no store here."));
3302 int which = f_info[g_ptr->feat].subtype;
3303 old_town_num = player_ptr->town_num;
3304 if ((which == STORE_HOME) || (which == STORE_MUSEUM)) player_ptr->town_num = 1;
3305 if (player_ptr->current_floor_ptr->dun_level) player_ptr->town_num = NO_TOWN;
3306 inner_town_num = player_ptr->town_num;
3308 if ((town_info[player_ptr->town_num].store[which].store_open >= current_world_ptr->game_turn) ||
3311 msg_print(_("ドアに鍵がかかっている。", "The doors are locked."));
3312 player_ptr->town_num = old_town_num;
3316 int maintain_num = (current_world_ptr->game_turn - town_info[player_ptr->town_num].store[which].last_visit) / (TURNS_PER_TICK * STORE_TICKS);
3317 if (maintain_num > 10)
3321 for (int i = 0; i < maintain_num; i++)
3322 store_maint(player_ptr, player_ptr->town_num, which);
3324 town_info[player_ptr->town_num].store[which].last_visit = current_world_ptr->game_turn;
3327 forget_lite(player_ptr->current_floor_ptr);
3328 forget_view(player_ptr->current_floor_ptr);
3329 current_world_ptr->character_icky = TRUE;
3333 get_com_no_macros = TRUE;
3334 cur_store_num = which;
3335 cur_store_feat = g_ptr->feat;
3336 st_ptr = &town_info[player_ptr->town_num].store[cur_store_num];
3337 ot_ptr = &owners[cur_store_num][st_ptr->owner];
3339 play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_BUILD);
3340 display_store(player_ptr);
3341 leave_store = FALSE;
3343 while (!leave_store)
3346 clear_from(20 + xtra_stock);
3347 prt(_(" ESC) 建物から出る", " ESC) Exit from Building."), 21 + xtra_stock, 0);
3348 if (st_ptr->stock_num > store_bottom)
3350 prt(_(" -)前ページ", " -) Previous page"), 22 + xtra_stock, 0);
3351 prt(_(" スペース) 次ページ", " SPACE) Next page"), 23 + xtra_stock, 0);
3354 if (cur_store_num == STORE_HOME)
3356 prt(_("g) アイテムを取る", "g) Get an item."), 21 + xtra_stock, 27);
3357 prt(_("d) アイテムを置く", "d) Drop an item."), 22 + xtra_stock, 27);
3358 prt(_("x) 家のアイテムを調べる", "x) eXamine an item in the home."), 23 + xtra_stock, 27);
3360 else if (cur_store_num == STORE_MUSEUM)
3362 prt(_("d) アイテムを置く", "d) Drop an item."), 21 + xtra_stock, 27);
3363 prt(_("r) アイテムの展示をやめる", "r) order to Remove an item."), 22 + xtra_stock, 27);
3364 prt(_("x) 博物館のアイテムを調べる", "x) eXamine an item in the museum."), 23 + xtra_stock, 27);
3368 prt(_("p) 商品を買う", "p) Purchase an item."), 21 + xtra_stock, 30);
3369 prt(_("s) アイテムを売る", "s) Sell an item."), 22 + xtra_stock, 30);
3370 prt(_("x) 商品を調べる", "x) eXamine an item in the shop"), 23 + xtra_stock, 30);
3373 prt(_("i/e) 持ち物/装備の一覧", "i/e) Inventry/Equipment list"), 21 + xtra_stock, 56);
3374 if (rogue_like_commands)
3376 prt(_("w/T) 装備する/はずす", "w/T) Wear/Take off equipment"), 22 + xtra_stock, 56);
3380 prt(_("w/t) 装備する/はずす", "w/t) Wear/Take off equipment"), 22 + xtra_stock, 56);
3383 prt(_("コマンド:", "You may: "), 20 + xtra_stock, 0);
3384 request_command(player_ptr, TRUE);
3385 store_process_command(player_ptr);
3388 * Hack -- To redraw missiles damage and prices in store
3389 * If player's charisma changes, or if player changes a bow, PU_BONUS is set
3391 bool need_redraw_store_inv = (player_ptr->update & PU_BONUS) ? TRUE : FALSE;
3392 current_world_ptr->character_icky = TRUE;
3393 handle_stuff(player_ptr);
3394 if (player_ptr->inventory_list[INVEN_PACK].k_idx)
3396 INVENTORY_IDX item = INVEN_PACK;
3397 object_type *o_ptr = &player_ptr->inventory_list[item];
3398 if (cur_store_num != STORE_HOME)
3400 if (cur_store_num == STORE_MUSEUM)
3401 msg_print(_("ザックからアイテムがあふれそうなので、あわてて博物館から出た...", "Your pack is so full that you flee the Museum..."));
3403 msg_print(_("ザックからアイテムがあふれそうなので、あわてて店から出た...", "Your pack is so full that you flee the store..."));
3407 else if (!store_check_num(o_ptr))
3409 msg_print(_("ザックからアイテムがあふれそうなので、あわてて家から出た...", "Your pack is so full that you flee your home..."));
3417 GAME_TEXT o_name[MAX_NLEN];
3418 msg_print(_("ザックからアイテムがあふれてしまった!", "Your pack overflows!"));
3420 object_copy(q_ptr, o_ptr);
3421 object_desc(player_ptr, o_name, q_ptr, 0);
3422 msg_format(_("%sが落ちた。(%c)", "You drop %s (%c)."), o_name, index_to_label(item));
3423 vary_item(player_ptr, item, -255);
3424 handle_stuff(player_ptr);
3426 item_pos = home_carry(player_ptr, q_ptr);
3429 store_top = (item_pos / store_bottom) * store_bottom;
3430 display_store_inventory(player_ptr);
3435 if (need_redraw_store_inv) display_store_inventory(player_ptr);
3437 if (st_ptr->store_open >= current_world_ptr->game_turn) leave_store = TRUE;
3440 select_floor_music(player_ptr);
3441 player_ptr->town_num = old_town_num;
3442 take_turn(player_ptr, 100);
3443 current_world_ptr->character_icky = FALSE;
3445 command_see = FALSE;
3446 get_com_no_macros = FALSE;
3451 player_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
3452 player_ptr->update |= (PU_MONSTERS);
3453 player_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_EQUIPPY);
3454 player_ptr->redraw |= (PR_MAP);
3455 player_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
3460 * @brief 現在の町の店主を交代させる /
3461 * Shuffle one of the stores.
3462 * @param which 店舗種類のID
3465 void store_shuffle(player_type *player_ptr, int which)
3467 if (which == STORE_HOME) return;
3468 if (which == STORE_MUSEUM) return;
3470 cur_store_num = which;
3471 st_ptr = &town_info[player_ptr->town_num].store[cur_store_num];
3472 int j = st_ptr->owner;
3475 st_ptr->owner = (byte)randint0(MAX_OWNERS);
3476 if (j == st_ptr->owner) continue;
3478 for (i = 1; i < max_towns; i++)
3480 if (i == player_ptr->town_num) continue;
3481 if (st_ptr->owner == town_info[i].store[cur_store_num].owner) break;
3484 if (i == max_towns) break;
3487 ot_ptr = &owners[cur_store_num][st_ptr->owner];
3488 st_ptr->insult_cur = 0;
3489 st_ptr->store_open = 0;
3490 st_ptr->good_buy = 0;
3491 st_ptr->bad_buy = 0;
3492 for (int i = 0; i < st_ptr->stock_num; i++)
3495 o_ptr = &st_ptr->stock[i];
3496 if (object_is_artifact(o_ptr)) continue;
3498 o_ptr->discount = 50;
3499 o_ptr->ident &= ~(IDENT_FIXED);
3500 o_ptr->inscription = quark_add(_("売出中", "on sale"));
3506 * @brief 店の品揃えを変化させる /
3507 * Maintain the inventory at the stores.
3508 * @param player_ptr プレーヤーへの参照ポインタ
3509 * @param town_num 町のID
3510 * @param store_num 店舗種類のID
3513 void store_maint(player_type *player_ptr, int town_num, int store_num)
3515 cur_store_num = store_num;
3516 if (store_num == STORE_HOME) return;
3517 if (store_num == STORE_MUSEUM) return;
3519 st_ptr = &town_info[town_num].store[store_num];
3520 ot_ptr = &owners[store_num][st_ptr->owner];
3521 st_ptr->insult_cur = 0;
3522 if (store_num == STORE_BLACK)
3524 for (INVENTORY_IDX j = st_ptr->stock_num - 1; j >= 0; j--)
3526 object_type *o_ptr = &st_ptr->stock[j];
3527 if (black_market_crap(player_ptr, o_ptr))
3529 store_item_increase(j, 0 - o_ptr->number);
3530 store_item_optimize(j);
3535 INVENTORY_IDX j = st_ptr->stock_num;
3536 j = j - randint1(STORE_TURNOVER);
3537 if (j > STORE_MAX_KEEP) j = STORE_MAX_KEEP;
3538 if (j < STORE_MIN_KEEP) j = STORE_MIN_KEEP;
3541 while (st_ptr->stock_num > j)
3544 j = st_ptr->stock_num;
3545 j = j + randint1(STORE_TURNOVER);
3546 if (j > STORE_MAX_KEEP) j = STORE_MAX_KEEP;
3547 if (j < STORE_MIN_KEEP) j = STORE_MIN_KEEP;
3548 if (j >= st_ptr->stock_size) j = st_ptr->stock_size - 1;
3550 while (st_ptr->stock_num < j) store_create(player_ptr);
3555 * @brief 店舗情報を初期化する /
3556 * Initialize the stores
3557 * @param town_num 町のID
3558 * @param store_num 店舗種類のID
3561 void store_init(int town_num, int store_num)
3563 cur_store_num = store_num;
3564 st_ptr = &town_info[town_num].store[store_num];
3567 st_ptr->owner = (byte)randint0(MAX_OWNERS);
3569 for (i = 1; i < max_towns; i++)
3571 if (i == town_num) continue;
3572 if (st_ptr->owner == town_info[i].store[store_num].owner) break;
3575 if (i == max_towns) break;
3578 ot_ptr = &owners[store_num][st_ptr->owner];
3580 st_ptr->store_open = 0;
3581 st_ptr->insult_cur = 0;
3582 st_ptr->good_buy = 0;
3583 st_ptr->bad_buy = 0;
3584 st_ptr->stock_num = 0;
3585 st_ptr->last_visit = -10L * TURNS_PER_TICK * STORE_TICKS;
3586 for (int k = 0; k < st_ptr->stock_size; k++)
3588 object_wipe(&st_ptr->stock[k]);