DQ3 すごろくシステム変更6

既存ダンジョンのフロアを水増しする作業ですが、1週間程度で1フロアできました。ギミックが無いのでツクール感覚でマップを作るだけでいいんで楽なんですが、改めて思う自分のフロアデザインのセンスの無さ。でかけりゃいいってもんでもねーんだよ、ということなんですが、すでにリリースしたK.Mixで追加したフロアにも言えるのですが、要は「飽きない作り」にすることが大事なのかなあとぼんやり思っています*1。ところで、ふと思い立ってFC版とSFC版のエンカウント率の違いを体感すべくそれぞれのバージョンで今回フロア追加作業をしていたラーの洞窟を歩いてみたのですが、B1FからB3Fまで落とし穴なしで歩いてSFC版が4回だったのに対し、FC版はB1Fの入り口付近ですでに3回エンカウントしていました。この大幅なエンカウント率の減少がSFC版のヌルさに拍車をかけているのではと思っています。ちなみにSFC版のラーの洞窟のエンカウント率は0(最小)~4(最大)のうち3が設定されているにもかかわらずこの始末。最大の4はクリア後の追加ダンジョンに設定されているくらいで、4だとちょっとウザいくらいのエンカウント率になります(余談ですがK.Mixの幽霊船の追加イベント中もエンカウント率は3です4です(勘違いでした。エンカウントのテーブル定義が正しくないせいで不正なデータを参照していました)。なのであの異常なエンカウント率になります)。これで忍び足も使われると大半のダンジョンはピクニック気分になってしまうわけで、この部分も何とかしたいなーと思っています。忍び足にMP消費以外のペナルティ(移動速度がフィールドと同じ=FC版と同じになるとか*2、戦闘開始時の強襲率が上がるとか)を追加することを考えていましたが、それ以前の問題のようです。当然今までノータッチだったエンカウント部分の調査もしないといけないのでこれまた面倒だなーというわけで再度モチベーション低下中。あと戦闘中の音楽は絶対FC版の方がいいと思うんですがどうなんでしょう。SFC版にするにあたってすぎやんのご意向を受けてオーケストラ調にしたんですかね。久しぶりに聞いたけどFC版の疾走感のほうがゲームにマッチしてると思うんですが。

さて、前回先送りにしたすごろく中のエンカウント時のモンスター決定部分の解説をします。からくりを完全に忘れていたので、再度調べるのに時間がかかったのは秘密。

  • SR: $01C3A6 すごろく平地エンカウント判定
01C3A6 JSR $C3F8 SR: $01C3F8 すごろく用乱数発生?
01C3A9 CMP #$0010 A>=#$0010? 平地のエンカウント閾値
01C3AC BCS #$0F if(c==on) goto $01C3BD
01C3AE LDA $7EC206 A=$7EC206
01C3B2 AND #$0001 A&=#$0001 何かフラグ?
01C3B5 BEQ #$06 if(z==on) goto $01C3BD
01C3B7 LDX #$0001 X=#$0001
01C3BA JSR $C403 SR: $01C403 すごろくエンカウントモンスター決定?
01C3BD RTL return

$01C3AA-Bが平地の場合のエンカウント閾値になっていて、森(SR: $01C3BE-)、山(SR: $01C3D6-)ではそれぞれ#$70, #$D0となっており乱数が閾値未満の場合はエンカウントするようになっているため、平地<森<山の順でエンカウント率が高くなっているというのがわかります(強パネルはエンカウント確定)。さらに、$01C3B8-9で、エンカウントモンスターテーブル($08F2E4-)のどのレコードを使用するかを指定しているようです。平地は#$01、森は#$02、山は#$03、強パネルは#$04のレコードをそれぞれ使用するようになっています。

  • SR: $01C403 すごろくエンカウントモンスター決定?
