5.16. ゴールド銀行解析

5.16.1. 解析
5.16.1.1. ゴールド銀行共通処理
5.16.1.2. 「あずける」処理
5.16.1.3. 「ひきだす」処理

ゴールド銀行の窓口業務処理について解析した結果を述べる。 アリアハンのルイーダの酒場入口近くにあるカウンターが銀行の窓口だが、 以下で述べるのは、窓口のオッサンの(人オブジェクトとしての)処理ではなく、 あくまでも銀行としての振る舞いである。

銀行解析の目的は、普通にプレイしている分にはまずお目にかからない例外的な状況における処理を探すことだ。 パーティーにカウンターストップ上限の 99,9999 ゴールドに近い額を持たせて、 その上で預金を引き出そうとしたときに銀行が何を言うのかを見た読者は多いだろう。 しかし、その逆、つまり銀行に預けられる金額の上限値を通常のプレイで確認した者は少ないと思う。 預金上限の金額はいくらで、その上限値を超える金額を預けようとすると何が起こるのか、 といったようなことを、逆アセンブリ解析を通じて知るのもいいだろう。

5.16.1. 解析

銀行処理の基点はサブルーチン $C3E2F2 である。 ここから台詞表示を含む窓口処理の実装がなされている。 そのサブルーチンのヘルパーサブルーチンとして、 「あずける」処理を実装する JSR 型サブルーチン $C3E39E と、 「ひきだす」処理を実装する JSR 型サブルーチン $C3E410 を利用する。

銀行処理周りの台詞表示はすべてサブルーチン $C1A92E 呼び出しで実現している。 このサブルーチンは、呼び出しコード直後に 2 バイトの定数を埋め込むことで、 その定数をメッセージ ID として解釈する。

以下の記述では、銀行の預金単位が 1000 ゴールド単位であることをいちいち断らない。 例えば 9999 という金額は、ゲーム的には 99,990,000 ゴールドのことである。

5.16.1.1. ゴールド銀行共通処理

サブルーチン $C3E2F2 は、基本的に銀行の窓口に「はなす」とすぐに開始される処理である。 以下のように実装されている。

  • 最初のあいさつ

    • 初めて話し掛けたときには、特別な台詞 (#$0AFF) を聞くことになる。 銀行に話しかけたことがあることを示すフラグビットは $7E353C & #$02 である。 このフラグのテストは汎用サブルーチン $C909AE で行い、 セットは汎用サブルーチン $C908F0 で行う。

    • 二度目以降は、銀行のあいさつはメッセージ ID #$0B00 のものとする。

  • 預金残高をパーティに告げて、用を尋ねる。

    • 銀行への預金残高を、汎用サブルーチン $C45BBA 呼び出しで行う。引数は #$FF である。

    • 預金残高がゼロか否かで、用件を尋ねる台詞のメッセージ ID が異なる。 預金がある場合は #$0B01 で、ゼロの場合は #$0B02 を用いる。

  • 「あずける」「ひきだす」メニューウィンドウを表示し、入力を待つ。

    • キャンセルボタンを押したとき、最後のあいさつ処理へ移る。

    • 「あずける」選択時は、サブルーチン $C3E39E を呼び出す。

    • 「ひきだす」選択時は、サブルーチン $C3E410 を呼び出す。

  • 用事(キャンセルを含む)が済んだ後は、 パーティの口座残高を告げ、あいさつをして窓口処理を終了する。

    • 銀行への預金残高を、汎用サブルーチン $C45BBA 呼び出しで行う。引数は #$FF である。

    • 預金残高がゼロか否かで、用件を尋ねる台詞のメッセージ ID が異なる。 預金がある場合は #$0B0E で、ゼロの場合は #$0B0B を用いる。

5.16.1.2. 「あずける」処理

「あずける」を選択したときの処理はサブルーチン $C3E39E に定義されている。 それは以下のようになっている。

  • 汎用サブルーチン $C45BBA で残高金額をチェックし、 10000 以上の値がセットされているときには、 メッセージ ID #$0B03 の台詞を表示して当処理を終了し、共通処理に戻る。

  • そうでないときは、いくらお預かりしましょうかの台詞を表示した後に、 金額入力ウィンドウを表示し、数値入力モードに入る。

    • 入力をキャンセル、もしくは入力金額がゼロの場合、台詞 「おやめになるのですね」を表示して、当処理を終了する。

    • それ以外の場合、まずは入力金額、パーティの所持金、預金残高を汎用ルーチン $C45BEB で比較する。

      • 入力金額がパーティの所持金以下かつ銀行の金庫に余裕がある場合、 「責任をもってお預かりします」台詞を表示し、 「あずける」処理を終了する。

      • 入力金額が、銀行の金庫の限界を超えるような値である場合、 (9999 + carry - 預金残高) を計算した後に、 「申しわけありませんが~」の台詞で、入金可能金額の上限を告げる。 そのあと、制御を「いくらお預かり~」まで戻す。

      • それ以外の場合、すなわち入力金額がパーティの所持金を越える場合は、 「失礼ですが~」台詞を表示し、制御を「いくらお預かり~」まで戻す。

5.16.1.3. 「ひきだす」処理

「ひきだす」を選択したときの処理はサブルーチン $C3E410 に定義されている。 それは以下のようになっている。

  • 汎用サブルーチン $C45BBA で残高金額をチェックし、 0 がセットされている場合は、 「お客さまのお金は 1 ゴールドもお預かりしていません」の台詞 (ID = #$0B08) を表示して当処理を終了、共通処理に戻る。

  • 残高が 0 でない場合は、$7EBE81 に残高金額をセットする。そして 「現在~ゴールドをお預かりしていますが、いくらお引き出ししますか」の台詞 (ID = #$0B09) を表示する。

  • 金額入力ウィンドウを表示し、入力待ちとなる。

    • 入力モードがキャンセル終了もしくは、入力金額がゼロである場合、 「おやめになるのですね」の台詞 (ID = #$0B0D) を表示して、 当処理を終了、共通処理に制御を戻す。

    • 入力金額がゼロでない場合、 入力金額、パーティの所持金、預金残高を汎用ルーチン $C45C5A で比較する。

      • 入力金額が預金残高以下かつ、パーティの現在の所持金に加えても、 所持金総額がその上限を超えない場合、引き出し処理は成功となる。 「はいどうぞ」の台詞 (ID = #$0B0C) を表示して、当処理を抜ける。

      • 入力金額が預金残高以下ではあるが、 引き出したい金額をパーティの所持金に加算すると所持可能金額上限を超える場合、 引き出し処理は失敗となる。 「そんなにたくさん~」の台詞 (ID = #$0B0B) を表示して、 当処理の最初に制御を戻す。

      • それ以外の場合、 すなわち入力金額が預金残高を越える値である場合は、引き出し処理は失敗となる。 「そんなにお預かりしておりませんが」の台詞 (ID = #$0B0A) を表示し、 当処理の最初に制御を戻す。