DQ3 ストーリー変更(幽霊船3)

今回は追加NPCの配置、モンスターデータの設定、イベント戦闘の実装を行います。イベントの発生条件をチェックして、愛の思い出を持った状態で追加イベントを終了させていない場合のみ、画面上に配置するNPCを変えます。配置するのは、骸骨(#$5C)、囚人(#$49)、モンスター(#$5D)です。NPC1のデータ(座標など)の設定は省略します。

  • SR: $0CCF31 幽霊船1FNPC設定
0CCF31-7 NOP
0CCF38 LDA #$0535 A=#$0535
0CCF3B JSL $C75828 SR: $075828
0CCF3F LDA #$008A A=#$008A
0CCF42 JSL $C758DE SR: $0758DE
0CCF46 JSL $CCF698 SR: $0CF698
0CCF4A RTL return
  • SR: $0CF698 幽霊船1FNPC設定(サブ)
0CF698 LDA $3629 A=$3629
0CF69B AND #$0004 A&=#$0004
0CF69E BNE #$07 if(z==off) goto $0CF6A7
0CF6A0 LDA #$0534 A=#$0534
0CF6A3 JSL $C75828 SR: $075828
0CF6A7 JSL $CCF15A SR: $0CF15A 追加イベント発生か
0CF6AB BCC #$48 if(c==off) goto $0CF6F5
0CF6AD LDA #$0574 A=#$0574
0CF6B0 JSL $C75828 SR: $075828
0CF6B4 LDA #$0575 A=#$0575
0CF6B7 JSL $C75828 SR: $075828
0CF6BB LDA #$0576 A=#$0576
0CF6BE JSL $C75828 SR: $075828
0CF6C2 LDA #$0577 A=#$0577
0CF6C5 JSL $C75828 SR: $075828
0CF6C9 LDA #$0578 A=#$0578
0CF6CC JSL $C75828 SR: $075828
0CF6D0 LDA #$0579 A=#$0579
0CF6D3 JSL $C75828 SR: $075828
0CF6D7 LDA #$057A A=#$057A
0CF6DA JSL $C75828 SR: $075828
0CF6DE LDA $35B1 A=$35B1
0CF6E1 AND #$0001 A&=#$0001
0CF6E4 BNE #$07 if(z==off) goto $0CF6ED
0CF6E6 LDA #$057B A=#$057B
0CF6E9 JSL $C75828 SR: $075828
0CF6ED LDA #$057C A=#$057C
0CF6F0 JSL $C75828 SR: $075828
0CF6F4 RTL return
0CF6F5 LDA #$0533 A=#$0533 骸骨船長のNPC
0CF6F8 JSL $C75828 SR: $075828
0CF6FC RTL return
  • SR: 0CF15A 幽霊船追加イベント発生条件かしらべる(該当c=on)
0CF15A LDA $35B1 A=$35B1
0CF15D AND #$0002 A&=#$0002
0CF160 BNE #$0A if(z==off) goto $0CF16C
0CF162 LDA $3542 A=$3542
0CF165 AND #$0080 A&=#$0080
0CF168 BEQ #$02 if(z==on) goto $0CF16C
0CF16A SEC c=on
0CF16B RTL return
0CF16C CLC c=off
0CF16D RTL return

SRの実装自体はこれといって特筆すべきものはありません。条件によって配置するNPCを変えているだけです。

追加NPCの配置は、甲板の出口に骸骨3体、舳先にいるボスに簡単に到達できないように囚人2体、骸骨2体とします。できれば囚人はDQ6から腐った死体のキャラクターグラフィックを移植したり、ボス専用グラフィックを用意したかったのですが、とりあえずスキップします。

次にこれらのNPCに話し掛けたときに戦闘になるモンスターの設定を行います。DQ6からグラコス、ボーンプリズナーの画像を移植し、新たに追加モンスターとして

  • グラコス(ボス)
  • ネクロマンサー(ボス、シャーマンの色違い)
  • ボーンプリズナー(イベント専用ザコ)
  • リビングデッド(イベント専用ザコ、くさった死体の色違い)

を定義します。今回モンスターの行動定義を初めてまじめにやってみたんですが、さじ加減が難しいですね。モンスターの強さの調整は最終段階の通しテストでバランス調整をする予定です。グラコスおなじみのげはげは笑ってのなぎ払いもまだ未実装です。

モンスターの定義が終わったので、追加NPCに話し掛けたときのイベント戦闘の実装を行います。イベント戦闘の処理はすでに存在するので基本的にはまんまコピーしてイベント戦闘IDだけ変えればいいだけですが、1点変える所があります。今まではオリジナルにならって4C(JMP,アドレス指定でジャンプ)を所々で使用していましたが、空き領域の効率的な使用の観点から、80(BRA,前後127バイトまで相対バイトで移動)の使用にできるだけ統一することにしました。作業開始時に複数のSRを定義/実装する場合に個々のSRのサイズがどれくらいになるかわからない/後で追加の可能性もあるので余裕を持ってSRの開始位置を決めますが、実際は隙間が空くので後でSRを移動して間を詰めたりします。その際に4Cを使ってジャンプ先のアドレスを固定で指定している場合はそのままにしておくとバグってしまうので再度設定しなおさないといけないですが、(論理的に)正しいジャンプ先を指定しなかったりなどバグの温床になるので作業が非常に煩雑になります。というわけで、小規模のSRであれば80を使っておけばSRを移動してもバグる心配はありません。こういうの他の開発環境なら関係ないんだろうなーと思いつつ、ガラパゴス化した環境で作業を続けます。

  • SR: $0DE4BB イベント戦闘(vsボーンプリズナー3体)
0DE4BB LDA #$0021 A=#$0021
0DE4BE JSL $C687A0 SR: $0687A0 イベント戦闘処理
0DE4C2 BRA #$10 goto $0DE4D4
0DE4C4 JSL $CCD383 SR: $0CD383 メニュー表示モードON?
0DE4C8 JSL $CDC5B0 SR: $0DC5B0
0DE4CC BRA #$17 goto $0DE4E5
0DE4CE JSL $C67A85 SR: $067A85 全滅時復活処理
0DE4D2 BRA #$11 goto $0DE4E5
0DE4D4 LDA $C149 A=$C149 戦闘終了フラグ?
0DE4D7 CMP #$0000 A==#$0000? 勝利時
0DE4DA BNE #$02 if(z==off) goto $0DE4DE
0DE4DC BRA #$E6 goto $0DE4C4
0DE4DE CMP #$0002 A==#$0002? 全滅時
0DE4E1 BNE #$02 if(z==off) goto $0DE4E5
0DE4E3 BRA #$E9 goto $0DE4CE
0DE4E5 RTL return
  • SR: $0DE456 イベント戦闘(vsボーンプリズナー)
0DE456 LDA #$0023 A=#$0023
0DE459 JSL $C687A0 SR: $0687A0 イベント戦闘処理
0DE45D BRA #$1F goto $0DE47E
0DE45F LDA #$0018 A=#$0018
0DE462 JSL $C74B8C SR: $074B8C 行動キャラクター指定
0DE466 JSL $C75930 SR: $075930 キャラクター消滅
0DE46A JSL $C74BC2 SR: $074BC2 ?
0DE46E JSL $CCD383 SR: $0CD383 メニュー表示モードON?
0DE472 JSL $CDC5B0 SR: $0DC5B0
0DE476 BRA #$17 goto $0DE48F
0DE478 JSL $C67A85 SR: $067A85 全滅時復活処理
0DE47C BRA #$11 goto $0DE48F
0DE47E LDA $C149 A=$C149 戦闘終了フラグ?
0DE481 CMP #$0000 A==#$0000? 勝利時
0DE484 BNE #$02 if(z==off) goto $0DE488
0DE486 BRA #$D7 goto $0DE45F
0DE488 CMP #$0002 A==#$0002? 全滅時
0DE48B BNE #$02 if(z==off) goto $0DE48F
0DE48D BRA #$E9 goto $0DE478
0DE48F RTL return

今回のイベントではNPCのほとんどが「死なない?アンデッド(なんか変ですね)」なので、SR: $0DE4BBのような実装になりますが、1体は例外で戦闘がおわったら消えるようにします(SR: $0DE456)。そのあたりの実装が$0DE45F-6Aなのですが、ここで#$18を指定していますが、どうやらこれはNPC1の0バイト目の0-5ビットの値に対応しているようです。マップ中に配置するNPCのうち、そのNPCに付随するSR(Move,Talk)ではなく、それ以外から操作する場合はこのID?をマップ中で一意にしておくとコントロールできるようです。ちなみに幽霊船の甲板にはもともとミニデーモンがいますが、このNPC(ID:#$534)のは#19が設定されており、ミニデーモンとのイベント戦闘(SR: $0D8DD3-)では戦闘に勝った場合には、#$19を指定して消滅処理を行っているようです。とりあえず今回はここまでにします。