攻撃系の行動はほとんど共通です。AIの行動区分の「攻撃系」にはニフラム・ザキなどの一発離脱系も含まれます(バシルーラはAIの選択対象外)。
- SR: $02D675 AI判断用_SR_001A(直接攻撃)
02D675 | LDX #$0004 | X=#$0004 | |
---|---|---|---|
02D678 | LDA $25DD | A=$25DD | 単体・グループ・全体かの情報 |
02D67B | BMI #$07 | if(n==on) goto $02D684 | |
02D67D | DEX | X– | |
02D67E | DEX | X– | |
02D67F | ASL | A< <1 | |
02D680 | BCS #$02 | if(c==on) goto $02D684 | |
02D682 | DEX | X– | |
02D683 | DEX | X– | |
02D684 | JSR $D688 | SR: $($02D688+X) | |
02D687 | RTS | return |
DQ6では単体・グループ・全体攻撃は戦闘行動IDは同じなので別の情報で判断して振り分けています。基本的にやってることはどれも同じなので、単体の直接攻撃をみてみます。
- SR: $02D478 AI判断用_SR_0001(単体対象行動)
02D478 | STZ $14 | DP($14)=#$00 | |
---|---|---|---|
02D47A | LDA #$0017 | A=#$0017 | 最大インデックスからデクリメントしていく |
02D47D | STA $258B | $258B=A | |
02D480 | LDY #$04AC | Y=#$04AC | 最大インデックスの開始アドレス |
02D483 | LDA #$0001 | A=#$0001 | |
02D486 | STA $254B | $254B=A | |
02D489 | STZ $2549 | $2549=#$00 | |
02D48C | LDA $203E,Y | A=$203E+Y | |
02D48F | BEQ #$14 | if(z==on) goto $02D4A5 | |
02D491 | JSR $D4B1 | SR: $02D4B1 | 対象のステータスを調べる(無効c=on 反射v=on) |
02D494 | BCS #$0F | if(c==on) goto $02D4A5 | |
02D496 | JSR $D4EB | SR: $02D4EB | 対象の戦闘行動の効果値取得(ダメージ系) |
02D499 | CMP $14 | A>=DP($14)? | |
02D49B | BCC #$08 | if(c==off) goto $02D4A5 | |
02D49D | STA $14 | DP($14)=A | 効果値が最大なら差し替え |
02D49F | LDA $258B | A=$258B | |
02D4A2 | STA $2591 | $2591=A | 対象情報も更新 |
02D4A5 | TYA | A=Y | |
02D4A6 | SEC | c=on | |
02D4A7 | SBC #$0034 | A-=(#$0034+!c) | |
02D4AA | TAY | Y=A | |
02D4AB | DEC $258B | $258B– | |
02D4AE | BPL #$DC | if(n==off) goto $02D48C | |
02D4B0 | RTS | return |
単体の行動なので、対象全てに対して効果値の算出を行い、効果値が最大の相手に対して行動するといういつものパターンです。
- SR: $02D4EB 対象の戦闘行動の効果値取得
02D4EB | JSL $C2E065 | SR: $02E065 | 効果値算出(ダメージ系) |
---|---|---|---|
02D4EF | STA $00 | DP($00)=A | |
02D4F1 | JSR $D52A | SR: $02D52A | 効果値の補正 |
02D4F4 | LDA $0C | A=DP($0C) | |
02D4F6 | CMP #$8020 | A==#$8020? | |
02D4F9 | BNE #$02 | if(z==off) goto $02D4FD | |
02D4FB | ASL $00 | DP($00)< <1 | 山彦の帽子装備でダメージが倍加するなら倍にする |
02D4FD | LDA $00 | A=DP($00) | |
02D4FF | SEC | c=on | |
02D500 | SBC $2030,Y | A-=($2030+Y+!c) | 対象の現HPと比較する |
02D503 | BCC #$22 | if(c==off) goto $02D527 | この行動で対象が倒せる場合 |
02D505 | STA $00 | DP($00)=A | |
02D507 | LDA $0E | A=DP($0E) | 作戦がガンガン行こうぜか |
02D509 | CMP #$0000 | A==#$0000? | |
02D50C | BEQ #$02 | if(z==on) goto $02D510 | |
02D50E | STZ $00 | DP($00)=#$00 | ガンガン行こうぜ以外は効果値は加算しない |
02D510 | LDA $00 | A=DP($00) | |
02D512 | CLC | c=off | |
02D513 | ADC $203E,Y | A+=($203E+Y+c) | 脅威値合計を加算する |
02D516 | BCC #$04 | if(c==off) goto $02D51C | |
02D518 | LDA #$FFFF | A=#$FFFF | |
02D51B | CLC | c=off | |
02D51C | ADC $203C,Y | A+=($203C+Y+c) | |
02D51F | BCC #$03 | if(c==off) goto $02D524 | |
02D521 | LDA #$FFFF | A=#$FFFF | オーバーフロー対策 |
02D524 | STA $00 | DP($00)=A | |
02D526 | RTS | return | |
02D527 | LDA $00 | A=DP($00) | |
02D529 | RTS | return |
ダメージ予想値が対象のHP以下であれば倒せないのでそのままダメージ予想値が効果値となりますが、倒せる場合は脅威値合計を加算します(脅威値合計のほうがダメージ値より大きくなるので優先的に選ばれやすくなる)。
- SR: $02E065 効果値算出
02E065 | PHP | Push P Flag | |
---|---|---|---|
02E066 | PHB | Push DB | |
02E067 | REP #$30 | m=off(A/M:16b) x=off(X/Y:16b) | |
02E069 | PEA #$7E7E | Push #$7E7E | |
02E06C | PLB | Pull DB | |
02E06D | PLB | Pull DB | |
02E06E | PHX | Push X | |
02E06F | PHY | Push Y | |
02E070 | LDA $255F | A=$255F | |
02E073 | ASL | A< <1 | |
02E074 | TAX | X=A | |
02E075 | LDA $C8EE67,X | A=$08EE67+X | |
02E079 | TAX | X=A | |
02E07A | LDA $C8C666,X | A=$08C666+X | |
02E07E | AND #$003F | A&=#$003F | 評価対象の戦闘行動の属性ID取得 |
02E081 | CMP #$0021 | A>=#$0021? | |
02E084 | BCS #$FE | if(c==on) goto $02E084 | |
02E086 | ASL | A< <1 | |
02E087 | TAX | X=A | |
02E088 | JSR $E0D6 | SR: $($02E0D6+X) | AI効果値算出用SRのインデックス |
02E08B | LDA $2517 | A=$2517 | |
02E08E | ORA #$0020 | Aor=#$0020 | |
02E091 | STA $2517 | $2517=A | |
02E094 | LDA $258B | A=$258B | |
02E097 | STA $2559 | $2559=A | |
02E09A | JSL $C2852F | SR: $02852F | ダメージ補正処理 |
02E09E | LDA $2559 | A=$2559 | |
02E0A1 | STA $258B | $258B=A | |
02E0A4 | LDA $00 | A=DP($00) | |
02E0A6 | PLY | Pull Y | |
02E0A7 | PLX | Pull X | |
02E0A8 | PLB | Pull DB | |
02E0A9 | PLP | Pull P Flag | |
02E0AA | RTL | return |
ダメージ補正処理は実際の戦闘行動でも使用しているダメージ補正処理と同じです(バイキルトなら2倍、防御なら半減、フバーハなら半減などの補正)。DQ3に移植する際にも同じようにしたかったのですが、関連するメモリがそのまま流用できるのかわからなかったため、補正用のSRを新規定義しています。バイキルト・防御状態はチェックしていますが、簡易版にしています(特に種族特攻の計算はすっ飛ばしています)。
- SR: $02E11B AI判断用効果値算出_SR_0001(直接攻撃)
02E11B | LDA $2555 | A=$2555 | |
---|---|---|---|
02E11E | ASL | A< <1 | |
02E11F | TAX | X=A | |
02E120 | LDA $C2F092,X | A=$02F092+X | |
02E124 | TAX | X=A | |
02E125 | LDA $205A,X | A=$205A+X | 行動主体の攻撃力取得 |
02E128 | AND #$03FF | A&=#$03FF | |
02E12B | STA $00 | DP($00)=A | |
02E12D | LDA $258B | A=$258B | |
02E130 | ASL | A< <1 | |
02E131 | TAX | X=A | |
02E132 | LDA $C2F092,X | A=$02F092+X | |
02E136 | TAX | X=A | |
02E137 | LDA $2058,X | A=$2058+X | 対象の守備力取得 |
02E13A | AND #$03FF | A&=#$03FF | |
02E13D | STA $02 | DP($02)=A | |
02E13F | JSR $E143 | SR: $02E143 | 直接攻撃推定ダメージ値取得 |
02E142 | RTS | return |
- SR: $02E143 直接攻撃推定ダメージ値取得
02E143 | LDA $02 | A=DP($02) | |
---|---|---|---|
02E145 | LSR | A>>1 | |
02E146 | STA $04 | DP($04)=A | |
02E148 | LDA $00 | A=DP($00) | |
02E14A | SEC | c=on | |
02E14B | SBC $04 | A-=(DP($04)+!c) | |
02E14D | BCC #$22 | if(c==off) goto $02E171 | |
02E14F | LSR | A>>1 | |
02E150 | BEQ #$1F | if(z==on) goto $02E171 | |
02E152 | STA $08 | DP($08)=A | |
02E154 | LDA $00 | A=DP($00) | |
02E156 | LSR | A>>1 | |
02E157 | LSR | A>>1 | |
02E158 | LSR | A>>1 | |
02E159 | LSR | A>>1 | |
02E15A | STA $06 | DP($06)=A | |
02E15C | CMP $08 | A>=DP($08)? | |
02E15E | BCS #$0B | if(c==on) goto $02E16B | |
02E160 | LDA $04 | A=DP($04) | |
02E162 | CMP $00 | A>=DP($00)? | |
02E164 | BCS #$05 | if(c==on) goto $02E16B | |
02E166 | LDA $08 | A=DP($08) | |
02E168 | STA $00 | DP($00)=A | |
02E16A | RTS | return | |
02E16B | LDA $06 | A=DP($06) | |
02E16D | LSR | A>>1 | |
02E16E | STA $00 | DP($00)=A | |
02E170 | RTS | return | |
02E171 | STZ $00 | DP($00)=#$00 | |
02E173 | RTS | return |
ここは直接攻撃によるダメージ値を乱数による変動なしで算出しています。いろいろやっていますが
- 攻撃力-守備力1/2< =1なら0
- 攻撃力1/16>(攻撃力-守備力1/2)1/2なら攻撃力1/32
- 攻撃力=守備力1/2なら攻撃力1/32
- 上記以外なら(攻撃力-守備力1/2)1/2
ということのようです。ちなみにダメージ呪文系はどうなっているかというと、
- SR: $02E236 AI判断用効果値算出_SR_0009(メラ系)
02E236 | JSL $C9291A | SR: $09291A | 戦闘行動の最小値を取得する |
---|---|---|---|
02E23A | RTS | return |
で、単純に数値設定の最小値を取ってくるだけです(この後対象の耐性による補正などが入りますが)。最後に一発離脱系を見てみます。
- SR: $02E23B AI判断用効果値算出_SR_000A(ザキ系)
02E23B | LDA $258B | A=$258B | |
---|---|---|---|
02E23E | ASL | A< <1 | |
02E23F | TAX | X=A | |
02E240 | LDA $C2F092,X | A=$02F092+X | |
02E244 | TAX | X=A | |
02E245 | LDA $2030,X | A=$2030+X | 現HPを効果値のベースとする |
02E248 | STA $04 | DP($04)=A | |
02E24A | LDA $255F | A=$255F | |
02E24D | STA $258D | $258D=A | |
02E250 | JSL $C2A665 | SR: $02A665 | 耐性を考慮した閾値取得? |
02E254 | CMP #$0081 | A>=#$0081? | 成功率が50%以下なら効果値を半減 |
02E257 | BCS #$01 | if(c==on) goto $02E25A | |
02E259 | LSR | A>>1 | |
02E25A | LDX #$0004 | X=#$0004 | |
02E25D | JSL $C00D0C | SR: $000D0C | DP($00+X)=A(1Byte)*DP($00+X) |
02E261 | LDA $05 | A=DP($05) | |
02E263 | BEQ #$01 | if(z==on) goto $02E266 | |
02E265 | DEC | A– | |
02E266 | STA $00 | DP($00)=A | |
02E268 | RTS | return |
ザキ系はダメージ系よりも効果値は低くなるようになっているようです(このへんはFC版DQ4のクリフトの反省があるのかもしれませんが)。省略しますが、ニフラム系は脅威値合計に成功率をかけてさらに1/32しているので、普通にプレイしていたらまず選択されることはありません(AIの区分がダメージ系と同じ区分なので)。DQ3に移植する際には一発離脱系の行動はダメージ系と別区分にしたので(効果値の計算式も若干変えた)、AIをONにしているとそこそこ目にする機会が多いと思います。マニュアルではまずやらないゾンビ系にもザキを撃ったりしてされ効いたりするのにはちょっとびっくりしましたが、AIがイメージと違う弱点を突くから耐性を変えるというのもどうかと思うのでそのままにしています。
結構長くなったので今回はこのへんで。次回は補助系行動を見てみます。
コメント