DQ6 モンスター側エフェクトを実装する2(攻撃呪文系)

今回は攻撃呪文系のエフェクトですが、まず結論から言って完全な移植はできていません。なんとかそれっぽく見せているというだけです。DQ3では、モンスターアニメーション中に別のBG1,2のアニメーション(エフェクト)が挿入されるのはバラモス、ゾーマのブレス攻撃と凍てつく波動のエフェクトのみです(ゾーマのマヒャドはアニメーション後なので除外)。DQ6のモンスター用スプライトのアニメーション定義部分を見ると、「フレーム数」に255が設定されているレコードが存在します。恐らく255のレコードで任意のフレーム数だけアニメーションをストップさせ、その間に別のアニメーションを実行してから残りのアニメーションを実行する、という手順になっているのでは、と想像しますが、DQ3の上記2モンスターのアニメーション定義についてはフレーム数が255というレコードは存在せず、固定フレーム数(バラモスのブレスは16フレーム、ゾーマのブレスは21フレーム、凍てつく波動は33フレーム)だけ動きを止めているようです。ざっと見たところ、DQ3にフレーム数255の場合の処理がなさそう、という結論に至ったので(DQ6の処理の解析にまるでヤル気がわかなかったのとDQ3で同じ処理をしている箇所を探すのが面倒になった)、少々アレンジしてねじ込むことにしました。ポイントとしては以下の3点です。

  1. 攻撃呪文エフェクト用のアニメーションパターンの定義
  2. エフェクトの実装
  3. 呪文SEの制御

1.攻撃呪文エフェクト用のアニメーションパターンの定義

まず、オリジナルのDQ6で同じアニメーションで途中で攻撃呪文を挟む戦闘行動と挟まない戦闘行動が存在するかを調べます。具体的な例としては、魔王の使い(DQ6)のマヒャドとルカナンは使用しているアニメーション自体は同じで、マヒャドの時は呪文エフェクト中は魔王の使い自体のアニメーションは止めています。DQ6ではフレーム数255のレコードを使って任意のフレームだけモンスターのアニメーションを止めていますが、この方法は使えません。従って、この場合はもう1つ攻撃呪文用のアニメーション定義を追加する必要があります(ここから先はこちらの都合の話ですが、DQ6からモンスターをインポートした時にこんなことになるとは思ってもいなかったため、スプライトデータを隙間なく並べてしまったために新しいアニメーション定義を追加することができません。スプライトインデックスの定義から推察するに、アニメーションの定義とスプライトの定義は連続している必要はなさそうだったため、試しにアニメーション定義だけを別の場所にしてみたところ、期待通りの動作をしました)。デバッグメニュー「モンスターを見る」でアニメーションが増えていることを確認してから次のステップに移ります。ちなみに攻撃呪文のエフェクトは小・中が16フレーム、大が22フレームです。

2.エフェクトの実装

次にメインとなるエフェクトの実装ですが、エフェクトの実体自体はバラモスのブレス攻撃のエフェクトをパクります。まずは枠から。

  • SR: $048774 モンスターアニメーション
0487C5 JSL $C5E96A SR: $05E96A DQ6インポートモンスター呪文エフェクト特殊処理
0487C9 NOP
0487CA NOP
  • SR: $05E96A DQ6インポートモンスター呪文エフェクト特殊処理(新SR)
05E96A JSL $C41749 SR: $041749 メタルキング特殊アニメーション処理
05E96E BCS #$16 if(c==on) goto $05E986
05E970 JSL $C4176C SR: $04176C 魔王の使い特殊アニメーション処理
05E974 BCS #$10 if(c==on) goto $05E986
05E976 JSL $C4178F SR: $04178F ブースカ特殊アニメーション処理
05E97A BCS #$0A if(c==on) goto $05E986
05E97C JSL $C417C6 SR: $0417C6 グラコス特殊アニメーション処理
05E980 BCS #$04 if(c==on) goto $05E986
05E982 JSL $C417E9 SR: $0417E9 ダークドレアム特殊アニメーション処理
05E986 RTL return

基本的にどのモンスターでもやることは「スプライトIDと戦闘行動を調べて該当以外はスキップ」なので、今回も魔王の使いを例にとって説明します。

  • SR: $04176C 魔王の使い特殊アニメーション処理(新SR)
04176C CMP #$00DD A==#$00DD? スプライトIDを調べる
04176F BEQ #$02 if(z==on) goto $041773
041771 CLC c=off
041772 RTL return
041773 PHX Push X
041774 PHY Push Y
041775 LDA $7E23EE A=$7E23EE
041779 CMP #$0015 A==#$0015? 戦闘行動がバギクロスか
04177C BNE #$0D if(z==off) goto $04178B
04177E JSR $B75F SR: $04B75F 描画レイヤー指定?
041781 LDA #$001B A=#$001B エフェクトが発生するまでのフレーム数を指定
041784 JSL $C02ABA SR: $002ABA 引数:1#$C418BD エフェクト処理
04178B PLY Pull Y
04178C PLX Pull X
04178D SEC c=on
04178E RTL return
  • SR: $0418BD モンスター側呪文エフェクト(大)黄(新SR)
