今回はルカニ系の処理を見てみます。基本的にはやってることはスカラの逆です。
- SR: $02DC86 AI判断用_SR_001C(ルカニ)
02DC86 | JSR $DCBB | SR: $02DCBB | PC側の攻撃力最小値取得 |
---|---|---|---|
02DC89 | STZ $14 | DP($14)=#$00 | |
02DC8B | LDA #$0017 | A=#$0017 | |
02DC8E | STA $258B | $258B=A | |
02DC91 | LDY #$04AC | Y=#$04AC | |
02DC94 | LDA $203E,Y | A=$203E+Y | 現HP+脅威値合計が0ならスキップ |
02DC97 | BEQ #$16 | if(z==on) goto $02DCAF | |
02DC99 | JSR $D4B1 | SR: $02D4B1 | 対象のステータスを調べる(無効c=on 反射v=on) |
02DC9C | BCS #$11 | if(c==on) goto $02DCAF | |
02DC9E | JSR $DD00 | SR: $02DD00 | モンスター側の現守備力最大値取得 |
02DCA1 | LDA $00 | A=DP($00) | |
02DCA3 | CMP $14 | A>=DP($14)? | |
02DCA5 | BCC #$08 | if(c==off) goto $02DCAF | |
02DCA7 | STA $14 | DP($14)=A | |
02DCA9 | LDA $258B | A=$258B | |
02DCAC | STA $2591 | $2591=A | |
02DCAF | DEC $258B | $258B– | |
02DCB2 | TYA | A=Y | |
02DCB3 | SEC | c=on | |
02DCB4 | SBC #$0034 | A-=(#$0034+!c) | |
02DCB7 | TAY | Y=A | |
02DCB8 | BPL #$DA | if(n==off) goto $02DC94 | |
02DCBA | RTS | return |
- SR: $02DCBB PC側の攻撃力最小値取得
02DCBB | LDY #$04AC | Y=#$04AC | |
---|---|---|---|
02DCBE | STZ $08 | DP($08)=#$00 | |
02DCC0 | LDA $205F,Y | A=$205F+Y | |
02DCC3 | AND #$0001 | A&=#$0001 | 戦闘に参加していなければスキップ |
02DCC6 | BEQ #$2F | if(z==on) goto $02DCF7 | |
02DCC8 | LDA $204E,Y | A=$204E+Y | |
02DCCB | AND #$0007 | A&=#$0007 | |
02DCCE | CMP #$0006 | A>=#$0006? | グループIDが味方でなければスキップ |
02DCD1 | BCC #$24 | if(c==off) goto $02DCF7 | |
02DCD3 | LDA $205E,Y | A=$205E+Y | |
02DCD6 | AND #$0004 | A&=#$0004 | 不明? |
02DCD9 | BNE #$1C | if(z==off) goto $02DCF7 | |
02DCDB | LDA $2050,Y | A=$2050+Y | |
02DCDE | AND #$0002 | A&=#$0002 | 生死判定 |
02DCE1 | BNE #$14 | if(z==off) goto $02DCF7 | |
02DCE3 | LDA $2050,Y | A=$2050+Y | |
02DCE6 | AND #$0008 | A&=#$0008 | 麻痺ならスキップ |
02DCE9 | BNE #$0C | if(z==off) goto $02DCF7 | |
02DCEB | LDA $205A,Y | A=$205A+Y | |
02DCEE | AND #$03FF | A&=#$03FF | 攻撃力取得 |
02DCF1 | CMP $08 | A>=DP($08)? | |
02DCF3 | BCC #$02 | if(c==off) goto $02DCF7 | |
02DCF5 | STA $08 | DP($08)=A | |
02DCF7 | TYA | A=Y | |
02DCF8 | SEC | c=on | |
02DCF9 | SBC #$0034 | A-=(#$0034+!c) | |
02DCFC | TAY | Y=A | |
02DCFD | BPL #$C1 | if(n==off) goto $02DCC0 | |
02DCFF | RTS | return |
- SR: $02DD00 モンスター側の現守備力の1/8を取得
02DD00 | LDA $2058,Y | A=$2058+Y | |
---|---|---|---|
02DD03 | AND #$03FF | A&=#$03FF | 守備力取得 |
02DD06 | ASL | A <<1 | |
02DD07 | SEC | c=on | |
02DD08 | SBC $08 | A-=(DP($08)+!c) | |
02DD0A | BCC #$15 | if(c==off) goto $02DD21 | |
02DD0C | STA $00 | DP($00)=A | |
02DD0E | LDA $258B | A=$258B | |
02DD11 | STA $2559 | $2559=A | |
02DD14 | PHY | Push Y | |
02DD15 | JSL $C2A656 | SR: $02A656 | 耐性を考慮した閾値取得 |
02DD19 | PLY | Pull Y | |
02DD1A | LSR $00 | DP($00)>>1 | |
02DD1C | LSR $00 | DP($00)>>1 | |
02DD1E | LSR $00 | DP($00)>>1 | |
02DD20 | RTS | return | |
02DD21 | STZ $00 | DP($00)=#$00 | |
02DD23 | RTS | return |
基本的には「ルカニを実行することでどれだけダメージが増えるか」を効果値として算出しているようです。当たり前といえば当たり前の話です。他にもメダパニなどは脅威値合計に成功率を書けたたもの(期待値?)を半減させるといった実装になっています。
というわけでざっくりとですがDQ6のAI実装を見てきました。基本的にはこの実装をベースに多少のアレンジを加えたものをDQ3に移植したわけですが、DQ6には存在しないピオリム、ボミオスについてはさじ加減がわからなかったので結局実装していません。素早さの上昇or低下がどれくらい効果値に変換できるのかというのが不明なため(明らかにスカラ・ルカニよりは低いでしょう)、実装したところで実際にAIが選択する局面はかなり限られると思ったのでとりあえず飛ばしました。次回総括のようなものをしてAIに関しては終わりにしようと思います。
コメント
DQ6や3で特技会心・呪文会心ってプログラム的に可能ですか?
「やれば出来るんじゃないんですか」という感じですね。ダメージ加算周辺は前回の回答を参考にしてください。エフェクトやら発生時のメッセージを変える必要があるのでもうちょっと面倒だと思いますが。
回答ありがとうございます!