OSDN Git Service

[Refactor] #40233 Separated purchase-order.c/h from store.c/h
authorHourier <hourier@users.sourceforge.jp>
Thu, 16 Jul 2020 12:59:21 +0000 (21:59 +0900)
committerHourier <hourier@users.sourceforge.jp>
Thu, 16 Jul 2020 13:00:52 +0000 (22:00 +0900)
Hengband/Hengband/Hengband.vcxproj
Hengband/Hengband/Hengband.vcxproj.filters
src/Makefile.am
src/io/store-key-processor.c
src/store/purchase-order.c [new file with mode: 0644]
src/store/purchase-order.h [new file with mode: 0644]
src/store/store.c
src/store/store.h

index 1acc0b1..3e009c3 100644 (file)
     <ClCompile Include="..\..\src\status\experience.c" />\r
     <ClCompile Include="..\..\src\status\temporary-resistance.c" />\r
     <ClCompile Include="..\..\src\store\home.c" />\r
+    <ClCompile Include="..\..\src\store\purchase-order.c" />\r
     <ClCompile Include="..\..\src\view\display-inventory.c" />\r
     <ClCompile Include="..\..\src\view\display-map.c" />\r
     <ClCompile Include="..\..\src\window\display-sub-window-items.c" />\r
     <ClInclude Include="..\..\src\status\experience.h" />\r
     <ClInclude Include="..\..\src\status\temporary-resistance.h" />\r
     <ClInclude Include="..\..\src\store\home.h" />\r
+    <ClInclude Include="..\..\src\store\purchase-order.h" />\r
     <ClInclude Include="..\..\src\system\alloc-entries.h" />\r
     <ClInclude Include="..\..\src\term\screen-processor.h" />\r
     <ClInclude Include="..\..\src\util\bit-flags-calculator.h" />\r
index c53297e..83abac1 100644 (file)
     <ClCompile Include="..\..\src\cmd-building\cmd-store.c">
       <Filter>cmd-building</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\store\purchase-order.c">
+      <Filter>store</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\src\combat\shoot.h">
     <ClInclude Include="..\..\src\cmd-building\cmd-store.h">
       <Filter>cmd-building</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\store\purchase-order.h">
+      <Filter>store</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\src\wall.bmp" />
index 2c2d8a7..d543073 100644 (file)
@@ -649,6 +649,7 @@ hengband_SOURCES = \
        store/home.c store/home.h \
        store/store.c store/store.h \
        store/black-market.c store/black-market.h \
+       store/purchase-order.c store/purchase-order.h \
        store/rumor.c store/rumor.h \
        store/say-comments.c store/say-comments.h \
        store/store-util.c store/store-util.h \
index e20be1d..66b0267 100644 (file)
@@ -21,6 +21,7 @@
 #include "mind/mind-sniper.h"
 #include "mind/mind.h"
 #include "store/home.h"
+#include "store/purchase-order.h"
 #include "store/store-util.h"
 #include "store/store.h"
 #include "util/int-char-converter.h"
