解説が抜けていた部分があるのでそこを補足。
- SR: $02B054 行動対象者を戦闘から離脱させる処理メイン
02B054 | PHP | Push P Flag | |
---|---|---|---|
02B055 | REP #$30 | m=off(A/M:16b), x=off(X/Y:16b) | |
02B057 | PHA | Push A | |
02B058 | PHX | Push X | |
02B059 | PHY | Push Y | |
02B05A | PHB | Push DB | |
02B05B | PEA $7E7E | Push $7E7E | |
02B05E | PLB | Pull DB | |
02B05F | PLB | Pull DB | |
02B060 | LDX $2428 | X=$7E2428 | |
02B063 | JSL $02CB2B | SR: $02CB2B 引数:1#$2050 引数:2#$0002 | 存在フラグチェック? |
02B06B | BEQ #$FE | if(z==on) goto $02B06B | 生死判定フラグが正しくセットされていない場合はフリーズ? |
02B06D | JSR $B08B | SR: $02B08B | |
02B070 | JSR $B0D0 | SR: $02B0D0 | 行動対象者が戦闘から離脱した場合にターン中行動順から外す |
02B073 | JSR $B0E8 | SR: $02B0E8 | 離脱者を各グループ生存者数から引く |
02B076 | JSR $B0FC | SR: $02B0FC | |
02B079 | JSL $02BAE8 | SR: $02BAE8 | 倒したモンスターがあやしいかげの場合の処理 |
02B07D | JSR $B1B4 | SR: $02B1B4 | 獲得経験値・ゴールド加算 |
02B080 | JSR $B271 | SR: $02B271 | |
02B083 | PLB | Pull DB | |
02B084 | REP #$30 | m=off(A/M:16b), x=off(X/Y:16b) | |
02B086 | PLY | Pull Y | |
02B087 | PLX | Pull X | |
02B088 | PLA | Pull A | |
02B089 | PLP | Pull P Flag | |
02B08A | RTL | return |
- SR: $02BAE8 倒したモンスターがあやしいかげの場合の処理
02BAE8 | PHP | Push P Flag | |
---|---|---|---|
02BAE9 | REP #$30 | m=off(A/M:16b), x=off(X/Y:16b) | |
02BAEB | PHA | Push A | |
02BAEC | PHX | Push X | |
02BAED | PHY | Push Y | |
02BAEE | PHB | Push DB | |
02BAEF | PEA $7E7E | Push $7E7E | |
02BAF2 | PLB | Pull DB | |
02BAF3 | PLB | Pull DB | |
02BAF4 | LDX $2428 | X=$7E2428 | |
02BAF7 | JSL $02CA5B | SR: $02CA5B 引数:1#$2049 | モンスターID取得 |
02BAFD | PHA | Push A | |
02BAFE | JSL $02CAD9 | SR: $02CAD9 引数:1#$2050 引数:2#$0001 | 敵味方判定? |
02BB06 | PHA | Push A | |
02BB07 | BNE #$07 | if(z==off) goto $02BB10 | |
02BB09 | LDA $03,S | A=Stack($03) | |
02BB0B | CMP #$0019 | A==#$0019? | モンスターIDが怪しい影なら正体のモンスターに差し替え |
02BB0E | BEQ #$12 | if(z==on) goto $02BB22 | |
02BB10 | LDA $01,S | A=Stack($01) | |
02BB12 | JSL $02CB70 | SR: $02CB70 引数:1#$2051 引数:2#$0001 | |
02BB1A | LDA $03,S | A=Stack($03) | |
02BB1C | JSL $02CA98 | SR: $02CA98 引数:1#$204B | 正体のモンスターID取得 |
02BB22 | PLA | Pull A | |
02BB23 | PLA | Pull A | |
02BB24 | PLB | Pull DB | |
02BB25 | REP #$30 | m=off(A/M:16b), x=off(X/Y:16b) | |
02BB27 | PLY | Pull Y | |
02BB28 | PLX | Pull X | |
02BB29 | PLA | Pull A | |
02BB2A | PLP | Pull P Flag | |
02BB2B | RTL | return |
- SR: $02B1B4 獲得経験値・ゴールド加算
02B1B4 | LDX $2428 | X=$7E2428 | |
---|---|---|---|
02B1B7 | JSL $02CAD9 | SR: $02CAD9 引数:1#$2052 引数:2#$0010 | ? |
02B1BF | BNE #$1A | if(z==off) goto $02B1DB | |
02B1C1 | JSL $02CAD9 | SR: $02CAD9 引数:1#$203C 引数:2#$00FF | グループID取得 |
02B1C9 | CMP #$0004 | A>=#$0004? | 離脱者がPCor格闘場で賭けたモンスター |
02B1CC | BCS #$0D | if(c==on) goto $02B1DB | |
02B1CE | JSL $02CAD9 | SR: $02CAD9 引数:1#$2051 引数:2#$0001 | ? |
02B1D6 | BNE #$03 | if(z==off) goto $02B1DB | |
02B1D8 | JSR $B1DC | SR: $02B1DC | 獲得経験値・ゴールド加算 |
02B1DB | RTS | return |
- SR: $02B1DC 獲得経験値・ゴールド加算
02B1DC | LDX $2428 | X=$7E2428 | |
---|---|---|---|
02B1DF | LDA #$0001 | A=#$0001 | |
02B1E2 | JSL $02CB70 | SR: $02CB70 引数:1#$2052 引数:2#$0010 | ? |
02B1EA | JSL $02CA5B | SR: $02CA5B 引数:1#$204B | モンスターID取得 |
02B1F0 | TAX | X=A | |
02B1F1 | LDY $23EE | Y=$7E23EE | |
02B1F4 | JSL $02CC2C | SR: $02CC2C 引数:1#$007C 引数:2#$0008 | 離脱時の戦闘行動がアイテム獲得可か |
02B1FC | BEQ #$0E | if(z==on) goto $02B20C | |
02B1FE | TXA | A=X | |
02B1FF | PEA $23A9 | Push $23A9 | |
02B202 | PEA $00FF | Push $00FF | |
02B205 | PEA $7E00 | Push $7E00 | |
02B208 | JSL $0902E9 | SR: $0902E9 | モンスターIDをセット? |
02B20C | JSL $02CC2C | SR: $02CC2C 引数:1#$007B 引数:2#$0001 | 離脱時の戦闘行動が経験値獲得可か |
02B214 | BEQ #$27 | if(z==on) goto $02B23D | |
02B216 | JSL $02CC69 | SR: $02CC69 引数:1#$0003 | 経験値情報取得 |
02B21C | CLC | c=off | |
02B21D | ADC $23DC | A+=$7E23DC | |
02B220 | STA $23DC | $7E23DC=A | |
02B223 | LDA $23DE | A=$7E23DE | |
02B226 | ADC #$0000 | A+=#$0000 | |
02B229 | STA $23DE | $7E23DE=A | |
02B22C | CMP #$0100 | A>=#$0100? | |
02B22F | BCC #$0C | if(c==off) goto $02B23D | |
02B231 | LDA #$FFFF | A=#$FFFF | オーバーフロー時に#$FFFFFFでクリップする |
02B234 | STA $23DC | $7E23DC=A | |
02B237 | LDA #$00FF | A=#$00FF | |
02B23A | STA $23DE | $7E23DE=A | |
02B23D | JSL $02CC2C | SR: $02CC2C 引数:1#$007C 引数:2#$0004 | 離脱時の戦闘行動がゴールド獲得可か |
02B245 | BEQ #$29 | if(z==on) goto $02B270 | |
02B247 | JSL $02CC8B | SR: $02CC8B 引数:1#$0005 引数:2#$03FF | ゴールド情報取得 |
02B24F | CLC | c=off | |
02B250 | ADC $23E0 | A+=$7E23E0 | |
02B253 | STA $23E0 | $7E23E0=A | |
02B256 | LDA $23E2 | A=$7E23E2 | |
02B259 | ADC #$0000 | A+=#$0000 | |
02B25C | STA $23E2 | $7E23E2=A | |
02B25F | CMP #$0100 | A>=#$0100? | |
02B262 | BCC #$0C | if(c==off) goto $02B270 | |
02B264 | LDA #$FFFF | A=#$FFFF | オーバーフロー時に#$FFFFFFでクリップする |
02B267 | STA $23E0 | $7E23E0=A | |
02B26A | LDA #$00FF | A=#$00FF | |
02B26D | STA $23E2 | $7E23E2=A | |
02B270 | RTS | return |
だいたいこれで、1キャラクター分の戦闘行動は終わりです。1ターン分の行動が終わると、ターン終了時の処理を行います。DQ3ではモンスターの自動回復を行っています。
- SR: $02A41F ターン終了時処理(全体)
02A41F | PHP | Push P Flag | |
---|---|---|---|
02A420 | PHB | Push DB | |
02A421 | REP #$30 | m=off(A/M:16b), x=off(X/Y:16b) | |
02A423 | PEA $7E7E | Push $7E7E | |
02A426 | PLB | Pull DB | |
02A427 | PLB | Pull DB | |
02A428 | LDA #$0000 | A=#$0000 | |
02A42B | PEA $23AB | Push $23AB | |
02A42E | PEA $0030 | Push $0030 | |
02A431 | PEA $7E00 | Push $7E00 | |
02A434 | JSL $0902E9 | SR: $0902E9 | RAM上情報変更 |
02A438 | LDA #$0001 | A=#$0001 | |
02A43B | PEA $23AE | Push $23AE | |
02A43E | PEA $0020 | Push $0020 | |
02A441 | PEA $7E00 | Push $7E00 | |
02A444 | JSL $0902E9 | SR: $0902E9 | RAM上情報変更 |
02A448 | JSR $A44E | SR: $02A44E | ターン終了時処理(各キャラクターごと) |
02A44B | PLB | Pull DB | |
02A44C | PLP | Pull P Flag | |
02A44D | RTL | return |
- SR: $02A44E ターン終了時処理(各キャラクターごと)
02A44E | JSL $028375 | SR: $028375 | 1キャラクター行動開始時変数初期化処理 |
---|---|---|---|
02A452 | LDY #$0000 | Y=#$0000 | |
02A455 | LDA $243E,Y | A=$7E243E+Y | |
02A458 | AND #$00FF | A&=#$00FF | |
02A45B | CMP #$0018 | A>=#$0018? | |
02A45E | BCS #$18 | if(c==on) goto $02A478 | |
02A460 | STA $2428 | $7E2428=A | |
02A463 | TAX | X=A | |
02A464 | JSL $02CAD9 | SR: $02CAD9 引数:1#$2050 引数:2#$0002 | 生死判定? |
02A46C | BEQ #$0A | if(z==on) goto $02A478 | |
02A46E | JSL $02BE8A | SR: $02BE8A 引数:1#$1C | 生死判定? |
02A473 | BCS #$03 | if(c==on) goto $02A478 | |
02A475 | JSR $A47F | SR: $02A47F | 自然回復処理 |
02A478 | INY | Y++ | |
02A479 | CPY #$0018 | Y>=#$0018 ? | |
02A47C | BCC #$D7 | if(c==off) goto $02A455 | |
02A47E | RTS | return |
また、1キャラクター分の戦闘行動が終わると、その場で戦闘終了判定を行います(そうしないとどちらかが全滅しているのに別キャラクターの戦闘行動を実行してしまう)。
- SR: $02B32F 戦闘終了時フラグセット?
詳細不明のため省略
これでようやく1ターン分の処理が終わったので戦闘メインループに処理が戻ってきます。戦闘終了条件を満たしていれば終了処理を行います。
- SR: $02A48C ターン数オーバーによる戦闘終了条件チェック
02A48C | CLC | c=off | |
---|---|---|---|
02A48D | PHP | Push P Flag | |
02A48E | PHB | Push DB | |
02A48F | REP #$30 | m=off(A/M:16b), x=off(X/Y:16b) | |
02A491 | PEA $7E7E | Push $7E7E | |
02A494 | PLB | Pull DB | |
02A495 | PLB | Pull DB | |
02A496 | INC $23D0 | $7E23D0++ | |
02A499 | PEA $2011 | Push $2011 | |
02A49C | PEA $0040 | Push $0040 | |
02A49F | PEA $7E00 | Push $7E00 | |
02A4A2 | JSL $09029E | SR: $09029E | 格闘場戦闘か? |
02A4A6 | BNE #$0D | if(z==off) goto $02A4B5 | |
02A4A8 | LDA $23D0 | A=$7E23D0 | |
02A4AB | CMP #$FFFF | A>=#$FFFF? | ターン数が65535以上の場合 |
02A4AE | BCC #$33 | if(c==off) goto $02A4E3 | |
02A4B0 | LDA #$0004 | A=#$0004 | 終了フラグ4をセット |
02A4B3 | BRA #$1A | goto $02A4CF | |
02A4B5 | LDA $23D0 | A=$7E23D0 | |
02A4B8 | CMP #$000A | A>=#$000A? | 格闘場の場合は10ターンが限界 |
02A4BB | BCC #$26 | if(c==off) goto $02A4E3 | |
02A4BD | PEA $23AB | Push $23AB | |
02A4C0 | PEA $000F | Push $000F | |
02A4C3 | PEA $7E00 | Push $7E00 | |
02A4C6 | JSL $09029E | SR: $09029E | 10ターン終了時に決着が付いているか |
02A4CA | BNE #$10 | if(z==off) goto $02A4DC | |
02A4CC | LDA #$0007 | A=#$0007 | 終了フラグ7をセット |
02A4CF | PEA $23AB | Push $23AB | |
02A4D2 | PEA $000F | Push $000F | |
02A4D5 | PEA $7E00 | Push $7E00 | |
02A4D8 | JSL $0902E9 | SR: $0902E9 | |
02A4DC | LDA $02,S | A=Stack($02) | |
02A4DE | ORA #$0001 | Aor=#$0001 | |
02A4E1 | STA $02,S | Stack($02)=A | |
02A4E3 | PLB | Pull DB | |
02A4E4 | PLP | Pull P Flag | |
02A4E5 | RTL | return |
- SR: $02A4E6 戦闘終了判定+終了処理(戦闘続行c=on)
02A4E6 | CLC | c=off | |
---|---|---|---|
02A4E7 | PHP | Push P Flag | |
02A4E8 | PHB | Push DB | |
02A4E9 | REP #$30 | m=off(A/M:16b), x=off(X/Y:16b) | |
02A4EB | PEA $7E7E | Push $7E7E | |
02A4EE | PLB | Pull DB | |
02A4EF | PLB | Pull DB | |
02A4F0 | LDA #$0000 | A=#$0000 | |
02A4F3 | PEA $23AF | Push $23AF | |
02A4F6 | PEA $0004 | Push $0004 | |
02A4F9 | PEA $7E00 | Push $7E00 | |
02A4FC | JSL $0902E9 | SR: $0902E9 | |
02A500 | JSR $A521 | SR: $02A521 | |
02A503 | PEA $23AB | Push $23AB | |
02A506 | PEA $000F | Push $000F | |
02A509 | PEA $7E00 | Push $7E00 | |
02A50C | JSL $09029E | SR: $09029E | |
02A510 | ASL | A<<1 | |
02A511 | TAX | X=A | |
02A512 | JSR $A567 | SR: $($02A567+X) | 戦闘終了フラグに応じた戦後処理 |
02A515 | BCC #$07 | if(c==off) goto $02A51E | |
02A517 | LDA $02,S | A=Stack($02) | |
02A519 | ORA #$0001 | Aor=#$0001 | |
02A51C | STA $02,S | Stack($02)=A | |
02A51E | PLB | Pull DB | |
02A51F | PLP | Pull P Flag | |
02A520 | RTL | return |
- SR: $02A6AF 戦闘終了時処理SR_SR_0001(勝利時)
02A6AF | JSL $01E32E | SR: $01E32E 引数:1#$0029 | BGM再生 |
---|---|---|---|
02A6B5 | LDX #$0000 | X=#$0000 | |
02A6B8 | PEA $23AB | Push $23AB | |
02A6BB | PEA $00C0 | Push $00C0 | |
02A6BE | PEA $7E00 | Push $7E00 | |
02A6C1 | JSL $09029E | SR: $09029E | |
02A6C5 | BEQ #$0C | if(z==on) goto $02A6D3 | |
02A6C7 | INX | X++ | |
02A6C8 | INX | X++ | |
02A6C9 | DEC | A– | |
02A6CA | BEQ #$07 | if(z==on) goto $02A6D3 | |
02A6CC | INX | X++ | |
02A6CD | INX | X++ | |
02A6CE | DEC | A– | |
02A6CF | BEQ #$02 | if(z==on) goto $02A6D3 | |
02A6D1 | INX | X++ | |
02A6D2 | INX | X++ | |
02A6D3 | LDA #$8000 | A=#$8000 | |
02A6D6 | STA $23E4 | $7E23E4=A | |
02A6D9 | LDA $02A707,X | A=$02A707+X | |
02A6DD | JSL $01A87A | SR: $01A87A | |
02A6E1 | JSL $01E59C | SR: $01E59C 引数:1#$0029 | BGM停止 |
02A6E7 | BCS #$06 | if(c==on) goto $02A6EF | |
02A6E9 | JSL $0028B4 | SR: $0028B4 | |
02A6ED | BRA #$F2 | goto $02A6E1 | |
02A6EF | JSL $01E264 | SR: $01E264 | 移動中BGM再生 |
02A6F3 | JSR $A746 | SR: $02A746 | 一人当たりの獲得経験値計算処理 |
02A6F6 | JSR $A767 | SR: $02A767 | 経験値獲得メッセージ表示 |
02A6F9 | JSR $AA44 | SR: $02AA44 | 戦闘終了時ゴールド取得処理 |
02A6FC | JSR $A7B3 | SR: $02A7B3 | 経験値加算+レベルアップ処理 |
02A6FF | JSR $A907 | SR: $02A907 | 戦闘終了時アイテム取得処理 |
02A702 | JSR $AAF8 | SR: $02AAF8 | プロンプト表示2? |
02A705 | CLC | c=off | |
02A706 | RTS | return |
長くなったので一旦切ります。
(12/23追記)
- SR: $02A907 戦闘終了時アイテム取得処理
02A907 | JSR $A910 | SR: $02A910 | アイテム取得処理(盗賊) |
---|---|---|---|
02A90A | BCS #$03 | if(c==on) goto $02A90F | |
02A90C | JSR $A9AE | SR: $02A9AE | アイテム取得処理(宝箱) |
02A90F | RTS | return |
- SR: $02A907 アイテム取得処理(盗賊)
02A910 | STZ $00 | $000000=#$00 | |
---|---|---|---|
02A912 | STZ $02 | $000002=#$00 | |
02A914 | LDX #$0006 | X=#$0006 | |
02A917 | LDA $2008,X | A=$7E2008+X | モンスター出現数をセット? |
02A91A | CLC | c=off | |
02A91B | BEQ #$01 | if(z==on) goto $02A91E | |
02A91D | SEC | c=on | |
02A91E | ROL $00 | ($000000+C)<<1 | |
02A920 | DEX | X– | |
02A921 | DEX | X– | |
02A922 | BPL #$F3 | if(n==off) goto $02A917 | |
02A924 | LDX #$0000 | X=#$0000 | |
02A927 | JSL $001407 | SR: $001407 | 乱数発生 $0000-FFFF dp,Xの1になっているビットをランダムで0にする |
02A92B | BCC #$5A | if(c==off) goto $02A987 | |
02A92D | ASL | A<<1 | |
02A92E | TAX | X=A | |
02A92F | LDA $2000,X | A=$7E2000+X | 盗賊が盗む対象モンスター決定 |
02A932 | STA $BE71 | $7EBE71=A | |
02A935 | JSR $AA15 | SR: $02AA15 | ドロップアイテム・ドロップ率取得 |
02A938 | STA $00 | $000000=A | |
02A93A | JSL $04297C | SR: $04297C 引数:1#$01 引数:2#$02 | パーティ人数取得 |
02A940 | LDY #$0000 | Y=#$0000 | |
02A943 | JSL $02AF66 | SR: $02AF66 | 対象者の戦闘中キャラクタインデックスを取得 |
02A947 | STX $23E4 | $7E23E4=X | |
02A94A | STX $2428 | $7E2428=X | |
02A94D | JSL $02BE8A | SR: $02BE8A 引数:1#$1C | 生死判定? |
02A952 | BCS #$2E | if(c==on) goto $02A982 | |
02A954 | JSL $02BE8A | SR: $02BE8A 引数:1#$16 | 麻痺判定 |
02A959 | BCS #$27 | if(c==on) goto $02A982 | |
02A95B | JSL $02BE8A | SR: $02BE8A 引数:1#$28 | 混乱チェック |
02A960 | BCS #$20 | if(c==on) goto $02A982 | |
02A962 | JSL $02BE8A | SR: $02BE8A 引数:1#$24 | 職業ID取得 |
02A967 | CMP #$0006 | A==#$0006? | 盗賊か |
02A96A | BNE #$16 | if(z==off) goto $02A982 | |
02A96C | JSL $02C240 | SR: $02C240 引数:1#$0A | レベル取得 |
02A971 | LSR | A>>1 | |
02A972 | LSR | A>>1 | |
02A973 | LSR | A>>1 | |
02A974 | LSR | A>>1 | |
02A975 | INC | A++ | |
02A976 | PHA | Push A | レベル/16(+1)が閾値 |
02A977 | LDA $00 | A=$000000 | ドロップ率分母をAにセット |
02A979 | JSL $00135F | SR: $00135F | 乱数発生 00-A A(2B) |
02A97D | CMP $01,S | A==or>=Stack($01)? | |
02A97F | PLA | Pull A | |
02A980 | BCC #$07 | if(c==off) goto $02A989 | 盗み成功 |
02A982 | INY | Y++ | |
02A983 | CPY $02 | Y==$000002? | パーティ人数分ループする |
02A985 | BNE #$BC | if(z==off) goto $02A943 | |
02A987 | CLC | c=off | |
02A988 | RTS | return | |
02A989 | LDA $242C | A=$7E242C | |
02A98C | CMP #$0000 | A==#$0000? | ドロップアイテムIDが#$00(未設定)なら失敗扱い |
02A98F | BEQ #$F6 | if(z==on) goto $02A987 | |
02A991 | STA $BE79 | $7EBE79=A | |
02A994 | JSL $044739 | SR: $044739 引数:1#$FF 引数:2#$01 引数:3#$FD 引数:4#$40 | PCにアイテムを持たせる |
02A99C | BCC #$05 | if(c==off) goto $02A9A3 | c=onならいっぱいで持てない |
02A99E | JSL $045399 | SR: $045399 引数:1#$FF | アイテムを袋に入れる |
02A9A3 | JSR $AAF3 | SR: $02AAF3 | プロンプト表示 |
02A9A6 | JSL $01A867 | SR: $01A867 引数:1#$0038 | 戦闘メッセージ表示:「…をぬすんでいた!」 |
02A9AC | SEC | c=on | |
02A9AD | RTS | return |
- SR: $02AA15 ドロップアイテム・ドロップ率取得
02AA15 | PHX | Push X | |
---|---|---|---|
02AA16 | PHY | Push Y | |
02AA17 | TAY | Y=A | AにはモンスターIDがセットされていることが前提 |
02AA18 | JSL $02CC92 | SR: $02CC92 引数:1#$000C 引数:2#$00FF | ドロップアイテムID取得 |
02AA20 | STA $242C | $7E242C=A | |
02AA23 | JSL $02CC92 | SR: $02CC92 引数:1#$001D 引数:2#$0038 | ドロップ確率インデックス取得 |
02AA2B | ASL | A<<1 | |
02AA2C | TAX | X=A | |
02AA2D | LDA $02AA34,X | A=$02AA34+X | 実質ドロップ確率分母取得 |
02AA31 | PLY | Pull Y | |
02AA32 | PLX | Pull X | |
02AA33 | RTS | return |
これを見るとわかりますが、盗賊の盗みについては以下のような実装になっているようです。
- 死亡、麻痺、混乱していない盗賊がパーティ中にいる場合、レベル/16+1を閾値(=分子、最大7)にしてドロップ判定(分母はモンスターのドロップ率に準拠)して
- 戦闘に参加していたモンスター*1からランダムで*2盗む
- 判定はORなので、盗賊がいればいるほど有利
- 一度に複数個入手することはできない
- 盗みが成功した場合は宝箱ドロップは発生しない
下の通常ドロップと比較するとわかりますが、盗賊の場合、ドロップ率の分子が1ではなく、レベルによって最大7になるので、かなり有利になります。良く話題に上がるドーピングのための種集めには複数人のレベルの高い盗賊は必須と言えることがわかります。例えば、いのちのきのみのドロップ率が高いことで知られているコングですが、設定されているドロップ率は1/64です。Lv99の盗賊が4人いた場合にいのちのきのみを得られる確率は7/64 + 7/64 + 7/64 + 7/64 + 1/64 1- (57/64(盗賊1人目が盗めない確率) * 57/64(盗賊2人目が盗めない確率) * 57/64(盗賊3人目が盗めない確率) * 57/64(盗賊4人目が盗めない確率) * 63/64(ドロップしない確率)) で約38%となり、ほぼ3回に1回は入手できる計算になります(他のモンスターがいなかった場合)。スカイドラゴンも同じくドロップ率は1/64ですが、往々にして他のモンスターと組になって出てくることが多いので、スカイドラゴンが盗み先のモンスターとして選択される確率が低くなります(特に出現数の多いしびれあげやスライムつむりなどと一緒に出てきた場合は絶望的です)。コングはコングのみ3体で出てくることが多いのでランダム選択の余地がなくコングしか盗み先として選ばれないわけで、やはりコングのほうが効率がいい、ということになります。他の種集めについても同様で、モンスターそのもののドロップ確率も重要ですが、他のモンスターと組になって出現しない、出現数そのものが多い、ということにも注意を払うとより効率的に種集めができるでしょう。逆に、DQ3ではモンスターしかドロップしないレアアイテムの設定というのが難しい、とも言えます。エンカウント設定にもよりますが、ドロップ率が29倍に成り得るので、1/1024の確率に設定しても理論上は1/35まで確率が上がってしまいます。DQ3では1/1024のドロップ率を持つモンスターは実質存在しないので(設定はされているがドロップアイテムが空)、$02AA34-に配置されている分母の値を#$03FF(1023)から#0FFF(4095)にする、などの対応をする必要があるかもしれません。お供の小さいモンスターを沢山必ず一緒に出現させる、というふうにすれば盗まれる確率も減るでしょう。このへんはアイテムの重要性に応じていろいろ調整する余地がありそうです。
- SR: $02A9AE アイテム取得処理(宝箱ドロップ)
02A9AE | PEA $23A9 | Push $23A9 | |
---|---|---|---|
02A9B1 | PEA $00FF | Push $00FF | |
02A9B4 | PEA $7E00 | Push $7E00 | |
02A9B7 | JSL $09029E | SR: $09029E | 最後に倒したモンスターID取得 |
02A9BB | BEQ #$57 | if(z==on) goto $02AA14 | |
02A9BD | STA $BE71 | $7EBE71=A | |
02A9C0 | JSR $AA15 | SR: $02AA15 | ドロップアイテム・ドロップ率取得 |
02A9C3 | JSL $00135F | SR: $00135F | 乱数発生 00-A A(2B) |
02A9C7 | BNE #$4B | if(z==off) goto $02AA14 | |
02A9C9 | LDA $242C | A=$7E242C | |
02A9CC | CMP #$0000 | A==#$0000? | ドロップアイテムIDが#$00(未設定)なら失敗扱い |
02A9CF | BEQ #$43 | if(z==on) goto $02AA14 | |
02A9D1 | STA $BE79 | $7EBE79=A | |
02A9D4 | JSR $AAF3 | SR: $02AAF3 | プロンプト表示 |
02A9D7 | JSL $01A867 | SR: $01A867 引数:1#$0033 | 戦闘メッセージ:「…たからばこを おとしていった」 |
02A9DD | LDA #$0042 | A=#$0042 | 行動主体セット |
02A9E0 | STA $23E4 | $7E23E4=A | |
02A9E3 | JSL $01A867 | SR: $01A867 引数:1#$0034 | 戦闘メッセージ:「…たからばこを あけた」 |
02A9E9 | JSL $01E32E | SR: $01E32E 引数:1#$0040 | SE再生 |
02A9EF | JSL $01A867 | SR: $01A867 引数:1#$0035 | 戦闘メッセージ:「なんと〇〇をみつけた!」 |
02A9F5 | LDA $242C | A=$7E242C | |
02A9F8 | JSL $044824 | SR: $044824 引数:1#$FF 引数:2#$FF | アイテムを入手する |
02A9FE | STA $BE77 | $7EBE77=A | |
02AA01 | LDX #$0037 | X=#$0037 | 戦闘メッセージ:「どうぐぶくろに いれた」 |
02AA04 | CMP #$0020 | A==#$0020? | 入手先がふくろか |
02AA07 | BEQ #$03 | if(z==on) goto $02AA0C | |
02AA09 | LDX #$0036 | X=#$0036 | 戦闘メッセージ:「てにいれた いれた」 |
02AA0C | JSR $AAF3 | SR: $02AAF3 | プロンプト表示? |
02AA0F | TXA | A=X | |
02AA10 | JSL $01A87A | SR: $01A87A | 戦闘メッセージ表示 |
02AA14 | RTS | return |
宝箱ドロップもほとんど盗むと似たような実装になっています。こちらは特に解説する必要はないですね。
というわけで長々とやってきましたが、一通り戦闘部分の処理については説明が終わりました。取りこぼしている部分については気づき次第今までのエントリに追記もしくはその24以降という形で随時投下していくつもりです。
コメント
はじめまして、いつも参考にさせて貰っています。
盗賊の職業を廃止して、装飾品「盗賊の証」の装備の有無で盗み判定を行うという改造をしているのですが、$7E242CにドロップアイテムID
と装備アイテムIDを入れなくてはいけなくなり、作業が滞てしまっています。ない知識を振り絞って、$7E23EEにドロップアイテムIDを一時保持させてみたのですが、うまくいきませんでした。何かアドバイスをいただけないでしょうか?
よろしくお願いします。
どういう実装をしてるのかわかりませんが、すでに使ってる領域は使わないで別領域を使えばいいんじゃないんですかね?特に$7E23EEは戦闘行動IDを保持する重要な領域のはずなので下手に別用途で使うとまともに動きません。久しぶりに質問回答として後ほど別途エントリとしてを投下します。発動のタイミングは戦闘終了時でいいんでしょうか?
迅速な回答感謝いたします。
発動タイミングは戦闘終了時でお願いします。
実装内容もメールで送りましたので、お手数でなければご確認をお願いします。
例えばバスタードソードでイオナズンを打てるようにしてみましたが、AIが一向に実行してくれません。代わりに雷神の剣で打てるようにしても、AIの時は対象が元々のベギラゴンの性質に準じてるのか、1グループにしか効力が発生しません。対象選択ルーチンIDが若しや関係してるかと思い色々試してみてもうまくいきませんでした。
また、例えば水着係のアイテムの戦闘行動の内部データがあるにも関わらず、戦闘中道具コマンドで使用しても「~を使った!しかし何も起こりませんでした!」としか表示されず、用意されていた戦闘メッセージすら表示されずじまいで、どうやら最初からアイテム情報欄で指定された戦闘行動ID自体無視されてるようですが、何かそれを普通に実行できる方法がありますでしょうか。
SRが書けない前提でいい案がありましたら是非ご教示頂きたく存じます。
よろしくお願いします。m(._.)m
AI関連の設定は非公開です。あしからず。
水着系の戦闘行動は使用者の性別が女だと何も起きないように特殊対処がされています。男が使うとメッセージが表示されます。オリジナルからの動作です。特に変えていません。