DQ3 PCの情報管理2

前回のエントリの内容を踏まえると、ルイーダ以外でのキャラクターの追加・削除のやりかたが見えてきます。追加時には以下の手順を踏めばいいということになります。

  1. 空いているPC用アドレスを探して必要情報をセット
  2. $7E36E2の数を操作
  3. $7E36E8-の配列に追加したキャラクターのアドレスを挿入して1つずらす

1点注意があり、この操作をミスると登録済みのキャラクターが消えるという最悪のバグが起きることもあるのでテストは十分やるべき、ということです。追加キャラクター用のステータスをハードコードするのもどうかと思ったので新規に「追加キャラクター用ステータス」という固定長データを定義しました。

  • $3EEADE 追加キャラクターステータス(32Byte*5rec)
範囲(Byte) 範囲(bit) 意味
0-1Byte 名前(固定文字列ID)
2Byte 0-3bit 職業ID
2Byte 4bit 性別
2-3Byte 5-3bit(7bit) 性格
3-4Byte 4-2bit(7bit) レベル
4-5Byte 3-3bit(9bit)
5-6Byte 4-4bit(9bit) 素早さ
6-7Byte 5-5bit(9bit) 身の守り
7-8Byte 6-6bit(9bit) 体力
8-9Byte 7-7bit(9bit) 賢さ
10-11Byte 0-0bit(9bit) 運の良さ
11-12Byte 1-2bit(10bit) 最大HP
12-13Byte 3-4bit(10bit) 最大MP
14-16Byte 初期状態経験値
17Byte 装備武器アイテムID
18Byte 装備鎧アイテムID
19Byte 装備盾アイテムID
20Byte 装備兜アイテムID
21Byte 装備装飾品アイテムID
22-23Byte 呪文習得状態1
24-25Byte 呪文習得状態2
26-27Byte 呪文習得状態3
28-29Byte 呪文習得状態4
30-31Byte 呪文習得状態5

これといって特筆するべきこともなく、必要なステータスをベタっと横に並べただけです。アイテムは12個まで持てますが、余り必要性を感じなかったので装備品以外は何も持たない、ということにしました。次に追加用のSRを実装します。

  • SR: $05EE00 追加キャラクターをPC領域に追加(Y=インデックス)(新SR)
