diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 4bfef447b8..c62255f892 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -2374,8 +2374,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 @@ -2385,7 +2385,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 f4b2ab7a74..bff609d598 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -6837,12 +6837,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/graphics/interface_fr/menu.png b/graphics/interface_fr/menu.png index a04c981d5d..b16d008cb3 100644 Binary files a/graphics/interface_fr/menu.png and b/graphics/interface_fr/menu.png differ diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index 4c2e14f7f2..fffd85c5b5 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -77,7 +77,7 @@ s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef); u8 GetMoveDamageResult(u16 move); u32 GetCurrDamageHpPercent(u8 battlerAtk, u8 battlerDef); u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef); -u8 AI_GetMoveEffectiveness(u16 move); +u8 AI_GetMoveEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef); u16 *GetMovesArray(u32 battler); bool32 IsConfusionMoveEffect(u16 moveEffect); bool32 HasMove(u32 battlerId, u32 move); diff --git a/include/battle_message.h b/include/battle_message.h index 06f030860c..900c3b1eb6 100644 --- a/include/battle_message.h +++ b/include/battle_message.h @@ -286,6 +286,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 2c90289ed1..09812dff21 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -126,6 +126,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. #define B_MENTAL_HERB GEN_5 // In Gen5+, mental herb cures Taunt, Encore, Heal Block, and Disable // Flag settings @@ -152,23 +153,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 cd2ea68da6..6e9d9a22df 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; @@ -421,5 +423,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_main.c b/src/battle_ai_main.c index efa5cfc2b8..932b19037e 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -515,7 +515,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) u8 moveType = gBattleMoves[move].type; u8 moveTarget = gBattleMoves[move].target; u16 accuracy = AI_GetMoveAccuracy(battlerAtk, battlerDef, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect, move); - u8 effectiveness = AI_GetMoveEffectiveness(move); + u8 effectiveness = AI_GetMoveEffectiveness(move, battlerAtk, battlerDef); bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk); u32 i; u16 predictedMove = gLastMoves[battlerDef]; // TODO better move prediction @@ -547,8 +547,21 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) } // check if negates type - if (!IS_MOVE_STATUS(move) && (effectiveness == AI_EFFECTIVENESS_x0 || effectiveness == AI_EFFECTIVENESS_x0)) - score -= 10; + if (!(gBattleMoves[move].target & MOVE_TARGET_USER)) + { + if (gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE && GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) != 1) + RETURN_SCORE_MINUS(20); // if target off screen and we go first, don't use move + + switch (effectiveness) + { + case AI_EFFECTIVENESS_x0: + RETURN_SCORE_MINUS(20); + break; + case AI_EFFECTIVENESS_x0_25: + RETURN_SCORE_MINUS(10); + break; + } + } // target ability checks if (!DoesBattlerIgnoreAbilityChecks(AI_DATA->atkAbility, move)) @@ -2421,7 +2434,7 @@ static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) if (GetMoveDamageResult(move) == MOVE_POWER_DISCOURAGED) score--; - if (AI_GetMoveEffectiveness(move) == AI_EFFECTIVENESS_x4) + if (AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x4) { // AI_TryToFaint_DoubleSuperEffective if ((Random() % 256) >= 80) @@ -2506,7 +2519,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) case EFFECT_MAGNET_RISE: if (IsBattlerGrounded(battlerAtk) && (HasMove(battlerAtkPartner, MOVE_EARTHQUAKE) || HasMove(battlerAtkPartner, MOVE_MAGNITUDE)) - && (AI_GetMoveEffectiveness(MOVE_EARTHQUAKE) != AI_EFFECTIVENESS_x0)) // Doesn't resist ground move + && (AI_GetMoveEffectiveness(MOVE_EARTHQUAKE, battlerAtk, battlerAtkPartner) != AI_EFFECTIVENESS_x0)) // Doesn't resist ground move { RETURN_SCORE_PLUS(2); // partner has earthquake or magnitude -> good idea to use magnet rise } @@ -2808,7 +2821,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) { // move data u16 moveEffect = gBattleMoves[move].effect; - u8 effectiveness = AI_GetMoveEffectiveness(move); + u8 effectiveness = AI_GetMoveEffectiveness(move, battlerAtk, battlerDef); u8 atkPriority = GetMovePriority(battlerAtk, move); u16 predictedMove = gLastMoves[battlerDef]; //for now bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk); @@ -2861,7 +2874,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) }*/ // check status move preference - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_PREFER_STATUS_MOVES && IS_MOVE_STATUS(move)) + if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_PREFER_STATUS_MOVES && IS_MOVE_STATUS(move) && effectiveness != AI_EFFECTIVENESS_x0) score++; // check thawing moves diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 0bd00de65b..2a5bdd34b5 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -774,7 +774,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; @@ -884,6 +888,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) @@ -896,6 +901,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_ai_util.c b/src/battle_ai_util.c index a580060dcf..018dc55a51 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -892,14 +892,15 @@ u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef) return typeEffectiveness; } -u8 AI_GetMoveEffectiveness(u16 move) +u8 AI_GetMoveEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef) { u8 damageVar; u32 effectivenessMultiplier; gMoveResultFlags = 0; gCurrentMove = move; - effectivenessMultiplier = AI_GetTypeEffectiveness(gCurrentMove, sBattler_AI, gBattlerTarget); + effectivenessMultiplier = AI_GetTypeEffectiveness(gCurrentMove, battlerAtk, battlerDef); + switch (effectivenessMultiplier) { case UQ_4_12(0.0): @@ -2555,6 +2556,7 @@ bool32 CanSleep(u8 battler, u16 ability) bool32 AI_CanPutToSleep(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove) { if (!CanSleep(battlerDef, defAbility) + || AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 || DoesSubstituteBlockMove(battlerAtk, battlerDef, move) || PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove)) // shouldn't try to sleep mon that partner is trying to make sleep return FALSE; @@ -2590,6 +2592,7 @@ bool32 ShouldPoisonSelf(u8 battler, u16 ability) bool32 AI_CanPoison(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove) { if (!CanBePoisoned(battlerDef, defAbility) + || AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 || DoesSubstituteBlockMove(battlerAtk, battlerDef, move) || PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove)) return FALSE; @@ -2614,6 +2617,7 @@ static bool32 CanBeParayzed(u8 battler, u16 ability) bool32 AI_CanParalyze(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove) { if (!CanBeParayzed(battlerDef, defAbility) + || AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 || gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD || DoesSubstituteBlockMove(battlerAtk, battlerDef, move) || PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove)) @@ -2633,6 +2637,7 @@ bool32 CanBeConfused(u8 battler, u16 ability) bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove) { if (!CanBeConfused(battlerDef, defAbility) + || AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 || gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD || DoesSubstituteBlockMove(battlerAtk, battlerDef, move) || DoesPartnerHaveSameMoveEffect(battlerAtkPartner, battlerDef, move, partnerMove)) @@ -2672,6 +2677,7 @@ bool32 ShouldBurnSelf(u8 battler, u16 ability) bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove) { if (!CanBeBurned(battlerDef, defAbility) + || AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 || DoesSubstituteBlockMove(battlerAtk, battlerDef, move) || PartnerMoveEffectIsStatusSameTarget(battlerAtkPartner, battlerDef, partnerMove)) { @@ -2683,6 +2689,7 @@ bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPar bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGender, u8 defGender) { if ((gBattleMons[battlerDef].status2 & STATUS2_INFATUATION) + || AI_GetMoveEffectiveness(AI_THINKING_STRUCT->moveConsidered, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 || defAbility == ABILITY_OBLIVIOUS || atkGender == defGender || atkGender == MON_GENDERLESS diff --git a/src/battle_controllers.c b/src/battle_controllers.c index b819fb5ea4..eefb110eb4 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 267b06ece1..a77aacde5d 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -1011,7 +1011,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 536273a693..90e8c89671 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!"); @@ -925,7 +925,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 953484506a..db2d05f855 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2467,9 +2467,9 @@ u8 DoBattlerEndTurnEffects(void) PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleStruct->wrappedMove[gActiveBattler]); gBattlescriptCurrInstr = BattleScript_WrapTurnDmg; if (GetBattlerHoldEffect(gBattleStruct->wrappedBy[gActiveBattler], TRUE) == HOLD_EFFECT_BINDING_BAND) - gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / (B_BINDING_DAMAGE >= GEN_6) ? 6 : 8; + gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / ((B_BINDING_DAMAGE >= GEN_6) ? 6 : 8); else - gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / (B_BINDING_DAMAGE >= GEN_6) ? 8 : 16; + gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / ((B_BINDING_DAMAGE >= GEN_6) ? 8 : 16); if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; @@ -7239,7 +7239,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/menu.c b/src/menu.c index 4813f7b028..69c7a98854 100644 --- a/src/menu.c +++ b/src/menu.c @@ -119,6 +119,7 @@ static const struct MenuInfoIcon sMenuInfoIcons[] = [TYPE_ICE + 1] = { 32, 12, 0x4C }, [TYPE_DRAGON + 1] = { 32, 12, 0xA0 }, [TYPE_DARK + 1] = { 32, 12, 0x8C }, + [TYPE_FAIRY + 1] = { 32, 12, 0x4 }, [MENU_INFO_ICON_TYPE] = { 42, 12, 0xA8 }, [MENU_INFO_ICON_POWER] = { 42, 12, 0xC0 }, [MENU_INFO_ICON_ACCURACY] = { 42, 12, 0xC8 }, 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 4bc6230f99..6ad66cc6f0 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -45,6 +45,7 @@ #include "constants/moves.h" #include "constants/songs.h" #include "constants/trainers.h" +#include "constants/battle_config.h" struct SpeciesItem { @@ -1385,6 +1386,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 @@ -2050,7 +2053,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 @@ -4432,21 +4439,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; @@ -4454,7 +4470,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; @@ -4465,7 +4484,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; @@ -4473,12 +4495,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) @@ -5026,7 +5125,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); } @@ -5049,6 +5156,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)) @@ -5073,6 +5181,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; } @@ -6724,3 +6867,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; +}