Emergency Exit

This commit is contained in:
DizzyEggg 2020-07-15 17:21:12 +02:00
parent 7cf5611c18
commit 1a94d27fe6
13 changed files with 180 additions and 21 deletions

View File

@ -668,6 +668,16 @@
.byte 0x75
.endm
.macro get_considered_move_target
.byte 0x76
.endm
.macro compare_speeds battler1:req, battler2:req
.byte 0x77
.byte \battler1
.byte \battler2
.endm
@ useful script macros
.macro if_has_physical_move battler:req, ptr:req
if_has_move_with_split \battler, SPLIT_PHYSICAL, \ptr

View File

@ -3610,10 +3610,39 @@ AI_ConsiderAllyChosenMove:
if_equal 0, AI_ConsiderAllyChosenMoveRet
get_move_effect_from_result
if_equal EFFECT_HELPING_HAND, AI_PartnerChoseHelpingHand
if_equal EFFECT_PERISH_SONG, AI_PartnerChosePerishSong
if_equal EFFECT_PERISH_SONG, AI_PartnerChosePerishSong
if_equal EFFECT_ALWAYS_CRIT, AI_PartnerChoseAlwaysCrit
AI_ConsiderAllyChosenMoveRet:
end
@ Ally decided to use Frost Breath on us. we must have Anger Point as our ability
AI_PartnerChoseAlwaysCrit:
if_no_ability AI_USER, ABILITY_ANGER_POINT, AI_PartnerChoseAlwaysCritEnd
@frost breath user should be faster
compare_speeds AI_USER, AI_USER_PARTNER
if_not_equal 1, AI_PartnerChoseAlwaysCritEnd
get_considered_move_effect
if_in_hwords sEffectsAtkRaise, Score_Minus3
@encourage moves hitting multiple opponents
get_considered_move_power
if_equal 0, AI_PartnerChoseAlwaysCritEnd
get_considered_move_target
if_equal MOVE_TARGET_BOTH, Score_Plus3
if_equal MOVE_TARGET_FOES_AND_ALLY, Score_Plus3
AI_PartnerChoseAlwaysCritEnd:
end
.align 1
sEffectsAtkRaise:
.2byte EFFECT_ATTACK_ACCURACY_UP
.2byte EFFECT_ATTACK_UP
.2byte EFFECT_ATTACK_UP_2
.2byte EFFECT_DRAGON_DANCE
.2byte EFFECT_COIL
.2byte EFFECT_BELLY_DRUM
.2byte EFFECT_BULK_UP
.2byte -1
AI_PartnerChoseHelpingHand:
@ Do not use a status move if you know your move's power will be boosted
get_considered_move_power

View File

@ -776,6 +776,7 @@ gBattleAnims_General::
.4byte General_TerrainPsychic
.4byte General_IllusionOff
.4byte General_FormChange
.4byte General_SlideOffScreen
.align 2
gBattleAnims_Special::
@ -24310,6 +24311,13 @@ General_FormChange:
waitforvisualfinish
clearmonbg ANIM_ATTACKER
end
General_SlideOffScreen:
createvisualtask AnimTask_SlideOffScreen, 5, ANIM_TARGET, +3
waitforvisualfinish
createvisualtask AnimTask_SetInvisible, 1, ANIM_TARGET, TRUE
waitforvisualfinish
end
General_MegaEvolution:
loadspritegfx ANIM_TAG_MEGA_STONE

View File

@ -6553,6 +6553,39 @@ BattleScript_MoodyLower:
waitmessage 0x40
BattleScript_MoodyEnd:
end3
BattleScript_EmergencyExit::
pause 0x5
call BattleScript_AbilityPopUp
pause 0x40
BattleScript_EmergencyExitNoPopUp::
playanimation BS_TARGET, B_ANIM_SLIDE_OFFSCREEN, NULL
waitanimation
openpartyscreen BS_TARGET, BattleScript_EmergencyExitRet
switchoutabilities BS_TARGET
waitstate
switchhandleorder BS_TARGET, 2
returntoball BS_TARGET
getswitchedmondata BS_TARGET
switchindataupdate BS_TARGET
hpthresholds BS_TARGET
printstring STRINGID_SWITCHINMON
switchinanim BS_TARGET, TRUE
waitstate
switchineffects BS_TARGET
BattleScript_EmergencyExitRet:
return
BattleScript_EmergencyExitWild::
pause 0x5
call BattleScript_AbilityPopUp
pause 0x40
BattleScript_EmergencyExitWildNoPopUp::
playanimation BS_TARGET, B_ANIM_SLIDE_OFFSCREEN, NULL
waitanimation
setoutcomeonteleport BS_TARGET
finishaction
return
BattleScript_TraceActivates::
pause 0x20

View File