05EE00 JSL $C41962 SR: $041962 新規PC追加可能かチェック+追加可能オフセットを返す(可能c=off, 全バンク用)
05EE04 BCC #$01 if(c==off) goto $05EE07
05EE06 RTL return
05EE07 PHX Push X
05EE08 JSL $C90501 SR: $090501 引数:1#$00 引数:2#$0020 引数:3#$FEEADE 引数:4#$00 構造体アクセス Y番目の先頭アドレスをDP($00,第4引数)にセット
05EE13 LDY #$0000 Y=#$0000
05EE16 LDA $00 A=$(DP[$00])+Y
05EE18 JSL $C1BA53 SR: $01BA53 固定文字列開始アドレス取得(オフセットをYにセット)
05EE1C LDX #$0000 X=#$0000
05EE1F JSL $C1BACC SR: $01BACC 固定文字列デコード+オフセットインクリメント
05EE23 SEP #$20 m=on(A/M:8b)
05EE25 STA $4056,X $4056+X=A
05EE28 REP #$20 m=off(A/M:16b)
05EE2A INX X++
05EE2B CMP #$00AC A==#$00AC?
05EE2E BNE #$EF if(z==off) goto $05EE1F
05EE30 PLX Pull X
05EE31 JSL $C4195E SR: $04195E PC追加場所を#$00で初期化(全バンク用)
05EE35 JSL $C42FD5 SR: $042FD5 名前変更
05EE39 JSL $C41966 SR: $041966 存在フラグオン(全バンク用)
05EE3D LDA #$0002 A=#$0002
05EE40 JSL $C42DFA SR: $042DFA ルイーダの酒場に預けられるかのフラグ変更
05EE44 LDY #$000E Y=#$000E
05EE47 LDA $00 A=$(DP[$00])+Y
05EE49 STA $0001,X $0001+X=A
05EE4C LDY #$0010 Y=#$0010
05EE4F LDA $00 A=$(DP[$00])+Y
05EE51 AND #$00FF A&=#$00FF
05EE54 STA $0003,X $0003+X=A
05EE57 LDY #$0002 Y=#$0002
05EE5A LDA $00 A=$(DP[$00])+Y
05EE5C AND #$000F A&=#$000F
05EE5F STA $0021,X $0021+X=A
05EE62 LDY #$0002 Y=#$0002
05EE65 LDA $00 A=$(DP[$00])+Y
05EE67 AND #$0010 A&=#$0010
05EE6A BEQ #$06 if(z==on) goto $05EE72
05EE6C LDA #$0020 A=#$0020
05EE6F STA $001F,X $001F+X=A
05EE72 PEA #$0000 Push #$0000
05EE75 PEA #$0FE0 Push #$0FE0
05EE78 PEA #$0002 Push #$0002
05EE7B JSL $C90717 SR: $090717 RAM上情報取得
05EE7F JSL $C42F06 SR: $042F06 性格変更
05EE83 PEA #$0000 Push #$0000
05EE86 PEA #$07F0 Push #$07F0
05EE89 PEA #$0003 Push #$0003
05EE8C JSL $C90717 SR: $090717 RAM上情報取得
05EE90 JSL $C43021 SR: $043021 レベル変更
05EE94 PEA #$0000 Push #$0000
05EE97 PEA #$0FF8 Push #$0FF8
05EE9A PEA #$0004 Push #$0004
05EE9D JSL $C90717 SR: $090717 RAM上情報取得
05EEA1 JSL $C43450 SR: $043450 力変更
05EEA5 PEA #$0000 Push #$0000
05EEA8 PEA #$1FF0 Push #$1FF0
05EEAB PEA #$0005 Push #$0005
05EEAE JSL $C90717 SR: $090717 RAM上情報取得
05EEB2 JSL $C43707 SR: $043707 素早さ変更
05EEB6 PEA #$0000 Push #$0000
05EEB9 PEA #$3FE0 Push #$3FE0
05EEBC PEA #$0006 Push #$0006
05EEBF JSL $C90717 SR: $090717 RAM上情報取得
05EEC3 JSL $C41F3B SR: $041F3B 身の守り変更
05EEC7 PEA #$0000 Push #$0000
05EECA PEA #$7FC0 Push #$7FC0
05EECD PEA #$0007 Push #$0007
05EED0 JSL $C90717 SR: $090717 RAM上情報取得
05EED4 JSL $C4358A SR: $04358A 体力変更
05EED8 PEA #$0000 Push #$0000
05EEDB PEA #$FF80 Push #$FF80
05EEDE PEA #$0008 Push #$0008
05EEE1 JSL $C90717 SR: $090717 RAM上情報取得
05EEE5 JSL $C43841 SR: $043841 賢さ変更
05EEE9 PEA #$0000 Push #$0000
05EEEC PEA #$01FF Push #$01FF
05EEEF PEA #$000A Push #$000A
05EEF2 JSL $C90717 SR: $090717 RAM上情報取得
05EEF6 JSL $C43988 SR: $043988 運のよさ変更
05EEFA PEA #$0000 Push #$0000
05EEFD PEA #$07FE Push #$07FE
05EF00 PEA #$000B Push #$000B
05EF03 JSL $C90717 SR: $090717 RAM上情報取得
05EF07 JSL $C43073 SR: $043073 最大HP変更
05EF0B JSL $C43183 SR: $043183 現在HP変更
05EF0F PEA #$0000 Push #$0000
05EF12 PEA #$1FF8 Push #$1FF8
05EF15 PEA #$000C Push #$000C
05EF18 JSL $C90717 SR: $090717 RAM上情報取得
05EF1C JSL $C43263 SR: $043263 最大MP変更
05EF20 JSL $C43366 SR: $043366 現在MP変更
05EF24 LDA #$0000 A=#$0000
05EF27 JSL $C43460 SR: $043460 力小数点部分変更
05EF2B JSL $C43717 SR: $043717 素早さ小数点部分変更
05EF2F JSL $C42349 SR: $042349 体力・身の守り小数点部分0セット
05EF33 JSL $C43851 SR: $043851 賢さ小数点部分変更
05EF37 JSL $C43998 SR: $043998 運のよさの小数点部分変更
05EF3B LDY #$0016 Y=#$0016
05EF3E LDA $00 A=$(DP[$00])+Y
05EF40 STA $0024,X $0024+X=A
05EF43 LDY #$0018 Y=#$0018
05EF46 LDA $00 A=$(DP[$00])+Y
05EF48 STA $0026,X $0026+X=A
05EF4B LDY #$001A Y=#$001A
05EF4E LDA $00 A=$(DP[$00])+Y
05EF50 STA $0028,X $0028+X=A
05EF53 LDY #$001C Y=#$001C
05EF56 LDA $00 A=$(DP[$00])+Y
05EF58 STA $002A,X $002A+X=A
05EF5B LDY #$001E Y=#$001E
05EF5E LDA $00 A=$(DP[$00])+Y
05EF60 STA $002C,X $002C+X=A
05EF63 STZ $40 DP($40)=#$00
05EF65 LDY #$0011 Y=#$0011
05EF68 LDA $00 A=$(DP[$00])+Y
05EF6A AND #$00FF A&=#$00FF
05EF6D BEQ #$06 if(z==on) goto $05EF75
05EF6F JSL $C44777 SR: $044777 PCにアイテムを持たせる
05EF73 INC $40 DP($40)++
05EF75 LDY #$0012 Y=#$0012
05EF78 LDA $00 A=$(DP[$00])+Y
05EF7A AND #$00FF A&=#$00FF
05EF7D BEQ #$06 if(z==on) goto $05EF85
05EF7F JSL $C44777 SR: $044777 PCにアイテムを持たせる
05EF83 INC $40 DP($40)++
05EF85 LDY #$0013 Y=#$0013
05EF88 LDA $00 A=$(DP[$00])+Y
05EF8A AND #$00FF A&=#$00FF
05EF8D BEQ #$06 if(z==on) goto $05EF95
05EF8F JSL $C44777 SR: $044777 PCにアイテムを持たせる
05EF93 INC $40 DP($40)++
05EF95 LDY #$0014 Y=#$0014
05EF98 LDA $00 A=$(DP[$00])+Y
05EF9A AND #$00FF A&=#$00FF
05EF9D BEQ #$06 if(z==on) goto $05EFA5
05EF9F JSL $C44777 SR: $044777 PCにアイテムを持たせる
05EFA3 INC $40 DP($40)++
05EFA5 LDY #$0015 Y=#$0015
05EFA8 LDA $00 A=$(DP[$00])+Y
05EFAA AND #$00FF A&=#$00FF
05EFAD BEQ #$06 if(z==on) goto $05EFB5
05EFAF JSL $C44777 SR: $044777 PCにアイテムを持たせる
05EFB3 INC $40 DP($40)++
05EFB5 LDA $40 A=DP($40)
05EFB7 PHA Push A
05EFB8 LDA #$0000 A=#$0000
05EFBB CMP $01,S A>=Stack($01)?
05EFBD BCS #$09 if(c==on) goto $05EFC8
05EFBF PHA Push A
05EFC0 JSL $C44C67 SR: $044C67 指定インデックスのアイテムを装備する?
05EFC4 PLA Pull A
05EFC5 INC A++
05EFC6 BRA #$F3 goto $05EFBB
05EFC8 PLA Pull A
05EFC9 RTL return

やたらと長いですが、やっていることは上の固定長データの特定のインデックス(このSRをコールした時点でYレジスタにセットされていることが前提)の値を右から左にせっせとくべているだけです。元は登録所で新規PCを追加する処理をコピーしているだけなのでそれほど難しいことではありません。このSRから戻ってくるとXレジスタに追加したキャラクターの開始アドレスがセットされます。続けてこのキャラクターをパーティに追加するSRを実装します。

  • SR: $05F000 追加キャラクターをパーティに追加する(新SR)
05F000 PHA Push A
05F001 PHX Push X
05F002 CMP #$0000 A==#$0000? 追加先はパーティ
05F005 BNE #$0D if(z==off) goto $05F014
05F007 LDA $36E2 A=$36E2
05F00A CMP #$0004 A>=#$0004? パーティ人数が4人なら何もしない
05F00D BCS #$54 if(c==on) goto $05F063
05F00F INC $36E2 $36E2++
05F012 BRA #$26 goto $05F03A
05F014 CMP #$0002 A==#$0002? 追加先はルイーダ
05F017 BNE #$09 if(z==off) goto $05F022
05F019 INC $36E4 $36E4++
05F01C CLC c=off
05F01D ADC $36E2 A+=($36E2+c)
05F020 BRA #$18 goto $05F03A
05F022 CMP #$0004 A==#$0004?
05F025 BNE #$3C if(z==off) goto $05F063
05F027 LDA $36E6 A=$36E6
05F02A CMP #$0003 A>=#$0003?
05F02D BCS #$34 if(c==on) goto $05F063
05F02F INC $36E6 $36E6++
05F032 CLC c=off
05F033 ADC $36E2 A+=($36E2+c)
05F036 CLC c=off
05F037 ADC $36E4 A+=($36E4+c)
05F03A ASL A<<1
05F03B STA $00 DP($00)=A
05F03D LDA #$0000 A=#$0000
05F040 CLC c=off
05F041 ADC $36E2 A+=($36E2+c)
05F044 CLC c=off
05F045 ADC $36E4 A+=($36E4+c)
05F048 CLC c=off
05F049 ADC $36E6 A+=($36E6+c)
05F04C ASL A<<1
05F04D TAY Y=A
05F04E LDA $36E8,Y A=$36E8+Y
05F051 STA $36EA,Y $36EA+Y=A
05F054 DEY Y–
05F055 DEY Y–
05F056 CPY $00 Y>=DP($00)?
05F058 BCS #$F4 if(c==on) goto $05F04E
05F05A LDY $00 Y=DP($00)
05F05C PLA Pull A
05F05D STA $36E8,Y $36E8+Y=A
05F060 SEC c=on
05F061 PLA Pull A
05F062 RTL return
05F063 CLC c=off
05F064 PLX Pull X
05F065 PLA Pull A
05F066 RTL return

Aレジスタには追加先(0:パーティ 2:酒場 4:一時待機)、Xレジスタには追加PCの開始アドレスをセットしていることが前提です。実際使っているのはパーティへの追加だけなので、その他の場合については正しく動作しないかもしれません。やっていることは追加先の最後に追加PCのアドレスをセットし、それ以外の配列の要素を1つずつ後ろにずらす、というものです。実際にこれらのSRをどう使うかを例示します。

  • SR: $0F09AF 呪術師の家イベント処理(新SR)
省略
0F09CB LDY #$0003 Y=#$0003 呪術師の追加キャラクターID
0F09CE JSL $C5EE00 SR: $05EE00 追加キャラクターをPC領域に追加(Y=インデックス)
省略
0F09D5 LDA #$0000 A=#$0000 追加先をパーティに指定
0F09D8 JSL $C5F000 SR: $05F000 追加キャラクターをパーティに追加する
省略

呪術師の家イベント処理全体としてはNPCとして表示されている呪術師がパーティの最後尾に移動する処理などがありますが、関係ないので省きます。