User talk:Kejardon
Semi-commented drop-chance code.
Summary of it: Drop chance is a ratio of probabilities for each type of object:
0 = Small energy, 1 = Large, 2 = missiles, 3 = nothing, 4 = super, 5 = power bomb
Example: 0x10, 0x20, 0x08, 0x20, 0x08, 0x08 Total drop chance is 0x68. 2/13 chance of small energy, 4/13 large energy, 1/13 missiles, 4/13 nothing, 1/13 super missiles, 1/13 power bombs. Note: Default Super Metroid drop chances all(?) add up to 0xFF if I remember right.
Furthermore, these drop chances are lumped into two groups: 0-3 and 4-5. The value of these groups should add up to less than 256 or overflow errors will happen during item drop chance calculations.
When a category is full (current == max, includes not having collected it yet), its probability is set to 0 and the other probabilities (in group one only, options 0-3) are multiplied to make up the difference. Group two, supers and power bombs, do NOT get their drop chance multiplied in this way - overflow probability defaults to dropping nothing.
Example (using the drop chances from last): A person has full energy and full super missiles. Group 1 drops are multiplied by 13/6 to account for this. Final drop chances: 1/6 missiles, 4/6 nothing, 1/13 power bombs. Total drop chance is ~91%. There is a ~9% chance of the drop defaulting to nothing (in addition to the given 4/6 drop chance).
Note: The final chances are actually calculated as x/255 chance. The values are multiplied up to these odds and then rounded down to be (integer)/255 chance. This can cause particularly high rolls from the RNG to drop nothing even if nothing is not a drop option.
$37106-$3725D { PHX PHY PHB PEA #$A000 PLB PLB LDA $7EF410, X AND #$7FFF STA $0E2A LDA $7EF3C8, X TAX STA $0E28 LDA $A0003A, X ; Get drop selection TAX BNE BRANCH_ALPHA JMP $F24D ; Drop Nothing if no drop selection is given. BRANCH_ALPHA JSL $808111 ; Produce a random number AND #$00FF BEQ BRANCH_ALPHA ; If number is 0, get a different number STA $1A ;I'll call this 'drop chance quota'. It'll make sense later. LDA #$00FF STA $14 STZ $18 LDY #$0001 ; Default for $0E1A LDA $09C2 ; Current Health CLC ADC $09D6 ; Reserve Tank health CMP #$001E ; 30 BCC BRANCH_BETA CMP #$0032 ; 50 BCC BRANCH_GAMMA DEY BRANCH_BETA STY $0E1A ; Basically, if total health is <30, set 0E1A. If >49, clear 0E1A. Else leave it alone. BRANCH_GAMMA SEP #$20 LDA $0E1A BEQ BRANCH_DELTA ; If cleared, go to normal drops ; This is for energy only drops. LDA $B40000, X CLC ADC $B40001, X STA $12 ;Set $12 to small and large enemy maximum LDA #$03 STA $16 ;Set small and large energy drop opportunities JMP $F1DF ; Go to choose drop code BRANCH_DELTA LDA $B40003, X STA $12 ;Set $12 to 'nothing' drop chance LDA #$08 STA $16 ;Set nothing drop chance LDY $09C2 CPY $09C4 ;Check health and max BNE BRANCH_EPSILON LDY $09D6 CPY $09D4 ;Also reserves and max BEQ BRANCH_ZETA BRANCH_EPSILON ;Enable energy drop LDA $12 CLC ADC $B40000, X ;Small drop ADC $B40001, X ;Large drop STA $12 ;Added chance for small and large energy LDA $16 ORA #$03 STA $16 ;Set small and large energy drop opportunities BRANCH_ZETA LDY $09C6 CPY $09C8 ;Check missiles and max BEQ BRANCH_THETA LDA $12 CLC ADC $B40002, X STA $12 ;Add missile drop chance LDA $16 ORA #$04 STA $16 ;Add missile drop opportunity BRANCH_THETA LDY $09CA CPY $09CC ;Check supers and max BEQ BRANCH_IOTA LDA $14 SEC SBC $B40004, X STA $14 ;'Add' supers drop chance. Odd code, I know. LDA $16 ORA #$10 STA $16 ;Add super drop opportunity. BRANCH_IOTA LDY $09CE CPY $09D0 ;Check power bombs and max BEQ BRANCH_KAPPA LDA $14 SEC SBC $B40005, X STA $14 ;'Add' power bomb drop chance LDA $16 ORA #$20 STA $16 ;Add power bomb drop opportunity $371DF ALTERNATE ENTRY POINT BRANCH_KAPPA ;Choose item drop LDY #$0000 BRANCH_XI SEP #$20 LDA $12 BEQ BRANCH_LAMBDA ;If no chance to drop small energy, large energy, missiles, or nothing, go here. LSR $16 ;Check the next drop opportunity bit BCC BRANCH_MU ;If clear, skip that item. LDA $14 ;Acumulative 'negative' drop chance of supers and power bombs. This acts basically as a X/256 multiplier for now STA $4202 LDA $B40000, X ;Drop chance STA $4203 PHY NOP NOP LDY $4216 ;Multiplier * drop chance STY $4204 LDA $12 ;Cumulative drop chance of first four items (including no drop) STA $4206 PLY NOP REP #$20 LDA $18 ; Acumulated drop chance CLC ADC $4214 ;This is basically current drop chance * (acumulative first 4 drop chance / acumulative super and power drop chance) CMP $1A ; Compared to the drop chance quota. BCS BRANCH_NU ;When the drop chance quota is met or exceeded, go here to set the drop STA $18 ;Else update the cumulative drop chance BRANCH_MU INX ;Go to next drop chance INY ;Go to next drop type CPY #$0004 BNE BRANCH_XI ;Loop back to choose item loop, unless BRA BRANCH_OMICRON ;The first four items haven't triggered the drop, go on to supers and power bombs. BRANCH_LAMBDA LDA $16 LSR A LSR A LSR A LSR A STA $16 ;Skip first 4 drop opportunity bits INX INX INX INX ;Skip 4 drop chances LDY #$0004 ;Go straight to drop type 4 (supers) BRANCH_OMICRON ;Super and power bomb drop choice loop SEP #$20 LSR $16 ;Check the next drop opportunity bit BCC BRANCH_PI ;If clear, skip that item. REP #$20 LDA $B40000, X ;Get drop chance AND #$00FF CLC ADC $18 ;Add to accumulated drop chance CMP $1A ;Compare to drop quota BCS BRANCH_NU STA $18 ;Update drop chance BRANCH_PI INX ;Go to next drop chance INY ;Go to next drop type CPY #$0006 BNE BRANCH_OMICRON ;Loop back $3724D ALTERNATE ENTRY POINT LDY #$0003 ;Drop nothing BRANCH_NU ;At this point, Y determines the drop. 0 = Small energy, 1 = Large, 2 = missiles, 3 = nothing, 4 = super, 5 = power bomb. REP #$20 TYX LDA $86F25E, X ;Translate chosen drop to some other index value. AND #$00FF ;1 byte PLB PLY PLX RTS }