DQ3 経験値、ゴールドを上限以上獲得できるようにする

スプライトがらみの作業が終わったのでまた無限回廊フロアを追加する作業に戻っているのですが、大体の理屈はわかったものの、その理屈に則って実装しても動作してくれません。まだ何か見逃している部分があると思うのですが見つからず。座標系のアドレスってあまり解明されてないので解析するのが結構苦痛。

DQ3はシリーズ中で珍しく獲得経験値を山分けするようになっています。その兼ね合いでモンスターに設定されている経験値は通常の4倍になっているわけですが、このため一人当たり獲得できる経験値の最大は65535/4=16384です。クリア後のダンジョンが経験値稼ぎの場になっておらず、結局補給の問題もあり、リムルダールが稼ぎやすい場なのはつまらないなーということで、クリア後のダンジョンにメタルキングを導入することにしました。メタルキングの経験値はお約束の一人当たり30000ちょい、トータル120000なのですが、当然ながらモンスター情報に設定できる経験値の上限(65535)を超えてしまいます。というわけで、メタルキングに限っては、モンスター情報には一人当たりの経験値をセットしておき、戦闘中の経験値加算時にモンスターIDをみてメタルキングならば4倍する、という処理を加えることにします。まあいわば特例です。同様に、獲得ゴールドが同じのおどるほうせき、ゴールドマンに対してすごろく中の不均衡を是正するため(数が多く出現でき逃げにくいおどるほうせきと戦った方が多くゴールドを獲得できるという問題)、おどるほうせきの獲得ゴールドを700Gに落とし、逆にゴールドマンは2046Gに変更します(変更前は両方共1023G)。おどるほうせきに関してはただ単にデータ中の値を変えるだけで問題ないのですが、ゴールドマンについては、モンスター情報の獲得ゴールドは10ビットで最大1023なので、メタルキング同様モンスターIDをみてゴールド加算時に2倍する、という処理を追加します。処理対象が局所的なので変更自体は気楽に行えます(多分)。ところで、初めてFC版DQ3をやったとき、「ゴールドマンが出る」と聞いたときには、あのゴーレムタイプのやつが出るのかとわくわくしたんですが、結局ようがんまじんの色違いということでがっかりしたのを覚えてます。可能ならDQ7から輸入したいですね。

(5/20米欄の指摘により大幅変更)

  • SR: $02B1DC 獲得経験値・ゴールド加算
02B216JSR $E7A9SR: $02E7A9戦闘中経験値計算(メタルキングなら経験値4倍)
02B219NOP
02B21ANOP
02B21BCLCc=off
02B21CLDA $23DCA=$23DC
02B21FADC $00A+=(DP($00)+c)
02B221STA $23DC$23DC=A
02B224LDA $23DEA=$23DE
02B227ADC $02A+=(DP($02)+c)
02B229STA $23DE$23DE=A
02B247JSR $E983SR: $02E983戦闘中ゴールド加算(ゴールドマンは設定値の2倍)
02B24A-ENOP

  • SR: $02E7A9 戦闘中経験値計算(メタルキングなら経験値4倍)(新SR)
02E7A9JSL $C2CC69SR: $02CC69 引数:1#$0003モンスター情報から経験値を取得
02E7AFSTZ $02DP($02)=#$00
02E7B1CPX #$00BBX==#$00BB?モンスターIDがメタルキングか
02E7B4BNE #$06if(z==off) goto $02E7BC
02E7B6ASLA<<1
02E7B7ROL $02DP($02)<<1
02E7B9ASLA<<1
02E7BAROL $02DP($02)<<1
02E7BCSTA $00DP($00)=A
02E7BERTSreturn

  • SR: $02E983 戦闘中ゴールド加算(ゴールドマンは設定値の2倍)(新SR)
02E983JSL $C2CC8BSR: $02CC8B 引数:1#$0005 引数:2#$03FFモンスター情報からゴールドを取得
02E98BCPX #$0072X==#$0072?モンスターIDがゴールドマンか
02E98EBNE #$01if(z==off) goto $02E991
02E990ASLA<<1
02E991RTSreturn

ゴールドの場合はゴールドマンでも2バイトを超えないので扱いが楽ですが、経験値の場合は扱う値が3バイトにまたがるので、処理を明確に分けるためにSRの頭で特例かどうかを判断しているので若干冗長になっています。もうちょっとすっきり書こうとしたらできるかもしれません

コメント

  1. m より:

    SEP #$20 : LDA $23DE : ADC $02 : STA $23DE : REP #$20
    はAの上位バイトの値が残るのでちょっと危険な気がします

    ($00-$03[$00199A-$00199D?]が変更可能であれば)以下のような
    感じでどうでしょうか

    org $C2B216
    JSR $E7A9
    NOP
    NOP
    CLC
    LDA $23DC
    ADC $00
    STA $23DC
    LDA $23DE
    ADC $02

    org $C2E7A9
    JSL $C2CC69 : dw $0003
    STZ $02
    CPX #$00BB
    BNE $06
    ASL
    ROL $02
    ASL
    ROL $02
    STA $00
    RTS

    管理者より返信:

    ご指摘ありがとうございます。確かにAレジスタにゴミがある場合に$02B22C以降の処理で経験値が膨大($FFFFFF)になる可能性がありますね。示してもらった実装のほうがシンプルですっきりしてるのでそのまま使わせていただきます。

タイトルとURLをコピーしました