Merge branch 'upcoming' into ghoulsaveblock

This commit is contained in:
ghoulslash 2024-02-08 08:37:57 -05:00 committed by GitHub
commit 4bfe6d3c6d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 172515 additions and 520 deletions

View File

@ -984,16 +984,62 @@
.byte \textTop
.endm
@ Gives the player a Pokémon of the specified species and level, holding the specified item. The trailing 0s are unused parameters.
@ Gives the player a Pokémon of the specified species and level, and allows to customize extra parameters.
@ VAR_RESULT will be set to MON_GIVEN_TO_PARTY, MON_GIVEN_TO_PC, or MON_CANT_GIVE depending on the outcome.
.macro givemon species:req, level:req, item=ITEM_NONE
.byte 0x79
.macro givemon species:req, level:req, item, ball, nature, abilityNum, gender, hpEv, atkEv, defEv, speedEv, spAtkEv, spDefEv, hpIv, atkIv, defIv, speedIv, spAtkIv, spDefIv, move1, move2, move3, move4, isShiny, ggMaxFactor, teraType
callnative ScrCmd_givemon
.set givemon_flags, 0
.2byte \species
.byte \level
.2byte \item
.4byte 0
.4byte 0
.byte 0
.2byte \level
.ifnb \item; .set givemon_flags, givemon_flags | (1 << 0); .endif
.ifnb \ball; .set givemon_flags, givemon_flags | (1 << 1); .endif
.ifnb \nature; .set givemon_flags, givemon_flags | (1 << 2); .endif
.ifnb \abilityNum; .set givemon_flags, givemon_flags | (1 << 3); .endif
.ifnb \gender; .set givemon_flags, givemon_flags | (1 << 4); .endif
.ifnb \hpEv; .set givemon_flags, givemon_flags | (1 << 5); .endif
.ifnb \atkEv; .set givemon_flags, givemon_flags | (1 << 6); .endif
.ifnb \defEv; .set givemon_flags, givemon_flags | (1 << 7); .endif
.ifnb \speedEv; .set givemon_flags, givemon_flags | (1 << 8); .endif
.ifnb \spAtkEv; .set givemon_flags, givemon_flags | (1 << 9); .endif
.ifnb \spDefEv; .set givemon_flags, givemon_flags | (1 << 10); .endif
.ifnb \hpIv; .set givemon_flags, givemon_flags | (1 << 11); .endif
.ifnb \atkIv; .set givemon_flags, givemon_flags | (1 << 12); .endif
.ifnb \defIv; .set givemon_flags, givemon_flags | (1 << 13); .endif
.ifnb \speedIv; .set givemon_flags, givemon_flags | (1 << 14); .endif
.ifnb \spAtkIv; .set givemon_flags, givemon_flags | (1 << 15); .endif
.ifnb \spDefIv; .set givemon_flags, givemon_flags | (1 << 16); .endif
.ifnb \move1; .set givemon_flags, givemon_flags | (1 << 17); .endif
.ifnb \move2; .set givemon_flags, givemon_flags | (1 << 18); .endif
.ifnb \move3; .set givemon_flags, givemon_flags | (1 << 19); .endif
.ifnb \move4; .set givemon_flags, givemon_flags | (1 << 20); .endif
.ifnb \isShiny; .set givemon_flags, givemon_flags | (1 << 21); .endif
.ifnb \ggMaxFactor; .set givemon_flags, givemon_flags | (1 << 22); .endif
.ifnb \teraType; .set givemon_flags, givemon_flags | (1 << 23); .endif
.4byte givemon_flags
.ifnb \item; .2byte \item; .endif
.ifnb \ball; .2byte \ball; .endif
.ifnb \nature; .2byte \nature; .endif
.ifnb \abilityNum; .2byte \abilityNum; .endif
.ifnb \gender; .2byte \gender; .endif
.ifnb \hpEv; .2byte \hpEv; .endif
.ifnb \atkEv; .2byte \atkEv; .endif
.ifnb \defEv; .2byte \defEv; .endif
.ifnb \speedEv; .2byte \speedEv; .endif
.ifnb \spAtkEv; .2byte \spAtkEv; .endif
.ifnb \spDefEv; .2byte \spDefEv; .endif
.ifnb \hpIv; .2byte \hpIv; .endif
.ifnb \atkIv; .2byte \atkIv; .endif
.ifnb \defIv; .2byte \defIv; .endif
.ifnb \speedIv; .2byte \speedIv; .endif
.ifnb \spAtkIv; .2byte \spAtkIv; .endif
.ifnb \spDefIv; .2byte \spDefIv; .endif
.ifnb \move1; .2byte \move1; .endif
.ifnb \move2; .2byte \move2; .endif
.ifnb \move3; .2byte \move3; .endif
.ifnb \move4; .2byte \move4; .endif
.ifnb \isShiny; .2byte \isShiny; .endif
.ifnb \ggMaxFactor; .2byte \ggMaxFactor; .endif
.ifnb \teraType; .2byte \teraType; .endif
.endm
@ Gives the player an Egg of the specified species.

