DQ6 AI処理の解析5

今回からは個別の戦闘行動の効果値の算出部分に移ります。算出用のSRは大きく分けて2種類あり、1つ目が「外枠のSR」、2つ目が「効果値算出の実体SR」です。外枠というのは「1体のみ」「グループ」「全体」で同じ外枠のSRを使います。対象が1体の戦闘行動は「モンスター1体毎に効果値を計算し、最大になるモンスターをターゲットにする」という処理自体は変わりません。グループ対象の場合はグループごとに効果値を合算し最大になるグループを、全体の場合は単に全てのモンスターの効果値を合算するだけです。モンスター側の耐性にもよりますが、基本的にはこの外枠は変わりません。従ってコード量を減らすために対象が同じ戦闘行動は同じ外枠を使い、効果値算出のところだけ個別のSRをコールすることで余計な重複をカットしています。

実装を見る前に、よく使われるメモリの意味を先に列挙しておきます。

アドレスビット意味
DP($00)テンポラリ計算領域
DP($02)テンポラリ計算領域
DP($04)テンポラリ計算領域
DP($0C)01
02マヌーサ中
04
08
10
20山彦の帽子装備中
40
80
DP($0E)作戦ID
DP($14)現在評価中の戦闘行動の効果値の最大値
$7E25F3グループ1効果値合計(グループ対象行動のみ)
$7E25F5グループ2効果値合計(グループ対象行動のみ)
$7E25F7グループ3効果値合計(グループ対象行動のみ)
$7E25F9グループ4効果値合計(グループ対象行動のみ)
$7E260901グループ1に実行すると反撃を食らうモンスターがいる
02グループ2に実行すると反撃を食らうモンスターがいる
04グループ3に実行すると反撃を食らうモンスターがいる
08グループ4に実行すると反撃を食らうモンスターがいる
  • SR: $02D478 AI判断用_SR_0001
02D478STZ $14DP($14)=#$00
02D47ALDA #$0017A=#$0017戦闘参加キャラクターの最後のインデックス
02D47DSTA $258B$258B=A
02D480LDY #$04ACY=#$04AC戦闘参加キャラクターの最後の開始アドレスオフセット
02D483LDA #$0001A=#$0001
02D486STA $254B$254B=A
02D489STZ $2549$2549=#$00
02D48CLDA $203E,YA=$203E+Y
02D48FBEQ #$14if(z==on) goto $02D4A5HP0ならスキップ
02D491JSR $D4B1SR: $02D4B1対象のステータスを調べる(無効c=on 反射v=on)
02D494BCS #$0Fif(c==on) goto $02D4A5
02D496JSR $D4EBSR: $02D4EB対象の戦闘行動の効果値取得(ダメージ系)
02D499CMP $14A>=DP($14)?効果値の比較
02D49BBCC #$08if(c==off) goto $02D4A5
02D49DSTA $14DP($14)=A最大なら差し替え
02D49FLDA $258BA=$258B
02D4A2STA $2591$2591=A対象インデックスも差し替え
02D4A5TYAA=Y
02D4A6SECc=on
02D4A7SBC #$0034A-=(#$0034+!c)1キャラクター分のアドレスを減らす
02D4AATAYY=A
02D4ABDEC $258B$258B–
02D4AEBPL #$DCif(n==off) goto $02D48C
02D4B0RTSreturn

これは単体対象の戦闘行動のAIの「外枠」に相当するものです。単体行動対象の場合、マニュアルでのコマンド入力とは異なり、対象となるモンスターをインデックスベースで指定できるので、マニュアルより有利ということになります。

  • SR: $02D56C AI判断用_SR_0002
