Reworked the effects of the X Items

Thanks to Karathan's indications.
This commit is contained in:
LOuroboros 2020-12-08 17:45:11 -03:00
parent 38b61ac5a0
commit 791d561f14
5 changed files with 158 additions and 0 deletions

View File

@ -123,6 +123,8 @@
// 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 X_ITEMS_REWORK FALSE // This flag changes the way in which X Items' effects are implemented in the code and relies on the item_expansion to work.
#define B_X_ITEMS_BUFF GEN_7 // In Gen7+, the X Items raise a stat by 2 stages instead of 1. This flag relies on X_ITEMS_REWORK, and by extension, the item_expansion.
// Flag settings.
// To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. Eg: Replace with FLAG_UNUSED_0x264 so you can use that flag for toggling the feature.

View File

@ -2,18 +2,32 @@
#define GUARD_CONSTANTS_ITEM_EFFECTS_H
// field 0 masks
#if X_ITEMS_REWORK == FALSE
#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
// field 1 masks
#if X_ITEMS_REWORK == FALSE
#define ITEM1_X_SPEED 0x0F
#define ITEM1_X_DEFEND 0xF0
// field 2 masks
#define ITEM2_X_SPATK 0x0F
#define ITEM2_X_ACCURACY 0xF0
#endif
// alt field 1 masks
#if X_ITEMS_REWORK == TRUE
#define ITEM1_X_ATTACK 0x1
#define ITEM1_X_DEFEND 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

View File

@ -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;
#if X_ITEMS_REWORK == TRUE
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;
#if X_ITEMS_REWORK == FALSE
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_DEFEND)
*(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:

View File

@ -5186,7 +5186,11 @@ u8 GetItemEffectType(u16 item)
else
itemEffect = gItemEffectTable[item - ITEM_POTION];
#if X_ITEMS_REWORK == FALSE
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;

View File

@ -45,6 +45,7 @@
#include "constants/moves.h"
#include "constants/songs.h"
#include "constants/trainers.h"
#include "constants/battle_config.h"
struct SpeciesItem
{
@ -2050,7 +2051,11 @@ static const u8 sGetMonDataEVConstants[] =
// For stat-raising items
static const u8 sStatsToRaise[] =
{
#if X_ITEMS_REWORK == FALSE
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
@ -4429,6 +4434,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
gBattleMons[gActiveBattler].status2 |= STATUS2_FOCUS_ENERGY;
retVal = FALSE;
}
#if X_ITEMS_REWORK == FALSE
if ((itemEffect[cmdIndex] & ITEM0_X_ATTACK)
&& gBattleMons[gActiveBattler].statStages[STAT_ATK] < MAX_STAT_STAGE)
{
@ -4437,8 +4443,10 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
gBattleMons[gActiveBattler].statStages[STAT_ATK] = MAX_STAT_STAGE;
retVal = FALSE;
}
#endif
break;
// in-battle stat boosting effects
#if X_ITEMS_REWORK == FALSE
case 1:
if ((itemEffect[cmdIndex] & ITEM1_X_DEFEND)
&& gBattleMons[gActiveBattler].statStages[STAT_DEF] < MAX_STAT_STAGE)
@ -4476,6 +4484,79 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
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_DEFEND)
&& 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:
#endif
case 3:
if ((itemEffect[cmdIndex] & ITEM3_GUARD_SPEC)
&& gSideTimers[GetBattlerSide(gActiveBattler)].mistTimer == 0)
@ -5046,6 +5127,7 @@ u8 *UseStatIncreaseItem(u16 itemId)
gPotentialItemEffectBattler = gBattlerInMenuId;
#if X_ITEMS_REWORK == FALSE
for (i = 0; i < 3; i++)
{
if (itemEffect[i] & (ITEM0_X_ATTACK | ITEM1_X_SPEED | ITEM2_X_SPATK))
@ -5070,6 +5152,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_DEFEND:
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;
}