View File

@ -121,7 +121,7 @@ gScriptCmdTable::
.4byte ScrCmd_hidemonpic @ 0x76
.4byte ScrCmd_showcontestpainting @ 0x77
.4byte ScrCmd_braillemessage @ 0x78
.4byte ScrCmd_givemon @ 0x79
.4byte ScrCmd_nop1 @ 0x79
.4byte ScrCmd_giveegg @ 0x7a
.4byte ScrCmd_setmonmove @ 0x7b
.4byte ScrCmd_checkpartymove @ 0x7c

View File

@ -95,6 +95,48 @@ Debug_BoxFilledMessage::
Debug_BoxFilledMessage_Text:
.string "Storage boxes filled!$"
Debug_EventScript_CheckEV::
lockall
getpartysize
goto_if_eq VAR_RESULT, 0, Debug_HatchAnEgg_NoPokemon
special ChoosePartyMon
waitstate
goto_if_ge VAR_0x8004, PARTY_SIZE, Debug_EventScript_CheckEV_End
callnative Script_GetChosenMonOffensiveEV
msgbox Debug_EventScript_Text_OffensiveEV, MSGBOX_DEFAULT
callnative Script_GetChosenMonDefensiveEV
msgbox Debug_EventScript_Text_DefensiveEV, MSGBOX_DEFAULT
Debug_EventScript_CheckEV_End::
releaseall
end
Debug_EventScript_Text_OffensiveEV:
.string "ATK EV: {STR_VAR_1}, SPATK EV: {STR_VAR_2}, SPEED EV: {STR_VAR_3}$"
Debug_EventScript_Text_DefensiveEV:
.string "HP EV: {STR_VAR_1}, DEF EV: {STR_VAR_2}, SPDEF EV: {STR_VAR_3}$"
Debug_EventScript_CheckIV::
lockall
getpartysize
goto_if_eq VAR_RESULT, 0, Debug_HatchAnEgg_NoPokemon
special ChoosePartyMon
waitstate
goto_if_ge VAR_0x8004, PARTY_SIZE, Debug_EventScript_CheckIV_End
callnative Script_GetChosenMonOffensiveIV
msgbox Debug_EventScript_Text_OffensiveIV, MSGBOX_DEFAULT
callnative Script_GetChosenMonDefensiveIV
msgbox Debug_EventScript_Text_DefensiveIV, MSGBOX_DEFAULT
Debug_EventScript_CheckIV_End::
releaseall
end
Debug_EventScript_Text_OffensiveIV:
.string "ATK IV: {STR_VAR_1}, SPATK IV: {STR_VAR_2}, SPEED IV: {STR_VAR_3}$"
Debug_EventScript_Text_DefensiveIV:
.string "HP IV: {STR_VAR_1}, DEF IV: {STR_VAR_2}, SPDEF IV: {STR_VAR_3}$"
Debug_EventScript_Script_1::
end
@ -247,4 +289,3 @@ Debug_FlagsAndVarNotSetBattleConfigMessage_Text:
.string "Feature unavailable! Please define a\n"
.string "usable flag and a usable var in:\l"
.string "'include/config/battle.h'!$"

View File

@ -550,3 +550,7 @@ gSpecials::
def_special ObjectEventInteractionBerryHasWeed
def_special ObjectEventInteractionBerryHasPests
def_special CanWaterBerryPlot
def_special Script_GetChosenMonOffensiveEV
def_special Script_GetChosenMonDefensiveEV
def_special Script_GetChosenMonOffensiveIV
def_special Script_GetChosenMonDefensiveIV

View File

@ -10,6 +10,14 @@
#define P_UPDATED_EVS GEN_LATEST // Some Pokémon have received EV updates after their introduction.
#define P_UPDATED_EXP_YIELDS GEN_LATEST // Since Gen 5, some Pokémon have received base Experience changes.
// Learnsets
#define P_LVL_UP_LEARNSETS GEN_LATEST // Choose which set of Level Up Learnsets to use.
// For generations that hadn't introduced a species yet, we use their first appearence (eg. Chikorita's Gen2 data if the config is set to GEN_1).
// For generations that don't include a previously introduced species, we use their last apperance (eg. Snivy's Gen7 data if the config is set to GEN_8).
// GEN_1/2/3/4/5/6/7: Yellow, Crystal, RSE, HGSS, B2W2, XY, USUM learnsets respectively.
// GEN_8: Use the following priority: BDSP for Gen1-4 Pokémon, then LA for species introduced in that game, then SwSh for species present in those games. Otherwise, use GEN_7.
// GEN_9: SV For species present in those games. Otherwise use GEN_8.
// Evolution settings
#define P_FRIENDSHIP_EVO_THRESHOLD GEN_LATEST // Since Gen 8, Pokémon that evolve by friendship evolve at or above 160 friendship instead of 220.

View File

