DQ3 ぐんたいよび実装3

結構苦戦してますぐんたいよびの実装(昨日もテストプレイ中にフリーズするバグが見つかりました。直したけど)。ここまで苦労して実装する必要があるのかとさえ考えてしまいます。残りは「生きている敵をランダムに選択して4回攻撃する」という作業です。

  • SR: $027D53 戦闘行動実行処理メイン
027D98 JSR $D61B SR: $02D61B
027D9B BCS #$1D if(c==on) goto $027DBA

もともと$028400を呼んでいた部分を潰して上記のように書き換えます。

  • SR: $02D61B 現在のインデックスのキャラクターに対して戦闘行動をスキップするか調べる(スキップc=on)(新SR)
02D61B LDA $243E,Y A=$243E+Y
02D61E AND #$00FF A&=#$00FF
02D621 CMP #$0018 A>=#$0018?
02D624 BCS #$4E if(c==on) goto $02D674
02D626 PHA Push A
02D627 LDA $23EE A=$23EE
02D62A CMP #$0114 A==#$0114?
02D62D BNE #$2A if(z==off) goto $02D659
02D62F PEA #$23AE Push #$23AE
02D632 PEA #$0004 Push #$0004
02D635 PEA #$7E00 Push #$7E00
02D638 JSL $C9029E SR: $09029E
02D63C CMP #$0001 A==#$0001?
02D63F BEQ #$32 if(z==on) goto $02D673
02D641 LDA $2600 A=$2600
02D644 CMP #$0004 A>=#$0004?
02D647 BCS #$2A if(c==on) goto $02D673
02D649 INC A++
02D64A STA $2600 $2600=A
02D64D JSR $D700 SR: $02D700
02D650 BCS #$21 if(c==on) goto $02D673
02D652 STA $00 DP($00)=A
02D654 PLA Pull A
02D655 LDA $00 A=DP($00)
02D657 BRA #$01 goto $02D65A
02D659 PLA Pull A
02D65A STA $23E8 $23E8=A
02D65D JSL $C2CA04 SR: $02CA04
02D661 LDA $00 A=DP($00)
02D663 AND $23EA A&=$23EA
02D666 STA $00 DP($00)=A
02D668 LDA $02 A=DP($02)
02D66A AND $23EC A&=$23EC
02D66D ORA $00 Aor=DP($00)
02D66F BEQ #$03 if(z==on) goto $02D674
02D671 CLC c=off
02D672 RTS return
02D673 PLA Pull A
02D674 SEC c=on
02D675 RTS return

後半はSR: $28400のコピーです。$28400は何をしていたかというと、戦闘参加者全員に対してこれから実行する戦闘行動の対象者となるかをチェックして対象となる場合は実体の行動を呼び出す、という非常に重要なものです。C言語のイメージでは

[cpp]
for(int i=0; i<0x18; i++)
{
if($28400(i)のリターンがc=on) continue;
・・・
}
[/cpp]

というところでしょうか。従って、通常の$28400の処理の前に戦闘行動がぐんたいよびの場合「生きている敵をランダムに選択し、そのキャラクターを行動の対象とする」処理を割り込ませればいいことになります。

  • SR: $02D700 ぐんたいよびの対象決定(新SR)
