diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 3672fc7d0d..b5bd09e0b9 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -2412,8 +2412,8 @@ Move_FOCUS_BLAST: loadspritegfx ANIM_TAG_CIRCLE_OF_LIGHT loadspritegfx ANIM_TAG_METEOR loadspritegfx ANIM_TAG_FLAT_ROCK - monbg ANIM_TARGET - monbgprio_28 ANIM_TARGET + monbg ANIM_ATK_PARTNER + monbgprio_28 ANIM_ATTACKER setalpha 12, 8 call SetHighSpeedBg createsprite gSuperpowerOrbSpriteTemplate, ANIM_TARGET, 2, 0 @@ -2423,7 +2423,7 @@ Move_FOCUS_BLAST: playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET waitforvisualfinish call UnsetHighSpeedBg - clearmonbg ANIM_TARGET + clearmonbg ANIM_ATK_PARTNER blendoff delay 1 end diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 202264ac35..f2d1c85b3b 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -6839,12 +6839,12 @@ BattleScript_IntimidateActivatesLoop: jumpifability BS_TARGET, ABILITY_CLEAR_BODY, BattleScript_IntimidatePrevented jumpifability BS_TARGET, ABILITY_HYPER_CUTTER, BattleScript_IntimidatePrevented jumpifability BS_TARGET, ABILITY_WHITE_SMOKE, BattleScript_IntimidatePrevented -#if B_UPDATED_INTIMIDATE >= GEN_8 +.if B_UPDATED_INTIMIDATE >= GEN_8 jumpifability BS_TARGET, ABILITY_INNER_FOCUS, BattleScript_IntimidatePrevented jumpifability BS_TARGET, ABILITY_SCRAPPY, BattleScript_IntimidatePrevented jumpifability BS_TARGET, ABILITY_OWN_TEMPO, BattleScript_IntimidatePrevented jumpifability BS_TARGET, ABILITY_OBLIVIOUS, BattleScript_IntimidatePrevented -#endif +.endif statbuffchange STAT_BUFF_NOT_PROTECT_AFFECTED | STAT_BUFF_ALLOW_PTR, BattleScript_IntimidateActivatesLoopIncrement jumpifbyte CMP_GREATER_THAN, cMULTISTRING_CHOOSER, 0x1, BattleScript_IntimidateActivatesLoopIncrement setgraphicalstatchangevalues diff --git a/include/battle_message.h b/include/battle_message.h index bc4ce8f007..299b536ce9 100644 --- a/include/battle_message.h +++ b/include/battle_message.h @@ -287,6 +287,7 @@ extern const u8 gText_BattleWallyName[]; extern const u8 gText_Win[]; extern const u8 gText_Loss[]; extern const u8 gText_Draw[]; +extern const u8 gText_StatSharply[]; extern const u8 gText_StatRose[]; extern const u8 gText_PkmnsStatChanged2[]; extern const u8 gText_PkmnGettingPumped[]; diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index baffb3cee8..8979ad2f27 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -161,6 +161,7 @@ // Item settings #define B_HP_BERRIES GEN_6 // In Gen4+, berries which restore hp activate immediately after hp drops to half. In gen3, the effect occurs at the end of the turn. #define B_BERRIES_INSTANT GEN_6 // In Gen4+, most berries activate on battle start/switch-in if applicable. In gen3, they only activate either at the move end or turn end. +#define B_X_ITEMS_BUFF GEN_7 // In Gen7+, the X Items raise a stat by 2 stages instead of 1. // Flag settings // To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. @@ -186,23 +187,23 @@ #define B_STEEL_RESISTANCES GEN_6 // In Gen6+, Steel-type Pokémon are no longer resistant to Dark and Ghost moves. // Animation Settings -#define B_NEW_SWORD_PARTICLE TRUE // If set to TRUE, it updates Swords Dance's particle. -#define B_NEW_LEECH_SEED_PARTICLE TRUE // If set to TRUE, it updates Leech Seed's animation particle. -#define B_NEW_HORN_ATTACK_PARTICLE TRUE // If set to TRUE, it updates Horn Attack's horn particle. -#define B_NEW_LEAF_PARTICLE TRUE // If set to TRUE, it updates leaf particle. -#define B_NEW_EMBER_PARTICLES TRUE // If set to TRUE, it updates Ember's fire particle. -#define B_NEW_MEAN_LOOK_PARTICLE TRUE // If set to TRUE, it updates Mean Look's eye particle. -#define B_NEW_TEETH_PARTICLE TRUE // If set to TRUE, it updates Bite/Crunch teeth particle. -#define B_NEW_HANDS_FEET_PARTICLE TRUE // If set to TRUE, it updates chop/kick/punch particles. -#define B_NEW_SPIKES_PARTICLE TRUE // If set to TRUE, it updates Spikes particle. -#define B_NEW_FLY_BUBBLE_PARTICLE TRUE // If set to TRUE, it updates Fly's 'bubble' particle. -#define B_NEW_CURSE_NAIL_PARTICLE TRUE // If set to TRUE, it updates Curse's nail. -#define B_NEW_BATON_PASS_BALL_PARTICLE TRUE // If set to TRUE, it updates Baton Pass' Poké Ball sprite. -#define B_NEW_MORNING_SUN_STAR_PARTICLE TRUE // If set to TRUE, it updates Morning Sun's star particles. -#define B_NEW_IMPACT_PALETTE TRUE // If set to TRUE, it updates the basic 'hit' palette. -#define B_NEW_SURF_PARTICLE_PALETTE TRUE // If set to TRUE, it updates Surf's wave palette. +#define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle. +#define B_NEW_LEECH_SEED_PARTICLE FALSE // If set to TRUE, it updates Leech Seed's animation particle. +#define B_NEW_HORN_ATTACK_PARTICLE FALSE // If set to TRUE, it updates Horn Attack's horn particle. +#define B_NEW_LEAF_PARTICLE FALSE // If set to TRUE, it updates leaf particle. +#define B_NEW_EMBER_PARTICLES FALSE // If set to TRUE, it updates Ember's fire particle. +#define B_NEW_MEAN_LOOK_PARTICLE FALSE // If set to TRUE, it updates Mean Look's eye particle. +#define B_NEW_TEETH_PARTICLE FALSE // If set to TRUE, it updates Bite/Crunch teeth particle. +#define B_NEW_HANDS_FEET_PARTICLE FALSE // If set to TRUE, it updates chop/kick/punch particles. +#define B_NEW_SPIKES_PARTICLE FALSE // If set to TRUE, it updates Spikes particle. +#define B_NEW_FLY_BUBBLE_PARTICLE FALSE // If set to TRUE, it updates Fly's 'bubble' particle. +#define B_NEW_CURSE_NAIL_PARTICLE FALSE // If set to TRUE, it updates Curse's nail. +#define B_NEW_BATON_PASS_BALL_PARTICLE FALSE // If set to TRUE, it updates Baton Pass' Poké Ball sprite. +#define B_NEW_MORNING_SUN_STAR_PARTICLE FALSE // If set to TRUE, it updates Morning Sun's star particles. +#define B_NEW_IMPACT_PALETTE FALSE // If set to TRUE, it updates the basic 'hit' palette. +#define B_NEW_SURF_PARTICLE_PALETTE FALSE // If set to TRUE, it updates Surf's wave palette. -#define HIDE_HEALTHBOXES_DURING_ANIMS TRUE // If set to TRUE, hides healthboxes during move animations +#define B_HIDE_HEALTHBOXES_DURING_ANIMS TRUE // If set to TRUE, hides healthboxes during move animations. #define B_TERRAIN_BG_CHANGE TRUE // If set to TRUE, terrain moves permanently change the default battle background until the effect fades. #define B_ENABLE_DEBUG TRUE // If set to TRUE, enables a debug menu to use in battles by pressing the Select button. diff --git a/include/constants/item_effects.h b/include/constants/item_effects.h index 6e61c4d7f9..e68914c7b1 100644 --- a/include/constants/item_effects.h +++ b/include/constants/item_effects.h @@ -2,11 +2,14 @@ #define GUARD_CONSTANTS_ITEM_EFFECTS_H // field 0 masks +#ifndef ITEM_EXPANSION #define ITEM0_X_ATTACK 0x0F +#endif #define ITEM0_DIRE_HIT 0x30 // Works the same way as the move Focus Energy. #define ITEM0_SACRED_ASH 0x40 #define ITEM0_INFATUATION 0x80 +#ifndef ITEM_EXPANSION // field 1 masks #define ITEM1_X_SPEED 0x0F #define ITEM1_X_DEFEND 0xF0 @@ -14,6 +17,15 @@ // field 2 masks #define ITEM2_X_SPATK 0x0F #define ITEM2_X_ACCURACY 0xF0 +#else +// new field 1 masks +#define ITEM1_X_ATTACK 0x1 +#define ITEM1_X_DEFENSE 0x2 +#define ITEM1_X_SPEED 0x4 +#define ITEM1_X_SPATK 0x8 +#define ITEM1_X_SPDEF 0x10 +#define ITEM1_X_ACCURACY 0x20 +#endif // field 3 masks #define ITEM3_CONFUSION 0x1 diff --git a/include/pokemon.h b/include/pokemon.h index e7f08ab6cb..8c4a78a34f 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -4,6 +4,8 @@ #include "constants/pokemon.h" #include "sprite.h" +#define GET_BASE_SPECIES_ID(speciesId) (GetFormSpeciesId(speciesId, 0)) + struct PokemonSubstruct0 { u16 species; @@ -423,5 +425,7 @@ bool8 HasTwoFramesAnimation(u16 species); struct Unknown_806F160_Struct *sub_806F2AC(u8 id, u8 arg1); void sub_806F47C(u8 id); u8 *sub_806F4F8(u8 id, u8 arg1); +u16 GetFormSpeciesId(u16 speciesId, u8 formId); +u8 GetFormIdFromFormSpeciesId(u16 formSpeciesId); #endif // GUARD_POKEMON_H diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 3d3bdc4c01..d0fd8224dd 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -773,7 +773,11 @@ static u8 GetAI_ItemType(u16 itemId, const u8 *itemEffect) return AI_ITEM_HEAL_HP; else if (itemEffect[3] & ITEM3_STATUS_ALL) return AI_ITEM_CURE_CONDITION; +#ifdef ITEM_EXPANSION + else if ((itemEffect[0] & ITEM0_DIRE_HIT) || itemEffect[1]) +#else else if (itemEffect[0] & (ITEM0_DIRE_HIT | ITEM0_X_ATTACK) || itemEffect[1] != 0 || itemEffect[2] != 0) +#endif return AI_ITEM_X_STAT; else if (itemEffect[3] & ITEM3_GUARD_SPEC) return AI_ITEM_GUARD_SPECS; @@ -883,6 +887,7 @@ static bool8 ShouldUseItem(void) *(gBattleStruct->AI_itemFlags + gActiveBattler / 2) = 0; if (gDisableStructs[gActiveBattler].isFirstTurn == 0) break; + #ifndef ITEM_EXPANSION if (itemEffects[0] & ITEM0_X_ATTACK) *(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x1; if (itemEffects[1] & ITEM1_X_DEFEND) @@ -895,6 +900,22 @@ static bool8 ShouldUseItem(void) *(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x20; if (itemEffects[0] & ITEM0_DIRE_HIT) *(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x80; + #else + if (itemEffects[1] & ITEM1_X_ATTACK) + *(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x1; + if (itemEffects[1] & ITEM1_X_DEFENSE) + *(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x2; + if (itemEffects[1] & ITEM1_X_SPEED) + *(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x4; + if (itemEffects[1] & ITEM1_X_SPATK) + *(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x8; + if (itemEffects[1] & ITEM1_X_SPDEF) + *(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x10; + if (itemEffects[1] & ITEM1_X_ACCURACY) + *(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x20; + if (itemEffects[0] & ITEM0_DIRE_HIT) + *(gBattleStruct->AI_itemFlags + gActiveBattler / 2) |= 0x40; + #endif shouldUse = TRUE; break; case AI_ITEM_GUARD_SPECS: diff --git a/src/battle_controllers.c b/src/battle_controllers.c index eb6d73ba78..79f1ff7ad0 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -62,7 +62,6 @@ void SetUpBattleVarsAndBirchZigzagoon(void) ClearBattleMonForms(); BattleAI_SetupItems(); BattleAI_SetupFlags(); - BattleAI_SetupAIData(0xF); if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE) { diff --git a/src/battle_interface.c b/src/battle_interface.c index 8f898403b1..611035db27 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -1012,7 +1012,7 @@ void UpdateOamPriorityInAllHealthboxes(u8 priority) if (indicatorSpriteId != 0xFF) gSprites[indicatorSpriteId].oam.priority = priority; - #if HIDE_HEALTHBOXES_DURING_ANIMS + #if B_HIDE_HEALTHBOXES_DURING_ANIMS if (IsBattlerAlive(i)) TryToggleHealboxVisibility(priority, healthboxLeftSpriteId, healthboxRightSpriteId, healthbarSpriteId, indicatorSpriteId); #endif diff --git a/src/battle_message.c b/src/battle_message.c index 23b0160399..8558aeb18d 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -305,7 +305,7 @@ static const u8 sText_PkmnsXPreventsFlinching[] = _("{B_EFF_NAME_WITH_PREFIX}'s static const u8 sText_PkmnsXPreventsYsZ[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}\nprevents {B_DEF_NAME_WITH_PREFIX}'s\l{B_DEF_ABILITY} from working!"); static const u8 sText_PkmnsXCuredItsYProblem[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\ncured its {B_BUFF1} problem!"); static const u8 sText_PkmnsXHadNoEffectOnY[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nhad no effect on {B_EFF_NAME_WITH_PREFIX}!"); -static const u8 sText_StatSharply[] = _("sharply "); +const u8 gText_StatSharply[] = _("sharply "); const u8 gText_StatRose[] = _("rose!"); static const u8 sText_StatHarshly[] = _("harshly "); static const u8 sText_StatFell[] = _("fell!"); @@ -942,7 +942,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_PKMNPREVENTSSTATLOSSWITH - 12] = sText_PkmnPreventsStatLossWith, [STRINGID_PKMNHURTSWITH - 12] = sText_PkmnHurtsWith, [STRINGID_PKMNTRACED - 12] = sText_PkmnTraced, - [STRINGID_STATSHARPLY - 12] = sText_StatSharply, + [STRINGID_STATSHARPLY - 12] = gText_StatSharply, [STRINGID_STATROSE - 12] = gText_StatRose, [STRINGID_STATHARSHLY - 12] = sText_StatHarshly, [STRINGID_STATFELL - 12] = sText_StatFell, diff --git a/src/battle_util.c b/src/battle_util.c index ad54517da6..39a32d8032 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7153,7 +7153,9 @@ static u32 CalcAttackStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, b switch (GetBattlerHoldEffect(battlerAtk, TRUE)) { case HOLD_EFFECT_THICK_CLUB: - if ((gBattleMons[battlerAtk].species == SPECIES_CUBONE || gBattleMons[battlerAtk].species == SPECIES_MAROWAK) && IS_MOVE_PHYSICAL(move)) + if ((GET_BASE_SPECIES_ID(gBattleMons[battlerAtk].species) == SPECIES_CUBONE + || GET_BASE_SPECIES_ID(gBattleMons[battlerAtk].species) == SPECIES_MAROWAK) + && IS_MOVE_PHYSICAL(move)) MulModifier(&modifier, UQ_4_12(2.0)); break; case HOLD_EFFECT_DEEP_SEA_TOOTH: diff --git a/src/data/pokemon/form_species_table_pointers.h b/src/data/pokemon/form_species_table_pointers.h new file mode 100644 index 0000000000..22e32ae421 --- /dev/null +++ b/src/data/pokemon/form_species_table_pointers.h @@ -0,0 +1,80 @@ +const u16 *const gFormSpeciesIdTables[NUM_SPECIES] = +{ + [SPECIES_VENUSAUR] = sVenusaurFormSpeciesIdTable, + [SPECIES_CHARIZARD] = sCharizardFormSpeciesIdTable, + [SPECIES_BLASTOISE] = sBlastoiseFormSpeciesIdTable, + [SPECIES_BEEDRILL] = sBeedrillFormSpeciesIdTable, + [SPECIES_PIDGEOT] = sPidgeotFormSpeciesIdTable, + [SPECIES_RATTATA] = sRattataFormSpeciesIdTable, + [SPECIES_RATICATE] = sRaticateFormSpeciesIdTable, + [SPECIES_PIKACHU] = sPikachuFormSpeciesIdTable, + [SPECIES_RAICHU] = sRaichuFormSpeciesIdTable, + [SPECIES_SANDSHREW] = sSandshrewFormSpeciesIdTable, + [SPECIES_SANDSLASH] = sSandslashFormSpeciesIdTable, + [SPECIES_VULPIX] = sVulpixFormSpeciesIdTable, + [SPECIES_NINETALES] = sNinetalesFormSpeciesIdTable, + [SPECIES_DIGLETT] = sDiglettFormSpeciesIdTable, + [SPECIES_DUGTRIO] = sDugtrioFormSpeciesIdTable, + [SPECIES_MEOWTH] = sMeowthFormSpeciesIdTable, + [SPECIES_PERSIAN] = sPersianFormSpeciesIdTable, + [SPECIES_ALAKAZAM] = sAlakazamFormSpeciesIdTable, + [SPECIES_GEODUDE] = sGeodudeFormSpeciesIdTable, + [SPECIES_GRAVELER] = sGravelerFormSpeciesIdTable, + [SPECIES_GOLEM] = sGolemFormSpeciesIdTable, + [SPECIES_PONYTA] = sPonytaFormSpeciesIdTable, + [SPECIES_RAPIDASH] = sRapidashFormSpeciesIdTable, + [SPECIES_SLOWPOKE] = sSlowpokeFormSpeciesIdTable, + [SPECIES_SLOWBRO] = sSlowbroFormSpeciesIdTable, + [SPECIES_FARFETCHD] = sFarfetchdFormSpeciesIdTable, + [SPECIES_GRIMER] = sGrimerFormSpeciesIdTable, + [SPECIES_MUK] = sMukFormSpeciesIdTable, + [SPECIES_GENGAR] = sGengarFormSpeciesIdTable, + [SPECIES_EXEGGUTOR] = sExeggutorFormSpeciesIdTable, + [SPECIES_MAROWAK] = sMarowakFormSpeciesIdTable, + [SPECIES_WEEZING] = sWeezingFormSpeciesIdTable, + [SPECIES_KANGASKHAN] = sKangaskhanFormSpeciesIdTable, + [SPECIES_MR_MIME] = sMrMimeFormSpeciesIdTable, + [SPECIES_PINSIR] = sPinsirFormSpeciesIdTable, + [SPECIES_GYARADOS] = sGyaradosFormSpeciesIdTable, + [SPECIES_AERODACTYL] = sAerodactylFormSpeciesIdTable, + [SPECIES_ARTICUNO] = sArticunoFormSpeciesIdTable, + [SPECIES_ZAPDOS] = sZapdosFormSpeciesIdTable, + [SPECIES_MOLTRES] = sMoltresFormSpeciesIdTable, + [SPECIES_MEWTWO] = sMewtwoFormSpeciesIdTable, + [SPECIES_PICHU] = sPichuFormSpeciesIdTable, + [SPECIES_AMPHAROS] = sAmpharosFormSpeciesIdTable, + [SPECIES_SLOWKING] = sSlowkingFormSpeciesIdTable, + [SPECIES_UNOWN] = sUnownFormSpeciesIdTable, + [SPECIES_STEELIX] = sSteelixFormSpeciesIdTable, + [SPECIES_SCIZOR] = sScizorFormSpeciesIdTable, + [SPECIES_HERACROSS] = sHeracrossFormSpeciesIdTable, + [SPECIES_CORSOLA] = sCorsolaFormSpeciesIdTable, + [SPECIES_HOUNDOOM] = sHoundoomFormSpeciesIdTable, + [SPECIES_TYRANITAR] = sTyranitarFormSpeciesIdTable, + [SPECIES_SCEPTILE] = sSceptileFormSpeciesIdTable, + [SPECIES_BLAZIKEN] = sBlazikenFormSpeciesIdTable, + [SPECIES_SWAMPERT] = sSwampertFormSpeciesIdTable, + [SPECIES_ZIGZAGOON] = sZigzagoonFormSpeciesIdTable, + [SPECIES_LINOONE] = sLinooneFormSpeciesIdTable, + [SPECIES_GARDEVOIR] = sGardevoirFormSpeciesIdTable, + [SPECIES_SABLEYE] = sSableyeFormSpeciesIdTable, + [SPECIES_MAWILE] = sMawileFormSpeciesIdTable, + [SPECIES_AGGRON] = sAggronFormSpeciesIdTable, + [SPECIES_MEDICHAM] = sMedichamFormSpeciesIdTable, + [SPECIES_MANECTRIC] = sManectricFormSpeciesIdTable, + [SPECIES_SHARPEDO] = sSharpedoFormSpeciesIdTable, + [SPECIES_CAMERUPT] = sCameruptFormSpeciesIdTable, + [SPECIES_ALTARIA] = sAltariaFormSpeciesIdTable, + [SPECIES_CASTFORM] = sCastformFormSpeciesIdTable, + [SPECIES_BANETTE] = sBanetteFormSpeciesIdTable, + [SPECIES_ABSOL] = sAbsolFormSpeciesIdTable, + [SPECIES_GLALIE] = sGlalieFormSpeciesIdTable, + [SPECIES_SALAMENCE] = sSalamenceFormSpeciesIdTable, + [SPECIES_METAGROSS] = sMetagrossFormSpeciesIdTable, + [SPECIES_LATIAS] = sLatiasFormSpeciesIdTable, + [SPECIES_LATIOS] = sLatiosFormSpeciesIdTable, + [SPECIES_KYOGRE] = sKyogreFormSpeciesIdTable, + [SPECIES_GROUDON] = sGroudonFormSpeciesIdTable, + [SPECIES_RAYQUAZA] = sRayquazaFormSpeciesIdTable, + [SPECIES_DEOXYS] = sDeoxysFormSpeciesIdTable, +}; diff --git a/src/data/pokemon/form_species_tables.h b/src/data/pokemon/form_species_tables.h new file mode 100644 index 0000000000..632bdd9be0 --- /dev/null +++ b/src/data/pokemon/form_species_tables.h @@ -0,0 +1,386 @@ +#define FORM_SPECIES_END (0xffff) + +static const u16 sVenusaurFormSpeciesIdTable[] = { + SPECIES_VENUSAUR, + FORM_SPECIES_END, +}; + +static const u16 sCharizardFormSpeciesIdTable[] = { + SPECIES_CHARIZARD, + FORM_SPECIES_END, +}; + +static const u16 sBlastoiseFormSpeciesIdTable[] = { + SPECIES_BLASTOISE, + FORM_SPECIES_END, +}; + +static const u16 sBeedrillFormSpeciesIdTable[] = { + SPECIES_BEEDRILL, + FORM_SPECIES_END, +}; + +static const u16 sPidgeotFormSpeciesIdTable[] = { + SPECIES_PIDGEOT, + FORM_SPECIES_END, +}; + +static const u16 sRattataFormSpeciesIdTable[] = { + SPECIES_RATTATA, + FORM_SPECIES_END, +}; + +static const u16 sRaticateFormSpeciesIdTable[] = { + SPECIES_RATICATE, + FORM_SPECIES_END, +}; + +static const u16 sPikachuFormSpeciesIdTable[] = { + SPECIES_PIKACHU, + FORM_SPECIES_END, +}; + +static const u16 sRaichuFormSpeciesIdTable[] = { + SPECIES_RAICHU, + FORM_SPECIES_END, +}; + +static const u16 sSandshrewFormSpeciesIdTable[] = { + SPECIES_SANDSHREW, + FORM_SPECIES_END, +}; + +static const u16 sSandslashFormSpeciesIdTable[] = { + SPECIES_SANDSLASH, + FORM_SPECIES_END, +}; + +static const u16 sVulpixFormSpeciesIdTable[] = { + SPECIES_VULPIX, + FORM_SPECIES_END, +}; + +static const u16 sNinetalesFormSpeciesIdTable[] = { + SPECIES_NINETALES, + FORM_SPECIES_END, +}; + +static const u16 sDiglettFormSpeciesIdTable[] = { + SPECIES_DIGLETT, + FORM_SPECIES_END, +}; + +static const u16 sDugtrioFormSpeciesIdTable[] = { + SPECIES_DUGTRIO, + FORM_SPECIES_END, +}; + +static const u16 sMeowthFormSpeciesIdTable[] = { + SPECIES_MEOWTH, + FORM_SPECIES_END, +}; + +static const u16 sPersianFormSpeciesIdTable[] = { + SPECIES_PERSIAN, + FORM_SPECIES_END, +}; + +static const u16 sAlakazamFormSpeciesIdTable[] = { + SPECIES_ALAKAZAM, + FORM_SPECIES_END, +}; + +static const u16 sGeodudeFormSpeciesIdTable[] = { + SPECIES_GEODUDE, + FORM_SPECIES_END, +}; + +static const u16 sGravelerFormSpeciesIdTable[] = { + SPECIES_GRAVELER, + FORM_SPECIES_END, +}; + +static const u16 sGolemFormSpeciesIdTable[] = { + SPECIES_GOLEM, + FORM_SPECIES_END, +}; + +static const u16 sPonytaFormSpeciesIdTable[] = { + SPECIES_PONYTA, + FORM_SPECIES_END, +}; + +static const u16 sRapidashFormSpeciesIdTable[] = { + SPECIES_RAPIDASH, + FORM_SPECIES_END, +}; + +static const u16 sSlowpokeFormSpeciesIdTable[] = { + SPECIES_SLOWPOKE, + FORM_SPECIES_END, +}; + +static const u16 sSlowbroFormSpeciesIdTable[] = { + SPECIES_SLOWBRO, + FORM_SPECIES_END, +}; + +static const u16 sFarfetchdFormSpeciesIdTable[] = { + SPECIES_FARFETCHD, + FORM_SPECIES_END, +}; + +static const u16 sGrimerFormSpeciesIdTable[] = { + SPECIES_GRIMER, + FORM_SPECIES_END, +}; + +static const u16 sMukFormSpeciesIdTable[] = { + SPECIES_MUK, + FORM_SPECIES_END, +}; + +static const u16 sGengarFormSpeciesIdTable[] = { + SPECIES_GENGAR, + FORM_SPECIES_END, +}; + +static const u16 sExeggutorFormSpeciesIdTable[] = { + SPECIES_EXEGGUTOR, + FORM_SPECIES_END, +}; + +static const u16 sMarowakFormSpeciesIdTable[] = { + SPECIES_MAROWAK, + FORM_SPECIES_END, +}; + +static const u16 sWeezingFormSpeciesIdTable[] = { + SPECIES_WEEZING, + FORM_SPECIES_END, +}; + +static const u16 sKangaskhanFormSpeciesIdTable[] = { + SPECIES_KANGASKHAN, + FORM_SPECIES_END, +}; + +static const u16 sMrMimeFormSpeciesIdTable[] = { + SPECIES_MR_MIME, + FORM_SPECIES_END, +}; + +static const u16 sPinsirFormSpeciesIdTable[] = { + SPECIES_PINSIR, + FORM_SPECIES_END, +}; + +static const u16 sGyaradosFormSpeciesIdTable[] = { + SPECIES_GYARADOS, + FORM_SPECIES_END, +}; + +static const u16 sAerodactylFormSpeciesIdTable[] = { + SPECIES_AERODACTYL, + FORM_SPECIES_END, +}; + +static const u16 sArticunoFormSpeciesIdTable[] = { + SPECIES_ARTICUNO, + FORM_SPECIES_END, +}; + +static const u16 sZapdosFormSpeciesIdTable[] = { + SPECIES_ZAPDOS, + FORM_SPECIES_END, +}; + +static const u16 sMoltresFormSpeciesIdTable[] = { + SPECIES_MOLTRES, + FORM_SPECIES_END, +}; + +static const u16 sMewtwoFormSpeciesIdTable[] = { + SPECIES_MEWTWO, + FORM_SPECIES_END, +}; + +static const u16 sPichuFormSpeciesIdTable[] = { + SPECIES_PICHU, + FORM_SPECIES_END, +}; + +static const u16 sAmpharosFormSpeciesIdTable[] = { + SPECIES_AMPHAROS, + FORM_SPECIES_END, +}; + +static const u16 sSlowkingFormSpeciesIdTable[] = { + SPECIES_SLOWKING, + FORM_SPECIES_END, +}; + +static const u16 sUnownFormSpeciesIdTable[] = { + SPECIES_UNOWN, + FORM_SPECIES_END, +}; + +static const u16 sSteelixFormSpeciesIdTable[] = { + SPECIES_STEELIX, + FORM_SPECIES_END, +}; + +static const u16 sScizorFormSpeciesIdTable[] = { + SPECIES_SCIZOR, + FORM_SPECIES_END, +}; + +static const u16 sHeracrossFormSpeciesIdTable[] = { + SPECIES_HERACROSS, + FORM_SPECIES_END, +}; + +static const u16 sCorsolaFormSpeciesIdTable[] = { + SPECIES_CORSOLA, + FORM_SPECIES_END, +}; + +static const u16 sHoundoomFormSpeciesIdTable[] = { + SPECIES_HOUNDOOM, + FORM_SPECIES_END, +}; + +static const u16 sTyranitarFormSpeciesIdTable[] = { + SPECIES_TYRANITAR, + FORM_SPECIES_END, +}; + +static const u16 sSceptileFormSpeciesIdTable[] = { + SPECIES_SCEPTILE, + FORM_SPECIES_END, +}; + +static const u16 sBlazikenFormSpeciesIdTable[] = { + SPECIES_BLAZIKEN, + FORM_SPECIES_END, +}; + +static const u16 sSwampertFormSpeciesIdTable[] = { + SPECIES_SWAMPERT, + FORM_SPECIES_END, +}; + +static const u16 sZigzagoonFormSpeciesIdTable[] = { + SPECIES_ZIGZAGOON, + FORM_SPECIES_END, +}; + +static const u16 sLinooneFormSpeciesIdTable[] = { + SPECIES_LINOONE, + FORM_SPECIES_END, +}; + +static const u16 sGardevoirFormSpeciesIdTable[] = { + SPECIES_GARDEVOIR, + FORM_SPECIES_END, +}; + +static const u16 sSableyeFormSpeciesIdTable[] = { + SPECIES_SABLEYE, + FORM_SPECIES_END, +}; + +static const u16 sMawileFormSpeciesIdTable[] = { + SPECIES_MAWILE, + FORM_SPECIES_END, +}; + +static const u16 sAggronFormSpeciesIdTable[] = { + SPECIES_AGGRON, + FORM_SPECIES_END, +}; + +static const u16 sMedichamFormSpeciesIdTable[] = { + SPECIES_MEDICHAM, + FORM_SPECIES_END, +}; + +static const u16 sManectricFormSpeciesIdTable[] = { + SPECIES_MANECTRIC, + FORM_SPECIES_END, +}; + +static const u16 sSharpedoFormSpeciesIdTable[] = { + SPECIES_SHARPEDO, + FORM_SPECIES_END, +}; + +static const u16 sCameruptFormSpeciesIdTable[] = { + SPECIES_CAMERUPT, + FORM_SPECIES_END, +}; + +static const u16 sAltariaFormSpeciesIdTable[] = { + SPECIES_ALTARIA, + FORM_SPECIES_END, +}; + +static const u16 sCastformFormSpeciesIdTable[] = { + SPECIES_CASTFORM, + FORM_SPECIES_END, +}; + +static const u16 sBanetteFormSpeciesIdTable[] = { + SPECIES_BANETTE, + FORM_SPECIES_END, +}; + +static const u16 sAbsolFormSpeciesIdTable[] = { + SPECIES_ABSOL, + FORM_SPECIES_END, +}; + +static const u16 sGlalieFormSpeciesIdTable[] = { + SPECIES_GLALIE, + FORM_SPECIES_END, +}; + +static const u16 sSalamenceFormSpeciesIdTable[] = { + SPECIES_SALAMENCE, + FORM_SPECIES_END, +}; + +static const u16 sMetagrossFormSpeciesIdTable[] = { + SPECIES_METAGROSS, + FORM_SPECIES_END, +}; + +static const u16 sLatiasFormSpeciesIdTable[] = { + SPECIES_LATIAS, + FORM_SPECIES_END, +}; + +static const u16 sLatiosFormSpeciesIdTable[] = { + SPECIES_LATIOS, + FORM_SPECIES_END, +}; + +static const u16 sKyogreFormSpeciesIdTable[] = { + SPECIES_KYOGRE, + FORM_SPECIES_END, +}; + +static const u16 sGroudonFormSpeciesIdTable[] = { + SPECIES_GROUDON, + FORM_SPECIES_END, +}; + +static const u16 sRayquazaFormSpeciesIdTable[] = { + SPECIES_RAYQUAZA, + FORM_SPECIES_END, +}; + +static const u16 sDeoxysFormSpeciesIdTable[] = { + SPECIES_DEOXYS, + FORM_SPECIES_END, +}; diff --git a/src/party_menu.c b/src/party_menu.c index 63737dacf4..8e30f7733c 100755 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -5184,7 +5184,11 @@ u8 GetItemEffectType(u16 item) else itemEffect = gItemEffectTable[item - ITEM_POTION]; +#ifndef ITEM_EXPANSION if ((itemEffect[0] & (ITEM0_DIRE_HIT | ITEM0_X_ATTACK)) || itemEffect[1] || itemEffect[2] || (itemEffect[3] & ITEM3_GUARD_SPEC)) +#else + if ((itemEffect[0] & ITEM0_DIRE_HIT) || itemEffect[1] || (itemEffect[3] & ITEM3_GUARD_SPEC)) +#endif return ITEM_EFFECT_X_ITEM; else if (itemEffect[0] & ITEM0_SACRED_ASH) return ITEM_EFFECT_SACRED_ASH; diff --git a/src/pokemon.c b/src/pokemon.c index 136aa4f174..d2e87f26d1 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -46,6 +46,7 @@ #include "constants/moves.h" #include "constants/songs.h" #include "constants/trainers.h" +#include "constants/battle_config.h" struct SpeciesItem { @@ -1386,6 +1387,8 @@ const s8 gNatureStatTable[NUM_NATURES][NUM_NATURE_STATS] = #include "data/pokemon/level_up_learnsets.h" #include "data/pokemon/evolution.h" #include "data/pokemon/level_up_learnset_pointers.h" +#include "data/pokemon/form_species_tables.h" +#include "data/pokemon/form_species_table_pointers.h" // SPECIES_NONE are ignored in the following two tables, so decrement before accessing these arrays to get the right result @@ -2051,7 +2054,11 @@ static const u8 sGetMonDataEVConstants[] = // For stat-raising items static const u8 sStatsToRaise[] = { +#ifndef ITEM_EXPANSION STAT_ATK, STAT_ATK, STAT_SPEED, STAT_DEF, STAT_SPATK, STAT_ACC +#else + STAT_ATK, STAT_ATK, STAT_DEF, STAT_SPEED, STAT_SPATK, STAT_SPDEF, STAT_ACC +#endif }; // 3 modifiers each for how much to change friendship for different ranges @@ -4433,21 +4440,30 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov gBattleMons[gActiveBattler].status2 |= STATUS2_FOCUS_ENERGY; retVal = FALSE; } + #ifndef ITEM_EXPANSION if ((itemEffect[cmdIndex] & ITEM0_X_ATTACK) && gBattleMons[gActiveBattler].statStages[STAT_ATK] < MAX_STAT_STAGE) { - gBattleMons[gActiveBattler].statStages[STAT_ATK] += itemEffect[cmdIndex] & ITEM0_X_ATTACK; + if (B_X_ITEMS_BUFF == GEN_7) + gBattleMons[gActiveBattler].statStages[STAT_ATK] += 2; + else + gBattleMons[gActiveBattler].statStages[STAT_ATK] += itemEffect[cmdIndex] & ITEM0_X_ATTACK; if (gBattleMons[gActiveBattler].statStages[STAT_ATK] > MAX_STAT_STAGE) gBattleMons[gActiveBattler].statStages[STAT_ATK] = MAX_STAT_STAGE; retVal = FALSE; } + #endif break; // in-battle stat boosting effects + #ifndef ITEM_EXPANSION case 1: if ((itemEffect[cmdIndex] & ITEM1_X_DEFEND) && gBattleMons[gActiveBattler].statStages[STAT_DEF] < MAX_STAT_STAGE) { - gBattleMons[gActiveBattler].statStages[STAT_DEF] += (itemEffect[cmdIndex] & ITEM1_X_DEFEND) >> 4; + if (B_X_ITEMS_BUFF == GEN_7) + gBattleMons[gActiveBattler].statStages[STAT_DEF] += 2; + else + gBattleMons[gActiveBattler].statStages[STAT_DEF] += (itemEffect[cmdIndex] & ITEM1_X_DEFEND) >> 4; if (gBattleMons[gActiveBattler].statStages[STAT_DEF] > MAX_STAT_STAGE) gBattleMons[gActiveBattler].statStages[STAT_DEF] = MAX_STAT_STAGE; retVal = FALSE; @@ -4455,7 +4471,10 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov if ((itemEffect[cmdIndex] & ITEM1_X_SPEED) && gBattleMons[gActiveBattler].statStages[STAT_SPEED] < MAX_STAT_STAGE) { - gBattleMons[gActiveBattler].statStages[STAT_SPEED] += itemEffect[cmdIndex] & ITEM1_X_SPEED; + if (B_X_ITEMS_BUFF == GEN_7) + gBattleMons[gActiveBattler].statStages[STAT_SPEED] += 2; + else + gBattleMons[gActiveBattler].statStages[STAT_SPEED] += itemEffect[cmdIndex] & ITEM1_X_SPEED; if (gBattleMons[gActiveBattler].statStages[STAT_SPEED] > MAX_STAT_STAGE) gBattleMons[gActiveBattler].statStages[STAT_SPEED] = MAX_STAT_STAGE; retVal = FALSE; @@ -4466,7 +4485,10 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov if ((itemEffect[cmdIndex] & ITEM2_X_ACCURACY) && gBattleMons[gActiveBattler].statStages[STAT_ACC] < MAX_STAT_STAGE) { - gBattleMons[gActiveBattler].statStages[STAT_ACC] += (itemEffect[cmdIndex] & ITEM2_X_ACCURACY) >> 4; + if (B_X_ITEMS_BUFF == GEN_7) + gBattleMons[gActiveBattler].statStages[STAT_ACC] += 2; + else + gBattleMons[gActiveBattler].statStages[STAT_ACC] += (itemEffect[cmdIndex] & ITEM2_X_ACCURACY) >> 4; if (gBattleMons[gActiveBattler].statStages[STAT_ACC] > MAX_STAT_STAGE) gBattleMons[gActiveBattler].statStages[STAT_ACC] = MAX_STAT_STAGE; retVal = FALSE; @@ -4474,12 +4496,89 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov if ((itemEffect[cmdIndex] & ITEM2_X_SPATK) && gBattleMons[gActiveBattler].statStages[STAT_SPATK] < MAX_STAT_STAGE) { - gBattleMons[gActiveBattler].statStages[STAT_SPATK] += itemEffect[cmdIndex] & ITEM2_X_SPATK; + if (B_X_ITEMS_BUFF == GEN_7) + gBattleMons[gActiveBattler].statStages[STAT_SPATK] += 2; + else + gBattleMons[gActiveBattler].statStages[STAT_SPATK] += itemEffect[cmdIndex] & ITEM2_X_SPATK; if (gBattleMons[gActiveBattler].statStages[STAT_SPATK] > MAX_STAT_STAGE) gBattleMons[gActiveBattler].statStages[STAT_SPATK] = MAX_STAT_STAGE; retVal = FALSE; } break; + #else + // in-battle stat boosting effects + case 1: + if ((itemEffect[cmdIndex] & ITEM1_X_ATTACK) + && gBattleMons[gActiveBattler].statStages[STAT_ATK] < MAX_STAT_STAGE) + { + if (B_X_ITEMS_BUFF == GEN_7) + gBattleMons[gActiveBattler].statStages[STAT_ATK] += 2; + else + gBattleMons[gActiveBattler].statStages[STAT_ATK] += 1; + if (gBattleMons[gActiveBattler].statStages[STAT_ATK] > MAX_STAT_STAGE) + gBattleMons[gActiveBattler].statStages[STAT_ATK] = MAX_STAT_STAGE; + retVal = FALSE; + } + if ((itemEffect[cmdIndex] & ITEM1_X_DEFENSE) + && gBattleMons[gActiveBattler].statStages[STAT_DEF] < MAX_STAT_STAGE) + { + if (B_X_ITEMS_BUFF == GEN_7) + gBattleMons[gActiveBattler].statStages[STAT_DEF] += 2; + else + gBattleMons[gActiveBattler].statStages[STAT_DEF] += 1; + if (gBattleMons[gActiveBattler].statStages[STAT_DEF] > MAX_STAT_STAGE) + gBattleMons[gActiveBattler].statStages[STAT_DEF] = MAX_STAT_STAGE; + retVal = FALSE; + } + if ((itemEffect[cmdIndex] & ITEM1_X_SPEED) + && gBattleMons[gActiveBattler].statStages[STAT_SPEED] < MAX_STAT_STAGE) + { + if (B_X_ITEMS_BUFF == GEN_7) + gBattleMons[gActiveBattler].statStages[STAT_SPEED] += 2; + else + gBattleMons[gActiveBattler].statStages[STAT_SPEED] += 1; + if (gBattleMons[gActiveBattler].statStages[STAT_SPEED] > MAX_STAT_STAGE) + gBattleMons[gActiveBattler].statStages[STAT_SPEED] = MAX_STAT_STAGE; + retVal = FALSE; + } + if ((itemEffect[cmdIndex] & ITEM1_X_SPATK) + && gBattleMons[gActiveBattler].statStages[STAT_SPATK] < MAX_STAT_STAGE) + { + if (B_X_ITEMS_BUFF == GEN_7) + gBattleMons[gActiveBattler].statStages[STAT_SPATK] += 2; + else + gBattleMons[gActiveBattler].statStages[STAT_SPATK] += 1; + if (gBattleMons[gActiveBattler].statStages[STAT_SPATK] > MAX_STAT_STAGE) + gBattleMons[gActiveBattler].statStages[STAT_SPATK] = MAX_STAT_STAGE; + retVal = FALSE; + } + if ((itemEffect[cmdIndex] & ITEM1_X_SPDEF) + && gBattleMons[gActiveBattler].statStages[STAT_SPDEF] < MAX_STAT_STAGE) + { + if (B_X_ITEMS_BUFF == GEN_7) + gBattleMons[gActiveBattler].statStages[STAT_SPDEF] += 2; + else + gBattleMons[gActiveBattler].statStages[STAT_SPDEF] += 1; + if (gBattleMons[gActiveBattler].statStages[STAT_SPDEF] > MAX_STAT_STAGE) + gBattleMons[gActiveBattler].statStages[STAT_SPDEF] = MAX_STAT_STAGE; + retVal = FALSE; + } + if ((itemEffect[cmdIndex] & ITEM1_X_ACCURACY) + && gBattleMons[gActiveBattler].statStages[STAT_ACC] < MAX_STAT_STAGE) + { + if (B_X_ITEMS_BUFF == GEN_7) + gBattleMons[gActiveBattler].statStages[STAT_ACC] += 2; + else + gBattleMons[gActiveBattler].statStages[STAT_ACC] += 1; + if (gBattleMons[gActiveBattler].statStages[STAT_ACC] > MAX_STAT_STAGE) + gBattleMons[gActiveBattler].statStages[STAT_ACC] = MAX_STAT_STAGE; + retVal = FALSE; + } + break; + // formerly used by the item effects of the X Sp. Atk and the X Accuracy + case 2: + break; + #endif case 3: if ((itemEffect[cmdIndex] & ITEM3_GUARD_SPEC) && gSideTimers[GetBattlerSide(gActiveBattler)].mistTimer == 0) @@ -5027,7 +5126,15 @@ static void BufferStatRoseMessage(s32 arg0) { gBattlerTarget = gBattlerInMenuId; StringCopy(gBattleTextBuff1, gStatNamesTable[sStatsToRaise[arg0]]); - StringCopy(gBattleTextBuff2, gText_StatRose); + if (B_X_ITEMS_BUFF == GEN_7) + { + StringCopy(gBattleTextBuff2, gText_StatSharply); + StringAppend(gBattleTextBuff2, gText_StatRose); + } + else + { + StringCopy(gBattleTextBuff2, gText_StatRose); + } BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnsStatChanged2); } @@ -5050,6 +5157,7 @@ u8 *UseStatIncreaseItem(u16 itemId) gPotentialItemEffectBattler = gBattlerInMenuId; +#ifndef ITEM_EXPANSION for (i = 0; i < 3; i++) { if (itemEffect[i] & (ITEM0_X_ATTACK | ITEM1_X_SPEED | ITEM2_X_SPATK)) @@ -5074,6 +5182,41 @@ u8 *UseStatIncreaseItem(u16 itemId) gBattlerAttacker = gBattlerInMenuId; BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnShroudedInMist); } +#else + if (itemEffect[0] & ITEM0_DIRE_HIT) + { + gBattlerAttacker = gBattlerInMenuId; + BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnGettingPumped); + } + + switch (itemEffect[1]) + { + case ITEM1_X_ATTACK: + BufferStatRoseMessage(STAT_ATK); + break; + case ITEM1_X_DEFENSE: + BufferStatRoseMessage(STAT_DEF); + break; + case ITEM1_X_SPEED: + BufferStatRoseMessage(STAT_SPEED); + break; + case ITEM1_X_SPATK: + BufferStatRoseMessage(STAT_SPATK); + break; + case ITEM1_X_SPDEF: + BufferStatRoseMessage(STAT_SPDEF); + break; + case ITEM1_X_ACCURACY: + BufferStatRoseMessage(STAT_ACC); + break; + } + + if (itemEffect[3] & ITEM3_GUARD_SPEC) + { + gBattlerAttacker = gBattlerInMenuId; + BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnShroudedInMist); + } +#endif return gDisplayedStringBattle; } @@ -6725,3 +6868,26 @@ u8 *sub_806F4F8(u8 id, u8 arg1) return structPtr->byteArrays[arg1]; } } + +u16 GetFormSpeciesId(u16 speciesId, u8 formId) +{ + if (gFormSpeciesIdTables[speciesId] != NULL) + return gFormSpeciesIdTables[speciesId][formId]; + else + return speciesId; +} + +u8 GetFormIdFromFormSpeciesId(u16 formSpeciesId) +{ + u8 targetFormId = 0; + + if (gFormSpeciesIdTables[formSpeciesId] != NULL) + { + for (targetFormId = 0; gFormSpeciesIdTables[formSpeciesId][targetFormId] != FORM_SPECIES_END; targetFormId++) + { + if (formSpeciesId == gFormSpeciesIdTables[formSpeciesId][targetFormId]) + break; + } + } + return targetFormId; +}