Scale Gym Leader Teams Based on Number of Badges - pret/pokecrystal GitHub Wiki

Intro

The code for this feature is based on Pokémon Crystal Legacy.

This tutorial will show you how to scale a gym leader's team based on the player’s number of badges. This is handy when you have a set of leaders that can be tackled in any order and you want the challenge to scale based on the player’s progress.

A great example of where this could be applied to in vanilla Gen 2 is Chuck, Jasmine, and Pryce. Their teams are all around the same level, meaning the second and third leader are easily steamrolled, while the gym leader that comes after them jumps in level significantly.

This tutorial will teach you how to scale Pryce’s team as an example.

[!NOTE] If you're building something that requires teams to be defined for each gym badge, from 0 badges - to 16 badges (like an open world game where gyms can be tackled in any order), you can achieve that using this tutorial. However, a cleaner implementation for that specific solution is outlined in this tutorial. Specifically, follow the refactor section and the variable team section of that tutorial.

Overview of Code Changes We’ll Make

Let’s go over what we’ll be doing from a high level before diving in. First, we’ll define a team for each badge that we’d like to scale the leader to. Then, we’ll update the map script for the map where the gym leader is battled to load different teams based on the number of badges that the player has. That’s it!

1. Defining Team Constants

Edit constants/trainer_constants.asm

	trainerclass PRYCE ; 5
  const PRYCE1
+ const PRYCE2
+ const PRYCE3

PRYCE1 will be used for the battle for the 5th gym badge, PRYCE2 for the 6th, and PRYCE3 for the 7th.

2. Define Teams

Now, we’ll define the teams for each badge.

Please note that the changes I’ve provided below should be adjusted for your hack. The updates I’ve made are arbitrary and are not balanced.

Edit data/trainers/parties.asm

PryceGroup:
+	; PRYCE (1): Battle for the 5th gym badge
	db "PRYCE@", TRAINERTYPE_MOVES
	db 27, SEEL,       HEADBUTT, ICY_WIND, AURORA_BEAM, REST
	db 29, DEWGONG,    HEADBUTT, ICY_WIND, AURORA_BEAM, REST
	db 31, PILOSWINE,  ICY_WIND, FURY_ATTACK, MIST, BLIZZARD
	db -1 ; end
	
+ ; PRYCE (2): Battle for the 6th gym badge
+	db "PRYCE@", TRAINERTYPE_MOVES
+	db 31, SEEL,       HEADBUTT, ICY_WIND, AURORA_BEAM, REST
+	db 33, DEWGONG,    HEADBUTT, ICY_WIND, AURORA_BEAM, REST
+	db 35, PILOSWINE,  ICY_WIND, FURY_ATTACK, MIST, BLIZZARD
+	db -1 ; end

+ ; PRYCE (3): Battle for the 7th gym badge
+	db "PRYCE@", TRAINERTYPE_MOVES
+	db 35, DEWGONG,    HEADBUTT, ICY_WIND, AURORA_BEAM, REST
+	db 35, DEWGONG,    HEADBUTT, ICY_WIND, AURORA_BEAM, REST
+	db 37, PILOSWINE,  ICY_WIND, FURY_ATTACK, MIST, BLIZZARD
+	db -1 ; end

3. Update the Map Script

You battle Pryce for his gym badge in Mahogony Gym, so let’s update that map script.

Edit maps/MahoganyGym.asm

MahoganyGymPryceScript:
	faceplayer
	opentext
	checkevent EVENT_BEAT_PRYCE
	iftrue .FightDone
	writetext PryceText_Intro
	waitbutton
	closetext
	winlosstext PryceText_Impressed, 0
  readvar VAR_BADGES
+ ifequal 6, .LoadTeamForSeventhBadge
+ ifequal 5, .LoadTeamForSixthBadge
+ ifequal 4, .LoadTeamForFifthBadge
+.LoadTeamForFifthBadge:
	loadtrainer PRYCE, PRYCE1
+ sjump .FinishedLoadingTrainer
+.LoadTeamForSixthBadge:
+ loadtrainer PRYCE, 2
+ sjump .FinishedLoadingTrainer
+.LoadTeamForSeventhBadge:
+ loadtrainer PRYCE, 3
+.FinishedLoadingTrainer
	startbattle
	reloadmapafterbattle
	setevent EVENT_BEAT_PRYCE
	opentext
	writetext Text_ReceivedGlacierBadge
	playsound SFX_GET_BADGE
	waitsfx
	setflag ENGINE_GLACIERBADGE
	readvar VAR_BADGES
	scall MahoganyGymActivateRockets
.FightDone:
	checkevent EVENT_GOT_TM16_ICY_WIND
	iftrue PryceScript_Defeat
	setevent EVENT_BEAT_SKIER_ROXANNE
	setevent EVENT_BEAT_SKIER_CLARISSA
	setevent EVENT_BEAT_BOARDER_RONALD
	setevent EVENT_BEAT_BOARDER_BRAD
	setevent EVENT_BEAT_BOARDER_DOUGLAS
	writetext PryceText_GlacierBadgeSpeech
	promptbutton
	verbosegiveitem TM_ICY_WIND
	iffalse MahoganyGym_NoRoomForIcyWind
	setevent EVENT_GOT_TM16_ICY_WIND
	writetext PryceText_IcyWindSpeech
	waitbutton
	closetext
	end

Summary

And there you go! All that’s left is to update Chuck and Jasmine’s teams.

This approach can actually be applied to any trainer, not just gym leaders! Since defining a bunch of teams for each trainer would take up a lot of space, I would suggest only defining multiple teams for significant trainers like gym leaders, and using an alternative approach for other trainers. One example of a basic alternative approach would be to define a new scaling trainer type that adjusts each team member’s level based on the number of badges the player has. If you want to get fancy, you could even update the scaling code to use an evolved form based on its level.