まねまねの実装を行います。実質これが戦闘部分に関しての変更としては今のところ最後となります。まだいくつか新しい案が浮かんできたのですが、それはまた後でということにします。さて、戦闘関連の変更をしていて今のところこれが一番厄介でした。例によってDQ6で動作を確認してみます。
- 反撃をするのは攻撃が終わってから(2回攻撃の1回目では反撃しない)。
- 複数回攻撃を受けても反撃するのは最後の戦闘行動でのみ。
- 味方からの行動は反撃?対象にはならない。
- まねまねによる反撃はまねされないのでまねまね合戦が延々と続くことはない。
- (未確認だが)マホトーン中でも呪文の反撃は可能。MPも消費しない。
実装を簡単にするために、とりあえず敵が使うことは想定しないことにします。事前準備としてまねまねの戦闘行動の定義を#$0115にしておきます。※まねまね実装は一気に実装してしまわないとあっさりフリーズします。実装をパクる場合は一連の記事が完結してからにしてください(全3回を予定)。
- SR: $02D580 直接攻撃反射ダメージ計算等
略 | |||
---|---|---|---|
02D58C | JSR $D970 | SR: $02D970 | |
略 |
- SR: $02D980 まねまね中のキャラクタがいるかチェックし反撃するか決定
02D970 | LDA $23EE | A=$23EE | |
---|---|---|---|
02D973 | CMP #$0115 | A==#$0115? | |
02D976 | BNE #$03 | if(z==off) goto $02D97B | |
02D978 | JMP $D9FB ($02D9FB) | goto $02D9FB | |
02D97B | LDX $23E4 | X=$23E4 | |
02D97E | STX $2428 | $2428=X | |
02D981 | JSL $C2CB2B | SR: $02CB2B 引数:1#$2050 引数:2#$0001 | |
02D989 | BNE #$70 | if(z==off) goto $02D9FB | |
02D98B | JSL $C2CB2B | SR: $02CB2B 引数:1#$2049 引数:2#$00FF | |
02D993 | BEQ #$66 | if(z==on) goto $02D9FB | |
02D995 | JSL $C2BE8A | SR: $02BE8A 引数:1#$1C | |
02D99A | BCS #$5F | if(c==on) goto $02D9FB | |
02D99C | LDX $23E8 | X=$23E8 | |
02D99F | STX $2428 | $2428=X | |
02D9A2 | JSL $C2CB2B | SR: $02CB2B 引数:1#$2050 引数:2#$0001 | |
02D9AA | BEQ #$4F | if(z==on) goto $02D9FB | |
02D9AC | JSL $C2BE8A | SR: $02BE8A 引数:1#$16 | |
02D9B1 | BCS #$48 | if(c==on) goto $02D9FB | |
02D9B3 | JSL $C2CB2B | SR: $02CB2B 引数:1#$2047 引数:2#$00FF | |
02D9BB | BNE #$3E | if(z==off) goto $02D9FB | |
02D9BD | JSL $C2CB2B | SR: $02CB2B 引数:1#$2034 引数:2#$01FF | |
02D9C5 | CMP #$0115 | A==#$0115? | |
02D9C8 | BNE #$31 | if(z==off) goto $02D9FB | |
02D9CA | PHY | Push Y | |
02D9CB | LDY #$0000 | Y=#$0000 | |
02D9CE | TXA | A=X | |
02D9CF | SEP #$20 | m=on(A/M:8b) | |
02D9D1 | CMP $2620,Y | A==$2620+Y? | |
02D9D4 | BEQ #$19 | if(z==on) goto $02D9EF | |
02D9D6 | REP #$20 | m=off(A/M:16b) | |
02D9D8 | LDA $2620,Y | A=$2620+Y | |
02D9DB | AND #$00FF | A&=#$00FF | |
02D9DE | CMP #$0018 | A>=#$0018? | |
02D9E1 | BCS #$06 | if(c==on) goto $02D9E9 | |
02D9E3 | INY | Y++ | |
02D9E4 | CPY #$0018 | Y>=#$0018? | |
02D9E7 | BCC #$E5 | if(c==off) goto $02D9CE | |
02D9E9 | TXA | A=X | |
02D9EA | SEP #$20 | m=on(A/M:8b) | |
02D9EC | STA $2620,Y | $2620+Y=A | |
02D9EF | REP #$20 | m=off(A/M:16b) | |
02D9F1 | TYA | A=Y | |
02D9F2 | ASL | A<<1 | |
02D9F3 | TAY | Y=A | |
02D9F4 | LDA $23EE | A=$23EE | |
02D9F7 | STA $2630,Y | $2630+Y=A | |
02D9FA | PLY | Pull Y | |
02D9FB | RTS | return |
ぐんたいよびの実装同様「まねまねによる反撃を行うキャラのID」および「反撃の際に使用される戦闘行動ID」を1セットとして保存しておく領域を新たに定義する必要があります。それぞれ、$7E2610-1F、$7E2620-2Fに保存することにします。また、これらの領域は初期化時にFFで埋めておくことを前提とします。今回はまず攻撃を受けたときにその行動IDを保存するところまで実装します。実装の内容は以下のとおりです。
- 戦闘行動がまねまね(#$0115)、逃げる(#$006A)の場合は処理をスキップする。$02D980は行動対象でないキャラクターもループでまわされるため、スキップしないとフリーズしたりする。($02D980-8B)
- 現在の戦闘行動の行動主体($7E23E4)を調べて主体が味方である、もしくは死亡している(念のため)ば反撃しないのでスキップする。($02D98D-A2)
- 行動対象($7E23E8)が味方かつその戦闘行動がまねまね(#$0115)であれば反撃用バッファにセットする。セットする際に行動対象のインデックスがすでにバッファ内に存在していれば現在の戦闘行動で上書きする。($02D9AA-EE)
こう書いてしまうと割とさらっと実装できたみたいに見えますが、実際は試行錯誤の上たどりついたもので、途中で何度かやめようかと思うくらいでした。
コメント