FF4 > ドロップ確率

SFC 版

  • アイテムドロップ判定は戦闘終了後に一括して行われる。
  • アイテムドロップの確率は以下の通り。

    ランク\設定値 設定 1 設定 2
    0 457/15360 2264/15360
    1 278/15360 1406/15360
    2 150/15360 754/15360
    3 15/15360 76/15360

    ※ NMI 割り込みは起きないと仮定した場合。

上記確率は、以下のコードにより算出しています。

rands = [
    0x07, 0xb6, 0xf0, 0x1f, 0x55, 0x5b, 0x37, 0xe3, 0xae, 0x4f, 0xb2, 0x5e, 0x99, 0xf6, 0x77, 0xcb, 
    0x60, 0x8f, 0x43, 0x3e, 0xa7, 0x4c, 0x2d, 0x88, 0xc7, 0x68, 0xd7, 0xd1, 0xc2, 0xf2, 0xc1, 0xdd, 
    0xaa, 0x93, 0x16, 0xf7, 0x26, 0x04, 0x36, 0xa1, 0x46, 0x4e, 0x56, 0xbe, 0x6c, 0x6e, 0x80, 0xd5, 
    0xb5, 0x8e, 0xa4, 0x9e, 0xe7, 0xca, 0xce, 0x21, 0xff, 0x0f, 0xd4, 0x8c, 0xe6, 0xd3, 0x98, 0x47, 
    0xf4, 0x0d, 0x15, 0xed, 0xc4, 0xe4, 0x35, 0x78, 0xba, 0xda, 0x27, 0x61, 0xab, 0xb9, 0xc3, 0x7d, 
    0x85, 0xfc, 0x95, 0x6b, 0x30, 0xad, 0x86, 0x00, 0x8d, 0xcd, 0x7e, 0x9f, 0xe5, 0xef, 0xdb, 0x59, 
    0xeb, 0x05, 0x14, 0xc9, 0x24, 0x2c, 0xa0, 0x3c, 0x44, 0x69, 0x40, 0x71, 0x64, 0x3a, 0x74, 0x7c, 
    0x84, 0x13, 0x94, 0x9c, 0x96, 0xac, 0xb4, 0xbc, 0x03, 0xde, 0x54, 0xdc, 0xc5, 0xd8, 0x0c, 0xb7, 
    0x25, 0x0b, 0x01, 0x1c, 0x23, 0x2b, 0x33, 0x3b, 0x97, 0x1b, 0x62, 0x2f, 0xb0, 0xe0, 0x73, 0xcc, 
    0x02, 0x4a, 0xfe, 0x9b, 0xa3, 0x6d, 0x19, 0x38, 0x75, 0xbd, 0x66, 0x87, 0x3f, 0xaf, 0xf3, 0xfb, 
    0x83, 0x0a, 0x12, 0x1a, 0x22, 0x53, 0x90, 0xcf, 0x7a, 0x8b, 0x52, 0x5a, 0x49, 0x6a, 0x72, 0x28, 
    0x58, 0x8a, 0xbf, 0x0e, 0x06, 0xa2, 0xfd, 0xfa, 0x41, 0x65, 0xd2, 0x4d, 0xe2, 0x5c, 0x1d, 0x45, 
    0x1e, 0x09, 0x11, 0xb3, 0x5f, 0x29, 0x79, 0x39, 0x2e, 0x2a, 0x51, 0xd9, 0x5d, 0xa6, 0xea, 0x31, 
    0x81, 0x89, 0x10, 0x67, 0xf5, 0xa9, 0x42, 0x82, 0x70, 0x9d, 0x92, 0x57, 0xe1, 0x3d, 0xf1, 0xf9, 
    0xee, 0x08, 0x91, 0x18, 0x20, 0xb1, 0xa5, 0xbb, 0xc6, 0x48, 0x50, 0x9a, 0xd6, 0x7f, 0x7b, 0xe9, 
    0x76, 0xdf, 0x32, 0x6f, 0x34, 0xa8, 0xd0, 0xb8, 0x63, 0xc8, 0xc0, 0xec, 0x4b, 0xe8, 0x17, 0xf8, 
]

rank = [0] * 256
for i in range(0x80, 0xd0): rank[i] = 1
for i in range(0xd0, 0xfc): rank[i] = 2
for i in range(0xfc, 0x100): rank[i] = 3

for thres in [5, 25]:
    counts = [0] * 4
    for f in range(60):
        for r in range(256):
            if rands[r] % 99 < thres:
                counts[rank[rands[(r + 1 + (f + 1)) & 0xff]]] += 1
    print(counts)

RAM

  • $7e:0097: 戦闘用乱数 Index (0~255)
  • $7e:16a3: 経過フレーム数 (0~59) ; $03:ed2e では carry 込みで加算されることに注意してください。

