前回まででAI行動決定のための準備処理が終わっています。ここからはAIのメイン処理となる各戦闘行動の評価が始まります。
- SR: $02D191 AI行動決定
02D191 | JSL $C46CD9 | SR: $046CD9 | 戦闘参加パーティ人数取得 |
---|---|---|---|
02D195 | STA $1A | DP($1A)=A | |
02D197 | STZ $0C | DP($0C)=#$00 | |
02D199 | LDA $2555 | A=$2555 | 行動主体の戦闘中インデックス |
02D19C | ASL | A<<1 | |
02D19D | TAX | X=A | |
02D19E | LDA $C2F092,X | A=$02F092+X | 行動主体の戦闘中アドレス開始位置 |
02D1A2 | TAX | X=A | |
02D1A3 | LDA $2052,X | A=$2052+X | |
02D1A6 | AND #$00F0 | A&=#$00F0 | 呪文が使える状態か |
02D1A9 | BEQ #$07 | if(z==on) goto $02D1B2 | |
02D1AB | LDA $0C | A=DP($0C) | |
02D1AD | ORA #$0002 | Aor=#$0002 | 呪文使用可能フラグON |
02D1B0 | STA $0C | DP($0C)=A | |
02D1B2 | LDA $204F,X | A=$204F+X | |
02D1B5 | AND #$00FF | A&=#$00FF | |
02D1B8 | LDY #$00B4 | Y=#$00B4 | 山彦の帽子のアイテムID |
02D1BB | JSL $C45217 | SR: $045217 引数:1#$FD 引数:2#$07 引数:3#$FF 引数:4#$40 | アイテム装備チェック |
02D1C3 | BVC #$09 | if(v==off) goto $02D1CE | |
02D1C5 | PHA | Push A | |
02D1C6 | LDA $0C | A=DP($0C) | |
02D1C8 | ORA #$0020 | Aor=#$0020 | 山彦フラグON |
02D1CB | STA $0C | DP($0C)=A | |
02D1CD | PLA | Pull A | |
02D1CE | JSL $C45B66 | SR: $045B66 引数:1#$07 引数:2#$FF 引数:3#$40 | 行動主体者が取りうる戦闘行動の列挙 |
02D1D5 | STZ $18 | DP($18)=#$00 | |
02D1D7 | JSL $C43488 | SR: $043488 引数:1#$0E | DP($0E)に作戦取得 |
02D1DC | LDA $2011 | A=$2011 | |
02D1DF | AND #$0010 | A&=#$0010 | |
02D1E2 | BEQ #$05 | if(z==on) goto $02D1E9 | スライム格闘場か |
02D1E4 | LDA #$0005 | A=#$0005 | 「命令させろ」(コマンド入力は不可)を強制設定 |
02D1E7 | STA $0E | DP($0E)=A | |
02D1E9 | JSL $C2C9D5 | SR: $02C9D5 | 複数対象攻撃武器による期待ダメージ取得? |
02D1ED | LDX $18 | X=DP($18) | |
02D1EF | LDA $48D8,X | A=$48D8+X | |
02D1F2 | CMP #$0000 | A==#$0000? | |
02D1F5 | BEQ #$06 | if(z==on) goto $02D1FD | |
02D1F7 | STA $255F | $255F=A | |
02D1FA | JSR $D2A2 | SR: $02D2A2 | 対象の戦闘行動の効果値算出? |
02D1FD | INC $18 | DP($18)++ | |
02D1FF | INC $18 | DP($18)++ | |
02D201 | LDA $18 | A=DP($18) | |
02D203 | CMP #$0140 | A>=#$0140? | |
02D206 | BCC #$E5 | if(c==off) goto $02D1ED | |
02D208 | LDA #$0042 | A=#$0042 | 攻撃 |
02D20B | STA $255F | $255F=A | |
02D20E | JSR $D2A2 | SR: $02D2A2 | 対象の戦闘行動の効果値算出? |
02D211 | LDA #$0099 | A=#$0099 | 防御 |
02D214 | STA $255F | $255F=A | |
02D217 | JSR $D2A2 | SR: $02D2A2 | 対象の戦闘行動の効果値算出? |
02D21A | LDA $0E | A=DP($0E) | |
02D21C | ASL | A<<1 | |
02D21D | ASL | A<<1 | |
02D21E | ASL | A<<1 | |
02D21F | TAX | X=A | |
02D220 | LDY #$0000 | Y=#$0000 | |
02D223 | STZ $04 | DP($04)=#$00 | |
02D225 | LDA $260B,Y | A=$260B+Y | 各行動種別ごとの最大値取得 |
02D228 | STA $00 | DP($00)=A | |
02D22A | LDA $C2D272,X | A=$02D272+X | 作戦に応じた戦闘行動種別倍加 |
02D22E | AND #$00FF | A&=#$00FF | |
02D231 | PHX | Push X | |
02D232 | LDX #$0000 | X=#$0000 | |
02D235 | JSL $C00D0C | SR: $000D0C | DP($00+X)=A(1Byte)*DP($00+X) |
02D239 | PLX | Pull X | |
02D23A | LDA $02 | A=DP($02) | |
02D23C | BEQ #$05 | if(z==on) goto $02D243 | |
02D23E | LDA #$FFFF | A=#$FFFF | #$FFFFでクリップ |
02D241 | STA $00 | DP($00)=A | |
02D243 | LDA $04 | A=DP($04) | |
02D245 | CMP $00 | A>=DP($00)? | |
02D247 | BCS #$10 | if(c==on) goto $02D259 | |
02D249 | LDA $262B,Y | A=$262B+Y | |
02D24C | STA $258D | $258D=A | 決定された戦闘行動セット |
02D24F | LDA $263B,Y | A=$263B+Y | |
02D252 | STA $2591 | $2591=A | 対象情報をセット |
02D255 | LDA $00 | A=DP($00) | |
02D257 | STA $04 | DP($04)=A | |
02D259 | INX | X++ | |
02D25A | INY | Y++ | |
02D25B | INY | Y++ | |
02D25C | CPY #$0009 | Y>=#$0009? | なぜ9? |
02D25F | BCC #$C4 | if(c==off) goto $02D225 | |
02D261 | LDA $04 | A=DP($04) | |
02D263 | BNE #$0C | if(z==off) goto $02D271 | |
02D265 | LDA #$0042 | A=#$0042 | |
02D268 | STA $258D | $258D=A | |
02D26B | LDA #$0041 | A=#$0041 | |
02D26E | STA $2591 | $2591=A | |
02D271 | RTS | return |
このSRの中で戦闘行動の列挙→各戦闘行動の評価→補正→最終的な行動の決定を全て行っています。まず、戦闘行動の列挙ですが、呪文・特技のみで使用して効果のあるアイテムは含まれません。AIに任せていると賢者の石や雷鳴の剣は絶対に使われないということです。消費MP0の使い勝手のいい特技が多数あるDQ6では大して問題にはなりませんが、DQ3に移植する際には道具もAIの評価対象に含めるべきでしょう(携帯版やスマホ版はどうなってるかわかりませんが)。PS版以降のDQでは道具も対象に含まれているようなので(確かPS版DQ4は道具を使ってくれたはず)、これはSFC版DQ6特有の動作だと言えます。SFC版DQ5はどうだったか忘れました。
次に列挙した戦闘行動について1つずつ評価を行います。ここでは、各戦闘行動について固有のAI評価用のSRを呼び出し評価を行います。評価の結果はダメージ系以外の戦闘行動でも数値で表されます。便宜上ここでは「効果値」と呼ぶことにします。以前にもチラッと触れましたが、DQ6のAIは各戦闘行動を選択したとしたらどれだけの効果があるかを効果値で表現することでその大小の比較で効果値の高いものを選択するという極めてシンプルなものになっています。各戦闘行動は「行動種別」という値を持っており、それぞれ「ダメージ系」「補助(敵弱体)」「補助(味方強化)」「回復系(ステータス異常回復も含む)」「蘇生系」の5種類に分別されます。ある戦闘行動を評価した結果、すでにセットされている自分の所属する種別の最大効果値と比較し、大きければ差し替える、という処理を繰り返します。これにより全ての選択可能な戦闘行動の評価が終わると各行動種別の最大値がバッファにセットされた状態になります。最後に直接攻撃、防御についても評価を行います(列挙したリストに含まれないため)。
全部の評価が終わったあとは、作戦による各行動種別の補正を行います。一部の戦闘行動については評価中に作戦に応じた特殊な処理が含まれたりしますが、作戦方針によるざっくりとした補正を行います。補正内容は以下のとおり。
数値は全部倍率です。当然0になっている行動種別は一切実行されません。この補正を行ったあと、効果値が最大になる行動を探して最終的な決定になります。次回からは個別の評価SRの中身を見ていくことにします。
コメント
dq3 K.Mix、楽しませてもらっています。
ちょっとした要望なのですが、ルイーダの酒場で仲間を預ける際にアイテムが自動でふくろに入らないようにできませんか?
いろいろなキャラを育てながらプレイしているのですが、メンバーを入れ替えるときにうっかり薬草や毒消し草が消えるのが貧乏性な自分は気になってしまいまして。