- SR:$0238BB 戦闘コマンド処理_SRアドレス_戦う
0238BB | JSL $C42B1C | SR: $042B1C 引数:1#$01 引数:2#$FF | パーティ人数取得 |
---|---|---|---|
0238C1 | PHA | Push A | |
0238C2 | LDY #$0000 | Y=#$0000 | |
0238C5 | JSL $C2BB34 | SR: $02BB34 | 戦闘中キャラクターIDから通常キャラクターIDへ変換 |
0238C9 | STX $258B | $258B=X | |
0238CC | JSR $3965 | SR: $023965 | コマンド入力の必要があるか(ないc=on) |
0238CF | BCS #$55 | if(c==on) goto $023926 | |
0238D1 | JSL $C2CAC6 | SR: $02CAC6 | |
0238D5 | STY $386E | $386E=Y | |
0238D8 | LDA #$00DA | A=#$00DA | 戦闘コマンド入力のウィンドウID |
0238DB | JSL $C37236 | SR: $037236 | ウィンドウ描画+ユーザー入力を得る(キャンセルc=on) |
0238DF | BCS #$4E | if(c==on) goto $02392F | |
0238E1 | LDX $258B | X=$258B | |
0238E4 | JSL $C2C331 | SR: $02C331 | |
0238E8 | LDX #$000A | X=#$000A | |
0238EB | LDA $3874 | A=$3874 | |
0238EE | CMP $C2394D,X | A==$02394D+X? | |
0238F2 | BEQ #$06 | if(z==on) goto $0238FA | |
0238F4 | DEX | X– | |
0238F5 | DEX | X– | |
0238F6 | BPL #$F6 | if(n==off) goto $0238EE | |
0238F8 | BRA #$FE | goto $0238F8 | |
0238FA | JSR $3959 | SR: $($023959+X) | 戦闘コマンド各種処理 |
0238FD | BCC #$06 | if(c==off) goto $023905 | |
0238FF | JSL $C3B0B9 | SR: $03B0B9 | ウィンドウ消去(フェードなし) |
023903 | BRA #$DA | goto $0238DF | |
023905 | LDX $258B | X=$258B | |
023908 | JSL $C2EFA7 | SR: $02EFA7 引数:1#$2052 引数:2#$0002 | 混乱中かチェック |
023910 | BEQ #$14 | if(z==on) goto $023926 | |
023912 | LDA #$8198 | A=#$8198 | 混乱していたら「行動直前に戦闘行動を決定」の戦闘行動・対象値に差し替え |
023915 | JSL $C2EF6B | SR: $02EF6B 引数:1#$2034 | |
02391B | LDA #$0000 | A=#$0000 | |
02391E | JSL $C2F034 | SR: $02F034 引数:1#$2061 引数:2#$0080 | |
023926 | INY | Y++ | |
023927 | TYA | A=Y | |
023928 | CMP $01,S | A>=Stack($01)? | |
02392A | BCC #$99 | if(c==off) goto $0238C5 | |
02392C | PLA | Pull A | |
02392D | CLC | c=off | |
02392E | RTS | return | |
02392F | DEY | Y– | 戦闘コマンドキャンセル時の処理 |
023930 | BMI #$18 | if(n==on) goto $02394A | |
023932 | JSL $C2BB34 | SR: $02BB34 | 戦闘中キャラクターIDから通常キャラクターIDへ変換 |
023936 | STX $258B | $258B=X | |
023939 | JSR $3965 | SR: $023965 | コマンド入力の必要があるか(ないc=on) |
02393C | BCS #$F1 | if(c==on) goto $02392F | |
02393E | DEC $38B0 | $38B0– | |
023941 | LDA $38B0 | A=$38B0 | |
023944 | JSL $C3B4F9 | SR: $03B4F9 | 指定ページ以上の深さのバッファクリア |
023948 | BRA #$87 | goto $0238D1 | |
02394A | PLA | Pull A | |
02394B | SEC | c=on | |
02394C | RTS | return |
基本的にはパーティ人数を取得し、コマンド入力の必要があるかどうかを判断し、必要がなければスキップするというループを人数分繰り返しています。$02392F-以降の処理は戦闘コマンド入力ウィンドウでキャンセルをおした時の処理です。1つ前に戻るわけですが、死人などコマンド入力のひつようのないキャラクターをスキップするということをやっています。Yが#$FFFFになったら一番先頭ということなので1つ前のウィンドウに戻ります。
- SR:$02C197 AI行動決定の必要があるか(ないc=on)
02C197 | PHP | Push P Flag | |
---|---|---|---|
02C198 | REP #$30 | m=off(A/M:16b) x=off(X/Y:16b) | |
02C19A | PHA | Push A | |
02C19B | PHX | Push X | |
02C19C | PHY | Push Y | |
02C19D | PHB | Push DB | |
02C19E | PEA #$7E7E | Push #$7E7E | |
02C1A1 | PLB | Pull DB | |
02C1A2 | PLB | Pull DB | |
02C1A3 | LDX $258B | X=$258B | |
02C1A6 | JSL $C2EFA7 | SR: $02EFA7 引数:1#$204E 引数:2#$0007 | グループIDを収得 |
02C1AE | CMP #$0006 | A>=#$0006? | PC側でなければスキップ |
02C1B1 | BCC #$30 | if(c==off) goto $02C1E3 | |
02C1B3 | JSL $C2EFA7 | SR: $02EFA7 引数:1#$204F 引数:2#$00FF | キャラクターID取得 |
02C1BB | JSL $C45D7A | SR: $045D7A 引数:1#$FF 引数:2#$FF | |
02C1C1 | CMP #$0002 | A==#$0002? | |
02C1C4 | BEQ #$1D | if(z==on) goto $02C1E3 | |
02C1C6 | JSL $C2EFF4 | SR: $02EFF4 引数:1#$2052 引数:2#$0004 | ドラゴラム中ならスキップ |
02C1CE | BNE #$13 | if(z==off) goto $02C1E3 | |
02C1D0 | JSL $C2EFF4 | SR: $02EFF4 引数:1#$2053 引数:2#$0020 | 名前がもどき中ならスキップ |
02C1D8 | BNE #$09 | if(z==off) goto $02C1E3 | |
02C1DA | PLB | Pull DB | |
02C1DB | REP #$30 | m=off(A/M:16b) x=off(X/Y:16b) | |
02C1DD | PLY | Pull Y | |
02C1DE | PLX | Pull X | |
02C1DF | PLA | Pull A | |
02C1E0 | PLP | Pull P Flag | |
02C1E1 | CLC | c=off | |
02C1E2 | RTL | return | |
02C1E3 | PLB | Pull DB | |
02C1E4 | REP #$30 | m=off(A/M:16b) x=off(X/Y:16b) | |
02C1E6 | PLY | Pull Y | |
02C1E7 | PLX | Pull X | |
02C1E8 | PLA | Pull A | |
02C1E9 | PLP | Pull P Flag | |
02C1EA | SEC | c=on | |
02C1EB | RTL | return |
このSRはAI行動決定の際にも使用されていて他でも何箇所かで使われています。よくわからないのは$02C1BB-C4あたりで、恐らく「PC情報の何か」を参照しているようですが、全てのキャラクターで値が2のキャラクターは存在しないので事実上意味ありません。
- SR:$023965 コマンド入力の必要があるか(ないc=on)
023965 | PHY | Push Y | |
---|---|---|---|
023966 | JSL $C2C197 | SR: $02C197 | AI行動決定の必要があるか(ないc=on) |
02396A | BCS #$59 | if(c==on) goto $0239C5 | |
02396C | JSL $C42C26 | SR: $042C26 引数:1#$01 引数:2#$FD 引数:3#$FF | |
023973 | CMP #$0001 | A==#$0001? | キャラクターIDが主人公ならステータス判断部分に強制ジャンプ |
023976 | BEQ #$0A | if(z==on) goto $023982 | |
023978 | JSL $C43488 | SR: $043488 引数:1#$FF | 作戦取得 |
02397D | CMP #$0005 | A==#$0005? | さくせんが「めいれいさせろ」以外ならコマンド入力の必要なし |
023980 | BNE #$3F | if(z==off) goto $0239C1 | |
023982 | LDX $258B | X=$258B | |
023985 | JSL $C2E4DC | SR: $02E4DC 引数:1#$18 | 戦闘中情報取得/変更 死んでいたらスキップ |
02398A | BCS #$39 | if(c==on) goto $0239C5 | |
02398C | JSL $C2EFA7 | SR: $02EFA7 引数:1#$2050 引数:2#$0008 | 麻痺中ならスキップ |
023994 | BNE #$2B | if(z==off) goto $0239C1 | |
023996 | JSL $C2EFA7 | SR: $02EFA7 引数:1#$2050 引数:2#$00E0 | 眠っていたらスキップ |
02399E | BNE #$21 | if(z==off) goto $0239C1 | |
0239A0 | JSL $C2EFA7 | SR: $02EFA7 引数:1#$2055 引数:2#$00C0 | 休み中ならスキップ |
0239A8 | BNE #$17 | if(z==off) goto $0239C1 | |
0239AA | JSL $C2EFA7 | SR: $02EFA7 引数:1#$2056 引数:2#$0080 | 精霊の歌を歌っている最中ならスキップ |
0239B2 | BNE #$0D | if(z==off) goto $0239C1 | |
0239B4 | JSL $C2EFA7 | SR: $02EFA7 引数:1#$205D 引数:2#$0080 | パルプンテによる凍りつき中ならスキップ |
0239BC | BNE #$03 | if(z==off) goto $0239C1 | |
0239BE | PLY | Pull Y | |
0239BF | CLC | c=off | |
0239C0 | RTS | return | |
0239C1 | JSL $C2C2F5 | SR: $02C2F5 | 知能が神の場合の戦闘行動決定 |
0239C5 | PLY | Pull Y | |
0239C6 | SEC | c=on | |
0239C7 | RTS | return |
この辺はお約束というか、行動不能フラグを1個ずつ見ていってどれかに該当していたらコマンド入力はなし、というだけです。この辺は基本的な部分なのでこれといっていじるような場所でもないので「そういうもの」という理解でいいと思います。
- SR:$02C2F5 知能が神の場合の戦闘行動決定
02C2F5 | PHP | Push P Flag | |
---|---|---|---|
02C2F6 | REP #$30 | m=off(A/M:16b) x=off(X/Y:16b) | |
02C2F8 | PHA | Push A | |
02C2F9 | PHX | Push X | |
02C2FA | PHY | Push Y | |
02C2FB | PHB | Push DB | |
02C2FC | PEA #$7E7E | Push #$7E7E | |
02C2FF | PLB | Pull DB | |
02C300 | PLB | Pull DB | |
02C301 | LDX $258B | X=$258B | |
02C304 | JSL $C2C331 | SR: $02C331 | 行動情報リセット |
02C308 | JSL $C2E7DB | SR: $02E7DB 引数:1#$04 | 行動回数決定 |
02C30D | TAY | Y=A | Yが0になるまでセットし続ける |
02C30E | LDA #$8198 | A=#$8198 | 「行動直前に戦闘行動を決定」の戦闘行動・対象値 |
02C311 | JSL $C2EF6B | SR: $02EF6B 引数:1#$2034 | 戦闘中キャラクター情報変更 インデックス:X |
02C317 | DEY | Y– | |
02C318 | BEQ #$0F | if(z==on) goto $02C329 | |
02C31A | JSL $C2EF6B | SR: $02EF6B 引数:1#$2036 | 戦闘中キャラクター情報変更 インデックス:X |
02C320 | DEY | Y– | |
02C321 | BEQ #$06 | if(z==on) goto $02C329 | |
02C323 | JSL $C2EF6B | SR: $02EF6B 引数:1#$2038 | 戦闘中キャラクター情報変更 インデックス:X |
02C329 | PLB | Pull DB | |
02C32A | REP #$30 | m=off(A/M:16b) x=off(X/Y:16b) | |
02C32C | PLY | Pull Y | |
02C32D | PLX | Pull X | |
02C32E | PLA | Pull A | |
02C32F | PLP | Pull P Flag | |
02C330 | RTL | return |
「知能が神の場合の戦闘行動決定」の「神」というのは要は「行動直前に戦闘行動を決められる」キャラクターのことです。モンスター側は「人間」「バカ」があるのでこういう呼び名になっているようです。PC側のAIはすべて直前に行動を決めているので全員神扱いです。
- SR:$02E8C6 PC側固定情報取得SR_SR_0002(行動回数決定)
02E8C6 | JSL $C45DE4 | SR: $045DE4 引数:1#$FD 引数:2#$FF | AI時行動回数設定を取得 |
---|---|---|---|
02E8CC | CMP #$0000 | A==#$0000? | 1回 |
02E8CF | BNE #$02 | if(z==off) goto $02E8D3 | |
02E8D1 | INC | A++ | |
02E8D2 | RTS | return | |
02E8D3 | DEC | A– | |
02E8D4 | BNE #$09 | if(z==off) goto $02E8DF | 1~2回 |
02E8D6 | JSL $C00E97 | SR: $000E97 | |
02E8DA | AND #$0001 | A&=#$0001 | 50%の確率で2回行動 |
02E8DD | INC | A++ | |
02E8DE | RTS | return | |
02E8DF | DEC | A– | 2回行動 |
02E8E0 | BNE #$03 | if(z==off) goto $02E8E5 | |
02E8E2 | INC | A++ | |
02E8E3 | INC | A++ | |
02E8E4 | RTS | return | |
02E8E5 | INC | A++ | 3回行動は強すぎるのでボツ? |
02E8E6 | INC | A++ | |
02E8E7 | RTS | return |
SR: $02E7DBは最終的にはこのSRを呼び出します。各キャラクターのAI行動時の行動回数情報を取得し、行動回数を決定します。行動回数1~2回のキャラ(キラーマシン2だけ)は50%の確率で2回行動をすることがわかります。2ビット使って3パターンしかないのでもう1パターン追加するのは比較的簡単そうです。いじるなら2回行動の確率を33%にするとか、66%にするとかでしょうか。そもそもAIのほうが有利な行動をするというのはどうかと思うんですが(誰もマニュアルを使わなくなるので)、DQ6では個別作戦指定ができないのと、戦闘中使用して効果のある道具を使ってくれないのであっという間にMPが枯渇するくらいがデメリットと言えなくもないのですが、もうちょっと何とかしたい部分ではあります。
コメント
レベルに依存して2回行動の確率があがっていくとか面白そうです
それもありでしょうね。オリジナルでは1~2回攻撃をするのはキラーマシン2しかいませんが、レベル上限の高い弱めの(笑)仲間に対しても適用すれば2回攻撃が発生する率がそっちの方が高い、という状況を作れていいかもしれません。
敵モンスターにもレベル設定されてるみたいなのでいろいろ強弱つけれそうですね
上記の部分はPC側の話なので、モンスター側の行動回数決定はまた別の箇所にあるはずです。まだ調べていませんが。恐らく1~2回行動は同じように1/2の確率で決めてると思います。レベルによる回数判定の変化をモンスター側にも導入するというのは、モンスター側、PC側を統一するという意味ではいいかもしれませんが、労力に見合う目に見える差が実感できるかが疑問です。