02D700 PHX Push X
02D701 LDA $2428 A=$2428
02D704 PHA Push A
02D705 LDY #$0000 Y=#$0000
02D708 STZ $00 DP($00)=#$00
02D70A LDA $243E,Y A=$243E+Y
02D70D AND #$00FF A&=#$00FF
02D710 TAX X=A
02D711 STX $2428 $2428=X
02D714 JSL $C2CAD9 SR: $02CAD9 引数:1#$203C 引数:2#$00FF
02D71C CMP #$0005 A>=#$0005?
02D71F BCS #$03 if(c==on) goto $02D724
02D721 INY Y++
02D722 BRA #$E6 goto $02D70A
02D724 STY $2602 $2602=Y
02D727 LDY #$0000 Y=#$0000
02D72A LDX #$0000 X=#$0000
02D72D LDA $243E,Y A=$243E+Y
02D730 AND #$00FF A&=#$00FF
02D733 STA $2428 $2428=A
02D736 JSL $C2BE8A SR: $02BE8A 引数:1#$1C
02D73B BCS #$13 if(c==on) goto $02D750
02D73D LDA $243E,Y A=$243E+Y
02D740 AND #$00FF A&=#$00FF
02D743 SEP #$20 m=on(A/M:8b)
02D745 STA $2610,X $2610+X=A
02D748 REP #$20 m=off(A/M:16b)
02D74A INX X++
02D74B CPY $2602 Y>=$2602?
02D74E BCS #$03 if(c==on) goto $02D753
02D750 INY Y++
02D751 BRA #$DA goto $02D72D
02D753 STX $2604 $2604=X
02D756 LDY #$0001 Y=#$0001
02D759 CPY $2604 Y>=$2604?
02D75C BCS #$06 if(c==on) goto $02D764
02D75E SEC c=on
02D75F ROL $00 DP($00)<<1
02D761 INY Y++
02D762 BRA #$F5 goto $02D759
02D764 LDA $00 A=DP($00)
02D766 BEQ #$2D if(z==on) goto $02D795
02D768 LDX #$0000 X=#$0000
02D76B JSL $C01407 SR: $001407
02D76F BCC #$FE if(c==off) goto $02D76F
02D771 TAY Y=A
02D772 LDA $2610,Y A=$2610+Y
02D775 AND #$00FF A&=#$00FF
02D778 STA $00 DP($00)=A
02D77A PLA Pull A
02D77B STA $2428 $2428=A
02D77E LDA $00 A=DP($00)
02D780 PHA Push A
02D781 LDX #$000E X=#$000E
02D784 LDA #$FFFF A=#$FFFF
02D787 STA $2610,X $2610+X=A
02D78A DEX X–
02D78B DEX X–
02D78C BPL #$F9 if(n==off) goto $02D787
02D78E PLA Pull A
02D78F LDX #$0000 X=#$0000
02D792 PLX Pull X
02D793 CLC c=off
02D794 RTS return
02D795 PLA Pull A
02D796 PLX Pull X
02D797 SEC c=on
02D798 RTS return

このSRではぐんたいよびの攻撃対象を決めるわけですが、いくつかの部分に分けて実装していきます。

  1. グループ順に並んでいる戦闘中キャラクターインデックスからグループ番号が5以上になる場所を調べ、その場所を$7E2602に保存する。($02D700-24)
  2. 1で調べた場所に到達するまで各キャラクターの生死状態を調べて生きていれば$7E2610+Xに加えていく。Xのカウントは最終的には$7E2604に保存する。($02D727-53)
  3. $7E2604のカウントの数だけ$00のビットを立てランダムでONのビットをOFFにするSR: $001407を呼び、ONのビットが1つになるまで(リターンがc=on)くり返し、onになっているビットの番号に該当するインデックスを$7E2610+Xで取得し、対象とする。($02D757-7A)
  4. 使用した領域の初期化($02D781-)

さて、一通り実装は終わったのですが、「誰に覚えさせるか」という点について少し考えてみました。覚えるキャラクターは商人でいいのですが、「商人なら誰でも覚えられるのか」か「バークの商人のみに覚えさせるか」という案が浮かびました。SFC版では牢屋に入れられた後再度ルイーダの酒場に戻ってPCとしてパーティに参加させることが可能です。「街を大きくする過程で知り合った傭兵団?をよぶことができる」という文脈でこの商人専用の特技として習得させれば、この商人のキャラ付けを他より際立てることができるかもしれません。しかし、この商人を戦闘で使えるようにするにはバークに預ける前にある程度呪文を覚えさせる必要があり、ベホマクラスの呪文を覚えてからバークに預けるのは話の進行上ちょっときついです。かといって逆にぐんたいよびを転職しても使えるようにすると、今度は呪文スペース上特殊な処理(位置をずらす?)をする必要があります。というわけで、とりあえずは商人がレベル35で覚える、という設定にしておきます。