マヌーサ・マホトーンなどの補助呪文の他に戦闘中重要なのはバイキルト・スカラ系・ルカニ系・フバーハ・マジックバリアなどがあります。DQ3に移植する際にマジックバリア以外は避けて通れないので解析にかなり手間がかかりました。このへんになってくるとどう数値化したもんかというのが問題になってきます。
- SR: $02DDDF AI判断用_SR_0019(バイキルト)
02DDDF | STZ $14 | DP($14)=#$00 | |
---|---|---|---|
02DDE1 | LDX #$0017 | X=#$0017 | 最終インデックス |
02DDE4 | LDY #$04AC | Y=#$04AC | 最終インデックス開始オフセット |
02DDE7 | STZ $04 | DP($04)=#$00 | |
02DDE9 | LDA $205F,Y | A=$205F+Y | |
02DDEC | AND #$0001 | A&=#$0001 | 戦闘に参加していなければスキップ |
02DDEF | BEQ #$6C | if(z==on) goto $02DE5D | |
02DDF1 | LDA $204E,Y | A=$204E+Y | |
02DDF4 | AND #$0007 | A&=#$0007 | |
02DDF7 | CMP #$0006 | A>=#$0006? | グループIDがモンスター側ならスキップ |
02DDFA | BCC #$61 | if(c==off) goto $02DE5D | |
02DDFC | LDA $205E,Y | A=$205E+Y | |
02DDFF | AND #$0004 | A&=#$0004 | 条件不明 |
02DE02 | BNE #$59 | if(z==off) goto $02DE5D | |
02DE04 | LDA $2050,Y | A=$2050+Y | |
02DE07 | AND #$0002 | A&=#$0002 | 生死判定 |
02DE0A | BNE #$51 | if(z==off) goto $02DE5D | |
02DE0C | LDA $2059,Y | A=$2059+Y | |
02DE0F | AND #$00C0 | A&=#$00C0 | マホカンタ・マホターン |
02DE12 | BNE #$49 | if(z==off) goto $02DE5D | |
02DE14 | LDA $2050,Y | A=$2050+Y | |
02DE17 | AND #$0008 | A&=#$0008 | マヒ |
02DE1A | BNE #$41 | if(z==off) goto $02DE5D | |
02DE1C | LDA $204E,Y | A=$204E+Y | |
02DE1F | AND #$0020 | A&=#$0020 | バイキルト |
02DE22 | BNE #$39 | if(z==off) goto $02DE5D | |
02DE24 | LDA $2052,Y | A=$2052+Y | |
02DE27 | AND #$00F0 | A&=#$00F0 | マヌーサ中 |
02DE2A | BNE #$31 | if(z==off) goto $02DE5D | |
02DE2C | LDA $2052,Y | A=$2052+Y | |
02DE2F | AND #$0002 | A&=#$0002 | 混乱 |
02DE32 | BNE #$29 | if(z==off) goto $02DE5D | |
02DE34 | LDA $2050,Y | A=$2050+Y | |
02DE37 | AND #$00E0 | A&=#$00E0 | 眠り |
02DE3A | BNE #$21 | if(z==off) goto $02DE5D | |
02DE3C | LDA $0E | A=DP($0E) | |
02DE3E | CMP #$0002 | A==#$0002? | 作戦が俺に任せろなら主人公のみ対象 |
02DE41 | BNE #$0B | if(z==off) goto $02DE4E | |
02DE43 | LDA $204F,Y | A=$204F+Y | |
02DE46 | AND #$01FF | A&=#$01FF | |
02DE49 | CMP #$0101 | A==#$0101? | |
02DE4C | BNE #$0F | if(z==off) goto $02DE5D | |
02DE4E | LDA $205A,Y | A=$205A+Y | |
02DE51 | AND #$03FF | A&=#$03FF | 攻撃力取得 |
02DE54 | CMP $04 | A>=DP($04)? | |
02DE56 | BCC #$05 | if(c==off) goto $02DE5D | |
02DE58 | STA $04 | DP($04)=A | 攻撃力最大値をセット |
02DE5A | STX $2591 | $2591=X | 対象のインデックスを保存 |
02DE5D | TYA | A=Y | |
02DE5E | SEC | c=on | |
02DE5F | SBC #$0034 | A-=(#$0034+!c) | |
02DE62 | TAY | Y=A | |
02DE63 | DEX | X– | |
02DE64 | BPL #$83 | if(n==off) goto $02DDE9 | |
02DE66 | LDA $04 | A=DP($04) | 最大攻撃力が0なら該当者なし |
02DE68 | BEQ #$4F | if(z==on) goto $02DEB9 | |
02DE6A | JSL $C2E939 | SR: $02E939 引数:1#$00 | ターゲット情報セット(戦闘参加者かつ生者のみ) |
02DE6F | JSL $C2E966 | SR: $02E966 引数:1#$06 | ターゲット情報セット(リストアップ済みから味方側を抜く) |
02DE74 | LDA $04 | A=DP($04) | |
02DE76 | LSR | A>>1 | |
02DE77 | LSR | A>>1 | |
02DE78 | PHA | Push A | |
02DE79 | LDA $04 | A=DP($04) | |
02DE7B | ASL | A< <1 | |
02DE7C | SEC | c=on | |
02DE7D | SBC $01,S | A-=(Stack($01)+!c) | |
02DE7F | STA $01,S | Stack($01)=A | |
02DE81 | PLA | Pull A | 最大攻撃力の1.75倍の値を作る |
02DE82 | JSL $C2E966 | SR: $02E966 引数:1#$38 | ターゲット情報セット(リストアップ済みから最大攻撃力1.75倍より守備力が多いものを抜く) |
02DE87 | LDA $04 | A=DP($04) | |
02DE89 | JSL $C2E966 | SR: $02E966 引数:1#$60 | ターゲット情報セット(リストアップ済みから最大攻撃力よりHPが少ないものを抜く) |
02DE8E | LDA $00 | A=DP($00) | |
02DE90 | ORA $02 | Aor=DP($02) | |
02DE92 | BEQ #$25 | if(z==on) goto $02DEB9 | 該当するモンスターがいなければ終わり |
02DE94 | LDY #$0000 | Y=#$0000 | |
02DE97 | LSR $02 | DP($02)>>1 | |
02DE99 | ROR $00 | DP($00)>>1 | |
02DE9B | BCC #$0D | if(c==off) goto $02DEAA | |
02DE9D | LDA $204A,Y | A=$204A+Y | 条件に該当したモンスターの脅威値合計を加算する |
02DEA0 | CLC | c=off | |
02DEA1 | ADC $14 | A+=(DP($14)+c) | |
02DEA3 | BCC #$03 | if(c==off) goto $02DEA8 | |
02DEA5 | LDA #$FFFF | A=#$FFFF | オーバーフロー調整 |
02DEA8 | STA $14 | DP($14)=A | |
02DEAA | TYA | A=Y | |
02DEAB | CLC | c=off | |
02DEAC | ADC #$0034 | A+=(#$0034+c) | 1戦闘中キャラクター分のアドレスを加算 |
02DEAF | TAY | Y=A | |
02DEB0 | CMP #$04AD | A>=#$04AD? | 最終インデックスのアドレスオフセットまで続ける |
02DEB3 | BCC #$E2 | if(c==off) goto $02DE97 | |
02DEB5 | LSR $14 | DP($14)>>1 | |
02DEB7 | LSR $14 | DP($14)>>1 | 作成した脅威値を1/4する |
02DEB9 | RTS | return |
補助系の呪文の問題点は「数値化が難しい」という一点につきます。もちろんいかようにでも実装は可能ですが、「はたして算出された効果値が妥当か」どうかでやたらと連発するようになったり、逆に全く実行してくれなかったりということになります。上のSRの流れはおおまかに言うと以下のようになっています。
- バイキルトをかけて意味のある((すでにバイキルトがかかっている、生きている、麻痺っていない、マヌーサにかかっていないなどの条件判断をする))味方のうちの最大攻撃力(とインデックス)を探す
- モンスター側のリストアップ(ターゲット情報セットSRを使う)
- 1で取得した最大攻撃力の1.75倍より守備力が大きいモンスターをリストから消す
- 1で取得した最大攻撃力の2倍よりHPが小さいモンスターをリストから消す
- 残ったモンスターの脅威値合計を合算し、1/4する
1では「おれにまかせろの場合には主人公のみを対象にする」という作戦別の特殊な処理が練りこまれています。正直3と4はなぜそういう判断になっているのか不明ですが、要は「バイキルトをかけて効果のあるモンスターだけを残す」を意図しているようです。3についてはDQ6のバイキルトは「ダメージ値を2倍」するものなので、守備力が高過ぎるモンスターに対しては意味がありません(ダメージ0を2倍しても0)。なので守備力が高すぎる場合には条件から外すということのようです。4についてはHPが低ければ長期戦にならないのですぐ倒せるという想定のもとバイキルトをかけるまでもないということで条件から外すということのようです。最後の5の1/4は補助系ということもあって効果値を控え目にするということなのでしょう。DQ3に移植する際はアレンジして意味があるとも思えないので((そのまま移植すれば文句もあるまいという))、バイキルトに関しては何も考えずこのまま移植することにしました。
コメント