@ -51,16 +51,6 @@
#define MSG_DISPLAY 0x7
#define BATTLE_COMMUNICATION_ENTRIES_COUNT 0x8
#define MOVE_TARGET_SELECTED 0x0
#define MOVE_TARGET_DEPENDS 0x1
#define MOVE_TARGET_USER_OR_SELECTED 0x2
#define MOVE_TARGET_RANDOM 0x4
#define MOVE_TARGET_BOTH 0x8
#define MOVE_TARGET_USER 0x10
#define MOVE_TARGET_FOES_AND_ALLY 0x20
#define MOVE_TARGET_OPPONENTS_FIELD 0x40
#define MOVE_TARGET_ALLY 0x80
#define BATTLE_BUFFER_LINK_SIZE 0x1000
struct ResourceFlags
@ -68,11 +58,12 @@ struct ResourceFlags
u32 flags[4];
};
#define RESOURCE_FLAG_FLASH_FIRE 0x1
#define RESOURCE_FLAG_ROOST 0x2
#define RESOURCE_FLAG_UNBURDEN 0x4
#define RESOURCE_FLAG_INTIMIDATED 0x8
#define RESOURCE_FLAG_TRACED 0x10
#define RESOURCE_FLAG_FLASH_FIRE 0x1
#define RESOURCE_FLAG_ROOST 0x2
#define RESOURCE_FLAG_UNBURDEN 0x4
#define RESOURCE_FLAG_INTIMIDATED 0x8
#define RESOURCE_FLAG_TRACED 0x10
#define RESOURCE_FLAG_EMERGENCY_EXIT 0x20
struct DisableStruct
{

View File

@ -343,5 +343,9 @@ extern const u8 BattleScript_FriskActivates[];
extern const u8 BattleScript_FriskMsg[];
extern const u8 BattleScript_FriskMsgWithPopup[];
extern const u8 BattleScript_MoodyActivates[];
extern const u8 BattleScript_EmergencyExit[];
extern const u8 BattleScript_EmergencyExitNoPopUp[];
extern const u8 BattleScript_EmergencyExitWild[];
extern const u8 BattleScript_EmergencyExitWildNoPopUp[];
#endif // GUARD_BATTLE_SCRIPTS_H

View File

@ -346,4 +346,15 @@
#define BATTLE_TERRAIN_BUILDING 8
#define BATTLE_TERRAIN_PLAIN 9
// Move targets
#define MOVE_TARGET_SELECTED 0x0
#define MOVE_TARGET_DEPENDS 0x1
#define MOVE_TARGET_USER_OR_SELECTED 0x2
#define MOVE_TARGET_RANDOM 0x4
#define MOVE_TARGET_BOTH 0x8
#define MOVE_TARGET_USER 0x10
#define MOVE_TARGET_FOES_AND_ALLY 0x20
#define MOVE_TARGET_OPPONENTS_FIELD 0x40
#define MOVE_TARGET_ALLY 0x80
#endif // GUARD_CONSTANTS_BATTLE_H

View File

@ -347,7 +347,7 @@
#define ANIM_TAG_STEAM_ERUPTION (ANIM_SPRITES_START + 335)
#define ANIM_TAG_CONFIDE (ANIM_SPRITES_START + 336)
#define ANIM_TAG_VERTICAL_HEX (ANIM_SPRITES_START + 337)
#define ANIM_TAG_UNAVAILABLE_1 (ANIM_SPRITES_START + 338) //0x2862.. supposedly used elsewhere?
#define ANIM_TAG_UNAVAILABLE_1 (ANIM_SPRITES_START + 338) //0x2862.. supposedly used elsewhere?
#define ANIM_TAG_UNAVAILABLE_2 (ANIM_SPRITES_START + 339)
#define ANIM_TAG_POWER_TRICK (ANIM_SPRITES_START + 340)
#define ANIM_TAG_CHAIN_LINK (ANIM_SPRITES_START + 341)
@ -524,6 +524,7 @@
#define B_ANIM_TERRAIN_PSYCHIC 0x1B
#define B_ANIM_ILLUSION_OFF 0x1C
#define B_ANIM_FORM_CHANGE 0x1D
#define B_ANIM_SLIDE_OFFSCREEN 0x1E // for Emergency Exit
// special animations table
#define B_ANIM_LVL_UP 0x0

View File

@ -211,8 +211,9 @@
#define MOVEEND_NEXT_TARGET 20
#define MOVEEND_LIFE_ORB 21
#define MOVEEND_DANCER 22
#define MOVEEND_CLEAR_BITS 23
#define MOVEEND_COUNT 24
#define MOVEEND_EMERGENCY_EXIT 23
#define MOVEEND_CLEAR_BITS 24
#define MOVEEND_COUNT 25
// stat flags for Cmd_playstatchangeanimation
#define BIT_HP 0x1

View File

@ -176,6 +176,8 @@ static void Cmd_get_best_dmg_hp_percent(void);
static void Cmd_get_curr_dmg_hp_percent(void);
static void Cmd_get_move_split_from_result(void);
static void Cmd_get_considered_move_split(void);
static void Cmd_get_considered_move_target(void);
static void Cmd_compare_speeds(void);
// ewram
EWRAM_DATA const u8 *gAIScriptPtr = NULL;
@ -304,6 +306,8 @@ static const BattleAICmdFunc sBattleAICmdTable[] =
Cmd_get_curr_dmg_hp_percent, // 0x73
Cmd_get_move_split_from_result, // 0x74
Cmd_get_considered_move_split, // 0x75
Cmd_get_considered_move_target, // 0x76
Cmd_compare_speeds, // 0x77
};
static const u16 sDiscouragedPowerfulMoveEffects[] =
@ -2808,3 +2812,17 @@ static void Cmd_get_considered_move_split(void)
AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].split;
gAIScriptPtr += 1;
}
static void Cmd_get_considered_move_target(void)
{
AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].target;
gAIScriptPtr += 1;
}
static void Cmd_compare_speeds(void)
{
u8 battler1 = BattleAI_GetWantedBattler(gAIScriptPtr[1]);
u8 battler2 = BattleAI_GetWantedBattler(gAIScriptPtr[2]);
AI_THINKING_STRUCT->funcResult = GetWhoStrikesFirst(battler1, battler2, TRUE);
gAIScriptPtr += 3;
}

