5.16. 冒険者たちの登録所

5.16.1. 構造に関する構成要素
5.16.1.1. 構造体 $C30EFD: 初期性格条件
5.16.1.2. 構造体 C30FFC: 初期性格確率分布
5.16.1.3. 配列 $C3E2EA: 登録所性格評価台詞
5.16.2. 振る舞いに関する構成要素
5.16.2.1. サブルーチン $C3DAEB: 登録所メイン
5.16.2.2. サブルーチン $C3DD13: キャラクター削除
5.16.2.3. サブルーチン $C3DE95: 性格決定

本節ではルイーダの酒場二階に併設されている冒険者たちの登録所について述べる。

5.16.1. 構造に関する構成要素

キャラクター作成処理のためにしか参照されないオブジェクト型が二つ存在する。 それぞれ初期性格条件と初期性格確率分布と呼ぶことにしよう。

5.16.1.1. 構造体 $C30EFD: 初期性格条件

アドレス $C30EFD には以下の表が示すようなオブジェクト型の要素が配列されている。

表 5.36 構造体 $C30EFD

オフセット 属性
#$00 #$007F 閾値 0
#$00 #$0080 第二位考慮 0
#$01 #$00FF キャラクター属性 0
#$02 #$00FF 初期性格確率分布 0
#$03 #$007F 閾値 1
#$03 #$0080 第二位考慮 1
#$04 #$00FF キャラクター属性 1
#$05 #$00FF 初期性格確率分布 1
#$06 #$007F 閾値 2
#$06 #$0080 第二位考慮 2
#$07 #$00FF キャラクター属性 2
#$08 #$00FF 初期性格確率分布 2
#$09 #$007F 閾値 3
#$09 #$0080 第二位考慮 3
#$0A #$00FF キャラクター属性 3
#$0B #$00FF 初期性格確率分布 3
#$0C #$007F 閾値 4
#$0C #$0080 第二位考慮 4
#$0D #$00FF キャラクター属性 4
#$0E #$00FF 初期性格確率分布 4

以下に各属性を説明する。

閾値 k (k = 0..3), 第二位考慮 k (k = 0..3)

閾値 k とはスカラー値属性であり、型は下で説明するキャラクター属性 k によって「ちから」「すばやさ」等に決まる。 第二位考慮 k とはブーリアン型属性だ。

第二位考慮 k 属性値が 1 のとき、後述する初期性格決定処理において、 第一位増分キャラクター属性値と閾値 k との比較を無視し、 代わりに第二位増分キャラクター属性値と閾値 k とを比較することを意味する。

キャラクター属性 k (k = 0..3)

ちから、すばやさ、たいりょく、かしこさ、うんのよさのいずれなのかを表す値を取る属性だ。

初期性格確率分布 k (k = 0..3)

後述する初期性格確率分布オブジェクトの ID を値とする属性だ。

5.16.1.2. 構造体 C30FFC: 初期性格確率分布

アドレス $C30FFC には以下の表が示すようなオブジェクト型の要素が配列されている。

表 5.37 構造体 $C30FFC

オフセット 属性
#$00 #$000F 頻度 0
#$00 #$00F0 頻度 1
#$01 #$000F 頻度 2
#$01 #$00F0 頻度 3
#$02 #$000F 頻度 4
#$02 #$00F0 頻度 5
#$03 #$000F 頻度 6
#$03 #$00F0 頻度 7
#$04 #$00FF 性格 0
#$05 #$00FF 性格 1
#$06 #$00FF 性格 2
#$07 #$00FF 性格 3
#$08 #$00FF 性格 4
#$09 #$00FF 性格 5
#$0A #$00FF 性格 6
#$0B #$00FF 性格 7

以下に各属性を説明する。

頻度 k (k = 0..7), 性格 k (k = 0..7)

これらの属性は対になっているのでまとめて説明する。 初期性格が性格 k 属性値となる確率が頻度 k 属性値で決まるということを表している。

頻度属性値の和を取ると 256 になるので、実際の確率は頻度 k 属性値を 256 で割った値となる。

5.16.1.3. 配列 $C3E2EA: 登録所性格評価台詞

アドレス $C3E2EA に次の内容のメッセージ ID の配列がある。 これは、キャラクター完成直前に登録所の係員がその性格を説明するときに用いられる。

表 5.38 配列 $C3E2EA

ID 台詞
0 [D6]なかなか [B2][AD]のようですね。[AF]
1 [D6]なかなか [B2][AD]なようですね。[AF]
2 [D6]なかなか [B2][AD]ようですね。[AF]
3 [D6]なかなか [B2]さん[AD]のようですね。[AF]

5.16.2. 振る舞いに関する構成要素

本節では登録所の処理を述べる。

5.16.2.1. サブルーチン $C3DAEB: 登録所メイン

