Lose money proportional to badges and level - pret/pokecrystal GitHub Wiki
In RBY, GSC, and RSE, if you lost a battle you would simply lose half of your money. Starting in FRLG, you lose an amount proportional to how many badges you have and the maximum level of your party Pokémon. This tutorial ports that feature to pokecrystal.
(The code for this feature was adapted from Twitch Plays Pokémon: Anniversary Crystal.)
- Prepare to print how much money you lost in wild and trainer battles
- Save whether the battle was with a trainer or a wild Pokémon
- Implement the Gen 3+ money loss formula
Edit data/text/common_2.asm:
_WhitedOutText::
text "<PLAYER> is out of"
line "useable #MON!"
para "<PLAYER> whited"
line "out!"
done
+
+_WhitedOutToWildMonText::
+ text "<PLAYER> is out of"
+ line "useable #MON!"
+
+ para "<PLAYER> panicked"
+ line "and dropped"
+ cont "¥@"
+ text_decimal hMoneyTemp, 3, 6
+ text "…"
+
+ para "<……><……><……>"
+ line "<……><……><……>"
+
+ para "<PLAYER> whited"
+ line "out!"
+ done
+
+_WhitedOutToTrainerText::
+ text "<PLAYER> is out of"
+ line "useable #MON!"
+
+ para "<PLAYER> paid"
+ line "¥@"
+ text_decimal hMoneyTemp, 3, 6
+ text " to the"
+ cont "winner…"
+
+ para "<……><……><……>"
+ line "<……><……><……>"
+
+ para "<PLAYER> whited"
+ line "out!"
+ done
Edit wram.asm:
...
- ds 1
+wWildBattlePanic:: db
wWildEncounterCooldown:: db ; d452
wXYComparePointer:: dw ; d453
ds 4
wBattleScriptFlags:: dw ; d459
...
And edit engine/overworld/scripting.asm:
Script_reloadmapafterbattle:
; script command 0x60
ld hl, wBattleScriptFlags
ld d, [hl]
ld [hl], 0
+ ld hl, wWildBattlePanic
+ ld [hl], d
...
We have to cache the value of [wBattleScriptFlags]
in [wWildBattlePanic]
since [wBattleScriptFlags]
gets reset to 0 here.
Edit engine/events/whiteout.asm:
Script_Whiteout:
+ checkflag ENGINE_BUG_CONTEST_TIMER
+ iftrue .bug_contest
+ callasm LoseWhiteOutMoney
+ iffalse .plain_whiteout_text
+ callasm CheckWildBattlePanic
+ iffalse .wild_whiteout_text
+ writetext .WhitedOutToTrainerText
+ sjump .text_done
+.wild_whiteout_text
+ writetext .WhitedOutToWildMonText
+ sjump .text_done
+.plain_whiteout_text
writetext .WhitedOutText
+.text_done
waitbutton
special FadeOutToWhite ;older versions have FadeOutPalettes instead
pause 40
special HealParty
- checkflag ENGINE_BUG_CONTEST_TIMER
- iftrue .bug_contest
- callasm HalveMoney
callasm GetWhiteoutSpawn
farscall Script_AbortBugContest
special WarpToSpawnPoint
newloadmap MAPSETUP_WARP
endall
.bug_contest
+ writetext .WhitedOutText
+ waitbutton
+ special FadeOutToWhite ;older versions have FadeOutPalettes instead
+ pause 40
+ special HealParty
jumpstd BugContestResultsWarpScript
.WhitedOutText:
; is out of useable #MON! whited out!
text_far UnknownText_0x1c0a4e
text_end
+
+.WhitedOutToWildMonText:
+ text_far _WhitedOutToWildMonText
+ text_end
+
+.WhitedOutToTrainerText:
+ text_far _WhitedOutToTrainerText
+ text_end
Here we determine which message to print. Note that we don't lose any money during the Bug-Catching Contest.
-HalveMoney:
- farcall StubbedTrainerRankings_WhiteOuts
-
-; Halve the player's money.
- ld hl, wMoney
- ld a, [hl]
- srl a
- ld [hli], a
- ld a, [hl]
- rra
- ld [hli], a
- ld a, [hl]
- rra
- ld [hl], a
- ret
+LoseWhiteOutMoney:
+; Lose money proportional to your badges and highest-level Pokémon.
+ ld hl, wMoney
+; Check if you have any money
+ ld a, [hli]
+ or [hl]
+ inc hl
+ or [hl]
+ jr z, .done
+; Count your badges (capped at 8)
+ ld hl, wBadges
+ ld b, 2
+ call CountSetBits
+ cp 9
+ jr c, .got_badge_count
+ ld c, 8
+.got_badge_count
+; Get the payout factor for your badge count
+ ld b, 0
+ ld hl, .PayoutBadgeFactors
+ add hl, bc
+ ld a, [hl]
+ ldh [hMultiplier], a
+; Get your highest party mon level
+ ld a, [wPartyCount]
+ ld c, a
+ ld hl, wPartyMon1Level
+ ld de, PARTYMON_STRUCT_LENGTH
+.loop
+ ld a, [hl]
+ cp b
+ jr c, .next
+ ld b, a
+.next
+ add hl, de
+ dec c
+ jr nz, .loop
+; Multiply the badge factor by the max level
+ xor a
+ ldh [hMultiplicand + 0], a
+ ldh [hMultiplicand + 1], a
+ ld a, b
+ ldh [hMultiplicand + 2], a
+ call Multiply
+; Save the amount (capped at your total) in hMoneyTemp to print
+ ld de, hMoneyTemp
+ ld hl, hProduct + 1
+ ld bc, 3
+ call CopyBytes
+ ld de, wMoney
+ ld bc, hMoneyTemp
+ push bc
+ push de
+ farcall CompareMoney
+ jr nc, .not_enough
+ ld hl, wMoney
+ ld de, hMoneyTemp
+ ld bc, 3
+ call CopyBytes
+.not_enough
+ pop de
+ pop bc
+ farcall TakeMoney
+; Return TRUE in [wScriptVar] if you had any money to lose
+ ld a, TRUE
+.done
+ ld [wScriptVar], a
+ ret
+
+.PayoutBadgeFactors:
+ db 8 ; 0
+ db 16 ; 1
+ db 24 ; 2
+ db 36 ; 3
+ db 48 ; 4
+ db 64 ; 5
+ db 80 ; 6
+ db 100 ; 7
+ db 120 ; 8+
+
+CheckWildBattlePanic:
+ ld hl, wWildBattlePanic
+ ld a, [hl]
+ and 1
+ ld [wScriptVar], a
+ xor a
+ ld [hl], a
+ ret
The HalveMoney
routine is completely replaced by LoseWhiteOutMoney
, and we also implement CheckWildBattlePanic
for use in Script_Whiteout
. It makes use of various helper routines that already exist, like CountSetBits
and CompareMoney
, so we don't have to do everything in raw assembly instructions.
(Note that in Gen 3 and 4 the base payout for five badges was ¥60, not ¥64.)