View File

@ -1079,3 +1079,12 @@ void AnimTask_CanBattlerSwitch(u8 taskId)
gBattleAnimArgs[ARG_RET_ID] = CanBattlerSwitch(GetAnimBattlerId(gBattleAnimArgs[0]));
DestroyAnimVisualTask(taskId);
}
void AnimTask_SetInvisible(u8 taskId)
{
u32 battlerId = GetAnimBattlerId(gBattleAnimArgs[0]);
u32 spriteId = gBattlerSpriteIds[battlerId];
gSprites[spriteId].invisible = gBattleSpritesDataPtr->battlerData[battlerId].invisible = gBattleAnimArgs[1];
DestroyAnimVisualTask(taskId);
}

View File

@ -4830,6 +4830,33 @@ static void Cmd_moveend(void)
}
gBattleScripting.moveendState++;
break;
case MOVEEND_EMERGENCY_EXIT: // Special case, because moves hitting multiple opponents stop after switching out
for (i = 0; i < gBattlersCount; i++)
{
if (gBattleResources->flags->flags[i] & RESOURCE_FLAG_EMERGENCY_EXIT)
{
gBattleResources->flags->flags[i] &= ~(RESOURCE_FLAG_EMERGENCY_EXIT);
gBattlerTarget = gBattlerAbility = i;
BattleScriptPushCursor();
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER || GetBattlerSide(i) == B_SIDE_PLAYER)
{
if (B_ABILITY_POP_UP >= GEN_6)
gBattlescriptCurrInstr = BattleScript_EmergencyExit;
else
gBattlescriptCurrInstr = BattleScript_EmergencyExitNoPopUp;
}
else
{
if (B_ABILITY_POP_UP >= GEN_6)
gBattlescriptCurrInstr = BattleScript_EmergencyExitWild;
else
gBattlescriptCurrInstr = BattleScript_EmergencyExitWildNoPopUp;
}
return;
}
}
gBattleScripting.moveendState++;
break;
case MOVEEND_CLEAR_BITS: // Clear/Set bits for things like using a move for all targets and all hits.
if (gSpecialStatuses[gBattlerAttacker].instructedChosenTarget)
*(gBattleStruct->moveTarget + gBattlerAttacker) = gSpecialStatuses[gBattlerAttacker].instructedChosenTarget & 0x3;
@ -11701,7 +11728,7 @@ static void Cmd_handleballthrow(void)
{
if (IsCriticalCapture())
gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = 1;
gBattlescriptCurrInstr = BattleScript_SuccessBallThrow;
SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_POKEBALL, &gLastUsedItem);
if (CalculatePlayerPartyCount() == PARTY_SIZE)
@ -11715,7 +11742,7 @@ static void Cmd_handleballthrow(void)
gBattleCommunication[MULTISTRING_CHOOSER] = shakes + 3;
else
gBattleCommunication[MULTISTRING_CHOOSER] = shakes;
gBattlescriptCurrInstr = BattleScript_ShakeBallThrow;
}
}

View File

@ -3557,6 +3557,23 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
effect++;
}
break;
case ABILITY_EMERGENCY_EXIT:
case ABILITY_WIMP_OUT:
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& TARGET_TURN_DAMAGED
&& IsBattlerAlive(battler)
// Had more than half of hp before, now has less
&& gBattleStruct->hpBefore[battler] > gBattleMons[battler].maxHP / 2
&& gBattleMons[battler].hp < gBattleMons[battler].maxHP / 2
&& (gMultiHitCounter == 0 || gMultiHitCounter == 1)
&& !(GetBattlerAbility(gBattlerAttacker) == ABILITY_SHEER_FORCE && gBattleMoves[gCurrentMove].flags & FLAG_SHEER_FORCE_BOOST)
&& (CanBattlerSwitch(battler) || !(gBattleTypeFlags & BATTLE_TYPE_TRAINER))
&& !(gBattleTypeFlags & BATTLE_TYPE_ARENA))
{
gBattleResources->flags->flags[battler] |= RESOURCE_FLAG_EMERGENCY_EXIT;
effect++;
}
break;
case ABILITY_WEAK_ARMOR:
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& TARGET_TURN_DAMAGED