diff --git a/src/store/purchase-order.c b/src/store/purchase-order.c
new file mode 100644 (file)
index 0000000..6ed0946
--- /dev/null
@@ -0,0 +1,380 @@
+#include "store/purchase-order.h"
+#include "object/object-info.h"
+#include "object/object-value.h"
+#include "autopick/autopick.h"
+#include "core/asking-player.h"
+#include "core/stuff-handler.h"
+#include "flavor/flavor-describer.h"
+#include "flavor/object-flavor-types.h"
+#include "game-option/birth-options.h"
+#include "game-option/play-record-options.h"
+#include "grid/feature.h"
+#include "inventory/inventory-object.h"
+#include "io/write-diary.h"
+#include "main/sound-definitions-table.h"
+#include "main/sound-of-music.h"
+#include "object-enchant/item-feeling.h"
+#include "object-enchant/special-object-flags.h"
+#include "perception/object-perception.h"
+#include "object/object-generator.h"
+#include "object/object-stack.h"
+#include "player/avatar.h"
+#include "player/race-info-table.h"
+#include "store/home.h"
+#include "store/say-comments.h"
+#include "store/store-util.h"
+#include "store/store.h"
+#include "term/screen-processor.h"
+#include "util/int-char-converter.h"
+#include "view/display-messages.h"
+#include "view/display-store.h"
+#include "world/world.h"
+
+/*!
+ * @brief プレイヤーが購入する時の値切り処理メインルーチン /
+ * Haggling routine                            -RAK-
+ * @param player_ptr プレーヤーへの参照ポインタ
+ * @param o_ptr オブジェクトの構造体参照ポインタ
+ * @param price 最終価格を返す参照ポインタ
+ * @return プレイヤーの価格に対して店主が不服ならばTRUEを返す /
+ * Return TRUE if purchase is NOT successful
+ */
+static bool purchase_haggle(player_type *player_ptr, object_type *o_ptr, s32b *price)
+{
+    s32b cur_ask = price_item(player_ptr, o_ptr, ot_ptr->max_inflate, FALSE);
+    s32b final_ask = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, FALSE);
+    int noneed = noneedtobargain(final_ask);
+    bool final = FALSE;
+    concptr pmt = _("提示価格", "Asking");
+    if (noneed || !manual_haggle) {
+        if (noneed) {
+            msg_print(_("結局この金額にまとまった。", "You eventually agree upon the price."));
+            msg_print(NULL);
+        } else {
+            msg_print(_("すんなりとこの金額にまとまった。", "You quickly agree upon the price."));
+            msg_print(NULL);
+            final_ask += final_ask / 10;
+        }
+
+        cur_ask = final_ask;
+        pmt = _("最終提示価格", "Final Offer");
+        final = TRUE;
+    }
+
+    cur_ask *= o_ptr->number;
+    final_ask *= o_ptr->number;
+    s32b min_per = ot_ptr->haggle_per;
+    s32b max_per = min_per * 3;
+    s32b last_offer = object_value(player_ptr, o_ptr) * o_ptr->number;
+    last_offer = last_offer * (200 - (int)(ot_ptr->max_inflate)) / 100L;
+    if (last_offer <= 0)
+        last_offer = 1;
+
+    s32b offer = 0;
+    allow_inc = FALSE;
+    bool flag = FALSE;
+    int annoyed = 0;
+    bool cancel = FALSE;
+    *price = 0;
+    while (!flag) {
+        bool loop_flag = TRUE;
+
+        while (!flag && loop_flag) {
+            char out_val[160];
+            (void)sprintf(out_val, "%s :  %ld", pmt, (long)cur_ask);
+            put_str(out_val, 1, 0);
+            cancel = receive_offer(_("提示する金額? ", "What do you offer? "), &offer, last_offer, 1, cur_ask, final);
+            if (cancel) {
+                flag = TRUE;
+            } else if (offer > cur_ask) {
+                say_comment_6();
+                offer = last_offer;
+            } else if (offer == cur_ask) {
+                flag = TRUE;
+                *price = offer;
+            } else {
+                loop_flag = FALSE;
+            }
+        }
+
+        if (flag)
+            continue;
+
+        s32b x1 = 100 * (offer - last_offer) / (cur_ask - last_offer);
+        if (x1 < min_per) {
+            if (haggle_insults()) {
+                flag = TRUE;
+                cancel = TRUE;
+            }
+        } else if (x1 > max_per) {
+            x1 = x1 * 3 / 4;
+            if (x1 < max_per)
+                x1 = max_per;
+        }
+
+        s32b x2 = rand_range(x1 - 2, x1 + 2);
+        s32b x3 = ((cur_ask - offer) * x2 / 100L) + 1;
+        if (x3 < 0)
+            x3 = 0;
+        cur_ask -= x3;
+
+        if (cur_ask < final_ask) {
+            final = TRUE;
+            cur_ask = final_ask;
+            pmt = _("最終提示価格", "What do you offer? ");
+            annoyed++;
+            if (annoyed > 3) {
+                (void)increase_insults();
+                cancel = TRUE;
+                flag = TRUE;
+            }
+        } else if (offer >= cur_ask) {
+            flag = TRUE;
+            *price = offer;
+        }
+
+        if (flag)
+            continue;
+
+        last_offer = offer;
+        allow_inc = TRUE;
+        prt("", 1, 0);
+        char out_val[160];
+        (void)sprintf(out_val, _("前回の提示金額: $%ld", "Your last offer: %ld"), (long)last_offer);
+        put_str(out_val, 1, 39);
+        say_comment_2(cur_ask, annoyed);
+    }
+
+    if (cancel)
+        return TRUE;
+
+    updatebargain(*price, final_ask, o_ptr->number);
+    return FALSE;
+}
+
+/*!
+ * @brief 店からの購入処理のメインルーチン /
+ * Buy an item from a store                    -RAK-
+ * @param player_ptr プレーヤーへの参照ポインタ
+ * @return なし
+ */
+void store_purchase(player_type *player_ptr)
+{
+    if (cur_store_num == STORE_MUSEUM) {
+        msg_print(_("博物館から取り出すことはできません。", "Museum."));
+        return;
+    }
+
+    if (st_ptr->stock_num <= 0) {
+        if (cur_store_num == STORE_HOME)
+            msg_print(_("我が家には何も置いてありません。", "Your home is empty."));
+        else
+            msg_print(_("現在商品の在庫を切らしています。", "I am currently out of stock."));
+        return;
+    }
+
+    int i = (st_ptr->stock_num - store_top);
+    if (i > store_bottom)
+        i = store_bottom;
+
+    char out_val[160];
+#ifdef JP
+    /* ブラックマーケットの時は別のメッセージ */
+    switch (cur_store_num) {
+    case 7:
+        sprintf(out_val, "どのアイテムを取りますか? ");
+        break;
+    case 6:
+        sprintf(out_val, "どれ? ");
+        break;
+    default:
+        sprintf(out_val, "どの品物が欲しいんだい? ");
+        break;
+    }
+#else
+    if (cur_store_num == STORE_HOME) {
+        sprintf(out_val, "Which item do you want to take? ");
+    } else {
+        sprintf(out_val, "Which item are you interested in? ");
+    }
+#endif
+
+    COMMAND_CODE item;
+    if (!get_stock(&item, out_val, 0, i - 1))
+        return;
+
+    item = item + store_top;
+    object_type *o_ptr;
+    o_ptr = &st_ptr->stock[item];
+    ITEM_NUMBER amt = 1;
+    object_type forge;
+    object_type *j_ptr;
+    j_ptr = &forge;
+    object_copy(j_ptr, o_ptr);
+
+    /*
+     * If a rod or wand, allocate total maximum timeouts or charges
+     * between those purchased and left on the shelf.
+     */
+    reduce_charges(j_ptr, o_ptr->number - amt);
+    j_ptr->number = amt;
+    if (!check_store_item_to_inventory(player_ptr, j_ptr)) {
+        msg_print(_("そんなにアイテムを持てない。", "You cannot carry that many different items."));
+        return;
+    }
+
+    PRICE best = price_item(player_ptr, j_ptr, ot_ptr->min_inflate, FALSE);
+    if (o_ptr->number > 1) {
+        if ((cur_store_num != STORE_HOME) && (o_ptr->ident & IDENT_FIXED)) {
+            msg_format(_("一つにつき $%ldです。", "That costs %ld gold per item."), (long)(best));
+        }
+
+        amt = get_quantity(NULL, o_ptr->number);
+        if (amt <= 0)
+            return;
+    }
+
+    j_ptr = &forge;
+    object_copy(j_ptr, o_ptr);
+
+    /*
+     * If a rod or wand, allocate total maximum timeouts or charges
+     * between those purchased and left on the shelf.
+     */
+    reduce_charges(j_ptr, o_ptr->number - amt);
+    j_ptr->number = amt;
+    if (!check_store_item_to_inventory(player_ptr, j_ptr)) {
+        msg_print(_("ザックにそのアイテムを入れる隙間がない。", "You cannot carry that many items."));
+        return;
+    }
+
+    int choice;
+    COMMAND_CODE item_new;
+    PRICE price;
+    if (cur_store_num == STORE_HOME) {
+        bool combined_or_reordered;
+        distribute_charges(o_ptr, j_ptr, amt);
+        item_new = store_item_to_inventory(player_ptr, j_ptr);
+        GAME_TEXT o_name[MAX_NLEN];
+        describe_flavor(player_ptr, o_name, &player_ptr->inventory_list[item_new], 0);
+
+        msg_format(_("%s(%c)を取った。", "You have %s (%c)."), o_name, index_to_label(item_new));
+        handle_stuff(player_ptr);
+
+        i = st_ptr->stock_num;
+        store_item_increase(item, -amt);
+        store_item_optimize(item);
+        combined_or_reordered = combine_and_reorder_home(player_ptr, STORE_HOME);
+        if (i == st_ptr->stock_num) {
+            if (combined_or_reordered)
+                display_store_inventory(player_ptr);
+            else
+                display_entry(player_ptr, item);
+        } else {
+            if (st_ptr->stock_num == 0)
+                store_top = 0;
+            else if (store_top >= st_ptr->stock_num)
+                store_top -= store_bottom;
+            display_store_inventory(player_ptr);
+
+            chg_virtue(player_ptr, V_SACRIFICE, 1);
+        }
+
+        return;
+    }
+
+    if (o_ptr->ident & (IDENT_FIXED)) {
+        choice = 0;
+        price = (best * j_ptr->number);
+    } else {
+        GAME_TEXT o_name[MAX_NLEN];
+        describe_flavor(player_ptr, o_name, j_ptr, 0);
+        msg_format(_("%s(%c)を購入する。", "Buying %s (%c)."), o_name, I2A(item));
+        msg_print(NULL);
+        choice = purchase_haggle(player_ptr, j_ptr, &price);
+        if (st_ptr->store_open >= current_world_ptr->game_turn)
+            return;
+    }
+
+    if (choice != 0)
+        return;
+
+    if (price == (best * j_ptr->number))
+        o_ptr->ident |= (IDENT_FIXED);
+
+    if (player_ptr->au < price) {
+        msg_print(_("お金が足りません。", "You do not have enough gold."));
+        return;
+    }
+
+    say_comment_1(player_ptr);
+    if (cur_store_num == STORE_BLACK)
+        chg_virtue(player_ptr, V_JUSTICE, -1);
+    if ((o_ptr->tval == TV_BOTTLE) && (cur_store_num != STORE_HOME))
+        chg_virtue(player_ptr, V_NATURE, -1);
+
+    sound(SOUND_BUY);
+    decrease_insults();
+    player_ptr->au -= price;
+    store_prt_gold(player_ptr);
+    object_aware(player_ptr, j_ptr);
+    j_ptr->ident &= ~(IDENT_FIXED);
+    GAME_TEXT o_name[MAX_NLEN];
+    describe_flavor(player_ptr, o_name, j_ptr, 0);
+
+    msg_format(_("%sを $%ldで購入しました。", "You bought %s for %ld gold."), o_name, (long)price);
+
+    strcpy(record_o_name, o_name);
+    record_turn = current_world_ptr->game_turn;
+
+    if (record_buy)
+        exe_write_diary(player_ptr, DIARY_BUY, 0, o_name);
+    describe_flavor(player_ptr, o_name, o_ptr, OD_NAME_ONLY);
+    if (record_rand_art && o_ptr->art_name)
+        exe_write_diary(player_ptr, DIARY_ART, 0, o_name);
+
+    j_ptr->inscription = 0;
+    j_ptr->feeling = FEEL_NONE;
+    j_ptr->ident &= ~(IDENT_STORE);
+    item_new = store_item_to_inventory(player_ptr, j_ptr);
+
+    describe_flavor(player_ptr, o_name, &player_ptr->inventory_list[item_new], 0);
+    msg_format(_("%s(%c)を手に入れた。", "You have %s (%c)."), o_name, index_to_label(item_new));
+    autopick_alter_item(player_ptr, item_new, FALSE);
+    if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND)) {
+        o_ptr->pval -= j_ptr->pval;
+    }
+
+    handle_stuff(player_ptr);
+    i = st_ptr->stock_num;
+    store_item_increase(item, -amt);
+    store_item_optimize(item);
+    if (st_ptr->stock_num == 0) {
+        if (one_in_(STORE_SHUFFLE)) {
+            char buf[80];
+            msg_print(_("店主は引退した。", "The shopkeeper retires."));
+            store_shuffle(player_ptr, cur_store_num);
+
+            prt("", 3, 0);
+            sprintf(buf, "%s (%s)", ot_ptr->owner_name, race_info[ot_ptr->owner_race].title);
+            put_str(buf, 3, 10);
+            sprintf(buf, "%s (%ld)", (f_name + f_info[cur_store_feat].name), (long)(ot_ptr->max_cost));
+            prt(buf, 3, 50);
+        } else {
+            msg_print(_("店主は新たな在庫を取り出した。", "The shopkeeper brings out some new stock."));
+        }
+
+        for (i = 0; i < 10; i++) {
+            store_maintenance(player_ptr, player_ptr->town_num, cur_store_num);
+        }
+
+        store_top = 0;
+        display_store_inventory(player_ptr);
+    } else if (st_ptr->stock_num != i) {
+        if (store_top >= st_ptr->stock_num)
+            store_top -= store_bottom;
+        display_store_inventory(player_ptr);
+    } else {
+        display_entry(player_ptr, item);
+    }
+}
diff --git a/src/store/purchase-order.h b/src/store/purchase-order.h
new file mode 100644 (file)
index 0000000..eac9240
--- /dev/null
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "system/angband.h"
+
+void store_purchase(player_type *player_ptr);
index 1a62464..10df0a5 100644 (file)
@@ -106,11 +106,12 @@ const owner_type *ot_ptr = NULL;
 s16b old_town_num = 0;
 s16b inner_town_num = 0;
 
