I learnt MIPS and disassembled the RNG used for critical hits in FF7.
Here is how the randomness in critical hits is determined:
crit% = chance of critical
crit% = (luck + level - enemy level) / 4
800f85f1 = enemy level
800f83f5 = luck
800f83e9 = level
##Random Function##
lw r3,0x00d4(r28) # load word from 80062e18 = offset1
lui r2, 0x8006
addiu r2,r2,0x2e10 # 80062e10
addu r3,r3,r2 # 80062e10 + (word from 80062e18 as offset)
lbu r2,0x0(r3) # load byte from 80062e10(offset1) = offset2
nop
addiu r4,r2,0x01
andi r2,r2,0xff
sb r4,0x0(r3) # increment by 1 and store
lui r1,0x8008
addu r1,r1,r2 # 80083084
lbu r2,0x3084(r1) # load byte from 80083084(offset2) = rnd1
jr r31
nop
lw r3,0x0008(r28) # load word from 80062d4c
nop
addiu r4,r3,0x01 # increment by 1
andi r3,r3,0x07 # AND 7 (check that value < 8)
sw r4,0x08(r28) # store incremented value back to 8062d4c
beq r3,r0,0x14c18 # if crit% = 0 then no critical
addu r16,r2,r0 # move rnd1
jal 0x14b54
nop
lw r2,0xd4(r28) # load word from 80062e18
nop
addiu r2,r2,0x01 # increment by 1
andi r2,r2,0x07 # AND with 7 (check that value < 8) = offset2
sw r2,0xd4(r28) # store in 80026e18
jr r31
nop
jal 0x14b70
nop
lw r3,0xd4(r28) # load word from 80062e18 = offset3
lui r2,0x8006
addiu r2,r2,0x2e10
addu r3,r3,r2
lbu r2,0x0(r3) # load byte from 80062e10(offset3) = offset4
nop
addiu r4,r2,0x01
andi r2,r2,0xff
sb r4,0x0(r3) # increment byte by 1 and store in 80062e11
lui r1,0x8008
addu r1,r1,r2
lbu r2,0x3084(r1) # load byte from 80083084(offset4) = rnd2
jr r31
nop
andi r2,r2,0xff
sll r2,r2,0x08 # rnd2 * 256
andi r3,r16,0xff
or r2,r3,r2 # rnd1 OR rnd2 (combine rnd1 and rnd2) = rnd0
lw r31,0x14(r29)
lw r16,0x10(r29)
addiu r29,r29,0x18
jr r31
nop
lw r31,0x10(r29)
andi r2,r2,0xffff # take 2 bytes of rnd0
jr r31
addiu r29,r29,0x18
## calculate crit_rnd for which to compare against crit% ##
lui r4,0x8000
ori r4,r4,0x8001
andi r2,r2,0xffff
sll r3,r2,0x01 ## This section is actually simple, but compiler
addu r3,r3,r2 ## optimised for MIPS
sll r2,r3,0x05 ## Just: crit_rnd = ((rnd0 * 99) / 65535) + 1
addu r3,r3,r2
mult r3,r4
addu r2,r5,r3
sra r2,r2,0x0f
sra r3,r3,0x1f
subu r2,r2,r3
lw r31,0x10(r29)
addiu r2,r2,0x01
jr r31
addiu r29,r29,0x0018
slt r2,r16,r2
bne r2,r0,0xb0888 # if crit% >= crit_rnd then critical hit success
nop
Unfortunately I don't know any high level languages. I'm sure this can be written in all of 10 lines in C :-P
Anyway, I have no idea how to write a lua script that will calculate all of this (I'm only really familiar with assembly).
I would appreciate if someone could help make this into a script so that I can know if a critical is possible on that frame. I will need this for when I start my 'glitchless' run, in order to optimize boss battles.
I suppose more information may be needed for this script. In this case, what else is needed?