Add mirror herb (#2873)

This commit is contained in:
Eduardo Quezada D'Ottone 2023-05-06 21:20:37 -04:00 committed by GitHub
commit c530eb2445
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 120 additions and 6 deletions

View File

@ -10024,23 +10024,42 @@ BattleScript_PrintPlayerForfeitedLinkBattle::
end2
BattleScript_TotemFlaredToLife::
playanimation BS_ATTACKER, B_ANIM_TOTEM_FLARE
playanimation BS_ATTACKER, B_ANIM_TOTEM_FLARE, NULL
printstring STRINGID_AURAFLAREDTOLIFE
waitmessage B_WAIT_TIME_LONG
goto BattleScript_ApplyTotemVarBoost
call BattleScript_ApplyTotemVarBoost
end2
@ remove the mirror herb, do totem loop
BattleScript_MirrorHerbCopyStatChangeEnd2::
call BattleScript_MirrorHerbCopyStatChange
end2
BattleScript_MirrorHerbCopyStatChange::
playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, NULL
printstring STRINGID_MIRRORHERBCOPIED
waitmessage B_WAIT_TIME_LONG
removeitem BS_SCRIPTING
call BattleScript_TotemVar_Ret
copybyte gBattlerAttacker, sSAVED_BATTLER @ restore the original attacker just to be safe
return
BattleScript_TotemVar::
call BattleScript_TotemVar_Ret
end2
BattleScript_TotemVar_Ret::
gettotemboost BattleScript_ApplyTotemVarBoost
BattleScript_TotemVarEnd:
end2
return
BattleScript_ApplyTotemVarBoost:
statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_TotemVarEnd
setgraphicalstatchangevalues
playanimation BS_SCRIPTING, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
BattleScript_TotemVarPrintStatMsg:
printfromtable gStatUpStringIds
waitmessage B_WAIT_TIME_LONG
goto BattleScript_TotemVar @loop until stats bitfield is empty
goto BattleScript_TotemVar_Ret @loop until stats bitfield is empty
BattleScript_AnnounceAirLockCloudNine::
call BattleScript_AbilityPopUp

View File

@ -147,6 +147,7 @@ struct ProtectStruct
u16 quash:1;
u16 shellTrap:1;
u16 silkTrapped:1;
u16 eatMirrorHerb:1;
u32 physicalDmg;
u32 specialDmg;
u8 physicalBattlerId;

View File

@ -1,6 +1,8 @@
#ifndef GUARD_BATTLE_SCRIPTS_H
#define GUARD_BATTLE_SCRIPTS_H
extern const u8 BattleScript_MirrorHerbCopyStatChange[];
extern const u8 BattleScript_MirrorHerbCopyStatChangeEnd2[];
extern const u8 BattleScript_NotAffected[];
extern const u8 BattleScript_HitFromCritCalc[];
extern const u8 BattleScript_MoveEnd[];

View File

@ -659,8 +659,9 @@
#define STRINGID_PKMNFROSTBITEHEALED 657
#define STRINGID_PKMNFROSTBITEHEALED2 658
#define STRINGID_PKMNFROSTBITEHEALEDBY 659
#define STRINGID_MIRRORHERBCOPIED 660
#define BATTLESTRINGS_COUNT 660
#define BATTLESTRINGS_COUNT 661
// This is the string id that gBattleStringsTable starts with.
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,

View File

@ -794,9 +794,11 @@ static const u8 sText_ItemRestoredSpeciesHealth[] = _("{B_BUFF1} had its\nHP res
static const u8 sText_ItemCuredSpeciesStatus[] = _("{B_BUFF1} had\nits status healed!");
static const u8 sText_ItemRestoredSpeciesPP[] = _("{B_BUFF1} had its\nPP restored!");
static const u8 sText_AtkTrappedDef[] = _("{B_ATK_NAME_WITH_PREFIX} trapped\nthe {B_DEF_NAME_WITH_PREFIX}!");
static const u8 sText_MirrorHerbCopied[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} used its {B_LAST_ITEM}\nto mirror its opponent's stat changes!");
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
{
[STRINGID_MIRRORHERBCOPIED - BATTLESTRINGS_TABLE_START] = sText_MirrorHerbCopied,
[STRINGID_THUNDERCAGETRAPPED - BATTLESTRINGS_TABLE_START] = sText_AtkTrappedDef,
[STRINGID_ITEMRESTOREDSPECIESHEALTH - BATTLESTRINGS_TABLE_START] = sText_ItemRestoredSpeciesHealth,
[STRINGID_ITEMCUREDSPECIESSTATUS - BATTLESTRINGS_TABLE_START] = sText_ItemCuredSpeciesStatus,

View File

@ -12130,6 +12130,20 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
{
gBattleCommunication[MULTISTRING_CHOOSER] = (gBattlerTarget == gActiveBattler);
gProtectStructs[gActiveBattler].statRaised = TRUE;
// check mirror herb
for (index = 0; index < gBattlersCount; index++)
{
if (GetBattlerSide(index) == GetBattlerSide(gActiveBattler))
continue; // Only triggers on opposing side
if (GetBattlerHoldEffect(index, TRUE) == HOLD_EFFECT_MIRROR_HERB
&& gBattleMons[index].statStages[statId] < MAX_STAT_STAGE)
{
gProtectStructs[index].eatMirrorHerb = 1;
gTotemBoosts[index].stats |= (1 << (statId - 1)); // -1 to start at atk
gTotemBoosts[index].statChanges[statId - 1] = statValue;
}
}
}
}

View File

@ -6780,6 +6780,26 @@ static bool32 GetMentalHerbEffect(u8 battlerId)
return ret;
}
static u8 TryConsumeMirrorHerb(u8 battlerId, bool32 execute)
{
u8 effect = 0;
if (gProtectStructs[battlerId].eatMirrorHerb) {
gLastUsedItem = gBattleMons[battlerId].item;
gBattleScripting.savedBattler = gBattlerAttacker;
gBattleScripting.battler = gBattlerAttacker = battlerId;
gProtectStructs[battlerId].eatMirrorHerb = 0;
if (execute) {
BattleScriptExecute(BattleScript_MirrorHerbCopyStatChangeEnd2);
} else {
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MirrorHerbCopyStatChange;
}
effect = ITEM_STATS_CHANGE;
}
return effect;
}
static u8 ItemEffectMoveEnd(u32 battlerId, u16 holdEffect)
{
u8 effect = 0;
@ -6983,6 +7003,9 @@ static u8 ItemEffectMoveEnd(u32 battlerId, u16 holdEffect)
BattleScriptPushCursorAndCallback(BattleScript_BerserkGeneRet);
effect = ITEM_STATS_CHANGE;
break;
case HOLD_EFFECT_MIRROR_HERB:
effect = TryConsumeMirrorHerb(battlerId, FALSE);
break;
}
return effect;
@ -7547,6 +7570,9 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
BattleScriptPushCursorAndCallback(BattleScript_BerserkGeneRet);
effect = ITEM_STATS_CHANGE;
break;
case HOLD_EFFECT_MIRROR_HERB:
effect = TryConsumeMirrorHerb(battlerId, TRUE);
break;
}
if (effect != 0)