@ -1,12 +1,17 @@
#ifndef GUARD_SCRIPT_POKEMON_UTIL_H
#define GUARD_SCRIPT_POKEMON_UTIL_H
u8 ScriptGiveMon(u16, u8, u16, u32, u32, u8);
u32 ScriptGiveMon(u16, u8, u16);
u32 ScriptGiveMonParameterized(u16, u8, u16, u8, u8, u8, u8, u8 *, u8 *, u16 *, bool8, bool8, u8);
u8 ScriptGiveEgg(u16);
void CreateScriptedWildMon(u16, u8, u16);
void CreateScriptedDoubleWildMon(u16, u8, u16, u16, u8, u16);
void ScriptSetMonMoveSlot(u8, u16, u8);
void ReducePlayerPartyToSelectedMons(void);
void HealPlayerParty(void);
void Script_GetChosenMonOffensiveEV(void);
void Script_GetChosenMonDefensiveEV(void);
void Script_GetChosenMonOffensiveIV(void);
void Script_GetChosenMonDefensiveIV(void);
#endif // GUARD_SCRIPT_POKEMON_UTIL_H

View File

@ -968,7 +968,7 @@ static void CB2_GiveStarter(void)
*GetVarPointer(VAR_STARTER_MON) = gSpecialVar_Result;
starterMon = GetStarterPokemon(gSpecialVar_Result);
ScriptGiveMon(starterMon, 5, ITEM_NONE, 0, 0, 0);
ScriptGiveMon(starterMon, 5, ITEM_NONE);
ResetTasks();
PlayBattleBGM();
SetMainCallback2(CB2_StartFirstBattle);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -127,6 +127,9 @@ enum PartyDebugMenu
DEBUG_PARTY_MENU_ITEM_HATCH_AN_EGG,
DEBUG_PARTY_MENU_ITEM_HEAL_PARTY,
DEBUG_PARTY_MENU_ITEM_POISON_MONS,
DEBUG_PARTY_MENU_ITEM_CHECK_EV,
DEBUG_PARTY_MENU_ITEM_CHECK_IV,
DEBUG_PARTY_MENU_ITEM_CLEAR_PARTY,
};
enum ScriptDebugMenu
@ -389,6 +392,9 @@ static void DebugAction_Party_MoveReminder(u8 taskId);
static void DebugAction_Party_HatchAnEgg(u8 taskId);
static void DebugAction_Party_HealParty(u8 taskId);
static void DebugAction_Party_PoisonMons(u8 taskId);
static void DebugAction_Party_CheckEV(u8 taskId);
static void DebugAction_Party_CheckIV(u8 taskId);
static void DebugAction_Party_ClearParty(u8 taskId);
static void DebugAction_FlagsVars_Flags(u8 taskId);
static void DebugAction_FlagsVars_FlagsSelect(u8 taskId);
@ -446,6 +452,8 @@ static void DebugAction_BerryFunctions_Weeds(u8 taskId);
extern const u8 Debug_FlagsNotSetOverworldConfigMessage[];
extern const u8 Debug_FlagsNotSetBattleConfigMessage[];
extern const u8 Debug_FlagsAndVarNotSetBattleConfigMessage[];
extern const u8 Debug_EventScript_CheckEV[];
extern const u8 Debug_EventScript_CheckIV[];
extern const u8 Debug_EventScript_Script_1[];
extern const u8 Debug_EventScript_Script_2[];
extern const u8 Debug_EventScript_Script_3[];
@ -541,6 +549,9 @@ static const u8 sDebugText_Party_MoveReminder[] = _("Move Reminder");
static const u8 sDebugText_Party_HatchAnEgg[] = _("Hatch an Egg");
static const u8 sDebugText_Party_HealParty[] = _("Heal party");
static const u8 sDebugText_Party_PoisonParty[] = _("Poison party");
static const u8 sDebugText_Party_CheckEV[] = _("Check EV");
static const u8 sDebugText_Party_CheckIV[] = _("Check IV");
static const u8 sDebugText_Party_ClearParty[] = _("Clear Party");
// Flags/Vars Menu
static const u8 sDebugText_FlagsVars_Flags[] = _("Set Flag XYZ…{CLEAR_TO 110}{RIGHT_ARROW}");
static const u8 sDebugText_FlagsVars_Flag[] = _("Flag: {STR_VAR_1}{CLEAR_TO 90}\n{STR_VAR_2}{CLEAR_TO 90}\n{STR_VAR_3}");
@ -736,6 +747,9 @@ static const struct ListMenuItem sDebugMenu_Items_Party[] =
[DEBUG_PARTY_MENU_ITEM_HATCH_AN_EGG] = {sDebugText_Party_HatchAnEgg, DEBUG_PARTY_MENU_ITEM_HATCH_AN_EGG},
[DEBUG_PARTY_MENU_ITEM_HEAL_PARTY] = {sDebugText_Party_HealParty, DEBUG_PARTY_MENU_ITEM_HEAL_PARTY},
[DEBUG_PARTY_MENU_ITEM_POISON_MONS] = {sDebugText_Party_PoisonParty, DEBUG_PARTY_MENU_ITEM_POISON_MONS},
[DEBUG_PARTY_MENU_ITEM_CHECK_EV] = {sDebugText_Party_CheckEV, DEBUG_PARTY_MENU_ITEM_CHECK_EV},
[DEBUG_PARTY_MENU_ITEM_CHECK_IV] = {sDebugText_Party_CheckIV, DEBUG_PARTY_MENU_ITEM_CHECK_IV},
[DEBUG_PARTY_MENU_ITEM_CLEAR_PARTY] = {sDebugText_Party_ClearParty, DEBUG_PARTY_MENU_ITEM_CLEAR_PARTY},
};
static const struct ListMenuItem sDebugMenu_Items_Scripts[] =
@ -902,6 +916,9 @@ static void (*const sDebugMenu_Actions_Party[])(u8) =
[DEBUG_PARTY_MENU_ITEM_HATCH_AN_EGG] = DebugAction_Party_HatchAnEgg,
[DEBUG_PARTY_MENU_ITEM_HEAL_PARTY] = DebugAction_Party_HealParty,
[DEBUG_PARTY_MENU_ITEM_POISON_MONS] = DebugAction_Party_PoisonMons,
[DEBUG_PARTY_MENU_ITEM_CHECK_EV] = DebugAction_Party_CheckEV,
[DEBUG_PARTY_MENU_ITEM_CHECK_IV] = DebugAction_Party_CheckIV,
[DEBUG_PARTY_MENU_ITEM_CLEAR_PARTY] = DebugAction_Party_ClearParty,
};
static void (*const sDebugMenu_Actions_Scripts[])(u8) =
@ -3277,7 +3294,7 @@ static void DebugAction_Give_Pokemon_SelectLevel(u8 taskId)
if (gTasks[taskId].tIsComplex == FALSE)
{
PlaySE(MUS_LEVEL_UP);
ScriptGiveMon(sDebugMonData->species, gTasks[taskId].tInput, ITEM_NONE, 0, 0, 0);
ScriptGiveMon(sDebugMonData->species, gTasks[taskId].tInput, ITEM_NONE);
// Set flag for user convenience
FlagSet(FLAG_SYS_POKEMON_GET);
Free(sDebugMonData);
@ -5075,4 +5092,21 @@ static void DebugAction_Party_PoisonMons(u8 taskId)
Debug_DestroyMenu_Full(taskId);
}
static void DebugAction_Party_CheckEV(u8 taskId)
{
Debug_DestroyMenu_Full_Script(taskId, Debug_EventScript_CheckEV);
}
static void DebugAction_Party_CheckIV(u8 taskId)
{
Debug_DestroyMenu_Full_Script(taskId, Debug_EventScript_CheckIV);
}
static void DebugAction_Party_ClearParty(u8 taskId)
{
ZeroPlayerPartyMons();
ScriptContext_Enable();
Debug_DestroyMenu_Full(taskId);
}
#endif //DEBUG_OVERWORLD_MENU == TRUE

