Remove the gym badges boosts - pret/pokecrystal GitHub Wiki

In Pokémon generations I to III, after obtaining gym badges, the player is given an invisible and unfair advantage against in-game trainers and wild Pokémon battles. Removing those boosts is an easy way to make the game more difficult without overhauling all trainer teams. This tutorial explains how to remove the gym badge boosts from the game.

Contents

  1. Remove mentions about badge boosts
  2. Remove the stat boost effect
  3. Remove the type boost effect

1. Remove mentions about badge boosts

You should edit or remove mentions about badges boost at your convenience. There are 5 gym leaders talking about the badges boost:

We will remove Whitney's dialog about badge boost as an example.

Edit maps/GoldenrodGym.asm:

 WhitneyPlainBadgeText:
	text "PLAINBADGE lets"
	line "your #MON use"

	para "STRENGTH outside"
	line "of battle."

-	para "It also boosts"
-	line "your #MON's"
-	cont "SPEED."

	para "Oh, you can have"
	line "this too!"
	done

Then there are other mentions like:

If you are working with pokegold, there is also one trainer talking about badge boosts on Route 14. This text had been changed in Pokémon Crystal, so no need to worry about it.

Credits to @SatoMew for finding the in-game mention of Pokéfan Trevor.

2. Remove the stat boost effect

The badge boosts in gen II are divided into two groups, and we will remove them both:

  • stat boost
  • type boost

Let's start with the stat boost by removing the calls to BadgeStatBoosts.

Edit engine/battle/effect_commands.asm:

CalcPlayerStats:
	ld hl, wPlayerAtkLevel
	ld de, wPlayerStats
	ld bc, wBattleMonAttack

	ld a, NUM_BATTLE_STATS
	call CalcBattleStats

-	ld hl, BadgeStatBoosts
-	call CallBattleCore

	call BattleCommand_SwitchTurn

Edit engine/battle/core.asm:

InitBattleMon:
	ld a, MON_SPECIES
	call GetPartyParamLocation
        ...
	ld bc, PARTYMON_STRUCT_LENGTH - MON_ATK
	call CopyBytes
	call ApplyStatusEffectOnPlayerStats
-	call BadgeStatBoosts
	ret

        ...

GiveExperiencePoints:
        ...
.transformed
	xor a ; FALSE
	ld [wApplyStatLevelMultipliersToEnemy], a
	call ApplyStatLevelMultiplierOnAllStats
	callfar ApplyStatusEffectOnPlayerStats
-	callfar BadgeStatBoosts
	callfar UpdatePlayerHUD

In the same file, remove the entire BadgeStatBoosts and BadgeBoost functions (the latter is only called within the former).

INCLUDE "data/battle/stat_multipliers_2.asm"

