mirror of https://github.com/pret/pokecrystal.git
350 lines
6.0 KiB
NASM
350 lines
6.0 KiB
NASM
Special_CheckMagikarpLength: ; fbb32
|
||
; Returns 3 if you select a Magikarp that beats the previous record.
|
||
; Returns 2 if you select a Magikarp, but the current record is longer.
|
||
; Returns 1 if you press B in the Pokemon selection menu.
|
||
; Returns 0 if the Pokemon you select is not a Magikarp.
|
||
|
||
; Let's start by selecting a Magikarp.
|
||
farcall SelectMonFromParty
|
||
jr c, .declined
|
||
ld a, [CurPartySpecies]
|
||
cp MAGIKARP
|
||
jr nz, .not_magikarp
|
||
|
||
; Now let's compute its length based on its DVs and ID.
|
||
ld a, [CurPartyMon]
|
||
ld hl, PartyMon1Species
|
||
ld bc, PARTYMON_STRUCT_LENGTH
|
||
call AddNTimes
|
||
push hl
|
||
ld bc, MON_DVS
|
||
add hl, bc
|
||
ld d, h
|
||
ld e, l
|
||
pop hl
|
||
ld bc, MON_ID
|
||
add hl, bc
|
||
ld b, h
|
||
ld c, l
|
||
call CalcMagikarpLength
|
||
call PrintMagikarpLength
|
||
farcall TrainerRankings_MagikarpLength
|
||
ld hl, .MeasureItText
|
||
call PrintText
|
||
|
||
; Did we beat the record?
|
||
ld hl, wMagikarpLength
|
||
ld de, wBestMagikarpLengthFeet
|
||
ld c, 2
|
||
call StringCmp
|
||
jr nc, .not_long_enough
|
||
|
||
; NEW RECORD!!! Let's save that.
|
||
ld hl, wMagikarpLength
|
||
ld de, wBestMagikarpLengthFeet
|
||
ld a, [hli]
|
||
ld [de], a
|
||
inc de
|
||
ld a, [hl]
|
||
ld [de], a
|
||
inc de
|
||
ld a, [CurPartyMon]
|
||
ld hl, PartyMonOT
|
||
call SkipNames
|
||
call CopyBytes
|
||
ld a, MAGIKARPLENGTH_BEAT_RECORD
|
||
ld [ScriptVar], a
|
||
ret
|
||
|
||
.not_long_enough
|
||
ld a, MAGIKARPLENGTH_TOO_SHORT
|
||
ld [ScriptVar], a
|
||
ret
|
||
|
||
.declined
|
||
ld a, MAGIKARPLENGTH_REFUSED
|
||
ld [ScriptVar], a
|
||
ret
|
||
|
||
.not_magikarp
|
||
xor a ; MAGIKARPLENGTH_NOT_MAGIKARP
|
||
ld [ScriptVar], a
|
||
ret
|
||
; fbba9
|
||
|
||
.MeasureItText: ; 0xfbba9
|
||
; Let me measure that MAGIKARP. …Hm, it measures @ .
|
||
text_jump UnknownText_0x1c1203
|
||
db "@"
|
||
; 0xfbbae
|
||
|
||
Magikarp_LoadFeetInchesChars: ; fbbae
|
||
ld hl, vTiles2 tile "′" ; $6e
|
||
ld de, .feetinchchars
|
||
lb bc, BANK(.feetinchchars), 2
|
||
call Request2bpp
|
||
ret
|
||
; fbbbb
|
||
|
||
.feetinchchars ; fbbb
|
||
INCBIN "gfx/font/feet_inches.2bpp"
|
||
; fbbdb
|
||
|
||
PrintMagikarpLength: ; fbbdb
|
||
call Magikarp_LoadFeetInchesChars
|
||
ld hl, StringBuffer1
|
||
ld de, wMagikarpLength
|
||
lb bc, PRINTNUM_RIGHTALIGN | 1, 2
|
||
call PrintNum
|
||
ld [hl], "′"
|
||
inc hl
|
||
ld de, wMagikarpLength + 1
|
||
lb bc, PRINTNUM_RIGHTALIGN | 1, 2
|
||
call PrintNum
|
||
ld [hl], "″"
|
||
inc hl
|
||
ld [hl], "@"
|
||
ret
|
||
; fbbfc
|
||
|
||
CalcMagikarpLength: ; fbbfc
|
||
; Return Magikarp's length (in feet and inches) at wMagikarpLength (big endian).
|
||
;
|
||
; input:
|
||
; de: EnemyMonDVs
|
||
; bc: PlayerID
|
||
|
||
; This function is poorly commented.
|
||
|
||
; In short, it generates a value between 190 and 1786 using
|
||
; a Magikarp's DVs and its trainer ID. This value is further
|
||
; filtered in LoadEnemyMon to make longer Magikarp even rarer.
|
||
|
||
; The value is generated from a lookup table.
|
||
; The index is determined by the dv xored with the player's trainer id.
|
||
|
||
; bc = rrc(dv[0]) ++ rrc(dv[1]) ^ rrc(id)
|
||
|
||
; if bc < 10: [wMagikarpLength] = c + 190
|
||
; if bc ≥ $ff00: [wMagikarpLength] = c + 1370
|
||
; else: [wMagikarpLength] = z * 100 + (bc - x) / y
|
||
|
||
; X, Y, and Z depend on the value of b as follows:
|
||
|
||
; if b = 0: x = 310, y = 2, z = 3
|
||
; if b = 1: x = 710, y = 4, z = 4
|
||
; if b = 2-9: x = 2710, y = 20, z = 5
|
||
; if b = 10-29: x = 7710, y = 50, z = 6
|
||
; if b = 30-68: x = 17710, y = 100, z = 7
|
||
; if b = 69-126: x = 32710, y = 150, z = 8
|
||
; if b = 127-185: x = 47710, y = 150, z = 9
|
||
; if b = 186-224: x = 57710, y = 100, z = 10
|
||
; if b = 225-243: x = 62710, y = 50, z = 11
|
||
; if b = 244-251: x = 64710, y = 20, z = 12
|
||
; if b = 252-253: x = 65210, y = 5, z = 13
|
||
; if b = 254: x = 65410, y = 2, z = 14
|
||
|
||
|
||
; bc = rrc(dv[0]) ++ rrc(dv[1]) ^ rrc(id)
|
||
|
||
; id
|
||
ld h, b
|
||
ld l, c
|
||
ld a, [hli]
|
||
ld b, a
|
||
ld c, [hl]
|
||
rrc b
|
||
rrc c
|
||
|
||
; dv
|
||
ld a, [de]
|
||
inc de
|
||
rrca
|
||
rrca
|
||
xor b
|
||
ld b, a
|
||
|
||
ld a, [de]
|
||
rrca
|
||
rrca
|
||
xor c
|
||
ld c, a
|
||
|
||
; if bc < 10:
|
||
; de = bc + 190
|
||
; break
|
||
|
||
ld a, b
|
||
and a
|
||
jr nz, .no
|
||
ld a, c
|
||
cp 10
|
||
jr nc, .no
|
||
|
||
ld hl, 190
|
||
add hl, bc
|
||
ld d, h
|
||
ld e, l
|
||
jr .done
|
||
|
||
.no
|
||
|
||
ld hl, .Lengths
|
||
ld a, 2
|
||
ld [wd265], a
|
||
|
||
.read
|
||
ld a, [hli]
|
||
ld e, a
|
||
ld a, [hli]
|
||
ld d, a
|
||
call .BCLessThanDE
|
||
jr nc, .next
|
||
|
||
; c = (bc - de) / [hl]
|
||
call .BCMinusDE
|
||
ld a, b
|
||
ld [hDividend + 0], a
|
||
ld a, c
|
||
ld [hDividend + 1], a
|
||
ld a, [hl]
|
||
ld [hDivisor], a
|
||
ld b, 2
|
||
call Divide
|
||
ld a, [hQuotient + 2]
|
||
ld c, a
|
||
|
||
; de = c + 100 × (2 + i)
|
||
xor a
|
||
ld [hMultiplicand + 0], a
|
||
ld [hMultiplicand + 1], a
|
||
ld a, 100
|
||
ld [hMultiplicand + 2], a
|
||
ld a, [wd265]
|
||
ld [hMultiplier], a
|
||
call Multiply
|
||
ld b, 0
|
||
ld a, [hProduct + 3]
|
||
add c
|
||
ld e, a
|
||
ld a, [hProduct + 2]
|
||
adc b
|
||
ld d, a
|
||
jr .done
|
||
|
||
.next
|
||
inc hl ; align to next triplet
|
||
ld a, [wd265]
|
||
inc a
|
||
ld [wd265], a
|
||
cp 16
|
||
jr c, .read
|
||
|
||
call .BCMinusDE
|
||
ld hl, 1600
|
||
add hl, bc
|
||
ld d, h
|
||
ld e, l
|
||
|
||
.done
|
||
; convert from mm to feet and inches
|
||
; in = mm / 25.4
|
||
; ft = in / 12
|
||
|
||
; hl = de × 10
|
||
ld h, d
|
||
ld l, e
|
||
add hl, hl
|
||
add hl, hl
|
||
add hl, de
|
||
add hl, hl
|
||
|
||
; hl = hl / 254
|
||
ld de, -254
|
||
ld a, -1
|
||
.div_254
|
||
inc a
|
||
add hl, de
|
||
jr c, .div_254
|
||
|
||
; d, e = hl / 12, hl % 12
|
||
ld d, 0
|
||
.mod_12
|
||
cp 12
|
||
jr c, .ok
|
||
sub 12
|
||
inc d
|
||
jr .mod_12
|
||
.ok
|
||
ld e, a
|
||
|
||
ld hl, wMagikarpLength
|
||
ld [hl], d ; ft
|
||
inc hl
|
||
ld [hl], e ; in
|
||
ret
|
||
; fbc9a
|
||
|
||
.BCLessThanDE: ; fbc9a
|
||
; Intention: Return bc < de.
|
||
; Reality: Return b < d.
|
||
ld a, b
|
||
cp d
|
||
ret c
|
||
ret nc ; whoops
|
||
ld a, c
|
||
cp e
|
||
ret
|
||
; fbca1
|
||
|
||
.BCMinusDE: ; fbca1
|
||
; bc -= de
|
||
ld a, c
|
||
sub e
|
||
ld c, a
|
||
ld a, b
|
||
sbc d
|
||
ld b, a
|
||
ret
|
||
; fbca8
|
||
|
||
.Lengths: ; fbca8
|
||
; [wMagikarpLength] = z * 100 + (bc - x) / y
|
||
; First argument is the bc threshold as well as x.
|
||
; Second argument is y.
|
||
; In reality, due to the bug at .BCLessThanDE, the threshold is determined by only register b.
|
||
dwb 110, 1 ; not used unless the bug is fixed
|
||
dwb 310, 2
|
||
dwb 710, 4
|
||
dwb 2710, 20
|
||
dwb 7710, 50
|
||
dwb 17710, 100
|
||
dwb 32710, 150
|
||
dwb 47710, 150
|
||
dwb 57710, 100
|
||
dwb 62710, 50
|
||
dwb 64710, 20
|
||
dwb 65210, 5
|
||
dwb 65410, 2
|
||
dwb 65510, 1 ; not used
|
||
; fbcd2
|
||
|
||
|
||
|
||
Special_MagikarpHouseSign: ; fbcd2
|
||
ld a, [wBestMagikarpLengthFeet]
|
||
ld [wMagikarpLength], a
|
||
ld a, [wBestMagikarpLengthInches]
|
||
ld [wMagikarpLength + 1], a
|
||
call PrintMagikarpLength
|
||
ld hl, .CurrentRecordtext
|
||
call PrintText
|
||
ret
|
||
; fbce8
|
||
|
||
.CurrentRecordtext: ; 0xfbce8
|
||
; "CURRENT RECORD"
|
||
text_jump UnknownText_0x1c123a
|
||
db "@"
|
||
; 0xfbced
|