およそメガンテと言う呪文はDQをプレイして使ったことがないんですが、敵に使われた記憶もあまりなくて、DQ2でデビルロードに連発されて唖然としたくらいしか実際にお目にかかったことがありません。あの理不尽な死が今となっては懐かしい・・・。というわけで存在意義が怪しいので、DQ4-6でおなじみのメガザルを代わりに僧侶専用呪文として導入することにします(メガンテ自体は残すので爆弾岩は使ってきます)。まずはDQ6でメガザルの動きを確認します。
- 死者にはザオリク、生者にはベホマの効果
- 使用後術者は死亡
- 消費MPは全MP
オリジナルのメガザルはMPを全部使ってしまうと言うデメリットが大きすぎて「メガザルの腕輪」くらいしか使ったことがないんですが、あんまりなので消費MPは60ということにします。DQ4-6では馬車の中の死者も効果の対象なんで全MPを使うでもいいですが、DQ3では最大3人なのでそれだと割りにあわないので全MP消費というイレギュラーな仕様を実装するのが面倒なのでまあこのくらいでいいでしょう。
実装のポイントは2つです
- 死者にはザオリク、生者にはベホマの効果を実装する
- 使用後術者を死亡させる
・・・上とあんまり変わりませんが。2番目の実装はメガンテでもともと実装されているので新しくプログラムを書く必要はありません。ちょっと設定を追加するだけで実現できます。というわけで前半部分の実装を行います(本当はメガザル実装の説明の前に戦闘の流れの説明をしたかったんですが、まだまとめられていないので若干舌足らずになるかもしれません)。実は戦闘行動の行動プログラムアドレス(6-8バイト)に実装するのは「対象1体に対する処理内容」を実装すればいいようになっています。効果の範囲は対象数(21バイトの0-1ビット)の設定に従ってプログラムが自動でループしてくれます。というわけでここで実装すればいいのは「対象が死者であればザオリク、生者であればベホマ」となります。
- SR: $02D3E6 メガザル
02D3E6 | LDA #$0001 | A=#$0001 | |
---|---|---|---|
02D3E9 | PEA #$23AE | Push #$23AE | |
02D3EC | PEA #$0004 | Push #$0004 | |
02D3EF | PEA #$7E00 | Push #$7E00 | |
02D3F2 | JSL $C902E9 | SR: $0902E9 | |
02D3F6 | LDX $23E8 | X=$23E8 | |
02D3F9 | JSL $C2BE8A | SR: $02BE8A 引数:1#$1C | |
02D3FE | BCS #$42 | if(c==on) goto $02D442 | |
02D400 | LDA $23E8 | A=$23E8 | |
02D403 | STA $2428 | $2428=A | |
02D406 | JSL $C2BE8A | SR: $02BE8A 引数:1#$00 | |
02D40B | STA $02 | DP($02)=A | |
02D40D | LDA #$FFFF | A=#$FFFF | |
02D410 | STA $00 | DP($00)=A | |
02D412 | JSL $C2BE8A | SR: $02BE8A 引数:1#$04 | |
02D417 | JSL $C2BE8A | SR: $02BE8A 引数:1#$00 | |
02D41C | CMP $02 | A==DP($02)? | |
02D41E | BEQ #$4B | if(z==on) goto $02D46B | |
02D420 | LDX $23E8 | X=$23E8 | |
02D423 | JSL $C2CAD9 | SR: $02CAD9 引数:1#$203C 引数:2#$00FF | |
02D42B | CMP #$0005 | A>=#$0005? | |
02D42E | BCC #$3B | if(c==off) goto $02D46B | |
02D430 | JSL $C1E32E | SR: $01E32E 引数:1#$00C4 | |
02D436 | JSL $C2B977 | SR: $02B977 | |
02D43A | JSL $C1A867 | SR: $01A867 引数:1#$005E | |
02D440 | BRA #$29 | goto $02D46B | |
02D442 | LDA $23E8 | A=$23E8 | |
02D445 | STA $2428 | $2428=A | |
02D448 | JSR $9716 | SR: $029716 | |
02D44B | LDX $23E8 | X=$23E8 | |
02D44E | JSL $C2CAD9 | SR: $02CAD9 引数:1#$203C 引数:2#$00FF | |
02D456 | CMP #$0005 | A>=#$0005? | |
02D459 | BCC #$10 | if(c==off) goto $02D46B | |
02D45B | JSL $C1E32E | SR: $01E32E 引数:1#$00C4 | |
02D461 | JSL $C2B977 | SR: $02B977 | |
02D465 | JSL $C1A867 | SR: $01A867 引数:1#$005F | |
02D46B | SEC | c=on | |
02D46C | RTL | return |
それほど長い実装にはなりませんでした。処理自体はいたって簡単です。SR: $02BE8Aで対象者の生死判定をして生きていればベホマの実装をパクったコードを、死んでいればザオリクの実装をパクったコードを実行させるだけです。C言語のイメージでは
if(対象が生きている){
ベホマの実装の一部
}
else{
ザオリクの実装の一部
}
[/cpp]
といった感じです。これ自体はそれほど難しいわけではありません。このSRで注意してもらいたいのは先頭の部分です。
02D3E6 | LDA #$0001 | A=#$0001 | |
---|---|---|---|
02D3E9 | PEA #$23AE | Push #$23AE | |
02D3EC | PEA #$0004 | Push #$0004 | |
02D3EF | PEA #$7E00 | Push #$7E00 | |
02D3F2 | JSL $C902E9 | SR: $0902E9 |
この部分です。SR: $0902E9はちょっと変わったSRで、フラグのセット、取得を行う場面でたびたび呼ばれるのですが、直前でPushしている6バイトを見れば大体想像がつくのですが、この場合は「$7E23AEの3ビット目(マスクすると04)にAの値(1)をセットする」という意味になっているようです。
—- | LDA $23AE | A=$7E23AE | |
---|---|---|---|
—- | AND #$FFFB | A&=#$FFFB | |
—- | ORA #$0004 | A|=#$0004 | |
—- | STA $23AE | $7E23AE=A |
と同じことをしていると思われます。このSRを使う意味は恐らく関係ないビットに影響が出ないようにしたいというものではないかと思います。(逆に情報を取得するのは$09029Eです。こちらは同じようにして直前でPushした6バイトの情報を元に対象ビットのON/OFFをAレジスタに取得します。)さて、なぜこのビットをONにする必要があるかというと「メガンテ実行によって術者が死亡する必要があるか」を意味しているようで、これをONにしないと術者死亡処理で術者が死亡しないからです。メガンテ($0293E0)の先頭の実装も見てみてください。
長くなったので今日はこのへんで。
コメント