ROM

  • $03:ecef: アイテムドロップ処理
; 戦闘中の NMI の処理の一部
...
03F7CD  EE A3 16       inc $16a3   ; フレーム毎に $7e:16a3 を 1 増やす
03F7D0  AD A3 16       lda $16a3
03F7D3  C9 3C          cmp #$3c
03F7D5  90 10          bcc $03f7e7 ; 60 フレーム毎に

03F7D7  9C A3 16       stz $16a3   ; $7e:16a3 を 0 に設定し直す
03F7DA  EE A4 16       inc $16a4
03F7DD  D0 08          bne $03f7e7
03F7DF  EE A5 16       inc $16a5
03F7E2  D0 03          bne $03f7e7
03F7E4  EE A6 16       inc $16a6

03F7E7  6B             rtl
...

GBA 版

  • アイテムドロップ判定はモンスターを倒す毎に行われる。

  • アイテムドロップの確率は以下の通り。

    ランク\設定値 設定 1 設定 2
    0 約 160/6272 約 800/6272
    1 約 100/6272 約 500/6272
    2 約 55/6272 約 275/6272
    3 約 5/6272 約 25/6272

    アイテムドロップの処理は、おおよそ以下の通りになっている。

    rands = [
      0x07, 0xb6, 0xf0, 0x1f, 0x55, 0x5b, 0x37, 0xe3, 0xae, 0x4f, 0xb2, 0x5e, 0x99, 0xf6, 0x77, 0xcb, 
      0x60, 0x8f, 0x43, 0x3e, 0xa7, 0x4c, 0x2d, 0x88, 0xc7, 0x68, 0xd7, 0xd1, 0xc2, 0xf2, 0xc1, 0xdd, 
      0xaa, 0x93, 0x16, 0xf7, 0x26, 0x04, 0x36, 0xa1, 0x46, 0x4e, 0x56, 0xbe, 0x6c, 0x6e, 0x80, 0xd5, 
      0xb5, 0x8e, 0xa4, 0x9e, 0xe7, 0xca, 0xce, 0x21, 0xff, 0x0f, 0xd4, 0x8c, 0xe6, 0xd3, 0x98, 0x47, 
      0xf4, 0x0d, 0x15, 0xed, 0xc4, 0xe4, 0x35, 0x78, 0xba, 0xda, 0x27, 0x61, 0xab, 0xb9, 0xc3, 0x7d, 
      0x85, 0xfc, 0x95, 0x6b, 0x30, 0xad, 0x86, 0x00, 0x8d, 0xcd, 0x7e, 0x9f, 0xe5, 0xef, 0xdb, 0x59, 
      0xeb, 0x05, 0x14, 0xc9, 0x24, 0x2c, 0xa0, 0x3c, 0x44, 0x69, 0x40, 0x71, 0x64, 0x3a, 0x74, 0x7c, 
      0x84, 0x13, 0x94, 0x9c, 0x96, 0xac, 0xb4, 0xbc, 0x03, 0xde, 0x54, 0xdc, 0xc5, 0xd8, 0x0c, 0xb7, 
      0x25, 0x0b, 0x01, 0x1c, 0x23, 0x2b, 0x33, 0x3b, 0x97, 0x1b, 0x62, 0x2f, 0xb0, 0xe0, 0x73, 0xcc, 
      0x02, 0x4a, 0xfe, 0x9b, 0xa3, 0x6d, 0x19, 0x38, 0x75, 0xbd, 0x66, 0x87, 0x3f, 0xaf, 0xf3, 0xfb, 
      0x83, 0x0a, 0x12, 0x1a, 0x22, 0x53, 0x90, 0xcf, 0x7a, 0x8b, 0x52, 0x5a, 0x49, 0x6a, 0x72, 0x28, 
      0x58, 0x8a, 0xbf, 0x0e, 0x06, 0xa2, 0xfd, 0xfa, 0x41, 0x65, 0xd2, 0x4d, 0xe2, 0x5c, 0x1d, 0x45, 
      0x1e, 0x09, 0x11, 0xb3, 0x5f, 0x29, 0x79, 0x39, 0x2e, 0x2a, 0x51, 0xd9, 0x5d, 0xa6, 0xea, 0x31, 
      0x81, 0x89, 0x10, 0x67, 0xf5, 0xa9, 0x42, 0x82, 0x70, 0x9d, 0x92, 0x57, 0xe1, 0x3d, 0xf1, 0xf9, 
      0xee, 0x08, 0x91, 0x18, 0x20, 0xb1, 0xa5, 0xbb, 0xc6, 0x48, 0x50, 0x9a, 0xd6, 0x7f, 0x7b, 0xe9, 
      0x76, 0xdf, 0x32, 0x6f, 0x34, 0xa8, 0xd0, 0xb8, 0x63, 0xc8, 0xc0, 0xec, 0x4b, 0xe8, 0x17, 0xf8, 
    ]
    
    def item_rank(f, b, r, thres):
      # f: 非戦闘 経過フレーム数 (16 bit)
      # b: 汎用乱数 (16 bit)
      # r: 戦闘用乱数 Index (8 bit)
      # thres: アイテムドロップ境界値(設定1: 5, 設定2: 25) (8 bit)
      def g(n, divisor):
          if n == 0:
              n = 0x2a6d
          m = (n * 41) & 0xffff
          nb = ((m & 0xff) * 256) | (m // 256)
          nv = ((rands[r] + nb + f) & 0xffff) % divisor
          return nb, (r + 1) & 0xff, nv
      b, r, v = g(b, 98)
      if v < thres:
          b, r, v = g(b, 256)
          if v < 0x80:
              return 0
          elif v < 0xd0:
              return 1
          elif v < 0xfc:
              return 2
          else:
              return 3
      else:
          return -1 # ドロップなし

RAM (E4 版)

  • 0x02006c22: 戦闘用乱数 Index
  • 0x0200d9dc: 汎用乱数(戦闘中は 1 フレーム毎に +1 される)
  • 0x0200d9de: 非戦闘 経過フレーム数

ROM (E4 版)

  • 0x08089006: アイテムドロップ処理
;
; アイテムドロップ処理
;
808902A  28 78          LDRB R0, [R5, #$00] ; 確率設定値
808902C  00 28          CMP R0, #$00
808902E  66 D0          BEQ $080890FE ; 必ず落とさない

8089030  03 28          CMP R0, #$03
8089032  16 D0          BEQ $08089062 ; 必ず落とす

8089034  18 48          LDR R0, [PC, #$18] ; 0x0805905D
8089036  32 F0          BLL #$0032
8089038  D9 FD          BLH #$05D9
808903A  04 1C          ADD R4, R0, #$00   ; R4: 16 bit 乱数

808903C  17 48          LDR R0, [PC, #$17] ; 0x0805A245
808903E  32 F0          BLL #$0032
8089040  D5 FD          BLH #$05D5         ; R0: 8 bit 乱数

8089042  00 06          LSL R0, R0, #$18
8089044  00 0E          LSR R0, R0, #$18
8089046  24 18          ADD R4, R4, R0
8089048  24 04          LSL R4, R4, #$10
808904A  20 0C          LSR R0, R4, #$10
808904C  14 4A          LDR R2, [PC, #$14] ; 0x08000AB1
808904E  62 21          MOV R1, #$62       ; 除数 98 (SFC と異なり 99 ではない)
8089050  32 F0          BLL #$0032
8089052  D0 FD          BLH #$05D0         ; 

8089054  00 06          LSL R0, R0, #$18
8089056  00 0E          LSR R0, R0, #$18   ; R0: (((16 bit 乱数) + (8 bit 乱数)) mod 65536) mod 98
8089058  29 78          LDRB R1, [R5, #$00] ; 確率設定値
808905A  69 44          ADD R1, SP
808905C  09 78          LDRB R1, [R1, #$00] ; 境界値: 1: 4, 2: 24
808905E  88 42          CMP R0, R1
8089060  4D D8          BHI $080890FE

8089062  0D 48          LDR R0, [PC, #$0D] ; 0x0805905D
8089064  32 F0          BLL #$0032
8089066  C2 FD          BLH #$05C2
8089068  04 1C          ADD R4, R0, #$00
808906A  0C 48          LDR R0, [PC, #$0C] ; 0x0805A245
808906C  32 F0          BLL #$0032
808906E  BE FD          BLH #$05BE
8089070  00 06          LSL R0, R0, #$18
8089072  00 0E          LSR R0, R0, #$18
8089074  24 18          ADD R4, R4, R0
8089076  24 04          LSL R4, R4, #$10
8089078  FF 20          MOV R0, #$FF
808907A  00 04          LSL R0, R0, #$10
808907C  20 40          AND R0, R4
808907E  00 0C          LSR R0, R0, #$10 ; R0: ((16 bit 乱数) + (8 bit 乱数)) mod 256

8089080  01 26          MOV R6, #$01
8089082  7F 28          CMP R0, #$7F
8089084  0E D8          BHI $080890A4
8089086  6C 88          LDRH R4, [R5, #$02] ; 0x00-0x7f
8089088  15 E0          BAL $080890B6

808908C  68 A8 0F 08 50 4C 0F 08
8089094  5D 15 0C 08 5D 90 05 08
808909C  45 A2 05 08 B1 0A 00 08

80890A4  CF 28          CMP R0, #$CF
80890A6  01 D8          BHI $080890AC
80890A8  AC 88          LDRH R4, [R5, #$04] ; 0x80-0xcf
80890AA  04 E0          BAL $080890B6

80890AC  FB 28          CMP R0, #$FB
80890AE  01 D8          BHI $080890B4
80890B0  EC 88          LDRH R4, [R5, #$06] ; 0xd0-0xfb
80890B2  00 E0          BAL $080890B6

80890B4  2C 89          LDRH R4, [R5, #$08] ; 0xfc-0xff
...

;
; 16 bit 乱数取得
;
805905C  70 B5          PUSH {R4-R6,LR}
805905E  10 4D          LDR R5, [PC, #$10] ; 0x08069625
8059060  62 F0          BLL #$0062
8059062  CE FD          BLH #$05CE
8059064  0F 4E          LDR R6, [PC, #$0F] ; 0x00007690
8059066  80 19          ADD R0, R0, R6
8059068  04 88          LDRH R4, [R0, #$00] ; 16 bit 乱数 [1]
805906A  00 2C          CMP R4, #$00
805906C  00 D1          BNE $08059070
805906E  0E 4C          LDR R4, [PC, #$0E] ; 0x2a6d

8059070  A0 00          LSL R0, R4, #$02
8059072  00 19          ADD R0, R0, R4
8059074  C0 00          LSL R0, R0, #$03
8059076  00 19          ADD R0, R0, R4     ; R0 = R4 * 41 
8059078  00 04          LSL R0, R0, #$10
805907A  01 0E          LSR R1, R0, #$18
805907C  00 02          LSL R0, R0, #$08
805907E  04 0C          LSR R4, R0, #$10
8059080  0C 43          ORR R4, R1         ; R4 = (R0 & 0x00ff) * 256 | ((R0 & 0xff00) / 256)
8059082  62 F0          BLL #$0062
8059084  BD FD          BLH #$05BD
8059086  80 19          ADD R0, R0, R6
8059088  04 80          STRH R4, [R0, #$00] ; 16 bit 乱数 [1] 更新

805908A  62 F0          BLL #$0062
805908C  B9 FD          BLH #$05B9
805908E  07 49          LDR R1, [PC, #$07]
8059090  40 18          ADD R0, R0, R1
8059092  00 88          LDRH R0, [R0, #$00]
8059094  20 18          ADD R0, R4, R0      ; 16 bit 乱数 [2]
8059096  00 04          LSL R0, R0, #$10
8059098  00 0C          LSR R0, R0, #$10
805909A  70 BC          POP {R4-R6}
805909C  02 BC          POP {R1}
805909E  08 47          BX R1

80590A0  25 96 06 08 90 76 00 00
80590A8  6D 2A 00 00 92 76 00 00

;
; 8 bit 乱数取得
;
805A244  70 B5          PUSH {R4-R6,LR}
805A246  46 46          MOV R6, R8
805A248  40 B4          PUSH {R6}
805A24A  0E 4C          LDR R4, [PC, #$0E] ; 0x080EE382
805A24C  0E 4D          LDR R5, [PC, #$0E] ; 0x08069625
805A24E  61 F0          BLL #$0061
805A250  D7 FC          BLH #$04D7
805A252  0E 4E          LDR R6, [PC, #$0E] ; 0x000008D6
805A254  80 19          ADD R0, R0, R6
805A256  00 88          LDRH R0, [R0, #$00] ; 8 bit 乱数 index

805A258  00 19          ADD R0, R0, R4
805A25A  00 78          LDRB R0, [R0, #$00]
805A25C  80 46          MOV R8, R0          ; R8: 8 bit 乱数

805A25E  61 F0          BLL #$0061
805A260  CF FC          BLH #$04CF
805A262  04 1C          ADD R4, R0, #$00
805A264  61 F0          BLL #$0061
805A266  CC FC          BLH #$04CC
805A268  80 19          ADD R0, R0, R6
805A26A  00 88          LDRH R0, [R0, #$00] ; 8 bit 乱数 index

805A26C  01 30          ADD R0, #$01
805A26E  FF 21          MOV R1, #$FF
805A270  08 40          AND R0, R1
805A272  A4 19          ADD R4, R4, R6
805A274  20 80          STRH R0, [R4, #$00] ; 8 bit 乱数 index 更新

805A276  40 46          MOV R0, R8
805A278  08 BC          POP {R3}
805A27A  98 46          MOV R8, R3
805A27C  70 BC          POP {R4-R6}
805A27E  02 BC          POP {R1}
805A280  08 47          BX R1
805A282  00 00         
805A284  82 E3 0E 08 25 96 06 08
805A28C  D6 08 00 00
最終更新:2024年04月27日 23:08