pokecrystal-board/engine/events/magikarp.asm

315 lines
5.4 KiB
NASM
Raw Normal View History

2018-06-24 07:09:41 -07:00
CheckMagikarpLength:
; 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.
2017-12-24 09:47:30 -08:00
farcall SelectMonFromParty
jr c, .declined
2018-01-23 14:39:09 -08:00
ld a, [wCurPartySpecies]
cp MAGIKARP
jr nz, .not_magikarp
; Now let's compute its length based on its DVs and ID.
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
ld hl, wPartyMon1Species
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 StubbedTrainerRankings_MagikarpLength
ld hl, .MagikarpGuruMeasureText
call PrintText
; Did we beat the record?
2017-12-09 16:41:03 -08:00
ld hl, wMagikarpLength
ld de, wBestMagikarpLengthFeet
ld c, 2
call CompareBytes
jr nc, .not_long_enough
; NEW RECORD!!! Let's save that.
2017-12-09 16:41:03 -08:00
ld hl, wMagikarpLength
ld de, wBestMagikarpLengthFeet
ld a, [hli]
ld [de], a
inc de
ld a, [hl]
ld [de], a
inc de
2018-01-23 14:39:09 -08:00
ld a, [wCurPartyMon]
ld hl, wPartyMonOTs
call SkipNames
call CopyBytes
2018-01-11 22:40:20 -08:00
ld a, MAGIKARPLENGTH_BEAT_RECORD
2018-01-23 14:39:09 -08:00
ld [wScriptVar], a
ret
.not_long_enough
2018-01-11 22:40:20 -08:00
ld a, MAGIKARPLENGTH_TOO_SHORT
2018-01-23 14:39:09 -08:00
ld [wScriptVar], a
ret
.declined
2018-01-11 22:40:20 -08:00
ld a, MAGIKARPLENGTH_REFUSED
2018-01-23 14:39:09 -08:00
ld [wScriptVar], a
ret
.not_magikarp
2018-01-11 22:40:20 -08:00
xor a ; MAGIKARPLENGTH_NOT_MAGIKARP
2018-01-23 14:39:09 -08:00
ld [wScriptVar], a
ret
.MagikarpGuruMeasureText:
text_far _MagikarpGuruMeasureText
text_end
2018-06-24 07:09:41 -07:00
Magikarp_LoadFeetInchesChars:
2017-12-28 04:32:33 -08:00
ld hl, vTiles2 tile "" ; $6e
ld de, .feetinchchars
lb bc, BANK(.feetinchchars), 2
call Request2bpp
ret
2018-06-24 07:09:41 -07:00
.feetinchchars
INCBIN "gfx/font/feet_inches.2bpp"
2018-06-24 07:09:41 -07:00
PrintMagikarpLength:
call Magikarp_LoadFeetInchesChars
2018-01-23 14:39:09 -08:00
ld hl, wStringBuffer1
2017-12-09 16:41:03 -08:00
ld de, wMagikarpLength
2019-11-03 17:17:04 -08:00
lb bc, PRINTNUM_LEFTALIGN | 1, 2
call PrintNum
2015-10-13 16:50:58 -07:00
ld [hl], ""
inc hl
2017-12-09 16:41:03 -08:00
ld de, wMagikarpLength + 1
2019-11-03 17:17:04 -08:00
lb bc, PRINTNUM_LEFTALIGN | 1, 2
call PrintNum
2015-10-13 16:50:58 -07:00
ld [hl], "″"
inc hl
ld [hl], "@"
ret
2018-06-24 07:09:41 -07:00
CalcMagikarpLength:
2017-12-28 07:42:57 -08:00
; Return Magikarp's length (in feet and inches) at wMagikarpLength (big endian).
2013-02-18 01:40:01 -08:00
;
; input:
2018-01-23 14:39:09 -08:00
; de: wEnemyMonDVs
; bc: wPlayerID
2013-02-18 01:40:01 -08:00
; This function is poorly commented.
2013-02-18 01:40:01 -08:00
; 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.
2013-02-18 01:40:01 -08:00
; The value is generated from a lookup table.
; The index is determined by the dv xored with the player's trainer id.
2013-02-18 01:40:01 -08:00
; bc = rrc(dv[0]) ++ rrc(dv[1]) ^ rrc(id)
2013-02-18 01:40:01 -08:00
2017-12-09 16:41:03 -08:00
; if bc < 10: [wMagikarpLength] = c + 190
; if bc ≥ $ff00: [wMagikarpLength] = c + 1370
; else: [wMagikarpLength] = z * 100 + (bc - x) / y
2013-02-18 01:40:01 -08:00
; 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)
2013-02-18 01:40:01 -08:00
; id
2013-02-18 01:40:01 -08:00
ld h, b
ld l, c
ld a, [hli]
ld b, a
ld c, [hl]
rrc b
rrc c
; dv
2013-02-18 01:40:01 -08:00
ld a, [de]
inc de
rrca
rrca
xor b
ld b, a
2013-02-18 01:40:01 -08:00
ld a, [de]
rrca
rrca
xor c
ld c, a
; if bc < 10:
; de = bc + 190
; break
2013-02-18 01:40:01 -08:00
ld a, b
and a
jr nz, .no
2013-02-18 01:40:01 -08:00
ld a, c
cp 10
jr nc, .no
ld hl, 190
2013-02-18 01:40:01 -08:00
add hl, bc
ld d, h
ld e, l
jr .done
.no
2018-01-25 19:19:24 -08:00
ld hl, MagikarpLengths
ld a, 2
ld [wTempByteValue], a
.read
2013-02-18 01:40:01 -08:00
ld a, [hli]
ld e, a
ld a, [hli]
ld d, a
call .BCLessThanDE
jr nc, .next
; c = (bc - de) / [hl]
2013-02-18 01:40:01 -08:00
call .BCMinusDE
ld a, b
ldh [hDividend + 0], a
2013-02-18 01:40:01 -08:00
ld a, c
ldh [hDividend + 1], a
2013-02-18 01:40:01 -08:00
ld a, [hl]
ldh [hDivisor], a
ld b, 2
2013-02-18 01:40:01 -08:00
call Divide
ldh a, [hQuotient + 3]
2013-02-18 01:40:01 -08:00
ld c, a
2015-10-13 16:50:58 -07:00
; de = c + 100 × (2 + i)
2013-02-18 01:40:01 -08:00
xor a
ldh [hMultiplicand + 0], a
ldh [hMultiplicand + 1], a
ld a, 100
ldh [hMultiplicand + 2], a
ld a, [wTempByteValue]
ldh [hMultiplier], a
2013-02-18 01:40:01 -08:00
call Multiply
ld b, 0
ldh a, [hProduct + 3]
2013-02-18 01:40:01 -08:00
add c
ld e, a
ldh a, [hProduct + 2]
2013-02-18 01:40:01 -08:00
adc b
ld d, a
jr .done
.next
2013-02-18 01:40:01 -08:00
inc hl ; align to next triplet
ld a, [wTempByteValue]
2013-02-18 01:40:01 -08:00
inc a
ld [wTempByteValue], a
cp 16
jr c, .read
2013-02-18 01:40:01 -08:00
call .BCMinusDE
ld hl, 1600
2013-02-18 01:40:01 -08:00
add hl, bc
ld d, h
ld e, l
.done
2017-12-28 07:42:57 -08:00
; convert from mm to feet and inches
; in = mm / 25.4
; ft = in / 12
2015-10-13 16:50:58 -07:00
; hl = de × 10
2013-02-18 01:40:01 -08:00
ld h, d
ld l, e
add hl, hl
add hl, hl
2013-02-18 01:40:01 -08:00
add hl, de
add hl, hl
; hl = hl / 254
ld de, -254
ld a, -1
.div_254
2013-02-18 01:40:01 -08:00
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
2013-02-18 01:40:01 -08:00
inc d
jr .mod_12
.ok
2013-02-18 01:40:01 -08:00
ld e, a
2017-12-09 16:41:03 -08:00
ld hl, wMagikarpLength
2017-12-28 07:42:57 -08:00
ld [hl], d ; ft
2013-02-18 01:40:01 -08:00
inc hl
2017-12-28 07:42:57 -08:00
ld [hl], e ; in
2013-02-18 01:40:01 -08:00
ret
2018-06-24 07:09:41 -07:00
.BCLessThanDE:
; BUG: Magikarp lengths can be miscalculated (see docs/bugs_and_glitches.md)
2013-02-18 01:40:01 -08:00
ld a, b
cp d
ret c
ret nc
2013-02-18 01:40:01 -08:00
ld a, c
cp e
ret
2018-06-24 07:09:41 -07:00
.BCMinusDE:
2013-02-18 01:40:01 -08:00
; bc -= de
ld a, c
sub e
ld c, a
ld a, b
sbc d
ld b, a
ret
2018-01-25 19:19:24 -08:00
INCLUDE "data/events/magikarp_lengths.asm"
2018-06-24 07:09:41 -07:00
MagikarpHouseSign:
ld a, [wBestMagikarpLengthFeet]
2017-12-09 16:41:03 -08:00
ld [wMagikarpLength], a
ld a, [wBestMagikarpLengthInches]
2017-12-09 16:41:03 -08:00
ld [wMagikarpLength + 1], a
call PrintMagikarpLength
ld hl, .KarpGuruRecordText
call PrintText
ret
.KarpGuruRecordText:
text_far _KarpGuruRecordText
text_end