02D56CSTZ $258B$258B=#$00
02D56FLDY #$0000Y=#$0000
02D572STZ $25F3$25F3=#$00
02D575STZ $25F5$25F5=#$00
02D578STZ $25F7$25F7=#$00
02D57BSTZ $25F9$25F9=#$00
02D57ESTZ $25FB$25FB=#$00
02D581STZ $25FD$25FD=#$00
02D584STZ $25FF$25FF=#$00
02D587STZ $2601$2601=#$00
02D58ASTZ $2603$2603=#$00
02D58DSTZ $2605$2605=#$00
02D590STZ $2549$2549=#$00
02D593STZ $2609$2609=#$00
02D596LDA $203E,YA=$203E+Y
02D599BEQ #$3Aif(z==on) goto $02D5D5HP0ならスキップ
02D59BLDA $204E,YA=$204E+Y
02D59EAND #$0007A&=#$0007グループ番号を取得
02D5A1ASLA<<1
02D5A2STA $2607$2607=A
02D5A5TAXX=A
02D5A6LDA $C2D5F9,XA=$02D5F9+X
02D5AAAND $2609A&=$2609
02D5ADBNE #$26if(z==off) goto $02D5D5反射状態の敵がいるグループはスキップ
02D5AFJSR $D4B1SR: $02D4B1対象のステータスを調べる(無効c=on 反射v=on)
02D5B2BVS #$33if(v==on) goto $02D5E7
02D5B4BCS #$1Fif(c==on) goto $02D5D5
02D5B6LDX $2607X=$2607
02D5B9LDA $25FD,XA=$25FD+X
02D5BCINCA++
02D5BDSTA $25FD,X$25FD+X=A
02D5C0STA $254B$254B=A
02D5C3JSR $D4EBSR: $02D4EB対象の戦闘行動の効果値取得(ダメージ系)
02D5C6LDX $2607X=$2607
02D5C9CLCc=off
02D5CAADC $25F3,XA+=($25F3+X+c)
02D5CDBCC #$03if(c==off) goto $02D5D2
02D5CFLDA #$FFFFA=#$FFFF
02D5D2STA $25F3,X$25F3+X=A
02D5D5INC $258B$258B++
02D5D8TYAA=Y
02D5D9CLCc=off
02D5DAADC #$0034A+=(#$0034+c)1キャラクター分のアドレスを増やす
02D5DDTAYY=A
02D5DECMP #$04ADA>=#$04AD?
02D5E1BCC #$B3if(c==off) goto $02D596
02D5E3JSR $D603SR: $02D603グループ対象戦闘行動対象決定
02D5E6RTSreturn
02D5E7LDX $2607X=$2607反射する敵がいるのでこのグループは対象外にする
02D5EALDA $C2D5F9,XA=$02D5F9+X
02D5EEORA $2609Aor=$2609
02D5F1STA $2609$2609=A
02D5F4STZ $25F3,X$25F3+X=#$00
02D5F7BRA #$DCgoto $02D5D5

これはグループ対象の戦闘行動のAIの「外枠」に相当するものです。マホカンタやマホターン受け流しなど、実行すると自分がダメージを受けるような状態になってるモンスターがグループ中に存在する場合は実行をスキップするようにそのグループの値を0にして、以降そのグループに対しては評価を行わない、という点が単体とは異なります。あとは基本的にはグループごとに効果値を合算していき、その合計値の一番高いグループに対して行動する、となっています。

  • SR: $02D633 AI判断用_SR_0003
02D633STZ $14DP($14)=#$00
02D635STZ $258B$258B=#$00
02D638LDY #$0000Y=#$0000
02D63BSTZ $254B$254B=#$00
02D63ESTZ $2549$2549=#$00
02D641LDA $203E,YA=$203E+Y
02D644BEQ #$17if(z==on) goto $02D65DHP0ならスキップ
02D646JSR $D4B1SR: $02D4B1対象のステータスを調べる(無効c=on 反射v=on)
02D649BVS #$27if(v==on) goto $02D672反射するモンスターが居るなら実行しない
02D64BBCS #$10if(c==on) goto $02D65D
02D64DINC $254B$254B++
02D650JSR $D4EBSR: $02D4EB対象の戦闘行動の効果値取得(ダメージ系)
02D653CLCc=off
02D654ADC $14A+=(DP($14)+c)
02D656BCC #$03if(c==off) goto $02D65B
02D658LDA #$FFFFA=#$FFFF合計が#$FFFFを超えていたら#$FFFFでクリップする
02D65BSTA $14DP($14)=A
02D65DINC $258B$258B++
02D660TYAA=Y
02D661CLCc=off
02D662ADC #$0034A+=(#$0034+c)1キャラクター分のアドレスを増やす
02D665TAYY=A
02D666CMP #$04ADA>=#$04AD?
02D669BCC #$D6if(c==off) goto $02D641
02D66BLDA #$0041A=#$0041ターゲット情報は全体
02D66ESTA $2591$2591=A
02D671RTSreturn
02D672STZ $14DP($14)=#$00
02D674RTSreturn

これは全体対象の戦闘行動のAIの「外枠」に相当するものです。これも反射するモンスターがいた場合は即座に評価を中止しています。こうした枠組みは各戦闘行動の属性などとは異なり、どれも同じ仕組みで評価をすることができるため、対象毎に同じ外枠を使うことでコード量を節約することができます。とりあえず今回はこのへんで。

コメント

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