View File

@ -420,7 +420,27 @@ const s8 gNatureStatTable[NUM_NATURES][NUM_NATURE_STATS] =
#include "data/pokemon/trainer_class_lookups.h"
#include "data/pokemon/experience_tables.h"
#include "data/pokemon/level_up_learnsets.h"
#if P_LVL_UP_LEARNSETS >= GEN_9
#include "data/pokemon/level_up_learnsets/gen_9.h"
#elif P_LVL_UP_LEARNSETS >= GEN_8
#include "data/pokemon/level_up_learnsets/gen_8.h"
#elif P_LVL_UP_LEARNSETS >= GEN_7
#include "data/pokemon/level_up_learnsets/gen_7.h"
#elif P_LVL_UP_LEARNSETS >= GEN_6
#include "data/pokemon/level_up_learnsets/gen_6.h"
#elif P_LVL_UP_LEARNSETS >= GEN_5
#include "data/pokemon/level_up_learnsets/gen_5.h"
#elif P_LVL_UP_LEARNSETS >= GEN_4
#include "data/pokemon/level_up_learnsets/gen_4.h"
#elif P_LVL_UP_LEARNSETS >= GEN_3
#include "data/pokemon/level_up_learnsets/gen_3.h"
#elif P_LVL_UP_LEARNSETS >= GEN_2
#include "data/pokemon/level_up_learnsets/gen_2.h"
#elif P_LVL_UP_LEARNSETS >= GEN_1
#include "data/pokemon/level_up_learnsets/gen_1.h"
#endif
#include "data/pokemon/teachable_learnsets.h"
#include "data/pokemon/form_species_tables.h"
#include "data/pokemon/form_change_tables.h"

View File

