既存ダンジョンのフロアを水増しする作業ですが、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の確率でボーナスモンスターが出てくる、ということになります。まあコイン制にしてよろずやでの買い物がかなり厳しくなっているのでこれくらいはいいかなと。当然これらのモンスターのレベルは各上限レベルと同じにしておかないと一定レベル以上になると出現する確率がぐっと減る(多分)ので注意です。
コメント