DQ3 メガザル実装1

およそメガンテと言う呪文はDQをプレイして使ったことがないんですが、敵に使われた記憶もあまりなくて、DQ2でデビルロードに連発されて唖然としたくらいしか実際にお目にかかったことがありません。あの理不尽な死が今となっては懐かしい・・・。というわけで存在意義が怪しいので、DQ4-6でおなじみのメガザルを代わりに僧侶専用呪文として導入することにします(メガンテ自体は残すので爆弾岩は使ってきます)。まずはDQ6でメガザルの動きを確認します。

  1. 死者にはザオリク、生者にはベホマの効果
  2. 使用後術者は死亡
  3. 消費MPは全MP

オリジナルのメガザルはMPを全部使ってしまうと言うデメリットが大きすぎて「メガザルの腕輪」くらいしか使ったことがないんですが、あんまりなので消費MPは60ということにします。DQ4-6では馬車の中の死者も効果の対象なんで全MPを使うでもいいですが、DQ3では最大3人なのでそれだと割りにあわないので全MP消費というイレギュラーな仕様を実装するのが面倒なのでまあこのくらいでいいでしょう。

実装のポイントは2つです

  1. 死者にはザオリク、生者にはベホマの効果を実装する
  2. 使用後術者を死亡させる

・・・上とあんまり変わりませんが。2番目の実装はメガンテでもともと実装されているので新しくプログラムを書く必要はありません。ちょっと設定を追加するだけで実現できます。というわけで前半部分の実装を行います(本当はメガザル実装の説明の前に戦闘の流れの説明をしたかったんですが、まだまとめられていないので若干舌足らずになるかもしれません)。実は戦闘行動の行動プログラムアドレス(6-8バイト)に実装するのは「対象1体に対する処理内容」を実装すればいいようになっています。効果の範囲は対象数(21バイトの0-1ビット)の設定に従ってプログラムが自動でループしてくれます。というわけでここで実装すればいいのは「対象が死者であればザオリク、生者であればベホマ」となります。

  • SR: $02D3E6 メガザル
02D3E6LDA #$0001A=#$0001
02D3E9PEA #$23AEPush #$23AE
02D3ECPEA #$0004Push #$0004
02D3EFPEA #$7E00Push #$7E00
02D3F2JSL $C902E9SR: $0902E9
02D3F6LDX $23E8X=$23E8
02D3F9JSL $C2BE8ASR: $02BE8A 引数:1#$1C
02D3FEBCS #$42if(c==on) goto $02D442
02D400LDA $23E8A=$23E8
02D403STA $2428$2428=A
02D406JSL $C2BE8ASR: $02BE8A 引数:1#$00
02D40BSTA $02DP($02)=A
02D40DLDA #$FFFFA=#$FFFF
02D410STA $00DP($00)=A
02D412JSL $C2BE8ASR: $02BE8A 引数:1#$04
02D417JSL $C2BE8ASR: $02BE8A 引数:1#$00
02D41CCMP $02A==DP($02)?
02D41EBEQ #$4Bif(z==on) goto $02D46B
02D420LDX $23E8X=$23E8
02D423JSL $C2CAD9SR: $02CAD9 引数:1#$203C 引数:2#$00FF
02D42BCMP #$0005A>=#$0005?
02D42EBCC #$3Bif(c==off) goto $02D46B
02D430JSL $C1E32ESR: $01E32E 引数:1#$00C4
02D436JSL $C2B977SR: $02B977
02D43AJSL $C1A867SR: $01A867 引数:1#$005E
02D440BRA #$29goto $02D46B
02D442LDA $23E8A=$23E8
02D445STA $2428$2428=A
02D448JSR $9716SR: $029716
02D44BLDX $23E8X=$23E8
02D44EJSL $C2CAD9SR: $02CAD9 引数:1#$203C 引数:2#$00FF
02D456CMP #$0005A>=#$0005?
02D459BCC #$10if(c==off) goto $02D46B
02D45BJSL $C1E32ESR: $01E32E 引数:1#$00C4
02D461JSL $C2B977SR: $02B977
02D465JSL $C1A867SR: $01A867 引数:1#$005F
02D46BSECc=on
02D46CRTLreturn

それほど長い実装にはなりませんでした。処理自体はいたって簡単です。SR: $02BE8Aで対象者の生死判定をして生きていればベホマの実装をパクったコードを、死んでいればザオリクの実装をパクったコードを実行させるだけです。C言語のイメージでは

[cpp]
if(対象が生きている){
ベホマの実装の一部
}
else{
ザオリクの実装の一部
}
[/cpp]

といった感じです。これ自体はそれほど難しいわけではありません。このSRで注意してもらいたいのは先頭の部分です。

02D3E6LDA #$0001A=#$0001
02D3E9PEA #$23AEPush #$23AE
02D3ECPEA #$0004Push #$0004
02D3EFPEA #$7E00Push #$7E00
02D3F2JSL $C902E9SR: $0902E9

この部分です。SR: $0902E9はちょっと変わったSRで、フラグのセット、取得を行う場面でたびたび呼ばれるのですが、直前でPushしている6バイトを見れば大体想像がつくのですが、この場合は「$7E23AEの3ビット目(マスクすると04)にAの値(1)をセットする」という意味になっているようです。

—-LDA $23AEA=$7E23AE
—-AND #$FFFBA&=#$FFFB
—-ORA #$0004A|=#$0004
—-STA $23AE$7E23AE=A

と同じことをしていると思われます。このSRを使う意味は恐らく関係ないビットに影響が出ないようにしたいというものではないかと思います。(逆に情報を取得するのは$09029Eです。こちらは同じようにして直前でPushした6バイトの情報を元に対象ビットのON/OFFをAレジスタに取得します。)さて、なぜこのビットをONにする必要があるかというと「メガンテ実行によって術者が死亡する必要があるか」を意味しているようで、これをONにしないと術者死亡処理で術者が死亡しないからです。メガンテ($0293E0)の先頭の実装も見てみてください。

長くなったので今日はこのへんで。

コメント

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