DQ3成長限界上昇パッチの拡張2

今回から実装を行います。実装は大きく分けて以下の3つに分けられます。

  • 職業別ステータス最大値構造体の定義とそのアクセスSR実装
  • 成長限界パッチとの連動
  • その他ステータス変更部分との調整

というわけでまずは1番目から実装していきます。構造体の場所ですが、バンク$04は結構余裕がないのでバンク$05の後ろを使うことにしました。構造体の定義は以下のようにします。

  • 職業別ステータス最大値: $05FF45-$5FFDD(9Byte*17rec)
0 bit0-7 力最大値(下位8ビット)
1 bit0 力最大値(上位1ビット)
bit1-7 素早さ最大値(下位7ビット)
2 bit0-1 素早さ最大値(上位2ビット)
bit2-7 体力最大値(下位6ビット)
3 bit0-2 体力最大値(上位3ビット)
bit3-7 賢さ最大値(下位5ビット)
4 bit0-3 賢さ最大値(上位4ビット)
bit4-7 運のよさ最大値(下位4ビット)
5 bit0-4 運のよさ最大値(上位5ビット)
bit5-7 最大HP最大値(下位3ビット)
6 bit0-6 最大HP最大値(上位7ビット)
bit7 未使用
7 bit0-7 最大MP最大値(下位8ビット)
8 bit0-1 最大MP最大値(上位2ビット)
bit2-7 未使用
  • 職業別ステータス最大値アドレス: $05FFDE-$5FFFF(2Byte*17rec)
省略