0418BD LDY #$02CD Y=#$02CD パレットアクセスID指定
0418C0 BRA #$B2 goto $041874 後は共通なのでモンスター側呪文エフェクト(大)赤にジャンプ
  • SR: $041871 モンスター側呪文エフェクト(大)赤(新SR)
041871 LDY #$02CB Y=#$02CB パレットアクセスID指定
041874 STY $4F74 $4F74=Y
041877 PHA Push A エフェクト発生までのフレーム数を保存しておく
041878 NOP
041879 NOP
04187A LDA #$0016 A=#$0016 レイヤー指定?
04187D STA $7FC8 $7FC8=A
041880 LDY #$0002 Y=#$0002
041883 JSR $B4E6 SR: $04B4E6 モンスターエフェクト描画時XY座標取得?
041886 TXA A=X
041887 SEC c=on
041888 SBC #$0010 A-=(#$0010 +c) エフェクト発生X座標セット
04188B TAX X=A
04188C TYA A=Y
04188D SEC c=on
04188E SBC #$0011 A-=(#$0011 +c) エフェクト発生Y座標セット
041891 TAY Y=A
041892 LDA #$0025 A=#$0025
041895 JSR $B65B SR: $04B65B 呪文使用時エフェクト描画用データセット?
041898 PLY Pull Y $041877でPushしたエフェクト発生までのフレーム数を取得
041899 JSL $C02B9C SR: $002B9C
04189D DEY Y–
04189E BNE #$F9 if(z==off) goto $041899
0418A0 JSR $1E71 SR: $041E71 特殊モンスター用呪文SE再生処理
0418A3 PHX Push X
0418A4 JSR $83C2 SR: $0483C2 エフェクト中ウィンドウ背景色指定?
0418A7 PLX Pull X
0418A8 PHX Push X
0418A9 JSL $C4B212 SR: $04B212 呪文エフェクト用BG12描画
0418AD PLX Pull X
0418AE NOP
0418AF NOP
0418B0 NOP
0418B1 JSR $B6DA SR: $04B6DA
0418B4 JSR $B783 SR: $04B783
0418B7 RTL return

はじめにバラモスのブレスエフェクト処理(SR: $0488C2-)をパクったため、後ほど不要だとわかった処理をNOPで潰しているので所々NOPが挟まっていますが特に意味はありません。バラモスのブレスエフェクト処理と違うのは、ブレスエフェクト中のウィンドウの背景色の指定をしない点です。バラモスのブレスエフェクト処理中は、メッセージウィンドウ等の背景が完全に透明になりエフェクト終了後に元に戻りますが、これをそのまま流用するとウィンドウがちらついて非常に気になるため、周辺にあったSRで背景色を変更しないSRを探して置き換えています。SR: $041E71は単なるSE再生以外にちょっとした仕掛けが必要なので3で後述します。

3.呪文SEの制御

オリジナルのDQ6のアニメーションを見ると、攻撃呪文のエフェクトが発生した時点で呪文詠唱のSEが発生しています。通常はアニメーションが終わってからエフェクトが発生する仕組みになっているので、何らかの仕掛けがあるだろうということで、調べてみるとDQ3では使用されてはいないものの、仕組み自体はDQ6同様実装されていました。

  • SR: $027983 戦闘行動開始時の効果音を鳴らす
027996 LDA $4250 A=$4250 効果音が既に再生されているか
027999 BNE #$39 if(z==off) goto $0279D4 0以外なら再生されているので何もしない

というわけでアニメーション中の呪文SE再生時に$7E4250を1インクリメントします。

  • SR: $041E71 特殊モンスター用呪文SE再生処理(新SR)
041E71 LDA #$0066 A=#$0066
041E74 JSL $C1E314 SR: $01E314
041E78 INC $4250 $4250++ 戦闘行動開始時のSE再生をしないようにする
041E7B RTS return

これで1モンスターについての作業は終わりです。今回の実装でDQ6から移植したモンスターのアニメーションが随分オリジナルに近くなりました(正確に言うとモンスター側の行動時のSEを再生していないので違和感が残りますが)。最初から実装しろよという話なんですが、正直戦闘行動の設定をやってまともに動くところまでやると「これでいっか」という気になってしまい、リリースしてから後から気になってくるという困ったループに陥っています。先にプレイしてしまった人には申し訳ないですが。