@ -1777,19 +1777,6 @@ bool8 ScrCmd_bufferboxname(struct ScriptContext *ctx)
return FALSE;
}
bool8 ScrCmd_givemon(struct ScriptContext *ctx)
{
u16 species = VarGet(ScriptReadHalfword(ctx));
u8 level = ScriptReadByte(ctx);
u16 item = VarGet(ScriptReadHalfword(ctx));
u32 unkParam1 = ScriptReadWord(ctx);
u32 unkParam2 = ScriptReadWord(ctx);
u8 unkParam3 = ScriptReadByte(ctx);
gSpecialVar_Result = ScriptGiveMon(species, level, item, unkParam1, unkParam2, unkParam3);
return FALSE;
}
bool8 ScrCmd_giveegg(struct ScriptContext *ctx)
{
u16 species = VarGet(ScriptReadHalfword(ctx));

View File

@ -23,6 +23,7 @@
#include "string_util.h"
#include "tv.h"
#include "wild_encounter.h"
#include "constants/abilities.h"
#include "constants/items.h"
#include "constants/battle_frontier.h"
@ -55,46 +56,6 @@ static void HealPlayerBoxes(void)
}
}
u8 ScriptGiveMon(u16 species, u8 level, u16 item, u32 unused1, u32 unused2, u8 unused3)
{
u16 nationalDexNum;
int sentToPc;
u8 heldItem[2];
struct Pokemon mon;
u16 targetSpecies;
if (OW_SYNCHRONIZE_NATURE >= GEN_6 && (gSpeciesInfo[species].eggGroups[0] == EGG_GROUP_NO_EGGS_DISCOVERED || OW_SYNCHRONIZE_NATURE == GEN_7))
CreateMonWithNature(&mon, species, level, USE_RANDOM_IVS, PickWildMonNature());
else
CreateMon(&mon, species, level, USE_RANDOM_IVS, FALSE, 0, OT_ID_PLAYER_ID, 0);
heldItem[0] = item;
heldItem[1] = item >> 8;
SetMonData(&mon, MON_DATA_HELD_ITEM, heldItem);
// In case a mon with a form changing item is given. Eg: SPECIES_ARCEUS_NORMAL with ITEM_SPLASH_PLATE will transform into SPECIES_ARCEUS_WATER upon gifted.
targetSpecies = GetFormChangeTargetSpecies(&mon, FORM_CHANGE_ITEM_HOLD, 0);
if (targetSpecies != SPECIES_NONE)
{
SetMonData(&mon, MON_DATA_SPECIES, &targetSpecies);
CalculateMonStats(&mon);
}
sentToPc = GiveMonToPlayer(&mon);
nationalDexNum = SpeciesToNationalPokedexNum(species);
// Don't set Pokédex flag for MON_CANT_GIVE
switch(sentToPc)
{
case MON_GIVEN_TO_PARTY:
case MON_GIVEN_TO_PC:
GetSetPokedexFlag(nationalDexNum, FLAG_SET_SEEN);
GetSetPokedexFlag(nationalDexNum, FLAG_SET_CAUGHT);
break;
}
return sentToPc;
}
u8 ScriptGiveEgg(u16 species)
{
struct Pokemon mon;
@ -327,3 +288,197 @@ void ToggleGigantamaxFactor(struct ScriptContext *ctx)
gSpecialVar_Result = TRUE;
}
}
u32 ScriptGiveMonParameterized(u16 species, u8 level, u16 item, u8 ball, u8 nature, u8 abilityNum, u8 gender, u8 *evs, u8 *ivs, u16 *moves, bool8 isShiny, bool8 ggMaxFactor, u8 teraType)
{
u16 nationalDexNum;
int sentToPc;
struct Pokemon mon;
u32 i;
u8 genderRatio = gSpeciesInfo[species].genderRatio;
u16 targetSpecies;
// check whether to use a specific nature or a random one
if (OW_SYNCHRONIZE_NATURE >= GEN_6 && (gSpeciesInfo[species].eggGroups[0] == EGG_GROUP_NO_EGGS_DISCOVERED || OW_SYNCHRONIZE_NATURE == GEN_7))
nature = PickWildMonNature();
else if (nature >= NUM_NATURES)
nature = Random() % NUM_NATURES;
// create a Pokémon with basic data
if ((gender == MON_MALE && genderRatio != MON_FEMALE && genderRatio != MON_GENDERLESS)
|| (gender == MON_FEMALE && genderRatio != MON_MALE && genderRatio != MON_GENDERLESS)
|| (gender == MON_GENDERLESS && genderRatio == MON_GENDERLESS))
CreateMonWithGenderNatureLetter(&mon, species, level, 32, gender, nature, 0);
else
CreateMonWithNature(&mon, species, level, 32, nature);
// shininess
SetMonData(&mon, MON_DATA_IS_SHINY, &isShiny);
// gigantamax factor
SetMonData(&mon, MON_DATA_GIGANTAMAX_FACTOR, &ggMaxFactor);
// tera type
if (teraType >= NUMBER_OF_MON_TYPES)
teraType = gSpeciesInfo[species].types[0];
SetMonData(&mon, MON_DATA_TERA_TYPE, &teraType);
// EV and IV
for (i = 0; i < NUM_STATS; i++)
{
// EV
if (evs[i] <= MAX_PER_STAT_EVS)
SetMonData(&mon, MON_DATA_HP_EV + i, &evs[i]);
// IV
if (ivs[i] <= MAX_PER_STAT_IVS)
SetMonData(&mon, MON_DATA_HP_IV + i, &ivs[i]);
}
CalculateMonStats(&mon);
// moves
for (i = 0; i < MAX_MON_MOVES; i++)
{
if (moves[i] == MOVE_NONE || moves[i] >= MOVES_COUNT)
continue;
SetMonMoveSlot(&mon, moves[i], i);
}
// ability
if (abilityNum >= NUM_ABILITY_SLOTS || GetAbilityBySpecies(species, abilityNum) == ABILITY_NONE)
{
do {
abilityNum = Random() % NUM_ABILITY_SLOTS; // includes hidden abilities
} while (GetAbilityBySpecies(species, abilityNum) == ABILITY_NONE);
}
SetMonData(&mon, MON_DATA_ABILITY_NUM, &abilityNum);
// ball
if (ball >= POKEBALL_COUNT)
ball = ITEM_POKE_BALL;
SetMonData(&mon, MON_DATA_POKEBALL, &ball);
// held item
SetMonData(&mon, MON_DATA_HELD_ITEM, &item);
// In case a mon with a form changing item is given. Eg: SPECIES_ARCEUS_NORMAL with ITEM_SPLASH_PLATE will transform into SPECIES_ARCEUS_WATER upon gifted.
targetSpecies = GetFormChangeTargetSpecies(&mon, FORM_CHANGE_ITEM_HOLD, 0);
if (targetSpecies != SPECIES_NONE)
SetMonData(&mon, MON_DATA_SPECIES, &targetSpecies);
// assign OT name and gender
SetMonData(&mon, MON_DATA_OT_NAME, gSaveBlock2Ptr->playerName);
SetMonData(&mon, MON_DATA_OT_GENDER, &gSaveBlock2Ptr->playerGender);
// find empty party slot to decide whether the Pokémon goes to the Player's party or the storage system.
for (i = 0; i < PARTY_SIZE; i++)
{
if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) == SPECIES_NONE)
break;
}
if (i >= PARTY_SIZE)
{
sentToPc = CopyMonToPC(&mon);
}
else
{
sentToPc = MON_GIVEN_TO_PARTY;
CopyMon(&gPlayerParty[i], &mon, sizeof(mon));
gPlayerPartyCount = i + 1;
}
// set pokédex flags
nationalDexNum = SpeciesToNationalPokedexNum(species);
switch (sentToPc)
{
case MON_GIVEN_TO_PARTY:
case MON_GIVEN_TO_PC:
GetSetPokedexFlag(nationalDexNum, FLAG_SET_SEEN);
GetSetPokedexFlag(nationalDexNum, FLAG_SET_CAUGHT);
break;
case MON_CANT_GIVE:
break;
}
return sentToPc;
}
u32 ScriptGiveMon(u16 species, u8 level, u16 item)
{
u8 evs[NUM_STATS] = {0, 0, 0, 0, 0, 0};
u8 ivs[NUM_STATS] = {MAX_PER_STAT_IVS + 1, MAX_PER_STAT_IVS + 1, MAX_PER_STAT_IVS + 1, // We pass "MAX_PER_STAT_IVS + 1" here to ensure that
MAX_PER_STAT_IVS + 1, MAX_PER_STAT_IVS + 1, MAX_PER_STAT_IVS + 1}; // ScriptGiveMonParameterized won't touch the stats' IV.
u16 moves[MAX_MON_MOVES] = {MOVE_NONE, MOVE_NONE, MOVE_NONE, MOVE_NONE};
return ScriptGiveMonParameterized(species, level, item, ITEM_POKE_BALL, NUM_NATURES, NUM_ABILITY_SLOTS, MON_GENDERLESS, evs, ivs, moves, FALSE, FALSE, NUMBER_OF_MON_TYPES);
}
#define PARSE_FLAG(n, default_) (flags & (1 << (n))) ? VarGet(ScriptReadHalfword(ctx)) : (default_)
void ScrCmd_givemon(struct ScriptContext *ctx)
{
u16 species = VarGet(ScriptReadHalfword(ctx));
u8 level = VarGet(ScriptReadHalfword(ctx));
u32 flags = ScriptReadWord(ctx);
u16 item = PARSE_FLAG(0, ITEM_NONE);
u8 ball = PARSE_FLAG(1, ITEM_POKE_BALL);
u8 nature = PARSE_FLAG(2, NUM_NATURES);
u8 abilityNum = PARSE_FLAG(3, NUM_ABILITY_SLOTS);
u8 gender = PARSE_FLAG(4, MON_GENDERLESS); // TODO: Find a better way to assign a random gender.
u8 hpEv = PARSE_FLAG(5, 0);
u8 atkEv = PARSE_FLAG(6, 0);
u8 defEv = PARSE_FLAG(7, 0);
u8 speedEv = PARSE_FLAG(8, 0);
u8 spAtkEv = PARSE_FLAG(9, 0);
u8 spDefEv = PARSE_FLAG(10, 0);
u8 hpIv = PARSE_FLAG(11, Random() % MAX_PER_STAT_IVS + 1);
u8 atkIv = PARSE_FLAG(12, Random() % MAX_PER_STAT_IVS + 1);
u8 defIv = PARSE_FLAG(13, Random() % MAX_PER_STAT_IVS + 1);
u8 speedIv = PARSE_FLAG(14, Random() % MAX_PER_STAT_IVS + 1);
u8 spAtkIv = PARSE_FLAG(15, Random() % MAX_PER_STAT_IVS + 1);
u8 spDefIv = PARSE_FLAG(16, Random() % MAX_PER_STAT_IVS + 1);
u16 move1 = PARSE_FLAG(17, MOVE_NONE);
u16 move2 = PARSE_FLAG(18, MOVE_NONE);
u16 move3 = PARSE_FLAG(19, MOVE_NONE);
u16 move4 = PARSE_FLAG(20, MOVE_NONE);
bool8 isShiny = PARSE_FLAG(21, FALSE);
bool8 ggMaxFactor = PARSE_FLAG(22, FALSE);
u8 teraType = PARSE_FLAG(23, NUMBER_OF_MON_TYPES);
u8 evs[NUM_STATS] = {hpEv, atkEv, defEv, speedEv, spAtkEv, spDefEv};
u8 ivs[NUM_STATS] = {hpIv, atkIv, defIv, speedIv, spAtkIv, spDefIv};
u16 moves[MAX_MON_MOVES] = {move1, move2, move3, move4};
gSpecialVar_Result = ScriptGiveMonParameterized(species, level, item, ball, nature, abilityNum, gender, evs, ivs, moves, isShiny, ggMaxFactor, teraType);
}
#undef PARSE_FLAG
void Script_GetChosenMonOffensiveEV(void)
{
ConvertIntToDecimalStringN(gStringVar1, GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_ATK_EV), STR_CONV_MODE_LEFT_ALIGN, 3);
ConvertIntToDecimalStringN(gStringVar2, GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPATK_EV), STR_CONV_MODE_LEFT_ALIGN, 3);
ConvertIntToDecimalStringN(gStringVar3, GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPEED_EV), STR_CONV_MODE_LEFT_ALIGN, 3);
}
void Script_GetChosenMonDefensiveEV(void)
{
ConvertIntToDecimalStringN(gStringVar1, GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_HP_EV), STR_CONV_MODE_LEFT_ALIGN, 3);
ConvertIntToDecimalStringN(gStringVar2, GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_DEF_EV), STR_CONV_MODE_LEFT_ALIGN, 3);
ConvertIntToDecimalStringN(gStringVar3, GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPDEF_EV), STR_CONV_MODE_LEFT_ALIGN, 3);
}
void Script_GetChosenMonOffensiveIV(void)
{
ConvertIntToDecimalStringN(gStringVar1, GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_ATK_IV), STR_CONV_MODE_LEFT_ALIGN, 3);
ConvertIntToDecimalStringN(gStringVar2, GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPATK_IV), STR_CONV_MODE_LEFT_ALIGN, 3);
ConvertIntToDecimalStringN(gStringVar3, GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPEED_IV), STR_CONV_MODE_LEFT_ALIGN, 3);
}
void Script_GetChosenMonDefensiveIV(void)
{
ConvertIntToDecimalStringN(gStringVar1, GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_HP_IV), STR_CONV_MODE_LEFT_ALIGN, 3);
ConvertIntToDecimalStringN(gStringVar2, GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_DEF_IV), STR_CONV_MODE_LEFT_ALIGN, 3);
ConvertIntToDecimalStringN(gStringVar3, GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPDEF_IV), STR_CONV_MODE_LEFT_ALIGN, 3);
}