01C403 JSL $C90572 SR: $090572 引数:1#$00 引数:2#$0009 引数:3#$C8F2E4 引数:4#$0000 引数:5#$000001 構造体アクセス
01C412 CMP #$0001 A==#$0001?
01C415 BEQ #$14 if(z==on) goto $01C42B
01C417 JSR $C49B SR: $01C49B すごろくエンカウントレベル決定?
01C41A PHA Push A
01C41B LDA $DB1B A=$DB1B 先頭PCのレベル
01C41E SEC c=on
01C41F SBC $01,S A-=(Stack($01)+c)
01C421 BCS #$03 if(c==on) goto $01C426
01C423 LDA #$0000 A=#$0000
01C426 STA $01,S Stack($01)=A
01C428 PLA Pull A
01C429 BRA #$03 goto $01C42E
01C42B JSR $C49B SR: $01C49B すごろくエンカウントレベル決定?
01C42E PHA Push A
01C42F JSL $C903EE SR: $0903EE 引数:1#$00 引数:2#$0009 引数:3#$C8F2E4 引数:4#$0007 エンカウントレベルが上限以上なら固定値に差し替え
01C43B CMP $01,S A>=Stack($01)?
01C43D BCS #$02 if(c==on) goto $01C441
01C43F STA $01,S Stack($01)=A
01C441 JSL $C903EE SR: $0903EE 引数:1#$00 引数:2#$0009 引数:3#$C8F2E4 引数:4#$0005
01C44D CMP $01,S A>=Stack($01)?
01C44F BCC #$02 if(c==off) goto $01C453
01C451 STA $01,S Stack($01)=A エンカウントレベルが加減以下なら固定値に差し替え
01C453 PLA Pull A
01C454 STA $1C DP($1C)=A エンカウントレベル用バッファ
01C456 STZ $18 DP($18)=#$00 エンカウントレコードID用バッファ
01C458 LDA #$FFFF A=#$FFFF エンカウントレベルとの差分最大値用バッファ
01C45B STA $1A DP($1A)=A
01C45D LDY #$0000 Y=#$0000
01C460 JSL $C903E2 SR: $0903E2 引数:1#$01 引数:2#$0014 引数:3#$C8CDB8 引数:4#$0012
01C46C AND #$00FF A&=#$00FF
01C46F PHA Push A
01C470 BEQ #$1C if(z==on) goto $01C48E
01C472 LDA $1C A=DP($1C)
01C474 SEC c=on
01C475 SBC $01,S A-=(Stack($01)+c)
01C477 BCC #$15 if(c==off) goto $01C48E
01C479 CMP $1A A==DP($1A)?
01C47B BEQ #$08 if(z==on) goto $01C485
01C47D BCS #$0F if(c==on) goto $01C48E
01C47F STA $1A DP($1A)=A
01C481 STY $18 DP($18)=Y
01C483 BRA #$09 goto $01C48E
01C485 JSL $C012D1 SR: $0012D1
01C489 LSR A>>1
01C48A BCC #$02 if(c==off) goto $01C48E
01C48C STY $18 DP($18)=Y
01C48E PLA Pull A
01C48F INY Y++
01C490 CPY #$0070 Y>=#$0070? エンカウントレコード数 #$70に変更
01C493 BCC #$CB if(c==off) goto $01C460
01C495 LDA $18 A=DP($18)
01C497 STA $C1F5 $C1F5=A
01C49A RTS return

やたらと長いですが、適度に関数化されているのでそれほど意味不明というわけではないです。ざっくり説明すると、前半部分($01C403-53)で、エンカウントさせるモンスターのレベル(便宜上エンカウントレベルと呼ぶ)を決定します。先頭PC(つまりすごろくをしているPC)のレベルをベースにエンカウントモンスターテーブル($08F2E4-)の1-2バイト目を補正値下限、3-4バイトを補正値上限とした範囲で乱数を発生させ、それを先頭PCのレベルから引き、これをエンカウントレベルとします(平地パネルは例外)。これは一人で戦闘しないといけないため、PCレベルから多少弱いモンスターを出現させるための措置と思われます。また、すごろくエンカウントレベル設定($08F2E4-)の5-6バイト目を下限レベル、7-8バイト目を上限レベルとし、先頭PCレベルがこの範囲内にない場合はこれらの値でクリップされます。各パネルごとの下限上限レベルは以下の通り。

種別 下限 上限
平地 1 4
4 15
5 25
強パネル 7 45

次に後半部分($01C454-93)で、エンカウント($08AC7D-)*3の全レコードをループし、各レコードのエリアレベルと直前で決定したエンカウントレベルを比較し、合致した場合は1/2の確率でエンカウントするモンスターとして決定しています。また、当然エンカウントレベルとエリアレベルが合致しない場合もあるので、エンカウントレベルより小さい一番近いレコードも候補としてセットされる、というコードになっています。これにより、それぞれの上限レベル以上(正確に言うと上限レベル+補正値上限。強パネルの例で言うと45+2)になると同じパターンのモンスターがやたら出てくる現象が説明がつきます。また、この決定方法の性格上、上限レベル以上になると、エンカウントレベルに一致するエリアレベルを持つレコードのうち、一番最後に出てくるレコードが1/2で選択されることになり、これまた同じパターンのモンスターがよく出てくる可能性が高くなる、ということになります。今回ボーナスモンスターを追加するにあたって、当然エンカウント($08AC7D-)の既存レコードの最後に追加したわけですが、上限レベルを超えると1/2の確率でボーナスモンスターが出てくる、ということになります。まあコイン制にしてよろずやでの買い物がかなり厳しくなっているのでこれくらいはいいかなと。当然これらのモンスターのレベルは各上限レベルと同じにしておかないと一定レベル以上になると出現する確率がぐっと減る(多分)ので注意です。

*1:だだ長い一本道なんかは改良の余地ありです

*2:適当に思いついたにしては実現方法もわかっている(多分)ので悪くないとは思うんですが、操作性に影響を与えるのは良くないとも思うのでボツの予定です

*3:拡張パッチ使用によりアドレスが移動しています