-/*
- * We store the current "store feat" here so everyone can access it
- */
+/* We store the current "store feat" here so everyone can access it */
 int cur_store_feat;
 
+/* Enable "increments" */
+bool allow_inc = FALSE;
+
 /*!
  * @brief 店舗価格を決定する. 無料にはならない /
  * Determine the price of an item (qty one) in a store.
@@ -261,7 +262,7 @@ bool noneedtobargain(PRICE minprice)
  * @param num 売買数
  * @return なし
  */
-static void updatebargain(PRICE price, PRICE minprice, int num)
+void updatebargain(PRICE price, PRICE minprice, int num)
 {
     if (!manual_haggle)
         return;
@@ -302,7 +303,7 @@ void store_prt_gold(player_type *player_ptr)
  * @param j 選択範囲の最大値
  * @return 実際に選択したらTRUE、キャンセルしたらFALSE
  */
-static int get_stock(COMMAND_CODE *com_val, concptr pmt, int i, int j)
+int get_stock(COMMAND_CODE *com_val, concptr pmt, int i, int j)
 {
     if (repeat_pull(com_val) && (*com_val >= i) && (*com_val <= j)) {
         return TRUE;
@@ -353,7 +354,7 @@ static int get_stock(COMMAND_CODE *com_val, concptr pmt, int i, int j)
  * Increase the insult counter and get angry if too many -RAK-
  * @return プレイヤーを締め出す場合TRUEを返す
  */
-static int increase_insults(void)
+int increase_insults(void)
 {
     st_ptr->insult_cur++;
     if (st_ptr->insult_cur <= ot_ptr->insult_max)
@@ -374,7 +375,7 @@ static int increase_insults(void)
  * Decrease insults                            -RAK-
  * @return プレイヤーを締め出す場合TRUEを返す
  */
-static void decrease_insults(void)
+void decrease_insults(void)
 {
     if (st_ptr->insult_cur)
         st_ptr->insult_cur--;
@@ -385,7 +386,7 @@ static void decrease_insults(void)
  * Have insulted while haggling                        -RAK-
  * @return プレイヤーを締め出す場合TRUEを返す
  */
-static int haggle_insults(void)
+int haggle_insults(void)
 {
     if (increase_insults())
         return TRUE;
@@ -395,11 +396,6 @@ static int haggle_insults(void)
 }
 
 /*
- * Mega-Hack -- Enable "increments"
- */
-static bool allow_inc = FALSE;
-
-/*
  * Mega-Hack -- Last "increment" during haggling
  */
 static s32b last_inc = 0L;
@@ -495,7 +491,7 @@ static int get_haggle(concptr pmt, s32b *poffer, PRICE price, int final)
  * @return プレイヤーの価格に対して不服ならばTRUEを返す /
  * Return TRUE if offer is NOT okay
  */
-static bool receive_offer(concptr pmt, s32b *poffer, s32b last_offer, int factor, PRICE price, int final)
+bool receive_offer(concptr pmt, s32b *poffer, s32b last_offer, int factor, PRICE price, int final)
 {
     while (TRUE) {
         if (!get_haggle(pmt, poffer, price, final))
@@ -512,128 +508,6 @@ static bool receive_offer(concptr pmt, s32b *poffer, s32b last_offer, int factor
 }
 
 /*!
- * @brief プレイヤーが購入する時の値切り処理メインルーチン /
- * Haggling routine                            -RAK-
- * @param player_ptr プレーヤーへの参照ポインタ
- * @param o_ptr オブジェクトの構造体参照ポインタ
- * @param price 最終価格を返す参照ポインタ
- * @return プレイヤーの価格に対して店主が不服ならばTRUEを返す /
- * Return TRUE if purchase is NOT successful
- */
-static bool purchase_haggle(player_type *player_ptr, object_type *o_ptr, s32b *price)
-{
-    s32b cur_ask = price_item(player_ptr, o_ptr, ot_ptr->max_inflate, FALSE);
-    s32b final_ask = price_item(player_ptr, o_ptr, ot_ptr->min_inflate, FALSE);
-    int noneed = noneedtobargain(final_ask);
-    bool final = FALSE;
-    concptr pmt = _("提示価格", "Asking");
-    if (noneed || !manual_haggle) {
-        if (noneed) {
-            msg_print(_("結局この金額にまとまった。", "You eventually agree upon the price."));
-            msg_print(NULL);
-        } else {
-            msg_print(_("すんなりとこの金額にまとまった。", "You quickly agree upon the price."));
-            msg_print(NULL);
-            final_ask += final_ask / 10;
-        }
-
-        cur_ask = final_ask;
-        pmt = _("最終提示価格", "Final Offer");
-        final = TRUE;
-    }
-
-    cur_ask *= o_ptr->number;
-    final_ask *= o_ptr->number;
-    s32b min_per = ot_ptr->haggle_per;
-    s32b max_per = min_per * 3;
-    s32b last_offer = object_value(player_ptr, o_ptr) * o_ptr->number;
-    last_offer = last_offer * (200 - (int)(ot_ptr->max_inflate)) / 100L;
-    if (last_offer <= 0)
-        last_offer = 1;
-
-    s32b offer = 0;
-    allow_inc = FALSE;
-    bool flag = FALSE;
-    int annoyed = 0;
-    bool cancel = FALSE;
-    *price = 0;
-    while (!flag) {
-        bool loop_flag = TRUE;
-
-        while (!flag && loop_flag) {
-            char out_val[160];
-            (void)sprintf(out_val, "%s :  %ld", pmt, (long)cur_ask);
-            put_str(out_val, 1, 0);
-            cancel = receive_offer(_("提示する金額? ", "What do you offer? "), &offer, last_offer, 1, cur_ask, final);
-            if (cancel) {
-                flag = TRUE;
-            } else if (offer > cur_ask) {
-                say_comment_6();
-                offer = last_offer;
-            } else if (offer == cur_ask) {
-                flag = TRUE;
-                *price = offer;
-            } else {
-                loop_flag = FALSE;
-            }
-        }
-
-        if (flag)
-            continue;
-
-        s32b x1 = 100 * (offer - last_offer) / (cur_ask - last_offer);
-        if (x1 < min_per) {
-            if (haggle_insults()) {
-                flag = TRUE;
-                cancel = TRUE;
-            }
-        } else if (x1 > max_per) {
-            x1 = x1 * 3 / 4;
-            if (x1 < max_per)
-                x1 = max_per;
-        }
-
-        s32b x2 = rand_range(x1 - 2, x1 + 2);
-        s32b x3 = ((cur_ask - offer) * x2 / 100L) + 1;
-        if (x3 < 0)
-            x3 = 0;
-        cur_ask -= x3;
-
-        if (cur_ask < final_ask) {
-            final = TRUE;
-            cur_ask = final_ask;
-            pmt = _("最終提示価格", "What do you offer? ");
-            annoyed++;
-            if (annoyed > 3) {
-                (void)(increase_insults());
-                cancel = TRUE;
-                flag = TRUE;
-            }
-        } else if (offer >= cur_ask) {
-            flag = TRUE;
-            *price = offer;
-        }
-
-        if (flag)
-            continue;
-
-        last_offer = offer;
-        allow_inc = TRUE;
-        prt("", 1, 0);
-        char out_val[160];
-        (void)sprintf(out_val, _("前回の提示金額: $%ld", "Your last offer: %ld"), (long)last_offer);
-        put_str(out_val, 1, 39);
-        say_comment_2(cur_ask, annoyed);
-    }
-
-    if (cancel)
-        return TRUE;
-
-    updatebargain(*price, final_ask, o_ptr->number);
-    return FALSE;
-}
-
-/*!
  * @brief プレイヤーが売却する時の値切り処理メインルーチン /
  * Haggling routine                            -RAK-
  * @param player_ptr プレーヤーへの参照ポインタ
@@ -768,231 +642,6 @@ static bool sell_haggle(player_type *player_ptr, object_type *o_ptr, s32b *price
 }
 
 /*!
- * @brief 店からの購入処理のメインルーチン /
- * Buy an item from a store                    -RAK-
- * @param player_ptr プレーヤーへの参照ポインタ
- * @return なし
- */
-void store_purchase(player_type *player_ptr)
-{
-    if (cur_store_num == STORE_MUSEUM) {
-        msg_print(_("博物館から取り出すことはできません。", "Museum."));
-        return;
-    }
-
-    if (st_ptr->stock_num <= 0) {
-        if (cur_store_num == STORE_HOME)
-            msg_print(_("我が家には何も置いてありません。", "Your home is empty."));
-        else
-            msg_print(_("現在商品の在庫を切らしています。", "I am currently out of stock."));
-        return;
-    }
-
-    int i = (st_ptr->stock_num - store_top);
-    if (i > store_bottom)
-        i = store_bottom;
-
-    char out_val[160];
-#ifdef JP
-    /* ブラックマーケットの時は別のメッセージ */
-    switch (cur_store_num) {
-    case 7:
-        sprintf(out_val, "どのアイテムを取りますか? ");
-        break;
-    case 6:
-        sprintf(out_val, "どれ? ");
-        break;
-    default:
-        sprintf(out_val, "どの品物が欲しいんだい? ");
-        break;
-    }
-#else
-    if (cur_store_num == STORE_HOME) {
-        sprintf(out_val, "Which item do you want to take? ");
-    } else {
-        sprintf(out_val, "Which item are you interested in? ");
-    }
-#endif
-
-    COMMAND_CODE item;
-    if (!get_stock(&item, out_val, 0, i - 1))
-        return;
-
-    item = item + store_top;
-    object_type *o_ptr;
-    o_ptr = &st_ptr->stock[item];
-    ITEM_NUMBER amt = 1;
-    object_type forge;
-    object_type *j_ptr;
-    j_ptr = &forge;
-    object_copy(j_ptr, o_ptr);
-
-    /*
-     * If a rod or wand, allocate total maximum timeouts or charges
-     * between those purchased and left on the shelf.
-     */
-    reduce_charges(j_ptr, o_ptr->number - amt);
-    j_ptr->number = amt;
-    if (!check_store_item_to_inventory(player_ptr, j_ptr)) {
-        msg_print(_("そんなにアイテムを持てない。", "You cannot carry that many different items."));
-        return;
-    }
-
-    PRICE best = price_item(player_ptr, j_ptr, ot_ptr->min_inflate, FALSE);
-    if (o_ptr->number > 1) {
-        if ((cur_store_num != STORE_HOME) && (o_ptr->ident & IDENT_FIXED)) {
-            msg_format(_("一つにつき $%ldです。", "That costs %ld gold per item."), (long)(best));
-        }
-
-        amt = get_quantity(NULL, o_ptr->number);
-        if (amt <= 0)
-            return;
-    }
-
-    j_ptr = &forge;
-    object_copy(j_ptr, o_ptr);
-
-    /*
-     * If a rod or wand, allocate total maximum timeouts or charges
-     * between those purchased and left on the shelf.
-     */
-    reduce_charges(j_ptr, o_ptr->number - amt);
-    j_ptr->number = amt;
-    if (!check_store_item_to_inventory(player_ptr, j_ptr)) {
-        msg_print(_("ザックにそのアイテムを入れる隙間がない。", "You cannot carry that many items."));
-        return;
-    }
-
-    int choice;
-    COMMAND_CODE item_new;
-    PRICE price;
-    if (cur_store_num == STORE_HOME) {
-        bool combined_or_reordered;
-        distribute_charges(o_ptr, j_ptr, amt);
-        item_new = store_item_to_inventory(player_ptr, j_ptr);
-        GAME_TEXT o_name[MAX_NLEN];
-        describe_flavor(player_ptr, o_name, &player_ptr->inventory_list[item_new], 0);
-
-        msg_format(_("%s(%c)を取った。", "You have %s (%c)."), o_name, index_to_label(item_new));
-        handle_stuff(player_ptr);
-
-        i = st_ptr->stock_num;
-        store_item_increase(item, -amt);
-        store_item_optimize(item);
-        combined_or_reordered = combine_and_reorder_home(player_ptr, STORE_HOME);
-        if (i == st_ptr->stock_num) {
-            if (combined_or_reordered)
-                display_store_inventory(player_ptr);
-            else
-                display_entry(player_ptr, item);
-        } else {
-            if (st_ptr->stock_num == 0)
-                store_top = 0;
-            else if (store_top >= st_ptr->stock_num)
-                store_top -= store_bottom;
-            display_store_inventory(player_ptr);
-
-            chg_virtue(player_ptr, V_SACRIFICE, 1);
-        }
-
-        return;
-    }
-
-    if (o_ptr->ident & (IDENT_FIXED)) {
-        choice = 0;
-        price = (best * j_ptr->number);
-    } else {
-        GAME_TEXT o_name[MAX_NLEN];
-        describe_flavor(player_ptr, o_name, j_ptr, 0);
-        msg_format(_("%s(%c)を購入する。", "Buying %s (%c)."), o_name, I2A(item));
-        msg_print(NULL);
-        choice = purchase_haggle(player_ptr, j_ptr, &price);
-        if (st_ptr->store_open >= current_world_ptr->game_turn)
-            return;
-    }
-
-    if (choice != 0)
-        return;
-    if (price == (best * j_ptr->number))
-        o_ptr->ident |= (IDENT_FIXED);
-    if (player_ptr->au < price) {
-        msg_print(_("お金が足りません。", "You do not have enough gold."));
-        return;
-    }
-
-    say_comment_1(player_ptr);
-    if (cur_store_num == STORE_BLACK)
-        chg_virtue(player_ptr, V_JUSTICE, -1);
-    if ((o_ptr->tval == TV_BOTTLE) && (cur_store_num != STORE_HOME))
-        chg_virtue(player_ptr, V_NATURE, -1);
-
-    sound(SOUND_BUY);
-    decrease_insults();
-    player_ptr->au -= price;
-    store_prt_gold(player_ptr);
-    object_aware(player_ptr, j_ptr);
-    j_ptr->ident &= ~(IDENT_FIXED);
-    GAME_TEXT o_name[MAX_NLEN];
-    describe_flavor(player_ptr, o_name, j_ptr, 0);
-
-    msg_format(_("%sを $%ldで購入しました。", "You bought %s for %ld gold."), o_name, (long)price);
-
-    strcpy(record_o_name, o_name);
-    record_turn = current_world_ptr->game_turn;
-
-    if (record_buy)
-        exe_write_diary(player_ptr, DIARY_BUY, 0, o_name);
-    describe_flavor(player_ptr, o_name, o_ptr, OD_NAME_ONLY);
-    if (record_rand_art && o_ptr->art_name)
-        exe_write_diary(player_ptr, DIARY_ART, 0, o_name);
-
-    j_ptr->inscription = 0;
-    j_ptr->feeling = FEEL_NONE;
-    j_ptr->ident &= ~(IDENT_STORE);
-    item_new = store_item_to_inventory(player_ptr, j_ptr);
-
-    describe_flavor(player_ptr, o_name, &player_ptr->inventory_list[item_new], 0);
-    msg_format(_("%s(%c)を手に入れた。", "You have %s (%c)."), o_name, index_to_label(item_new));
-    autopick_alter_item(player_ptr, item_new, FALSE);
-    if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND)) {
-        o_ptr->pval -= j_ptr->pval;
-    }
-
-    handle_stuff(player_ptr);
-    i = st_ptr->stock_num;
-    store_item_increase(item, -amt);
-    store_item_optimize(item);
-    if (st_ptr->stock_num == 0) {
-        if (one_in_(STORE_SHUFFLE)) {
-            char buf[80];
-            msg_print(_("店主は引退した。", "The shopkeeper retires."));
-            store_shuffle(player_ptr, cur_store_num);
-
-            prt("", 3, 0);
-            sprintf(buf, "%s (%s)", ot_ptr->owner_name, race_info[ot_ptr->owner_race].title);
-            put_str(buf, 3, 10);
-            sprintf(buf, "%s (%ld)", (f_name + f_info[cur_store_feat].name), (long)(ot_ptr->max_cost));
-            prt(buf, 3, 50);
-        } else {
-            msg_print(_("店主は新たな在庫を取り出した。", "The shopkeeper brings out some new stock."));
-        }
-
-        for (i = 0; i < 10; i++) {
-            store_maintenance(player_ptr, player_ptr->town_num, cur_store_num);
-        }
-
-        store_top = 0;
-        display_store_inventory(player_ptr);
-    } else if (st_ptr->stock_num != i) {
-        if (store_top >= st_ptr->stock_num)
-            store_top -= store_bottom;
-        display_store_inventory(player_ptr);
-    } else {
-        display_entry(player_ptr, item);
-    }
-}
-
-/*!
  * @brief 店からの売却処理のメインルーチン /
  * Sell an item to the store (or home)
  * @param owner_ptr プレーヤーへの参照ポインタ
index 06250b5..f116c8f 100644 (file)
@@ -19,6 +19,7 @@ extern s16b old_town_num;
 extern s16b inner_town_num;
 
 extern int cur_store_feat;
+extern bool allow_inc;
 
 PRICE price_item(player_type *player_ptr, object_type *o_ptr, int greed, bool flip);
 bool noneedtobargain(PRICE minprice);
@@ -26,8 +27,13 @@ void store_prt_gold(player_type *player_ptr);
 void store_shuffle(player_type *player_ptr, int which);
 void store_maintenance(player_type *player_ptr, int town_num, int store_num);
 void store_init(int town_num, int store_num);
-void store_purchase(player_type *player_ptr);
 void store_sell(player_type *owner_ptr);
 void store_examine(player_type *player_ptr);
 void museum_remove_object(player_type *player_ptr);
 int store_check_num(object_type *o_ptr);
+int get_stock(COMMAND_CODE *com_val, concptr pmt, int i, int j);
+bool receive_offer(concptr pmt, s32b *poffer, s32b last_offer, int factor, PRICE price, int final);
+int increase_insults(void);
+void updatebargain(PRICE price, PRICE minprice, int num);
+void decrease_insults(void);
+int haggle_insults(void);