-BadgeStatBoosts:
-; Raise the stats of the battle mon in wBattleMon
-; depending on which badges have been obtained.
-
-; Every other badge boosts a stat, starting from the first.
-; GlacierBadge also boosts Special Defense, although the relevant code is buggy (see below).
-
-; 	ZephyrBadge:  Attack
-; 	PlainBadge:   Speed
-; 	MineralBadge: Defense
-; 	GlacierBadge: Special Attack and Special Defense
-
-; The boosted stats are in order, except PlainBadge and MineralBadge's boosts are swapped.
-
-	ld a, [wLinkMode]
-	and a
-	ret nz
-
-	ld a, [wInBattleTowerBattle]
-	and a
-	ret nz
-
-	ld a, [wJohtoBadges]
-
-; Swap badges 3 (PlainBadge) and 5 (MineralBadge).
-	ld d, a
-	and (1 << PLAINBADGE)
-	add a
-	add a
-	ld b, a
-	ld a, d
-	and (1 << MINERALBADGE)
-	rrca
-	rrca
-	ld c, a
-	ld a, d
-	and ((1 << ZEPHYRBADGE) | (1 << HIVEBADGE) | (1 << FOGBADGE) | (1 << STORMBADGE) | (1 << GLACIERBADGE) | (1 << RISINGBADGE))
-	or b
-	or c
-	ld b, a
-
-	ld hl, wBattleMonAttack
-	ld c, 4
-.CheckBadge:
-; BUG: Glacier Badge may not boost Special Defense depending on the value of Special Attack (see docs/bugs_and_glitches.md)
-	ld a, b
-	srl b
-	call c, BoostStat
-	inc hl
-	inc hl
-; Check every other badge.
-	srl b
-	dec c
-	jr nz, .CheckBadge
-	srl a
-	call c, BoostStat
-	ret
-
-BoostStat:
-; Raise stat at hl by 1/8.
-
-	ld a, [hli]
-	ld d, a
-	ld e, [hl]
-	srl d
-	rr e
-	srl d
-	rr e
-	srl d
-	rr e
-	ld a, [hl]
-	add e
-	ld [hld], a
-	ld a, [hl]
-	adc d
-	ld [hli], a
-
-; Cap at 999.
-	ld a, [hld]
-	sub LOW(MAX_STAT_VALUE)
-	ld a, [hl]
-	sbc HIGH(MAX_STAT_VALUE)
-	ret c
-	ld a, HIGH(MAX_STAT_VALUE)
-	ld [hli], a
-	ld a, LOW(MAX_STAT_VALUE)
-	ld [hld], a
-	ret

_LoadBattleFontsHPBar:

3. Remove the type boost effect

Remove the only call to DoBadgeTypeBoosts in engine/battle/effect_commands.asm:

 BattleCommand_Stab:
; STAB = Same Type Attack Bonus
	ld a, BATTLE_VARS_MOVE_ANIM
        ...

	push hl
	push de
	push bc
	farcall DoWeatherModifiers
	pop bc
	pop de
	pop hl

-	push de
-	push bc
-	farcall DoBadgeTypeBoosts
-	pop bc
-	pop de

Then remove the function DoBadgeTypeBoosts in engine/battle/misc.asm:

INCLUDE "data/battle/weather_modifiers.asm"

-DoBadgeTypeBoosts:
-	ld a, [wLinkMode]
-	and a
-	ret nz
-
-	ld a, [wInBattleTowerBattle]
-	and a
-	ret nz
-
-	ldh a, [hBattleTurn]
-	and a
-	ret nz
-
-	push de
-	push bc
-
-	ld hl, BadgeTypeBoosts
-
-	ld a, [wKantoBadges]
-	ld b, a
-	ld a, [wJohtoBadges]
-	ld c, a
-
-.CheckBadge:
-	ld a, [hl]
-	cp -1
-	jr z, .done
-
-	srl b
-	rr c
-	jr nc, .NextBadge
-
-	ld a, [wCurType]
-	cp [hl]
-	jr z, .ApplyBoost
-
-.NextBadge:
-	inc hl
-	jr .CheckBadge
-
-.ApplyBoost:
-	ld a, [wCurDamage]
-	ld h, a
-	ld d, a
-	ld a, [wCurDamage + 1]
-	ld l, a
-	ld e, a
-
-	srl d
-	rr e
-	srl d
-	rr e
-	srl d
-	rr e
-
-	ld a, e
-	or d
-	jr nz, .done_min
-	ld e, 1
-
-.done_min
-	add hl, de
-	jr nc, .Update
-
-	ld hl, $ffff
-
-.Update:
-	ld a, h
-	ld [wCurDamage], a
-	ld a, l
-	ld [wCurDamage + 1], a
-
-.done
-	pop bc
-	pop de
-	ret
-
-INCLUDE "data/types/badge_type_boosts.asm"

You can also remove the file data/types/badge_type_boosts.asm, as it is now unreferenced.


The strength of your Pokémon is now on par with the ones controlled by the AI! Well, almost. The AI controlled Pokémon still can miss Status moves, have low DVs on average, no stat experience, no held items (apart from 3 trainer Pokémon), etc.

If you want to make the single-player adventure more fair/balanced/difficult, here are some tutorials you may want to look into: