Rewards For Beating Elite Four With And Owning Specific Pokemon by scolandrea - pret/pokeemerald GitHub Wiki

original source: "Tita reward by scolandrea"

scolandrea wrote some great code that rewards beating the Elite Four with a specific team, as well as owning specific pokemon in your party or PC (AKA living dex)

full credit for this goes to scolandrea, I only modified some of the code to:
make it easier to duplicate and add more challenges
fix issue where the game drops to 1fps after the Hall Of Fame registers the party
move the NPCs to the Pokemon League Center
change the rewards to a Mew and Jirachi for this tutorial

(This code doesn't use the new pokemon "Cosme" and "Tita" or the NPCs outside of your home)


For this tutorial, I've kept scolandrea's "Cat Challenge" as Challenge 1
To add more challenges, duplicate the sections/lines as advised below

This code adds two NPCs at the Pokemon League Center for a "quest": battle the league and become champion while only using a team of specific pokemon, and secondly owning specific pokemon (in this example, cat pokemon Meowth, Perisian, Skitty, Delcatty, Absol, Zangoose).


How To Add To Your Hack

pull from my git branch or add manually using the below code

git remote add tenaya15 https://github.com/tenaya15/tenaya15emerald.git
git pull tenaya15 scolandrea_challenge_rewards

compare branch

If you only want to add 1 of these features, see here: Using only 1 feature


data/scripts/league_challenge_reward.inc

create new file and add this code:

/*
Challenge 1 gift mon = SPECIES_MEW
*/

LCR_Challenge1_EventScript_NPC_Start::
	lock
	faceplayer
	goto_if_set FLAG_LCR_CHALLENGE1_REWARD, LCR_Challenge1_EventScript_AlreadyReceived
	goto_if_set FLAG_LCR_WON_WITH_CH1_MONS_ONLY, LCR_Challenge1_EventScript_GiveReward

/* use if you want the challenge on the first attempt only (before becoming champion for the first time)
	goto_if_set FLAG_IS_CHAMPION, LCR_Challenge1_EventScript_ChampionNotEligible
*/
	msgbox LCR_Challenge1_Text_WaitingForTrainer, MSGBOX_NPC
	release
	end

/* use if you want the challenge on the first attempt only (before becoming champion for the first time)
LCR_Challenge1_EventScript_ChampionNotEligible::
	msgbox LCR_Challenge1_Text_ChampionNotEligible, MSGBOX_NPC
	release
	end
*/

LCR_Challenge1_EventScript_GiveReward::
	bufferspeciesname STR_VAR_2, SPECIES_MEW
	msgbox LCR_Challenge1_Text_EligibleIntro, MSGBOX_DEFAULT
	closemessage
	setvar VAR_TEMP_TRANSFERRED_SPECIES, SPECIES_MEW
	specialvar VAR_RESULT, GiveLeagueChallenge1Reward
	goto_if_eq VAR_RESULT, MON_GIVEN_TO_PARTY, LCR_Challenge1_EventScript_ReceiveMonParty
	goto_if_eq VAR_RESULT, MON_GIVEN_TO_PC, LCR_Challenge1_EventScript_ReceiveMonPC
	goto Common_EventScript_NoMoreRoomForPokemon
	end

LCR_Challenge1_EventScript_ReceiveMonParty::
	call LCR_Challenge1_EventScript_ReceiveMonFanfare
	msgbox gText_NicknameThisPokemon, MSGBOX_YESNO
	goto_if_eq VAR_RESULT, NO, LCR_Challenge1_EventScript_FinishReward
	call Common_EventScript_GetGiftMonPartySlot
	call Common_EventScript_NameReceivedPartyMon
	goto LCR_Challenge1_EventScript_FinishReward
	end

LCR_Challenge1_EventScript_ReceiveMonPC::
	call LCR_Challenge1_EventScript_ReceiveMonFanfare
	msgbox gText_NicknameThisPokemon, MSGBOX_YESNO
	goto_if_eq VAR_RESULT, NO, LCR_Challenge1_EventScript_TransferMonToPC
	call Common_EventScript_NameReceivedBoxMon
	goto LCR_Challenge1_EventScript_TransferMonToPC
	end

LCR_Challenge1_EventScript_TransferMonToPC::
	call Common_EventScript_TransferredToPC
	goto LCR_Challenge1_EventScript_FinishReward
	end

LCR_Challenge1_EventScript_ReceiveMonFanfare::
	bufferspeciesname STR_VAR_2, SPECIES_MEW
	playfanfare MUS_OBTAIN_ITEM
	message LCR_Challenge1_Text_ObtainedMon
	waitmessage
	waitfanfare
	bufferspeciesname STR_VAR_1, SPECIES_MEW
	return

LCR_Challenge1_EventScript_FinishReward::
	setflag FLAG_LCR_CHALLENGE1_REWARD
	msgbox LCR_Challenge1_Text_AfterReward, MSGBOX_DEFAULT
	release
	end

LCR_Challenge1_EventScript_AlreadyReceived::
	msgbox LCR_Challenge1_Text_AlreadyReceived, MSGBOX_NPC
	release
	end

LCR_Challenge1_Text_WaitingForTrainer:
	.string "Ah, a young TRAINER!\p"
	.string "I've been waiting here for a feline\n"
	.string "TRAINER who would conquer the\l"
	.string "POKéMON LEAGUE.\p"
	.string "Only a team of cats, from start to\n"
	.string "finish, would prove worthy.\p"
	.string "When that day comes, I have a very\n"
	.string "special gift waiting…$"

/* use if you want the challenge on the first attempt only (before becoming champion for the first time)
LCR_Challenge1_Text_ChampionNotEligible:
	.string "So you became CHAMPION!\n"
	.string "Congratulations, truly.\p"
	.string "But the gift I keep is not for any\n"
	.string "champion.\p"
	.string "It belongs to one who entered the\n"
	.string "HALL OF FAME with nothing but\l"
	.string "feline partners at their side.$"
*/

LCR_Challenge1_Text_EligibleIntro:
	.string "Incredible…!\p"
	.string "You conquered the LEAGUE with a team\n"
	.string "of cats, just as I dreamed!\p"
	.string "Please, accept this {STR_VAR_2}.\n"
	.string "It has earned its place beside you!$"

LCR_Challenge1_Text_ObtainedMon:
	.string "{PLAYER} received a {STR_VAR_2}!$"

LCR_Challenge1_Text_AfterReward:
	.string "Raise that {STR_VAR_2} with pride.\n"
	.string "The feline spirit runs in your team!$"

LCR_Challenge1_Text_AlreadyReceived:
	.string "My gift is already in your care.\p"
	.string "May your cats keep prowling\n"
	.string "victoriously across HOENN!$"

To add more challenges: Duplicate all of the above and change 1 to 2


data/scripts/living_dex_reward.inc

create file and add this code:

/*
Challenge 1 = Jirachi
*/

LivingDexReward_EventScript_1_LivingDexNpc::
	lock
	faceplayer
	goto_if_set FLAG_RECEIVED_LIVING_DEX_1_REWARD, LivingDexReward_EventScript_1_AlreadyReceived
	specialvar VAR_RESULT, CountPlayerLivingDex1Species
	goto_if_eq VAR_RESULT, 6, LivingDexReward_EventScript_1_GiveReward
	buffernumberstring STR_VAR_1, VAR_RESULT
	msgbox LivingDexReward_Text_1_InProgress, MSGBOX_NPC
	release
	end

LivingDexReward_EventScript_1_GiveReward::
	bufferspeciesname STR_VAR_2, SPECIES_JIRACHI
	msgbox LivingDexReward_Text_1_EligibleIntro, MSGBOX_DEFAULT
	closemessage
	setvar VAR_TEMP_TRANSFERRED_SPECIES, SPECIES_JIRACHI
	specialvar VAR_RESULT, GiveLivingDex1Reward
	goto_if_eq VAR_RESULT, MON_GIVEN_TO_PARTY, LivingDexReward_EventScript_1_ReceiveMonParty
	goto_if_eq VAR_RESULT, MON_GIVEN_TO_PC, LivingDexReward_EventScript_1_ReceiveMonPC
	goto Common_EventScript_NoMoreRoomForPokemon
	end

LivingDexReward_EventScript_1_ReceiveMonParty::
	call LivingDexReward_EventScript_1_ReceiveMonFanfare
	msgbox gText_NicknameThisPokemon, MSGBOX_YESNO
	goto_if_eq VAR_RESULT, NO, LivingDexReward_EventScript_1_FinishReward
	call Common_EventScript_GetGiftMonPartySlot
	call Common_EventScript_NameReceivedPartyMon
	goto LivingDexReward_EventScript_1_FinishReward
	end

LivingDexReward_EventScript_1_ReceiveMonPC::
	call LivingDexReward_EventScript_1_ReceiveMonFanfare
	msgbox gText_NicknameThisPokemon, MSGBOX_YESNO
	goto_if_eq VAR_RESULT, NO, LivingDexReward_EventScript_1_TransferMonToPC
	call Common_EventScript_NameReceivedBoxMon
	goto LivingDexReward_EventScript_1_TransferMonToPC
	end

LivingDexReward_EventScript_1_TransferMonToPC::
	call Common_EventScript_TransferredToPC
	goto LivingDexReward_EventScript_1_FinishReward
	end

LivingDexReward_EventScript_1_ReceiveMonFanfare::
	bufferspeciesname STR_VAR_2, SPECIES_JIRACHI
	playfanfare MUS_OBTAIN_ITEM
	message LivingDexReward_Text_1_ObtainedMon
	waitmessage
	waitfanfare
	bufferspeciesname STR_VAR_1, SPECIES_JIRACHI
	return

LivingDexReward_EventScript_1_FinishReward::
	setflag FLAG_RECEIVED_LIVING_DEX_1_REWARD
	msgbox LivingDexReward_Text_1_AfterReward, MSGBOX_DEFAULT
	release
	end

LivingDexReward_EventScript_1_AlreadyReceived::
	bufferspeciesname STR_VAR_2, SPECIES_JIRACHI
	msgbox LivingDexReward_Text_1_AlreadyReceived, MSGBOX_NPC
	release
	end

LivingDexReward_Text_1_InProgress:
	.string "Ah, a TRAINER with an eye for cats!\p"
	.string "I'm cataloguing every feline native\n"
	.string "to HOENN.\p"
	.string "Bring me one of each: MEOWTH, PERSIAN,\n"
	.string "SKITTY, DELCATTY, ZANGOOSE, and ABSOL.\p"
	.string "They must be yours alone, caught or\n"
	.string "raised by you. No trades.\p"
	.string "You currently have {STR_VAR_1} of\n"
	.string "those six feline companions...$"

LivingDexReward_Text_1_EligibleIntro:
	.string "Marvelous...!\p"
	.string "You have gathered every wild cat of\n"
	.string "HOENN, each one truly your own!\p"
	.string "Please, accept this {STR_VAR_2}.\n"
	.string "She has waited patiently for a\l"
	.string "collector like you!$"

LivingDexReward_Text_1_ObtainedMon:
	.string "{PLAYER} received a {STR_VAR_2}!$"

LivingDexReward_Text_1_AfterReward:
	.string "Care for that {STR_VAR_2} gently.\n"
	.string "She prefers a warm nap after a job\l"
	.string "well done!$"

LivingDexReward_Text_1_AlreadyReceived:
	.string "My {STR_VAR_2} is already with you.\p"
	.string "Keep building your bond with every\n"
	.string "cat in HOENN!$"

To add more challenges: Duplicate the above line and change 1 to 2


data/scripts/hall_of_fame.inc

add in section EverGrandeCity_HallOfFame_EventScript_SetGameClearFlags:: before after setflag FLAG_IS_CHAMPION

	special CheckLeagueWonWithChallenge1MonsOnly

To add more challenges: Duplicate the above line and change 1 to 2


data/event_scripts.s

this links the new file into your code

add in the file at the end

	.include "data/scripts/league_challenge_reward.inc"
	.include "data/scripts/living_dex_reward.inc"

This does not need duplicated when adding more challenges


data/specials.inc

add to end of file

	def_special CheckLeagueWonWithChallenge1MonsOnly
	def_special GiveLeagueChallenge1Reward
	def_special CountPlayerLivingDex1Species
	def_special GiveLivingDex1Reward

To add more challenges: Duplicate all of the above and change 1 to 2


include/constants/flags.h

rename 3 flags for each "reward" quest (0x30 / 0x31 / 0x32 chosen for this example)

#define FLAG_LCR_WON_WITH_CH1_MONS_ONLY   0x30
#define FLAG_LCR_CHALLENGE1_REWARD        0x31
#define FLAG_RECEIVED_LIVING_DEX_1_REWARD 0x32

To add more challenges: Duplicate all of the above and change 1 to 2


include/league_challenge.h

create new file and add this code:

#ifndef GUARD_LEAGUE_CHALLENGE_H
#define GUARD_LEAGUE_CHALLENGE_H

#include "global.h"

bool8 IsChallenge1MonSpecies(u16 species);
void CheckLeagueWonWithChallenge1MonsOnly(void);
u16 GiveLeagueChallenge1Reward(void);
u8 CountPlayerLivingDex1Species(void);
u16 GiveLivingDex1Reward(void);

#endif // GUARD_LEAGUE_CHALLENGE_H

To add more challenges: Duplicate the 5 lines above starting bool8 / void / u16 / u8 / u16 and change 1 to 2


src/data/league_challenge_species.h

create new file and add this code:

#ifndef GUARD_LEAGUE_CHALLENGE_SPECIES_H
#define GUARD_LEAGUE_CHALLENGE_SPECIES_H

#include "constants/species.h"

// Challenge 1 base species.
// All species that evolve from these species are allowed.
static const u16 sChallenge1Species[] =
{
    SPECIES_MEOWTH,
    SPECIES_SKITTY,
    SPECIES_ZANGOOSE,
    SPECIES_ABSOL,
};

#endif // GUARD_LEAGUE_CHALLENGE_SPECIES_H

To add more challenges: Duplicate the sChallenge1Species section and change 1 to 2 and add any pokemon for the next challenge


src/league_challenge.c

create file and add this code:

#include "global.h"
#include "event_data.h"
#include "pokedex.h"
#include "pokemon.h"
#include "pokemon_storage_system.h"
#include "string_util.h"
#include "constants/flags.h"
#include "constants/moves.h"
#include "constants/pokemon.h"
#include "constants/species.h"
#include "data/league_challenge_species.h"
#include "league_challenge.h"
#include "tv.h"

extern const struct Evolution gEvolutionTable[][EVOS_PER_MON];

// doesn't need duplicated
static bool8 IsBoxMonOwnedByPlayer(struct BoxPokemon *boxMon)
{
    u32 otId;
    u8 otName[PLAYER_NAME_LENGTH + 1];

    if (GetBoxMonData(boxMon, MON_DATA_SPECIES) == SPECIES_NONE)
        return FALSE;

    if (GetBoxMonData(boxMon, MON_DATA_IS_EGG))
        return FALSE;

    otId = GetBoxMonData(boxMon, MON_DATA_OT_ID);
    if (otId != GetPlayerIDAsU32())
        return FALSE;

    GetBoxMonData(boxMon, MON_DATA_OT_NAME, otName);
    if (StringCompare(otName, gSaveBlock2Ptr->playerName) != 0)
        return FALSE;

    return TRUE;
}

// doesn't need duplicated
static bool8 PlayerOwnsSpecies(u16 species)
{
    u32 i;
    u32 j;

    for (i = 0; i < PARTY_SIZE; i++)
    {
        if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) == SPECIES_NONE)
            continue;

        if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) == species
            && IsBoxMonOwnedByPlayer(&gPlayerParty[i].box))
            return TRUE;
    }

    for (i = 0; i < TOTAL_BOXES_COUNT; i++)
    {
        for (j = 0; j < IN_BOX_COUNT; j++)
        {
            if (GetBoxMonData(&gPokemonStoragePtr->boxes[i][j], MON_DATA_SPECIES) == species
                && IsBoxMonOwnedByPlayer(&gPokemonStoragePtr->boxes[i][j]))
                return TRUE;
        }
    }

    return FALSE;
}

// doesn't need duplicated
static void SetRewardMonIv(struct Pokemon *mon, u8 stat, u8 ivConfig)
{
	u8 iv;

	if (ivConfig == USE_RANDOM_IVS)
		return;

	iv = ivConfig;
	SetMonData(mon, MON_DATA_HP_IV + stat, &iv);
}

// doesn't need duplicated
static void ApplyRewardMonIvs(struct Pokemon *mon, u8 hp, u8 atk, u8 def, u8 speed, u8 spAtk, u8 spDef)
{
	SetRewardMonIv(mon, STAT_HP, hp);
	SetRewardMonIv(mon, STAT_ATK, atk);
	SetRewardMonIv(mon, STAT_DEF, def);
	SetRewardMonIv(mon, STAT_SPEED, speed);
	SetRewardMonIv(mon, STAT_SPATK, spAtk);
	SetRewardMonIv(mon, STAT_SPDEF, spDef);
	CalculateMonStats(mon);
}


// DUPLICATE EVERYTHING BELOW TO CREATE MORE CHALLENGES AND CHANGE REFERENCES FROM "CHALLENGE 1" TO "CHALLENGE 2"

// Edit reward level and moves here
//challenge 1
#define CHALLENGE_1_REWARD_SPECIES   SPECIES_MEW
#define CHALLENGE_1_REWARD_LEVEL     60
#define CHALLENGE_1_REWARD_MOVE_1    MOVE_PSYCHIC
#define CHALLENGE_1_REWARD_MOVE_2    MOVE_THUNDERBOLT
#define CHALLENGE_1_REWARD_MOVE_3    MOVE_HYPER_BEAM
#define CHALLENGE_1_REWARD_MOVE_4    MOVE_DIG

#define CHALLENGE_1_REWARD_IV_HP     31
#define CHALLENGE_1_REWARD_IV_ATK    31
#define CHALLENGE_1_REWARD_IV_DEF    USE_RANDOM_IVS
#define CHALLENGE_1_REWARD_IV_SPEED  31
#define CHALLENGE_1_REWARD_IV_SPATK  31
#define CHALLENGE_1_REWARD_IV_SPDEF  USE_RANDOM_IVS

static EWRAM_DATA bool8 sChallenge1SpeciesCacheBuilt = FALSE;
static EWRAM_DATA bool8 sIsChallenge1MonSpecies[NUM_SPECIES];

// Living Dex Challenge 1 reward level and moves here
#define LIVING_DEX_REWARD_1_SPECIES    SPECIES_JIRACHI
#define LIVING_DEX_REWARD_1_LEVEL      60
#define LIVING_DEX_REWARD_1_MOVE_1     MOVE_REST
#define LIVING_DEX_REWARD_1_MOVE_2     MOVE_CONFUSION
#define LIVING_DEX_REWARD_1_MOVE_3     MOVE_PAY_DAY
#define LIVING_DEX_REWARD_1_MOVE_4     MOVE_WISH

// Use 0–31 for a fixed IV, or USE_RANDOM_IVS to leave that stat random. Change `MON_1_CUTE_RIBBON_RANK` to adjust the contest ribbon tier (`1`–`4`).
#define LIVING_DEX_REWARD_1_IV_HP      31
#define LIVING_DEX_REWARD_1_IV_ATK     31
#define LIVING_DEX_REWARD_1_IV_DEF     31
#define LIVING_DEX_REWARD_1_IV_SPEED   31
#define LIVING_DEX_REWARD_1_IV_SPATK   USE_RANDOM_IVS
#define LIVING_DEX_REWARD_1_IV_SPDEF   USE_RANDOM_IVS

#define MON_1_CUTE_RIBBON_RANK         4

// challenge 1 species
// only the specific pokemon stated here count
// evolutions must be stated here if they are to be counted
static const u16 sLivingDex1Species[] =
{
    SPECIES_MEOWTH,
    SPECIES_PERSIAN,
    SPECIES_SKITTY,
    SPECIES_DELCATTY,
    SPECIES_ZANGOOSE,
    SPECIES_ABSOL,
};

static void BuildChallenge1SpeciesCache(void)
{
	u16 queue[NUM_SPECIES];
	u16 head = 0;
	u16 tail = 0;
	u32 i;

	for (i = 0; i < NUM_SPECIES; i++)
		sIsChallenge1MonSpecies[i] = FALSE;

	for (i = 0; i < ARRAY_COUNT(sChallenge1Species); i++)
	{
		u16 species = sChallenge1Species[i];

		if (species == SPECIES_NONE || species >= NUM_SPECIES)
			continue;

		if (!sIsChallenge1MonSpecies[species])
		{
			sIsChallenge1MonSpecies[species] = TRUE;
			queue[tail++] = species;
		}
	}

	while (head < tail)
	{
		u16 current = queue[head++];
		u32 j;

		for (j = 0; j < EVOS_PER_MON; j++)
		{
			u16 evolution = gEvolutionTable[current][j].targetSpecies;

			if (evolution == SPECIES_NONE || evolution >= NUM_SPECIES)
				continue;

			if (!sIsChallenge1MonSpecies[evolution])
			{
				sIsChallenge1MonSpecies[evolution] = TRUE;
				queue[tail++] = evolution;
			}
		}
	}

	sChallenge1SpeciesCacheBuilt = TRUE;
}

bool8 IsChallenge1MonSpecies(u16 species)
{
	if (species == SPECIES_NONE || species == SPECIES_EGG || species >= NUM_SPECIES)
	{
		return FALSE;
	}

	if (!sChallenge1SpeciesCacheBuilt)
		BuildChallenge1SpeciesCache();

	return sIsChallenge1MonSpecies[species];
}

void CheckLeagueWonWithChallenge1MonsOnly(void)
{
	u32 i;
	bool8 hasMon = FALSE;

	// Reset first so a failed check can never leave a stale TRUE flag set.
	FlagClear(FLAG_LCR_WON_WITH_CH1_MONS_ONLY);

	for (i = 0; i < PARTY_SIZE; i++)
	{
		u16 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES_OR_EGG);

		if (species == SPECIES_NONE)
			continue;

		hasMon = TRUE;

		if (species == SPECIES_EGG || !IsChallenge1MonSpecies(species))
			return;
	}

	if (hasMon)
		FlagSet(FLAG_LCR_WON_WITH_CH1_MONS_ONLY);
}

static void ApplyChallenge1RewardTraits(struct Pokemon *mon)
{
	u8 ribbon = TRUE;

	ApplyRewardMonIvs(mon,
		CHALLENGE_1_REWARD_IV_HP,
		CHALLENGE_1_REWARD_IV_ATK,
		CHALLENGE_1_REWARD_IV_DEF,
		CHALLENGE_1_REWARD_IV_SPEED,
		CHALLENGE_1_REWARD_IV_SPATK,
		CHALLENGE_1_REWARD_IV_SPDEF);
	SetMonData(mon, MON_DATA_WINNING_RIBBON, &ribbon);
}

u16 GiveLeagueChallenge1Reward(void)
{
	struct Pokemon mon;
	u8 result;
	u16 nationalDexNum;

	CreateMon(&mon, CHALLENGE_1_REWARD_SPECIES, CHALLENGE_1_REWARD_LEVEL,
		USE_RANDOM_IVS, FALSE, 0, OT_ID_PLAYER_ID, 0);
	SetMonMoveSlot(&mon, CHALLENGE_1_REWARD_MOVE_1, 0);
	SetMonMoveSlot(&mon, CHALLENGE_1_REWARD_MOVE_2, 1);
	SetMonMoveSlot(&mon, CHALLENGE_1_REWARD_MOVE_3, 2);
	SetMonMoveSlot(&mon, CHALLENGE_1_REWARD_MOVE_4, 3);
	ApplyChallenge1RewardTraits(&mon);

	result = GiveMonToPlayer(&mon);
	nationalDexNum = SpeciesToNationalPokedexNum(CHALLENGE_1_REWARD_SPECIES);

	if (result == MON_GIVEN_TO_PARTY || result == MON_GIVEN_TO_PC)
	{
		GetSetPokedexFlag(nationalDexNum, FLAG_SET_SEEN);
		GetSetPokedexFlag(nationalDexNum, FLAG_SET_CAUGHT);
	}

	return result;
}

u8 CountPlayerLivingDex1Species(void)
{
    u32 i;
    u8 count = 0;

    for (i = 0; i < ARRAY_COUNT(sLivingDex1Species); i++)
    {
        if (PlayerOwnsSpecies(sLivingDex1Species[i]))
            count++;
    }

    return count;
}

static void ApplyMon1RewardTraits(struct Pokemon *mon)
{
    u8 cuteRibbon = MON_1_CUTE_RIBBON_RANK;

    ApplyRewardMonIvs(mon,
        LIVING_DEX_REWARD_1_IV_HP,
        LIVING_DEX_REWARD_1_IV_ATK,
        LIVING_DEX_REWARD_1_IV_DEF,
        LIVING_DEX_REWARD_1_IV_SPEED,
        LIVING_DEX_REWARD_1_IV_SPATK,
        LIVING_DEX_REWARD_1_IV_SPDEF);
    SetMonData(mon, MON_DATA_CUTE_RIBBON, &cuteRibbon);
}

u16 GiveLivingDex1Reward(void)
{
    struct Pokemon mon;
    u8 result;
    u16 nationalDexNum;

    CreateMon(&mon, LIVING_DEX_REWARD_1_SPECIES, LIVING_DEX_REWARD_1_LEVEL, USE_RANDOM_IVS, FALSE, 0, OT_ID_PLAYER_ID, 0);
    SetMonMoveSlot(&mon, LIVING_DEX_REWARD_1_MOVE_1, 0);
    SetMonMoveSlot(&mon, LIVING_DEX_REWARD_1_MOVE_2, 1);
    SetMonMoveSlot(&mon, LIVING_DEX_REWARD_1_MOVE_3, 2);
    SetMonMoveSlot(&mon, LIVING_DEX_REWARD_1_MOVE_4, 3);
    ApplyMon1RewardTraits(&mon);

    result = GiveMonToPlayer(&mon);
    nationalDexNum = SpeciesToNationalPokedexNum(LIVING_DEX_REWARD_1_SPECIES);

    if (result == MON_GIVEN_TO_PARTY || result == MON_GIVEN_TO_PC)
    {
        GetSetPokedexFlag(nationalDexNum, FLAG_SET_SEEN);
        GetSetPokedexFlag(nationalDexNum, FLAG_SET_CAUGHT);
    }

    return result;
}

To add more challenges: Duplicate all the sections, leaving out the ones that state "doesn't need duplicated", change all references from challenge 1 to 2 and change the gift Pokemon and moves


porymap

in your chosen maps, add two new NPC objects and set the scripts as:
LCR_Challenge1_EventScript_NPC_Start for the Elite Four challenge
LivingDexReward_EventScript_1_LivingDexNpc for the living dex challenge

To add more challenges: add another 2 NPC objects in your chosen maps


Using only 1 feature

If you only want to use 1 of these features, see these branches:

league challenge rewards only / compare

living dex reward only / compare