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
|
waitstate
|
||||||
printstring STRINGID_PKMNWASDRAGGEDOUT
|
printstring STRINGID_PKMNWASDRAGGEDOUT
|
||||||
switchineffects BS_TARGET
|
switchineffects BS_TARGET
|
||||||
|
jumpifbyte CMP_EQUAL, sSWITCH_CASE, B_SWITCH_RED_CARD, BattleScript_RoarSuccessSwitch_Ret
|
||||||
|
setbyte sSWITCH_CASE, B_SWITCH_NORMAL
|
||||||
goto BattleScript_MoveEnd
|
goto BattleScript_MoveEnd
|
||||||
|
BattleScript_RoarSuccessSwitch_Ret:
|
||||||
|
swapattackerwithtarget @ continuation of RedCardActivates
|
||||||
|
removeitem BS_TARGET
|
||||||
|
setbyte sSWITCH_CASE, B_SWITCH_NORMAL
|
||||||
|
return
|
||||||
|
|
||||||
BattleScript_RoarSuccessEndBattle::
|
BattleScript_RoarSuccessEndBattle::
|
||||||
call BattleScript_RoarSuccessRet
|
call BattleScript_RoarSuccessRet
|
||||||
|
setbyte sSWITCH_CASE, B_SWITCH_NORMAL
|
||||||
setoutcomeonteleport BS_ATTACKER
|
setoutcomeonteleport BS_ATTACKER
|
||||||
finishaction
|
finishaction
|
||||||
|
|
||||||
BattleScript_RoarSuccessRet:
|
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
|
attackanimation
|
||||||
waitanimation
|
waitanimation
|
||||||
|
BattleScript_RoarSuccessRet_Ret:
|
||||||
switchoutabilities BS_TARGET
|
switchoutabilities BS_TARGET
|
||||||
returntoball BS_TARGET
|
returntoball BS_TARGET
|
||||||
waitstate
|
waitstate
|
||||||
@ -7790,3 +7801,31 @@ BattleScript_AnnounceAirLockCloudNine::
|
|||||||
waitmessage 0x40
|
waitmessage 0x40
|
||||||
call BattleScript_WeatherFormChanges
|
call BattleScript_WeatherFormChanges
|
||||||
end3
|
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;
|
u16 multihitMoveEffect;
|
||||||
u8 illusionNickHack; // To properly display nick in STRINGID_ENEMYABOUTTOSWITCHPKMN.
|
u8 illusionNickHack; // To properly display nick in STRINGID_ENEMYABOUTTOSWITCHPKMN.
|
||||||
bool8 fixedPopup; // force ability popup to stick until manually called back
|
bool8 fixedPopup; // force ability popup to stick until manually called back
|
||||||
|
u8 switchCase; // special switching conditions, eg. red card
|
||||||
};
|
};
|
||||||
|
|
||||||
// rom_80A5C6C
|
// rom_80A5C6C
|
||||||
|
@ -352,5 +352,6 @@ extern const u8 BattleScript_EmergencyExitWildNoPopUp[];
|
|||||||
extern const u8 BattleScript_CheekPouchActivates[];
|
extern const u8 BattleScript_CheekPouchActivates[];
|
||||||
extern const u8 BattleScript_AnnounceAirLockCloudNine[];
|
extern const u8 BattleScript_AnnounceAirLockCloudNine[];
|
||||||
extern const u8 BattleScript_AttackerItemStatRaise[];
|
extern const u8 BattleScript_AttackerItemStatRaise[];
|
||||||
|
extern const u8 BattleScript_RedCardActivates[];
|
||||||
|
|
||||||
#endif // GUARD_BATTLE_SCRIPTS_H
|
#endif // GUARD_BATTLE_SCRIPTS_H
|
||||||
|
@ -132,5 +132,6 @@ bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 battlerId);
|
|||||||
u8 GetBattleMoveSplit(u32 moveId);
|
u8 GetBattleMoveSplit(u32 moveId);
|
||||||
u8 TryHandleSeed(u8 battler, u32 terrainFlag, u8 statId, u16 itemId, bool32 execute);
|
u8 TryHandleSeed(u8 battler, u32 terrainFlag, u8 statId, u16 itemId, bool32 execute);
|
||||||
bool32 IsBattlerAffectedByHazards(u8 battlerId, bool32 toxicSpikes);
|
bool32 IsBattlerAffectedByHazards(u8 battlerId, bool32 toxicSpikes);
|
||||||
|
void SortBattlersBySpeed(u8 *battlers, bool8 slowToFast);
|
||||||
|
bool32 TestSheerForceFlag(u8 battler, u16 move);
|
||||||
#endif // GUARD_BATTLE_UTIL_H
|
#endif // GUARD_BATTLE_UTIL_H
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#define sMULTIHIT_EFFECT gBattleScripting + 0x30
|
#define sMULTIHIT_EFFECT gBattleScripting + 0x30
|
||||||
#define sILLUSION_NICK_HACK gBattleScripting + 0x32
|
#define sILLUSION_NICK_HACK gBattleScripting + 0x32
|
||||||
#define sFIXED_ABILITY_POPUP gBattleScripting + 0x33
|
#define sFIXED_ABILITY_POPUP gBattleScripting + 0x33
|
||||||
|
#define sSWITCH_CASE gBattleScripting + 0x34
|
||||||
|
|
||||||
#define cMULTISTRING_CHOOSER gBattleCommunication + 5
|
#define cMULTISTRING_CHOOSER gBattleCommunication + 5
|
||||||
|
|
||||||
@ -234,4 +235,9 @@
|
|||||||
#define BIT_ACC 0x40
|
#define BIT_ACC 0x40
|
||||||
#define BIT_EVASION 0x80
|
#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
|
#endif // GUARD_CONSTANTS_BATTLE_SCRIPT_COMMANDS_H
|
||||||
|
@ -558,8 +558,9 @@
|
|||||||
#define STRINGID_AURABREAKENTERS 554
|
#define STRINGID_AURABREAKENTERS 554
|
||||||
#define STRINGID_COMATOSEENTERS 555
|
#define STRINGID_COMATOSEENTERS 555
|
||||||
#define STRINGID_SCREENCLEANERENTERS 556
|
#define STRINGID_SCREENCLEANERENTERS 556
|
||||||
|
#define STRINGID_REDCARDACTIVATE 557
|
||||||
|
|
||||||
#define BATTLESTRINGS_COUNT 557
|
#define BATTLESTRINGS_COUNT 558
|
||||||
|
|
||||||
//// multichoice message IDs
|
//// multichoice message IDs
|
||||||
// switch in ability message
|
// switch in ability message
|
||||||
|
@ -3041,6 +3041,10 @@ void SwitchInClearSetData(void)
|
|||||||
gBattleResources->flags->flags[gActiveBattler] = 0;
|
gBattleResources->flags->flags[gActiveBattler] = 0;
|
||||||
gCurrentMove = 0;
|
gCurrentMove = 0;
|
||||||
gBattleStruct->arenaTurnCounter = 0xFF;
|
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);
|
ClearBattlerMoveHistory(gActiveBattler);
|
||||||
ClearBattlerAbilityHistory(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_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_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_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] =
|
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||||
{
|
{
|
||||||
|
[STRINGID_REDCARDACTIVATE - 12] = sText_RedCardActivate,
|
||||||
[STRINGID_STATWASNOTLOWERED - 12] = sText_StatWasNotLowered,
|
[STRINGID_STATWASNOTLOWERED - 12] = sText_StatWasNotLowered,
|
||||||
[STRINGID_CLOAKEDINAFREEZINGLIGHT - 12] = sText_CloakedInAFreezingLight,
|
[STRINGID_CLOAKEDINAFREEZINGLIGHT - 12] = sText_CloakedInAFreezingLight,
|
||||||
[STRINGID_DESTINYKNOTACTIVATES - 12] = sText_DestinyKnotActivates,
|
[STRINGID_DESTINYKNOTACTIVATES - 12] = sText_DestinyKnotActivates,
|
||||||
|
@ -5010,22 +5010,47 @@ static void Cmd_moveend(void)
|
|||||||
gBattleScripting.moveendState++;
|
gBattleScripting.moveendState++;
|
||||||
break;
|
break;
|
||||||
case MOVEEND_EJECT_BUTTON:
|
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++;
|
gBattleScripting.moveendState++;
|
||||||
break;
|
break;
|
||||||
case MOVEEND_RED_CARD:
|
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++;
|
gBattleScripting.moveendState++;
|
||||||
break;
|
break;
|
||||||
case MOVEEND_EJECT_PACK:
|
case MOVEEND_EJECT_PACK:
|
||||||
gBattleScripting.moveendState++;
|
gBattleScripting.moveendState++;
|
||||||
break;
|
break;
|
||||||
case MOVEEND_LIFE_ORB:
|
case MOVEEND_LIFE_ORB:
|
||||||
|
// TODO shell bell goes here too
|
||||||
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIFE_ORB
|
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIFE_ORB
|
||||||
&& IsBattlerAlive(gBattlerAttacker)
|
&& IsBattlerAlive(gBattlerAttacker)
|
||||||
&& !(GetBattlerAbility(gBattlerAttacker) == ABILITY_SHEER_FORCE && gBattleMoves[gCurrentMove].flags & FLAG_SHEER_FORCE_BOOST)
|
&& !(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)
|
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||||
&& TARGET_TURN_DAMAGED)
|
&& TARGET_TURN_DAMAGED)
|
||||||
{
|
{
|
||||||
|
gBattleScripting.switchCase = B_SWITCH_HIT;
|
||||||
gBattlescriptCurrInstr = BattleScript_ForceRandomSwitch;
|
gBattlescriptCurrInstr = BattleScript_ForceRandomSwitch;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -7930,3 +7930,49 @@ bool32 IsBattlerAffectedByHazards(u8 battlerId, bool32 toxicSpikes)
|
|||||||
}
|
}
|
||||||
return ret;
|
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