サブルーチン $C3DAEB は登録屋の通常処理だ。 以下に要点を挙げる。長いので分けて列挙する。

  • 係員がサービスの説明を初回しかしないように、フラグ$7E353C & #$20 を用いる。

  • 新しい人を名簿に登録することが可能であるかを判定する。これについては後述する。

  • 最初に名前を入力する。ただし、次の条件を満たすものは許されない。

    • 入力文字列が文字列「ロト」とマッチする場合

    • 入力文字列が予約名とマッチする場合

    • 入力文字列が既存の仲間キャラクターの誰かの名前と同一の場合

性別と職業を入力すると、サブルーチン $C441AE でキャラクターの初期状態を決定し、 係員がこれでどうか尋ねる(この時点では性格は無効値が設定されている)。 今興味があるのはこの初期状態におけるキャラクターの基本属性値がどのように決まるかなので、ここで説明する。

  • ちから、すばやさ、たいりょく、かしこさ、うんのよさの初期値として、職業構造体(5.24.1.1 構造体 $C4179E: 職業 参照)で設定されている値をそれぞれ用いる。 そこに、これらの属性値のいずれかをランダムに 2 回から 10 回選択して 1 ずつ加えるという処理が入る。 加算回数と属性選択の両方についてランダムであることを強調しておきたい。 これでちからからうんのよさ各属性値の初期値が確定した。

  • たいりょくが定まったので、最大 HP を たいりょく * randint(500, 525) / 256 で確定する。

  • かしこさが定まったので、最大 MP を かしこさ * randint(500, 525) / 256 で確定する。

再び登録所の処理の説明に戻る。

  • 係員が種使用について初回しか説明しないように、フラグ$7E353C & #$40 を用いる。

  • 一度の登録で使える種の個数は 1/64 の確率で 6 個となるが、たいていは 5 個となる。

  • 種の振り分けを終了すると、後述するサブルーチンを用いて新キャラクターの性格を確定させる。

  • 最後に係員が確認してくるので、承知すればこのオブジェクトをサブルーチン $C44566 で処理して、 ルイーダの酒場から呼び出せるようになる。

登録所の登録手続きの概要は以上だ。細部のうち重要なものは後述する。

5.16.2.2. サブルーチン $C3DD13: キャラクター削除

上述の登録処理中、名簿が満杯である場合には既存キャラクターを一人削除しない限り、新規登録手続きは取れない。 その判定処理の要点を以下に挙げる。

  • 名簿満杯判定はサブルーチン $C4467F による。 パーティーと酒場とバーク商人の人数が 24 以上であることが満杯条件となる。

  • 満杯のときに限り、係員が削除するかどうか尋ねる。

  • バーク商人を削除することは認められない。その人を消すことはできないと係員が言う。

  • または勇者を削除することは認められない。無茶を言うなと係員が言う。

  • 削除を決定すると、対象者の装備品全てをパーティーのふくろに移す。 それからキャラクターオブジェクトを削除する。

5.16.2.3. サブルーチン $C3DE95: 性格決定

サブルーチン $C3DE95 は、作成キャラクターの初期の性格を決定する処理だ。 処理の要点を以下に挙げる。

  • ちから~うんのよさの属性値ごとに、職業オブジェクトの初期値属性値に対する、種使用後の属性値の増分値を求める。

  • 増分値 5 個からなる配列を降順ソートする。タイブレイクは乱数で採決する。

  • 最大値を取る増分値が何であるかに依存して、職業オブジェクトの初期性格条件属性値を参照する。

  • 初期性格条件オブジェクトの定義に従って、採用する初期性格確率分布オブジェクトを決定する。

    • 初期性格条件属性値の第二位考慮 k 属性値が 0 ならば、 属性 k が第一位増分値を取る属性と一致する限りで閾値 k と比較する。 増分値が閾値以上ならば、初期性格確率分布 k 属性値を利用するものとする。

    • 第二位考慮 k が 1 であり、属性 k が第ニ位増分値を取る属性と一致すれば、 やはり初期性格確率分布 k 属性値を利用するものとする。

    • どちらでもなければ、次の k に進むものとし、 この手続きを検索が成功するまで k = 0..4 で反復する。

      どの初期性格条件オブジェクトも何らかの k で判定が停止するように設計されているので、 最後までどれにも当てはまらないという事態には陥らない。

  • 初期性格確率分布オブジェクトの定義に従って、抽選で性格を決定する。

とりわけ第二位考慮の周辺が理解しにくいので、例を挙げるなりシミュレーターを作成するなりで説明を尽くしたい。 次に、初期性格確率分布オブジェクトの操作の要点を挙げる。

  • 初期性格確率分布オブジェクトの属性のうち、対象キャラクターの性別とマッチしないものを除外する。

  • 残った性格(確率変数とみなせる)と対応する頻度(と呼んでいるが、総和で割れば確率に他ならない)について、抽選で性格を決定する。

この確率分布データ構造と抽選アルゴリズムの組み合わせは、通常戦の敵陣編成決定ルーチンや 敵陣キャラクターのコマンド決定ルーチン等、他の処理でもしばしば目にすることになる。