mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-27 04:04:17 +01:00
Implement trainer sliding
This commit is contained in:
parent
e9965dd341
commit
68d94ad316
@ -1553,6 +1553,19 @@
|
||||
various \battler, VARIOUS_JUMP_IF_NOT_GROUNDED
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro handletrainerslidemsg battler, field
|
||||
various \battler, VARIOUS_HANDLE_TRAINER_SLIDE_MSG
|
||||
.byte \field
|
||||
.endm
|
||||
|
||||
.macro trytrainerslidefirstdownmsg battler
|
||||
various \battler, VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF
|
||||
.endm
|
||||
|
||||
.macro trytrainerslidelastonmsg battler
|
||||
various \battler, VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON
|
||||
.endm
|
||||
|
||||
@ helpful macros
|
||||
.macro setstatchanger stat, stages, down
|
||||
|
@ -4213,6 +4213,7 @@ BattleScript_FaintAttacker::
|
||||
dofaintanimation BS_ATTACKER
|
||||
cleareffectsonfaint BS_ATTACKER
|
||||
printstring STRINGID_ATTACKERFAINTED
|
||||
trytrainerslidefirstdownmsg BS_ATTACKER
|
||||
return
|
||||
|
||||
BattleScript_FaintTarget::
|
||||
@ -4223,6 +4224,7 @@ BattleScript_FaintTarget::
|
||||
printstring STRINGID_TARGETFAINTED
|
||||
tryactivatemoxie BS_ATTACKER
|
||||
tryactivatefellstinger BS_ATTACKER
|
||||
trytrainerslidefirstdownmsg BS_TARGET
|
||||
return
|
||||
|
||||
BattleScript_GiveExp::
|
||||
@ -4288,6 +4290,7 @@ BattleScript_FaintedMonChooseAnother::
|
||||
switchinanim BS_FAINTED, FALSE
|
||||
waitstate
|
||||
various7 BS_ATTACKER
|
||||
trytrainerslidelastonmsg BS_FAINTED
|
||||
switchineffects BS_FAINTED
|
||||
jumpifbattletype BATTLE_TYPE_DOUBLE, BattleScript_FaintedMonEnd
|
||||
cancelallactions
|
||||
|
@ -213,3 +213,17 @@ BattleScript_ActionWallyThrow:
|
||||
printstring STRINGID_YOUTHROWABALLNOWRIGHT
|
||||
waitmessage 0x40
|
||||
end2
|
||||
|
||||
BattleScript_TrainerSlideMsgRet::
|
||||
handletrainerslidemsg BS_SCRIPTING, 0
|
||||
trainerslidein 1
|
||||
handletrainerslidemsg BS_SCRIPTING, 1
|
||||
waitstate
|
||||
trainerslideout 1
|
||||
handletrainerslidemsg BS_SCRIPTING, 2
|
||||
waitstate
|
||||
return
|
||||
|
||||
BattleScript_TrainerSlideMsgEnd2::
|
||||
call BattleScript_TrainerSlideMsgRet
|
||||
end2
|
||||
|
@ -583,6 +583,8 @@ struct BattleStruct
|
||||
u8 activeAbilityPopUps; // as bits for each battler
|
||||
bool8 throwingPokeBall;
|
||||
struct MegaEvolutionData mega;
|
||||
const u8 *trainerSlideMsg;
|
||||
bool8 trainerSlideLowHpMsgDone;
|
||||
};
|
||||
|
||||
#define GET_MOVE_TYPE(move, typeArg) \
|
||||
|
@ -214,12 +214,20 @@ struct BattleMsgData
|
||||
u8 textBuffs[3][TEXT_BUFF_ARRAY_COUNT];
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TRAINER_SLIDE_LAST_SWITCHIN,
|
||||
TRAINER_SLIDE_LAST_LOW_HP,
|
||||
TRAINER_SLIDE_FIRST_DOWN,
|
||||
};
|
||||
|
||||
void BufferStringBattle(u16 stringID);
|
||||
u32 BattleStringExpandPlaceholdersToDisplayedString(const u8* src);
|
||||
u32 BattleStringExpandPlaceholders(const u8* src, u8* dst);
|
||||
void BattlePutTextOnWindow(const u8* text, u8 arg1);
|
||||
void SetPpNumbersPaletteInMoveSelection(void);
|
||||
u8 GetCurrentPpToMaxPpState(u8 currentPp, u8 maxPp);
|
||||
bool32 ShouldDoTrainerSlide(u32 battlerId, u32 trainerId, u32 which);
|
||||
|
||||
extern struct BattleMsgData *gBattleMsgDataPtr;
|
||||
|
||||
|
@ -280,5 +280,7 @@ extern const u8 BattleScript_ForceRandomSwitch[];
|
||||
extern const u8 BattleScript_SideStatusWoreOffReturn[];
|
||||
extern const u8 BattleScript_MoveEffectSmackDown[];
|
||||
extern const u8 BattleScript_MoveEffectFlameBurst[];
|
||||
extern const u8 BattleScript_TrainerSlideMsgRet[];
|
||||
extern const u8 BattleScript_TrainerSlideMsgEnd2[];
|
||||
|
||||
#endif // GUARD_BATTLE_SCRIPTS_H
|
||||
|
@ -120,6 +120,9 @@
|
||||
#define VARIOUS_BESTOW 65
|
||||
#define VARIOUS_ARGUMENT_TO_MOVE_EFFECT 66
|
||||
#define VARIOUS_JUMP_IF_NOT_GROUNDED 67
|
||||
#define VARIOUS_HANDLE_TRAINER_SLIDE_MSG 68
|
||||
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF 69
|
||||
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON 70
|
||||
|
||||
// atk80, dmg manipulation
|
||||
#define ATK80_DMG_CHANGE_SIGN 0
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define STRINGID_SWITCHINMON 3
|
||||
#define STRINGID_USEDMOVE 4
|
||||
#define STRINGID_BATTLEEND 5
|
||||
#define STRINGID_TRAINERSLIDE 6
|
||||
|
||||
// todo: make some of those names less vague: attacker/target vs pkmn, etc.
|
||||
#define STRINGID_TRAINER1LOSETEXT 12
|
||||
|
@ -4052,6 +4052,8 @@ void BattleTurnPassed(void)
|
||||
BattleScriptExecute(BattleScript_82DB881);
|
||||
else if (gBattleTypeFlags & BATTLE_TYPE_ARENA && gBattleStruct->field_DA == 0)
|
||||
BattleScriptExecute(BattleScript_ArenaTurnBeginning);
|
||||
else if (ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), gTrainerBattleOpponent_A, TRAINER_SLIDE_LAST_LOW_HP))
|
||||
BattleScriptExecute(BattleScript_TrainerSlideMsgEnd2);
|
||||
}
|
||||
|
||||
u8 IsRunningFromBattleImpossible(void)
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "battle_message.h"
|
||||
#include "constants/battle_string_ids.h"
|
||||
#include "constants/moves.h"
|
||||
#include "constants/species.h"
|
||||
#include "text.h"
|
||||
#include "string_util.h"
|
||||
#include "constants/items.h"
|
||||
@ -2519,6 +2520,9 @@ void BufferStringBattle(u16 stringID)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STRINGID_TRAINERSLIDE:
|
||||
stringPtr = gBattleStruct->trainerSlideMsg;
|
||||
break;
|
||||
default: // load a string from the table
|
||||
if (stringID >= BATTLESTRINGS_COUNT + BATTLESTRINGS_ID_ADDER)
|
||||
{
|
||||
@ -3457,3 +3461,87 @@ u8 GetCurrentPpToMaxPpState(u8 currentPp, u8 maxPp)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct TrainerSlide
|
||||
{
|
||||
u16 trainerId;
|
||||
const u8 *msgLastSwitchIn;
|
||||
const u8 *msgLastLowHp;
|
||||
const u8 *msgFirstDown;
|
||||
};
|
||||
|
||||
static const struct TrainerSlide sTrainerSlides[] =
|
||||
{
|
||||
{0x291, sText_AarghAlmostHadIt, sText_BoxIsFull, sText_123Poof},
|
||||
};
|
||||
|
||||
static u32 GetEnemyMonCount(bool32 onlyAlive)
|
||||
{
|
||||
u32 i, count = 0;
|
||||
|
||||
for (i = 0; i < PARTY_SIZE; i++)
|
||||
{
|
||||
u32 species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2, NULL);
|
||||
if (species != SPECIES_NONE
|
||||
&& species != SPECIES_EGG
|
||||
&& (!onlyAlive || GetMonData(&gEnemyParty[i], MON_DATA_HP, NULL)))
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static bool32 IsBattlerHpLow(u32 battler)
|
||||
{
|
||||
if ((gBattleMons[battler].hp * 100) / gBattleMons[battler].maxHP < 25)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 ShouldDoTrainerSlide(u32 battlerId, u32 trainerId, u32 which)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER) || GetBattlerSide(battlerId) != B_SIDE_OPPONENT)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(sTrainerSlides); i++)
|
||||
{
|
||||
if (trainerId == sTrainerSlides[i].trainerId)
|
||||
{
|
||||
gBattleScripting.battler = battlerId;
|
||||
switch (which)
|
||||
{
|
||||
case TRAINER_SLIDE_LAST_SWITCHIN:
|
||||
if (sTrainerSlides[i].msgLastSwitchIn != NULL && GetEnemyMonCount(TRUE) == 1)
|
||||
{
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgLastSwitchIn;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case TRAINER_SLIDE_LAST_LOW_HP:
|
||||
if (sTrainerSlides[i].msgLastLowHp != NULL
|
||||
&& GetEnemyMonCount(TRUE) == 1
|
||||
&& IsBattlerHpLow(battlerId)
|
||||
&& !gBattleStruct->trainerSlideLowHpMsgDone)
|
||||
{
|
||||
gBattleStruct->trainerSlideLowHpMsgDone = TRUE;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgLastLowHp;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case TRAINER_SLIDE_FIRST_DOWN:
|
||||
if (sTrainerSlides[i].msgFirstDown != NULL && GetEnemyMonCount(TRUE) == GetEnemyMonCount(FALSE) - 1)
|
||||
{
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgFirstDown;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -7073,6 +7073,42 @@ static void atk76_various(void)
|
||||
else
|
||||
gBattlescriptCurrInstr += 7;
|
||||
return;
|
||||
case VARIOUS_HANDLE_TRAINER_SLIDE_MSG:
|
||||
if (gBattlescriptCurrInstr[3] == 0)
|
||||
{
|
||||
gBattleScripting.savedDmg = gBattlerSpriteIds[gActiveBattler];
|
||||
}
|
||||
else if (gBattlescriptCurrInstr[3] == 1)
|
||||
{
|
||||
BtlController_EmitPrintString(0, STRINGID_TRAINERSLIDE);
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlerSpriteIds[gActiveBattler] = gBattleScripting.savedDmg;
|
||||
if (gBattleMons[gActiveBattler].hp != 0)
|
||||
{
|
||||
BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler);
|
||||
}
|
||||
}
|
||||
gBattlescriptCurrInstr += 4;
|
||||
return;
|
||||
case VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF:
|
||||
if (ShouldDoTrainerSlide(gActiveBattler, gTrainerBattleOpponent_A, TRAINER_SLIDE_FIRST_DOWN))
|
||||
{
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 3);
|
||||
gBattlescriptCurrInstr = BattleScript_TrainerSlideMsgRet;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON:
|
||||
if (ShouldDoTrainerSlide(gActiveBattler, gTrainerBattleOpponent_A, TRAINER_SLIDE_LAST_SWITCHIN))
|
||||
{
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 3);
|
||||
gBattlescriptCurrInstr = BattleScript_TrainerSlideMsgRet;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr += 3;
|
||||
|
Loading…
Reference in New Issue
Block a user