View File

@ -180,3 +180,114 @@ TEST("togglegigantamaxfactor fails for Melmetal")
EXPECT(!VarGet(VAR_RESULT));
EXPECT(!GetMonData(&gPlayerParty[0], MON_DATA_GIGANTAMAX_FACTOR));
}
TEST("givemon [simple]")
{
ZeroPlayerPartyMons();
RUN_OVERWORLD_SCRIPT(
givemon SPECIES_WOBBUFFET, 100;
);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_WOBBUFFET);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_LEVEL), 100);
}
TEST("givemon [all]")
{
ZeroPlayerPartyMons();
RUN_OVERWORLD_SCRIPT(
givemon SPECIES_WOBBUFFET, 100, item=ITEM_LEFTOVERS, ball=ITEM_MASTER_BALL, nature=NATURE_BOLD, abilityNum=2, gender=MON_MALE, hpEv=1, atkEv=2, defEv=3, speedEv=4, spAtkEv=5, spDefEv=6, hpIv=7, atkIv=8, defIv=9, speedIv=10, spAtkIv=11, spDefIv=12, move1=MOVE_TACKLE, move2=MOVE_SPLASH, move3=MOVE_CELEBRATE, move4=MOVE_EXPLOSION, isShiny=TRUE, ggMaxFactor=TRUE, teraType=TYPE_FIRE;
);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_WOBBUFFET);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_LEVEL), 100);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_HELD_ITEM), ITEM_LEFTOVERS);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_POKEBALL), ITEM_MASTER_BALL);
EXPECT_EQ(GetNature(&gPlayerParty[0]), NATURE_BOLD);
EXPECT_EQ(GetMonAbility(&gPlayerParty[0]), gSpeciesInfo[SPECIES_WOBBUFFET].abilities[2]);
EXPECT_EQ(GetMonGender(&gPlayerParty[0]), MON_MALE);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_HP_EV), 1);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_ATK_EV), 2);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_DEF_EV), 3);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPEED_EV), 4);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPATK_EV), 5);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPDEF_EV), 6);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_HP_IV), 7);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_ATK_IV), 8);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_DEF_IV), 9);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPEED_IV), 10);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPATK_IV), 11);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPDEF_IV), 12);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_MOVE1), MOVE_TACKLE);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_MOVE2), MOVE_SPLASH);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_MOVE3), MOVE_CELEBRATE);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_MOVE4), MOVE_EXPLOSION);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_IS_SHINY), TRUE);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_GIGANTAMAX_FACTOR), TRUE);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_TERA_TYPE), TYPE_FIRE);
}
TEST("givemon [vars]")
{
ZeroPlayerPartyMons();
VarSet(VAR_TEMP_C, SPECIES_WOBBUFFET);
VarSet(VAR_TEMP_D, 100);
VarSet(VAR_0x8000, ITEM_LEFTOVERS);
VarSet(VAR_0x8001, ITEM_MASTER_BALL);
VarSet(VAR_0x8002, NATURE_BOLD);
VarSet(VAR_0x8003, 2);
VarSet(VAR_0x8004, MON_MALE);
VarSet(VAR_0x8005, 1);
VarSet(VAR_0x8006, 2);
VarSet(VAR_0x8007, 3);
VarSet(VAR_0x8008, 4);
VarSet(VAR_0x8009, 5);
VarSet(VAR_0x800A, 6);
VarSet(VAR_0x800B, 7);
VarSet(VAR_TEMP_0, 8);
VarSet(VAR_TEMP_1, 9);
VarSet(VAR_TEMP_2, 10);
VarSet(VAR_TEMP_3, 11);
VarSet(VAR_TEMP_4, 12);
VarSet(VAR_TEMP_5, MOVE_TACKLE);
VarSet(VAR_TEMP_6, MOVE_SPLASH);
VarSet(VAR_TEMP_7, MOVE_CELEBRATE);
VarSet(VAR_TEMP_8, MOVE_EXPLOSION);
VarSet(VAR_TEMP_9, TRUE);
VarSet(VAR_TEMP_A, TRUE);
VarSet(VAR_TEMP_B, TYPE_FIRE);
RUN_OVERWORLD_SCRIPT(
givemon VAR_TEMP_C, VAR_TEMP_D, item=VAR_0x8000, ball=VAR_0x8001, nature=VAR_0x8002, abilityNum=VAR_0x8003, gender=VAR_0x8004, hpEv=VAR_0x8005, atkEv=VAR_0x8006, defEv=VAR_0x8007, speedEv=VAR_0x8008, spAtkEv=VAR_0x8009, spDefEv=VAR_0x800A, hpIv=VAR_0x800B, atkIv=VAR_TEMP_0, defIv=VAR_TEMP_1, speedIv=VAR_TEMP_2, spAtkIv=VAR_TEMP_3, spDefIv=VAR_TEMP_4, move1=VAR_TEMP_5, move2=VAR_TEMP_6, move3=VAR_TEMP_7, move4=VAR_TEMP_8, isShiny=VAR_TEMP_9, ggMaxFactor=VAR_TEMP_A, teraType=VAR_TEMP_B;
);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_WOBBUFFET);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_LEVEL), 100);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_HELD_ITEM), ITEM_LEFTOVERS);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_POKEBALL), ITEM_MASTER_BALL);
EXPECT_EQ(GetNature(&gPlayerParty[0]), NATURE_BOLD);
EXPECT_EQ(GetMonAbility(&gPlayerParty[0]), gSpeciesInfo[SPECIES_WOBBUFFET].abilities[2]);
EXPECT_EQ(GetMonGender(&gPlayerParty[0]), MON_MALE);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_HP_EV), 1);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_ATK_EV), 2);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_DEF_EV), 3);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPEED_EV), 4);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPATK_EV), 5);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPDEF_EV), 6);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_HP_IV), 7);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_ATK_IV), 8);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_DEF_IV), 9);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPEED_IV), 10);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPATK_IV), 11);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPDEF_IV), 12);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_MOVE1), MOVE_TACKLE);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_MOVE2), MOVE_SPLASH);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_MOVE3), MOVE_CELEBRATE);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_MOVE4), MOVE_EXPLOSION);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_IS_SHINY), TRUE);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_GIGANTAMAX_FACTOR), TRUE);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_TERA_TYPE), TYPE_FIRE);
}