View File

@ -0,0 +1,49 @@
#include "global.h"
#include "test_battle.h"
ASSUMPTIONS
{
ASSUME(gItems[ITEM_MIRROR_HERB].holdEffect == HOLD_EFFECT_MIRROR_HERB);
}
SINGLE_BATTLE_TEST("Mirror Herb copies all of foe's stat changes in a turn", s16 damage)
{
u32 item;
PARAMETRIZE{ item = ITEM_NONE; }
PARAMETRIZE{ item = ITEM_MIRROR_HERB; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(5); Item(item); }
} WHEN {
TURN { MOVE(player, MOVE_DRAGON_DANCE); }
TURN { MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_TACKLE); }
} SCENE {
if (item == ITEM_NONE) {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
HP_BAR(player, captureDamage: &results[i].damage);
} else {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
HP_BAR(player, captureDamage: &results[i].damage);
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player);
}
} FINALLY {
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
EXPECT_EQ(player->statStages[STAT_ATK], opponent->statStages[STAT_ATK]);
EXPECT_EQ(player->statStages[STAT_SPEED], opponent->statStages[STAT_SPEED]);
}
}
SINGLE_BATTLE_TEST("Mirror Herb copies all of of Stuff Cheeks", s16 damage)
{
GIVEN {
ASSUME(gItems[ITEM_LIECHI_BERRY].holdEffect == HOLD_EFFECT_ATTACK_UP);
PLAYER(SPECIES_SKWOVET) { Item(ITEM_LIECHI_BERRY); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_MIRROR_HERB); }
} WHEN {
TURN { MOVE(player, MOVE_STUFF_CHEEKS); }
} THEN {
EXPECT_EQ(player->statStages[STAT_ATK], opponent->statStages[STAT_ATK]);
EXPECT_EQ(player->statStages[STAT_DEF], opponent->statStages[STAT_DEF]);
}
}