diff options
| -rwxr-xr-x | data/events/magikarp_lengths.asm | 20 | ||||
| -rwxr-xr-x | engine/events/magikarp.asm | 314 | ||||
| -rwxr-xr-x | gfx/font/feet_inches.2bpp | bin | 0 -> 32 bytes | |||
| -rwxr-xr-x | gfx/font/feet_inches.png | bin | 0 -> 89 bytes | |||
| -rw-r--r-- | main.asm | 8 | 
5 files changed, 335 insertions, 7 deletions
| diff --git a/data/events/magikarp_lengths.asm b/data/events/magikarp_lengths.asm new file mode 100755 index 00000000..1a1040d6 --- /dev/null +++ b/data/events/magikarp_lengths.asm @@ -0,0 +1,20 @@ +MagikarpLengths: +; [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 diff --git a/engine/events/magikarp.asm b/engine/events/magikarp.asm new file mode 100755 index 00000000..035148b5 --- /dev/null +++ b/engine/events/magikarp.asm @@ -0,0 +1,314 @@ +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. +	farcall SelectMonFromParty +	jr c, .declined +	ld a, [wCurPartySpecies] +	cp MAGIKARP +	jr nz, .not_magikarp + +	; Now let's compute its length based on its DVs and ID. +	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 +	ld hl, .MagikarpGuruMeasureText +	call PrintText + +	; Did we beat the record? +	ld hl, wMagikarpLength +	ld de, wBestMagikarpLengthFeet +	ld c, 2 +	call CompareBytes +	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, [wCurPartyMon] +	ld hl, wPartyMonOT +	call SkipNames +	call CopyBytes +	ld a, MAGIKARPLENGTH_BEAT_RECORD +	ld [wScriptVar], a +	ret + +.not_long_enough +	ld a, MAGIKARPLENGTH_TOO_SHORT +	ld [wScriptVar], a +	ret + +.declined +	ld a, MAGIKARPLENGTH_REFUSED +	ld [wScriptVar], a +	ret + +.not_magikarp +	xor a ; MAGIKARPLENGTH_NOT_MAGIKARP +	ld [wScriptVar], a +	ret + +.MagikarpGuruMeasureText: +	text_far _MagikarpGuruMeasureText +	text_end + +Magikarp_LoadFeetInchesChars: +	ld hl, vTiles2 tile "′" ; $6e +	ld de, .feetinchchars +	lb bc, BANK(.feetinchchars), 2 +	call Request2bpp +	ret + +.feetinchchars +INCBIN "gfx/font/feet_inches.2bpp" + +PrintMagikarpLength: +	call Magikarp_LoadFeetInchesChars +	ld hl, wStringBuffer1 +	ld de, wMagikarpLength +	lb bc, PRINTNUM_LEFTALIGN | 1, 2 +	call PrintNum +	ld [hl], "′" +	inc hl +	ld de, wMagikarpLength + 1 +	lb bc, PRINTNUM_LEFTALIGN | 1, 2 +	call PrintNum +	ld [hl], "″" +	inc hl +	ld [hl], "@" +	ret + +CalcMagikarpLength: +; Return Magikarp's length (in feet and inches) at wMagikarpLength (big endian). +; +; input: +;   de: wEnemyMonDVs +;   bc: wPlayerID + +; 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, MagikarpLengths +	ld a, 2 +	ld [wTempByteValue], 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 +	ldh [hDividend + 0], a +	ld a, c +	ldh [hDividend + 1], a +	ld a, [hl] +	ldh [hDivisor], a +	ld b, 2 +	call Divide +	ldh a, [hQuotient + 3] +	ld c, a + +	; de = c + 100 × (2 + i) +	xor a +	ldh [hMultiplicand + 0], a +	ldh [hMultiplicand + 1], a +	ld a, 100 +	ldh [hMultiplicand + 2], a +	ld a, [wTempByteValue] +	ldh [hMultiplier], a +	call Multiply +	ld b, 0 +	ldh a, [hProduct + 3] +	add c +	ld e, a +	ldh a, [hProduct + 2] +	adc b +	ld d, a +	jr .done + +.next +	inc hl ; align to next triplet +	ld a, [wTempByteValue] +	inc a +	ld [wTempByteValue], 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 + +.BCLessThanDE: +; Intention: Return bc < de. +; Reality: Return b < d. +	ld a, b +	cp d +	ret c +	ret nc ; whoops +	ld a, c +	cp e +	ret + +.BCMinusDE: +; bc -= de +	ld a, c +	sub e +	ld c, a +	ld a, b +	sbc d +	ld b, a +	ret + +INCLUDE "data/events/magikarp_lengths.asm" + +MagikarpHouseSign: +	ld a, [wBestMagikarpLengthFeet] +	ld [wMagikarpLength], a +	ld a, [wBestMagikarpLengthInches] +	ld [wMagikarpLength + 1], a +	call PrintMagikarpLength +	ld hl, .KarpGuruRecordText +	call PrintText +	ret + +.KarpGuruRecordText: +	text_far _KarpGuruRecordText +	text_end diff --git a/gfx/font/feet_inches.2bpp b/gfx/font/feet_inches.2bppBinary files differ new file mode 100755 index 00000000..fba5d65c --- /dev/null +++ b/gfx/font/feet_inches.2bpp diff --git a/gfx/font/feet_inches.png b/gfx/font/feet_inches.pngBinary files differ new file mode 100755 index 00000000..60f319eb --- /dev/null +++ b/gfx/font/feet_inches.png @@ -380,13 +380,7 @@ INCLUDE "engine/events/play_slow_cry.asm"  INCLUDE "engine/pokedex/new_pokedex_entry.asm"  INCLUDE "engine/link/time_capsule_2.asm"  INCLUDE "engine/pokedex/unown_dex.asm" - -CheckMagikarpLength:: -	dr $fbc3c, $fbd00 -CalcMagikarpLength:: -	dr $fbd00, $fbdd6 -MagikarpHouseSign:: -	dr $fbdd6, $fbdf1 +INCLUDE "engine/events/magikarp.asm"  HiddenPowerDamage::  	dr $fbdf1, $fbe5a | 
