mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-27 20:24:18 +01:00
add red card effect
This commit is contained in:
parent
bf644f23a7
commit
5eb49722c0
@ -5592,16 +5592,27 @@ BattleScript_RoarSuccessSwitch::
|
||||
waitstate
|
||||
printstring STRINGID_PKMNWASDRAGGEDOUT
|
||||
switchineffects BS_TARGET
|
||||
jumpifbyte CMP_EQUAL, sSWITCH_CASE, B_SWITCH_RED_CARD, BattleScript_RoarSuccessSwitch_Ret
|
||||
setbyte sSWITCH_CASE, B_SWITCH_NORMAL
|
||||
goto BattleScript_MoveEnd
|
||||
BattleScript_RoarSuccessSwitch_Ret:
|
||||
swapattackerwithtarget @ continuation of RedCardActivates
|
||||
removeitem BS_TARGET
|
||||
setbyte sSWITCH_CASE, B_SWITCH_NORMAL
|
||||
return
|
||||
|
||||
BattleScript_RoarSuccessEndBattle::
|
||||
call BattleScript_RoarSuccessRet
|
||||
setbyte sSWITCH_CASE, B_SWITCH_NORMAL
|
||||
setoutcomeonteleport BS_ATTACKER
|
||||
finishaction
|
||||
|
||||
BattleScript_RoarSuccessRet:
|
||||
jumpifbyte CMP_EQUAL, sSWITCH_CASE, B_SWITCH_HIT, BattleScript_RoarSuccessRet_Ret
|
||||
jumpifbyte CMP_EQUAL, sSWITCH_CASE, B_SWITCH_RED_CARD, BattleScript_RoarSuccessRet_Ret
|
||||
attackanimation
|
||||
waitanimation
|
||||
BattleScript_RoarSuccessRet_Ret:
|
||||
switchoutabilities BS_TARGET
|
||||
returntoball BS_TARGET
|
||||
waitstate
|
||||
@ -7790,3 +7801,31 @@ BattleScript_AnnounceAirLockCloudNine::
|
||||
waitmessage 0x40
|
||||
call BattleScript_WeatherFormChanges
|
||||
end3
|
||||
|
||||
BattleScript_RedCardActivates::
|
||||
jumpifcantswitch SWITCH_IGNORE_ESCAPE_PREVENTION | BS_ATTACKER, BattleScript_RedCardEnd
|
||||
playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, NULL
|
||||
printstring STRINGID_REDCARDACTIVATE
|
||||
waitmessage 0x40
|
||||
swapattackerwithtarget
|
||||
jumpifstatus3 BS_EFFECT_BATTLER, STATUS3_ROOTED, BattleScript_RedCardIngrain
|
||||
jumpifability BS_EFFECT_BATTLER, ABILITY_SUCTION_CUPS, BattleScript_RedCardSuctionCups
|
||||
setbyte sSWITCH_CASE, B_SWITCH_RED_CARD
|
||||
forcerandomswitch BattleScript_RedCardEnd
|
||||
@ changes the current battle script. the rest happens in BattleScript_RoarSuccessSwitch_Ret, if switch is successful
|
||||
return
|
||||
BattleScript_RedCardEnd:
|
||||
return
|
||||
BattleScript_RedCardIngrain:
|
||||
printstring STRINGID_PKMNANCHOREDITSELF
|
||||
waitmessage 0x40
|
||||
removeitem BS_SCRIPTING
|
||||
swapattackerwithtarget
|
||||
return
|
||||
BattleScript_RedCardSuctionCups:
|
||||
printstring STRINGID_PKMNANCHORSITSELFWITH
|
||||
waitmessage 0x40
|
||||
removeitem BS_SCRIPTING
|
||||
swapattackerwithtarget
|
||||
return
|
||||
|
||||
|
@ -614,6 +614,7 @@ struct BattleScripting
|
||||
u16 multihitMoveEffect;
|
||||
u8 illusionNickHack; // To properly display nick in STRINGID_ENEMYABOUTTOSWITCHPKMN.
|
||||
bool8 fixedPopup; // force ability popup to stick until manually called back
|
||||
u8 switchCase; // special switching conditions, eg. red card
|
||||
};
|
||||
|
||||
// rom_80A5C6C
|
||||
|
@ -352,5 +352,6 @@ extern const u8 BattleScript_EmergencyExitWildNoPopUp[];
|
||||
extern const u8 BattleScript_CheekPouchActivates[];
|
||||
extern const u8 BattleScript_AnnounceAirLockCloudNine[];
|
||||
extern const u8 BattleScript_AttackerItemStatRaise[];
|
||||
extern const u8 BattleScript_RedCardActivates[];
|
||||
|
||||
#endif // GUARD_BATTLE_SCRIPTS_H
|
||||
|
@ -132,5 +132,6 @@ bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 battlerId);
|
||||
u8 GetBattleMoveSplit(u32 moveId);
|
||||
u8 TryHandleSeed(u8 battler, u32 terrainFlag, u8 statId, u16 itemId, bool32 execute);
|
||||
bool32 IsBattlerAffectedByHazards(u8 battlerId, bool32 toxicSpikes);
|
||||
|
||||
void SortBattlersBySpeed(u8 *battlers, bool8 slowToFast);
|
||||
bool32 TestSheerForceFlag(u8 battler, u16 move);
|
||||
#endif // GUARD_BATTLE_UTIL_H
|
||||
|
@ -36,6 +36,7 @@
|
||||
#define sMULTIHIT_EFFECT gBattleScripting + 0x30
|
||||
#define sILLUSION_NICK_HACK gBattleScripting + 0x32
|
||||
#define sFIXED_ABILITY_POPUP gBattleScripting + 0x33
|
||||
#define sSWITCH_CASE gBattleScripting + 0x34
|
||||
|
||||
#define cMULTISTRING_CHOOSER gBattleCommunication + 5
|
||||
|
||||
@ -234,4 +235,9 @@
|
||||
#define BIT_ACC 0x40
|
||||
#define BIT_EVASION 0x80
|
||||
|
||||
// switch cases
|
||||
#define B_SWITCH_NORMAL 0
|
||||
#define B_SWITCH_HIT 1 // dragon tail, circle throw
|
||||
#define B_SWITCH_RED_CARD 2
|
||||
|
||||
#endif // GUARD_CONSTANTS_BATTLE_SCRIPT_COMMANDS_H
|
||||
|
@ -558,8 +558,9 @@
|
||||
#define STRINGID_AURABREAKENTERS 554
|
||||
#define STRINGID_COMATOSEENTERS 555
|
||||
#define STRINGID_SCREENCLEANERENTERS 556
|
||||
#define STRINGID_REDCARDACTIVATE 557
|
||||
|
||||
#define BATTLESTRINGS_COUNT 557
|
||||
#define BATTLESTRINGS_COUNT 558
|
||||
|
||||
//// multichoice message IDs
|
||||
// switch in ability message
|
||||
|
@ -3042,6 +3042,10 @@ void SwitchInClearSetData(void)
|
||||
gCurrentMove = 0;
|
||||
gBattleStruct->arenaTurnCounter = 0xFF;
|
||||
|
||||
// reset damage to prevent things like red card activating if the switched-in mon is holding it
|
||||
gSpecialStatuses[gActiveBattler].physicalDmg = 0;
|
||||
gSpecialStatuses[gActiveBattler].specialDmg = 0;
|
||||
|
||||
ClearBattlerMoveHistory(gActiveBattler);
|
||||
ClearBattlerAbilityHistory(gActiveBattler);
|
||||
}
|
||||
|
@ -685,9 +685,11 @@ static const u8 sText_FairyAuraActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}
|
||||
static const u8 sText_AuraBreakActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} reversed all\nother POKéMON's auras!");
|
||||
static const u8 sText_ComatoseActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is drowsing!");
|
||||
static const u8 sText_ScreenCleanerActivates[] = _("All screens on the field were\ncleansed!");
|
||||
static const u8 sText_RedCardActivate[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} held up its {B_LAST_ITEM}\nagainst {B_ATK_NAME_WITH_PREFIX}!");
|
||||
|
||||
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
{
|
||||
[STRINGID_REDCARDACTIVATE - 12] = sText_RedCardActivate,
|
||||
[STRINGID_STATWASNOTLOWERED - 12] = sText_StatWasNotLowered,
|
||||
[STRINGID_CLOAKEDINAFREEZINGLIGHT - 12] = sText_CloakedInAFreezingLight,
|
||||
[STRINGID_DESTINYKNOTACTIVATES - 12] = sText_DestinyKnotActivates,
|
||||
|
@ -5010,22 +5010,47 @@ static void Cmd_moveend(void)
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
case MOVEEND_EJECT_BUTTON:
|
||||
/*if (gCurrentMove != MOVE_DRAGON_TAIL && gCurrentMove != MOVE_CIRCLE_THROW)
|
||||
{
|
||||
u8 battlers[4] = {0, 1, 2, 3};
|
||||
SortBattlersBySpeed
|
||||
}
|
||||
|
||||
BattleScript_ForceRandomSwitch*/
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
case MOVEEND_RED_CARD:
|
||||
if (gCurrentMove != MOVE_DRAGON_TAIL
|
||||
&& gCurrentMove != MOVE_CIRCLE_THROW
|
||||
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !TestSheerForceFlag(gBattlerAttacker, gCurrentMove)
|
||||
&& (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER || (gBattleTypeFlags & BATTLE_TYPE_TRAINER)))
|
||||
{
|
||||
u8 battlers[4] = {0, 1, 2, 3};
|
||||
SortBattlersBySpeed(battlers, FALSE);
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
u8 battler = battlers[i];
|
||||
// attacker is the one to be switched out, battler is one with red card
|
||||
if (battler != gBattlerAttacker
|
||||
&& IsBattlerAlive(battler)
|
||||
&& !DoesSubstituteBlockMove(gCurrentMove, gBattlerAttacker, battler)
|
||||
&& GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_RED_CARD
|
||||
&& (gSpecialStatuses[battler].physicalDmg != 0 || gSpecialStatuses[battler].specialDmg != 0))
|
||||
{
|
||||
gLastUsedItem = gBattleMons[battler].item;
|
||||
gActiveBattler = gBattleScripting.battler = battler; // battler with red card
|
||||
gEffectBattler = gBattlerAttacker;
|
||||
if (gBattleMoves[gCurrentMove].effect == EFFECT_HIT_ESCAPE)
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEnd; // prevent user switch-in selection
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_RedCardActivates;
|
||||
effect = TRUE;
|
||||
break; // only fastest red card activates
|
||||
}
|
||||
}
|
||||
}
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
case MOVEEND_EJECT_PACK:
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
case MOVEEND_LIFE_ORB:
|
||||
// TODO shell bell goes here too
|
||||
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIFE_ORB
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !(GetBattlerAbility(gBattlerAttacker) == ABILITY_SHEER_FORCE && gBattleMoves[gCurrentMove].flags & FLAG_SHEER_FORCE_BOOST)
|
||||
@ -7981,6 +8006,7 @@ static void Cmd_various(void)
|
||||
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& TARGET_TURN_DAMAGED)
|
||||
{
|
||||
gBattleScripting.switchCase = B_SWITCH_HIT;
|
||||
gBattlescriptCurrInstr = BattleScript_ForceRandomSwitch;
|
||||
}
|
||||
else
|
||||
|
@ -7930,3 +7930,49 @@ bool32 IsBattlerAffectedByHazards(u8 battlerId, bool32 toxicSpikes)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool32 TestSheerForceFlag(u8 battler, u16 move)
|
||||
{
|
||||
if (GetBattlerAbility(battler) == ABILITY_SHEER_FORCE && gBattleMoves[move].flags & FLAG_SHEER_FORCE_BOOST)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void SortBattlersBySpeed(u8 *battlers, bool8 slowToFast)
|
||||
{
|
||||
int i, j, currSpeed, currBattler;
|
||||
u16 speeds[4] = {0};
|
||||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
speeds[i] = GetBattlerTotalSpeedStat(battlers[i]);
|
||||
|
||||
for (i = 1; i < gBattlersCount; i++)
|
||||
{
|
||||
currBattler = battlers[i];
|
||||
currSpeed = speeds[i];
|
||||
j = i - 1;
|
||||
|
||||
if (slowToFast)
|
||||
{
|
||||
while (j >= 0 && speeds[j] > currSpeed)
|
||||
{
|
||||
battlers[j + 1] = battlers[j];
|
||||
speeds[j + 1] = speeds[j];
|
||||
j = j - 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (j >= 0 && speeds[j] < currSpeed)
|
||||
{
|
||||
battlers[j + 1] = battlers[j];
|
||||
speeds[j + 1] = speeds[j];
|
||||
j = j - 1;
|
||||
}
|
||||
}
|
||||
|
||||
battlers[j + 1] = currBattler;
|
||||
speeds[j + 1] = currSpeed;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user