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

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

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

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

  • 職業別ステータス最大値: $05FF45-$5FFDD(9Byte*17rec)
0bit0-7力最大値(下位8ビット)
1bit0 力最大値(上位1ビット)
bit1-7素早さ最大値(下位7ビット)
2bit0-1素早さ最大値(上位2ビット)
bit2-7体力最大値(下位6ビット)
3bit0-2体力最大値(上位3ビット)
bit3-7賢さ最大値(下位5ビット)
4bit0-3賢さ最大値(上位4ビット)
bit4-7運のよさ最大値(下位4ビット)
5bit0-4運のよさ最大値(上位5ビット)
bit5-7最大HP最大値(下位3ビット)
6bit0-6最大HP最大値(上位7ビット)
bit7未使用
7bit0-7最大MP最大値(下位8ビット)
8bit0-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)
05F800PHPPush P Flag
05F801PHBPush DB
05F802REP #$30m=off(A/M:16b) x=off(X/Y:16b)
05F804TXAA=X
05F805PHXPush X
05F806PHYPush Y
05F807CMP #$0011A>=#$0011?
05F80ABCS #$FEif(c==on) goto $05F80A
05F80CASLA<<1
05F80DTAXX=A
05F80ELDA $C5FFDE,XA=$05FFDE+X
05F812TAXX=A
05F813LDA #$00C5A=#$00C5
05F816STA $62DP($62)=A
05F818LDA $08,SA=Stack($08)
05F81APHAPush A
05F81BPLBPull DB
05F81CPLBPull DB
05F81DLDY #$0001Y=#$0001
05F820LDA ($07,S),YA=Stack($07+Y)
05F822STA $60DP($60)=A
05F824INYY++
05F825INYY++
05F826LDA ($07,S),YA=Stack($07+Y)
05F828STA $66DP($66)=A
05F82ASTA $68DP($68)=A
05F82CLDA $07,SA=Stack($07)
05F82EINCA++
05F82FINCA++
05F830INCA++
05F831INCA++
05F832STA $07,SStack($07)=A
05F834TXYY=X
05F835LDA $60A=$(DP[$60])+Y
05F837AND $66A&=DP($66)
05F839LSR $68DP($68)>>1
05F83BBCS #$05if(c==on) goto $05F842
05F83DLSRA>>1
05F83ELSR $68DP($68)>>1
05F840BCC #$FBif(c==off) goto $05F83D
05F842STA $64DP($64)=A
05F844PLYPull Y
05F845PLXPull X
05F846PLBPull DB
05F847PLPPull P Flag
05F848PHAPush A
05F849PLAPull A
05F84ARTLreturn

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

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

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

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

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

  • SR: $05FE80 力職業別最大値取得(新SR)
05FE80PHXPush X
05FE81LDA $0021,XA=$0021+X
05FE84AND #$00FFA&=#$00FF
05FE87TAXX=A
05FE88JSL $C5F800SR: $05F800 引数:1#$0000 引数:2#$01FF
05FE90PLXPull X
05FE91RTLreturn

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

  • SR: $05FD4B 力を職業最大値でクリップする(新SR)
05FD4BPHAPush A
05FD4CJSL $C5FE80SR: $05FE80
05FD50CMP $01,SA>=Stack($01)?
05FD52BCS #$02if(c==on) goto $05FD56
05FD54STA $01,SStack($01)=A
05FD56PLAPull A
05FD57RTLreturn

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の場合は確実に成功?なので、オリジナル同様もう少し値を大きくしてもいいかもしれません。

タイトルとURLをコピーしました