Implement trainer sliding

This commit is contained in:
DizzyEggg 2018-11-03 01:17:16 +01:00
parent e9965dd341
commit 68d94ad316
11 changed files with 172 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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) \

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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;
}

View File

@ -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;