今回から実装を開始します。エフェクトは別途実装するとして、実処理は以下のようにして実装していきます。
- ガイアの剣による直接攻撃専用の戦闘行動(ID:#$135)を用意する(内容は通常の直接攻撃と同じ)
- ガイアの剣による追加攻撃用の戦闘行動(ID:#$136)を用意する
- 直接攻撃のコマンド入力時に装備をチェックし、ガイアの剣を装備していれば1の戦闘行動に差し替える
- 「行動後追加処理を行う戦闘行動」にID:#$135を追加する
- ID:#$135の行動後追加処理として、追加攻撃が発生する条件を満たしているか確認し、満たしていれば戦闘行動をID:#$136に差し替えて戦闘行動を入れ子で実行する
DQ6の解析はまるでやっていないのでわかりませんが、ラミアスの剣で直接攻撃した後の処理と表面上は似ているのでは、と思います。
- SR: $025F39 直接攻撃戦闘行動セット
略 | |||
---|---|---|---|
025F50 | JSR $EB00 | SR: $02EB00 | ガイアの剣装備時戦闘行動ID変更 |
略 |
- SR: $2EB00 ガイアの剣装備時戦闘行動ID変更(新SR)
02EB00 | CMP #$0012 | A==#$0012? | 装備武器がガイアの剣なら戦闘行動ID:#$135に差し替え |
---|---|---|---|
02EB03 | BEQ #$04 | if(z==on) goto $02EB09 | |
02EB05 | LDA #$0001 | A=#$0001 | 通常の直接攻撃 |
02EB08 | RTS | return | |
02EB09 | LDA #$0135 | A=#$0135 | ガイアの剣での直接攻撃 |
02EB0C | RTS | return |
$025F50の時点でAレジスタにはコマンド入力主体が装備しているアイテムIDがセットされています。したがって、Aレジスタを見て条件に一致していれば戦闘行動を差し替えてやればいい、ということになります。
- SR: $02EB0D 実行後追加処理を行う戦闘行動SR_SR_001D(新SR)
02EB0D | JSL $02B32F | SR: $02B32F | 戦闘終了時フラグセット 直接攻撃で戦闘が終了していれば追加攻撃を発動させない |
---|---|---|---|
02EB11 | BCC #$01 | if(c==off) goto $02EB14 | |
02EB13 | RTS | return | |
02EB14 | JSR $EAE7 | SR: $02EAE7 | ガイアの剣追加攻撃が発生するフロアか(該当c=on) |
02EB17 | BCC #$FA | if(c==off) goto $02EB13 | |
02EB19 | LDX $23E6 | X=$7E23E6 | |
02EB1C | STX $2428 | $7E2428=X | |
02EB1F | JSL $02CAD9 | SR: $02CAD9 引数:1#$203C 引数:2#$00FF | 行動対象のグループID取得 |
02EB27 | CMP #$0005 | A>=#$0005? | |
02EB2A | BCS #$E7 | if(c==on) goto $02EB13 | |
02EB2C | LDA #$0001 | A=#$0001 | |
02EB2F | JSL $00133E | SR: $00133E | 乱数発生 1/2の確率 |
02EB33 | BNE #$DE | if(z==off) goto $02EB13 | |
02EB35 | LDX $23E4 | X=$7E23E4 | |
02EB38 | STX $2428 | $7E2428=X | |
02EB3B | JSL $02BE8A | SR: $02BE8A 引数:1#$08 | 現在MP取得 |
02EB40 | CMP #$000A | A>=#$000A? | MPが10なければ発動しない |
02EB43 | BCC #$CE | if(c==off) goto $02EB13 | |
02EB45 | JSR $EAD0 | SR: $02EAD0 | ガイアの剣追加攻撃発動時MP減算+HPMPウィンドウ再描画 |
02EB48 | LDA $23EE | A=$7E23EE | |
02EB4B | PHA | Push A | |
02EB4C | LDA $23E6 | A=$7E23E6 | |
02EB4F | PHA | Push A | |
02EB50 | LDA #$0136 | A=#$0136 | 戦闘行動を差し替え |
02EB53 | STA $23EE | $7E23EE=A | |
02EB56 | LDA #$0041 | A=#$0041 | ターゲット情報を全体に差し替え |
02EB59 | STA $23E6 | $7E23E6=A | |
02EB5C | JSL $01A867 | SR: $01A867 引数:1#$01AE | 戦闘メッセージ表示:「ガイアのつるぎの きっさきが じめんに ふれた! だいちが はげしく ふるえだす!」 |
02EB62 | JSR $7D53 | SR: $027D53 | 戦闘行動実行 |
02EB65 | PLA | Pull A | |
02EB66 | STA $23E6 | $7E23E6=A | ターゲット情報を元に戻す |
02EB69 | PLA | Pull A | |
02EB6A | STA $23EE | $7E23EE=A | 戦闘行動をもとに戻す |
02EB6D | RTS | return |
追加攻撃が発生した後は何も起きないからいちいち戦闘行動情報をもとに戻さなくてもいいとは思うのですが、念のためということで。
- SR: $02EAE7 ガイアの剣追加攻撃が発生するフロアか(該当c=on)(新SR)
02EAE7 | LDA $DB05 | A=$7EDB05 | |
---|---|---|---|
02EAEA | CMP #$0002 | A==#$0002? | 地上の海上か |
02EAED | BEQ #$0F | if(z==on) goto $02EAFE | |
02EAEF | CMP #$000A | A==#$000A? | ALFの海上か |
02EAF2 | BEQ #$0A | if(z==on) goto $02EAFE | |
02EAF4 | LDA $99F9 | A=$7E99F9 | |
02EAF7 | CMP #$0142 | A==#$0142? | フロアが神竜のフロアか |
02EAFA | BEQ #$02 | if(z==on) goto $02EAFE | |
02EAFC | SEC | c=on | |
02EAFD | RTS | return | |
02EAFE | CLC | c=off | |
02EAFF | RTS | return |
あまり汎用性のある判定の仕方ではありませんが、特別対処ということでまあこれでいいでしょう。
- SR: $02EAD0 ガイアの剣追加攻撃発動時MP減算+HPMPウィンドウ再描画(新SR)
02EAD0 | LDA #$000A | A=#$000A | |
---|---|---|---|
02EAD3 | STA $00 | $000000=A | MPを10消費する |
02EAD5 | JSL $02BE8A | SR: $02BE8A 引数:1#$0E | MP減算 |
02EADA | JSL $02B977 | SR: $02B977 | 02B977 パーティウィンドウ再描画? |
02EADE | RTS | return |
あとは、行動対象1体に対するダメージ計算処理を実装して終わりです。
- SR: $02EA40 ガイアの剣追加攻撃(新SR)
02EA40 | STZ $00 | $000000=#$00 | 追加攻撃ダメージ値リセット |
---|---|---|---|
02EA42 | LDX $23E8 | X=$7E23E8 | |
02EA45 | STX $2428 | $7E2428=X | |
02EA48 | JSL $02CA5B | SR: $02CA5B 引数:1#$2049 | |
02EA4E | TAY | Y=A | |
02EA4F | JSL $02CC92 | SR: $02CC92 引数:1#$0024 引数:2#$0001 | メタル系判定 |
02EA57 | CMP #$0001 | A==#$0001? | メタル系ならノーダメージ |
02EA5A | BNE #$02 | if(z==off) goto $02EA5E | |
02EA5C | BRA #$4B | goto $02EAA9 | |
02EA5E | LDX $23E4 | X=$7E23E4 | |
02EA61 | STX $2428 | $7E2428=X | |
02EA64 | JSL $02C240 | SR: $02C240 引数:1#$0A | 行動主体のレベル取得 |
02EA69 | STA $04 | $000004=A | |
02EA6B | LDX #$0004 | X=#$0004 | |
02EA6E | LDA #$0014 | A=#$0014 | |
02EA71 | JSL $00121C | SR: $00121C | レベル/20で商を取得(0~4) |
02EA75 | INC $04 | $000004++ | |
02EA77 | STZ $06 | $000006=#$00 | |
02EA79 | STZ $08 | $000008=#$00 | |
02EA7B | STZ $0A | $00000A=#$00 | |
02EA7D | CLC | c=off | |
02EA7E | LDA #$0004 | A=#$0004 | |
02EA81 | ADC $08 | A+=$000008 | |
02EA83 | STA $08 | $000008=A | |
02EA85 | CLC | c=off | |
02EA86 | LDA #$0015 | A=#$0015 | |
02EA89 | ADC $0A | A+=$00000A | |
02EA8B | STA $0A | $00000A=A | |
02EA8D | INC $06 | $000006++ | |
02EA8F | LDA $06 | A=$000006 | |
02EA91 | CMP $04 | A>=$000004? | |
02EA93 | BCC #$E8 | if(c==off) goto $02EA7D | |
02EA95 | JSL $001383 | SR: $001383 | 乱数発生 $0000-FFFF |
02EA99 | STA $04 | $000004=A | |
02EA9B | LDX #$0004 | X=#$0004 | |
02EA9E | LDA $0A | A=$00000A | |
02EAA0 | JSL $00121C | SR: $00121C | |
02EAA4 | CLC | c=off | |
02EAA5 | ADC $08 | A+=$000008 | |
02EAA7 | STA $00 | $000000=A | |
02EAA9 | JSR $8E70 | SR: $028E70 | ダメージ確定メイン |
02EAAC | RTL | return |
パッと見分かりにくいですが、ダメージ値の計算方法は
- 行動主体のレベル/20の商を取得する(0~4)
- ダメージ変動値として1の回数分+1だけ21の倍数を取得する(21~105)。ダメージ基礎値として1の回数分+1だけ4の倍数を取得する(4~20)
- #$0000-FFFFの乱数を取得し、変動値で割り、余りを取得し、それに基礎値を加算する
となっています。こういうの数式で書くとどうなるんでしょうかね。これにより、低レベルではあまりダメージが高くならず、高レベルでは振り幅の多いダメージ値を算出することができます。表にすると以下のとおり。
レベル | 最小値 | 最大値 |
---|---|---|
1-19 | 4 | 24 |
20-39 | 8 | 49 |
40-59 | 12 | 75 |
60-79 | 16 | 99 |
80-99 | 20 | 124 |
この算出方法を対象1体毎に行うため、ダメージ値が安定しません。ただ、メタル系を除いて対象の防御無視でダメージを与えるため、防御力の高い敵にもある程度ダメージ値は見込めます。MPを10消費する上に発動もランダムなので、これを使うか使わないか、単純に攻撃力の高低では判断できない武器をプレイヤーに選択させることが実装の目的です。実体部分は終わったので次回はエフェクトを実装してこのギミックは終りになります。
コメント
たびたび質問すみません。
追加攻撃の攻撃範囲を単体にしたい場合は
02EB56 LDA #$0041 A=#$0041
の部分を変えるだけでいいのでしょうか?
そうです。
返信ありがとうございます。
該当部分の数値を変えることで攻撃範囲が単体やグループになることはなったのですが、
追加攻撃が発生するのがその戦闘中の最初の通常攻撃の後だけで2回目以降はメッセージのみ、
追加攻撃が発生したりしなかったり、
とどうも上手くいきません。
これで詳細なダメージ計算方法が分かりました。
ただ現在商人に鑑定させるとMP消費が8となっていて、データセンターでは5と示しています。
実際のMPの減り方を見れば分かることですが。
レベルが高いと中々強いのですが、単純なレベル上げ作業を強いられてしまいます。
やはり「大地の精霊の力が宿っている」ということで、「岩落とし」のような属性依存の方が勝手ながらより腑に落ちる気がしました。宙に浮いている敵にも効いてしまうのも少し言い訳が通るようになりますしね。(^^p
詳細鑑定時の消費MPの乖離は次回リリースに修正を含めます。ご指摘ありがとうございました。