スペースに余裕があるんだから詰めるのやめればという声も聞こえてきそうですが・・・。全部で17レコードというのはオリジナルの9職業+86氏の拡張パッチで追加されている7職業+システム最大値です。同時に各レコードの開始アドレス(下位2バイト)を$05FFDE-$5FFFF(2Byte*17rec)に定義します。1点注意点ですが、各職業別最大値はシステム最大値以下*1であることを前提とします。また、成長限界を上げた場合に起きる不具合*2についてはタッチしません。従って、職業最大値に500を設定してシステム最大値に300を設定した場合の動作の保証はしません。とりあえずはHPMPは999(#$3E7)、他は全て255(#$FF)をセットしておきます。値を設定する場合はこの点に注意してください。次にこの構造体からデータを取得するSRを定義します。

  • SR: $05F800 職業別ステータス最大値構造体アクセス(新SR)
05F800 PHP Push P Flag
05F801 PHB Push DB
05F802 REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
05F804 TXA A=X
05F805 PHX Push X
05F806 PHY Push Y
05F807 CMP #$0011 A>=#$0011?
05F80A BCS #$FE if(c==on) goto $05F80A
05F80C ASL A<<1
05F80D TAX X=A
05F80E LDA $C5FFDE,X A=$05FFDE+X
05F812 TAX X=A
05F813 LDA #$00C5 A=#$00C5
05F816 STA $62 DP($62)=A
05F818 LDA $08,S A=Stack($08)
05F81A PHA Push A
05F81B PLB Pull DB
05F81C PLB Pull DB
05F81D LDY #$0001 Y=#$0001
05F820 LDA ($07,S),Y A=Stack($07+Y)
05F822 STA $60 DP($60)=A
05F824 INY Y++
05F825 INY Y++
05F826 LDA ($07,S),Y A=Stack($07+Y)
05F828 STA $66 DP($66)=A
05F82A STA $68 DP($68)=A
05F82C LDA $07,S A=Stack($07)
05F82E INC A++
05F82F INC A++
05F830 INC A++
05F831 INC A++
05F832 STA $07,S Stack($07)=A
05F834 TXY Y=X
05F835 LDA $60 A=$(DP[$60])+Y
05F837 AND $66 A&=DP($66)
05F839 LSR $68 DP($68)>>1
05F83B BCS #$05 if(c==on) goto $05F842
05F83D LSR A>>1
05F83E LSR $68 DP($68)>>1
05F840 BCC #$FB if(c==off) goto $05F83D
05F842 STA $64 DP($64)=A
05F844 PLY Pull Y
05F845 PLX Pull X
05F846 PLB Pull DB
05F847 PLP Pull P Flag
05F848 PHA Push A
05F849 PLA Pull A
05F84A RTL return

このSRは引数として取得したいインデックス(この場合は職業ID)をXに、開始バイト2バイト、マスクするビットを2バイトで取ります。実装は似たようなことをやっている戦闘中PC情報取得SR: $02CA5Bを丸コピーしたあと、アドレス($05F80E)や要素数($05F807)などをちょっと変えて終わりです。ベースができたので次は各種ステータスを取得するSRをこのSRを使って書いていきます。まずは力の値がちゃんと取得できているかを確認するために力部分だけテストで作ってみます。成長限界上昇パッチでは(力に関して)変更されている部分はSR: $043442の中です。

  • SR: $043442 力取得(成長限界上昇パッチ適用後)
043442 LDA $000C,X A=$000C+X
043445 JSR $F82F SR: $04F82F
043448 RTL return

$043445の部分で処理を別SRに飛ばしています(オリジナルではたしか#$00FFとANDを取っていた思います)。ここでXとは各キャラクターの構造体の先頭アドレスです。つまり

—— LDA $0021,X A=$7E0021+X
—— AND #$00FF A&=#$00FF

とかやれば対象キャラクターの職業IDを入手できるので簡単ですね。

  • SR: $05FE80 力職業別最大値取得(新SR)
05FE80 PHX Push X
05FE81 LDA $0021,X A=$0021+X
05FE84 AND #$00FF A&=#$00FF
05FE87 TAX X=A
05FE88 JSL $C5F800 SR: $05F800 引数:1#$0000 引数:2#$01FF
05FE90 PLX Pull X
05FE91 RTL return

SR開始時にはXにキャラクターの先頭アドレスが入っているのですが、SR中で職業IDに変える必要があるのでスタックにPUSHして最後でPULLしています。それからもう1つSRを定義します。

  • SR: $05FD4B 力を職業最大値でクリップする(新SR)
05FD4B PHA Push A
05FD4C JSL $C5FE80 SR: $05FE80
05FD50 CMP $01,S A>=Stack($01)?
05FD52 BCS #$02 if(c==on) goto $05FD56
05FD54 STA $01,S Stack($01)=A
05FD56 PLA Pull A
05FD57 RTL return

Aに調整前の力の値、Xにキャラクターの先頭アドレスが入っていることを前提とし、調整前の力の値(スタック$01)と力の職業別最大値を比較して調整前の値が大きければ職業別最大値に変更してAにセットしなおして終わり、という処理をしています。長くなりすぎたので続きは次回。

*1:システム最大値>=職業最大値

*2:運のよさが320以上の場合に確率系呪文に必ずかかる等

コメント

  1. I.K より:

    はじめまして。ステータス限界上昇パッチで運のよさの問題が指摘されていますがWikiに 成功率×(1-運のよさ/320)と書かれておりました。
    DQ3SFCEditor内で$02C535 A9 40 01 $02C54E A9 40 01
    の2つがありどちらかがその計算式になっているようです。(片方はWikiを見る限りザオラルの成功率のようですがどちらなのかは未確認)両方のA9 40 01(320)の部分をA9 F4 01(500)に書き換えてみたところ、運のよさが320を超えても確率系の呪文や特技は100%ではなくなりました。Wikiの計算式が正確ならば約1.56倍オリジナルよりかかりやすくなりますが、はじめからプレイしてみても個人的に大きな問題ではないようでした。まあ、運のよさ自体軽視されがちなステなのでこれでかえって重要度が増してよいかもですがw 長文失礼しました。

    管理者より返信:

    コメントありがとうございます。実際にプレイした方の感想は非常に貴重です。成功率判定の解析は5/9にエントリを書きました。成長限界上昇パッチを宛てた状態で両方とも500に変える変更で問題ないと思います。ただ、運のよさが500の場合は確実に成功?なので、オリジナル同様もう少し値を大きくしてもいいかもしれません。