mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2025-02-05 02:40:56 +01:00
A couple of gen4 abilities
This commit is contained in:
parent
51dc76c7e8
commit
fee81d03ab
@ -589,7 +589,7 @@
|
||||
.byte \bank
|
||||
.endm
|
||||
|
||||
.macro recordlastability bank
|
||||
.macro recordability bank
|
||||
.byte 0x70
|
||||
.byte \bank
|
||||
.endm
|
||||
@ -1347,6 +1347,14 @@
|
||||
various \bank, VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC
|
||||
.endm
|
||||
|
||||
.macro stattextbuffer battler
|
||||
various \battler, VARIOUS_STAT_TEXT_BUFFER
|
||||
.endm
|
||||
|
||||
.macro switchinabilities battler
|
||||
various \battler, VARIOUS_SWITCHIN_ABILITIES
|
||||
.endm
|
||||
|
||||
@ helpful macros
|
||||
.macro setstatchanger stat, stages, down
|
||||
setbyte sSTATCHANGER \stat | \stages << 4 | \down << 7
|
||||
|
@ -4109,6 +4109,16 @@ BattleScript_DoTurnDmg::
|
||||
BattleScript_DoTurnDmgEnd::
|
||||
end2
|
||||
|
||||
BattleScript_PoisonHealActivates::
|
||||
printstring STRINGID_POISONHEALHPUP
|
||||
waitmessage 0x40
|
||||
recordability BS_ATTACKER
|
||||
statusanimation BS_ATTACKER
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000
|
||||
healthbarupdate BS_ATTACKER
|
||||
datahpupdate BS_ATTACKER
|
||||
end2
|
||||
|
||||
BattleScript_BurnTurnDmg::
|
||||
printstring STRINGID_PKMNHURTBYBURN
|
||||
waitmessage 0x40
|
||||
@ -4142,7 +4152,20 @@ BattleScript_MoveUsedIsParalyzed::
|
||||
BattleScript_MoveUsedFlinched::
|
||||
printstring STRINGID_PKMNFLINCHED
|
||||
waitmessage 0x40
|
||||
jumpifability BS_ATTACKER ABILITY_STEADFAST BattleScript_TryActivateSteadFast
|
||||
BattleScript_MoveUsedFlinchedEnd:
|
||||
goto BattleScript_MoveEnd
|
||||
BattleScript_TryActivateSteadFast:
|
||||
setstatchanger STAT_SPEED, 1, FALSE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | 0x1, BattleScript_MoveUsedFlinchedEnd
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_MoveUsedFlinchedEnd
|
||||
setgraphicalstatchangevalues
|
||||
playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
|
||||
setbyte gBattleCommunication STAT_SPEED
|
||||
stattextbuffer BS_ATTACKER
|
||||
printstring STRINGID_TARGETABILITYSTATRAISE
|
||||
waitmessage 0x40
|
||||
goto BattleScript_MoveUsedFlinchedEnd
|
||||
|
||||
BattleScript_PrintUproarOverTurns::
|
||||
printfromtable gUproarOverTurnStringIds
|
||||
@ -4354,6 +4377,7 @@ BattleScript_TraceActivates::
|
||||
pause 0x20
|
||||
printstring STRINGID_PKMNTRACED
|
||||
waitmessage 0x40
|
||||
switchinabilities BS_ATTACKER
|
||||
end3
|
||||
|
||||
BattleScript_RainDishActivates::
|
||||
@ -4471,6 +4495,18 @@ BattleScript_MoveHPDrain::
|
||||
orhalfword gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_MoveStatDrain_PPLoss::
|
||||
ppreduce
|
||||
BattleScript_MoveStatDrain::
|
||||
attackstring
|
||||
pause 0x20
|
||||
setgraphicalstatchangevalues
|
||||
playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
|
||||
waitanimation
|
||||
printstring STRINGID_TARGETABILITYSTATRAISE
|
||||
waitmessage 0x40
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_MonMadeMoveUseless_PPLoss::
|
||||
ppreduce
|
||||
BattleScript_MonMadeMoveUseless::
|
||||
@ -4564,6 +4600,34 @@ BattleScript_ColorChangeActivates::
|
||||
waitmessage 0x40
|
||||
return
|
||||
|
||||
BattleScript_AngryPointActivates::
|
||||
setbyte sB_ANIM_ARG1 0x38
|
||||
setbyte sB_ANIM_ARG2 0x0
|
||||
playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
|
||||
printstring STRINGID_ANGRYPOINTACTIVATES
|
||||
waitmessage 0x40
|
||||
return
|
||||
|
||||
BattleScript_TargetAbilityStatRaise::
|
||||
setgraphicalstatchangevalues
|
||||
playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
|
||||
waitanimation
|
||||
printstring STRINGID_TARGETABILITYSTATRAISE
|
||||
waitmessage 0x40
|
||||
return
|
||||
|
||||
BattleScript_AttackerAbilityStatRaise::
|
||||
setgraphicalstatchangevalues
|
||||
playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
|
||||
waitanimation
|
||||
printstring STRINGID_ATTACKERABILITYSTATRAISE
|
||||
waitmessage 0x40
|
||||
return
|
||||
|
||||
BattleScript_AttackerAbilityStatRaiseEnd3::
|
||||
call BattleScript_AttackerAbilityStatRaise
|
||||
end3
|
||||
|
||||
BattleScript_RoughSkinActivates::
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000
|
||||
healthbarupdate BS_ATTACKER
|
||||
|
@ -305,5 +305,12 @@ extern const u8 BattleScript_MudSportEnds[];
|
||||
extern const u8 BattleScript_WaterSportEnds[];
|
||||
extern const u8 BattleScript_SturdiedMsg[];
|
||||
extern const u8 BattleScript_GravityEnds[];
|
||||
extern const u8 BattleScript_MoveStatDrain[];
|
||||
extern const u8 BattleScript_MoveStatDrain_PPLoss[];
|
||||
extern const u8 BattleScript_TargetAbilityStatRaise[];
|
||||
extern const u8 BattleScript_AngryPointActivates[];
|
||||
extern const u8 BattleScript_AttackerAbilityStatRaise[];
|
||||
extern const u8 BattleScript_AttackerAbilityStatRaiseEnd3[];
|
||||
extern const u8 BattleScript_PoisonHealActivates[];
|
||||
|
||||
#endif // GUARD_BATTLE_SCRIPTS_H
|
||||
|
@ -72,6 +72,8 @@
|
||||
#define VARIOUS_RETURN_OPPONENT_MON2 20
|
||||
#define VARIOUS_SET_TELEPORT_OUTCOME 25
|
||||
#define VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC 26
|
||||
#define VARIOUS_STAT_TEXT_BUFFER 27
|
||||
#define VARIOUS_SWITCHIN_ABILITIES 28
|
||||
|
||||
// atk80, dmg manipulation
|
||||
#define ATK80_DMG_CHANGE_SIGN 0
|
||||
|
@ -450,7 +450,11 @@
|
||||
#define STRINGID_MISTYTERRAINENDS 447
|
||||
#define STRINGID_PSYCHICTERRAINENDS 448
|
||||
#define STRINGID_GRASSYTERRAINENDS 449
|
||||
#define STRINGID_TARGETABILITYSTATRAISE 450
|
||||
#define STRINGID_ANGRYPOINTACTIVATES 451
|
||||
#define STRINGID_ATTACKERABILITYSTATRAISE 452
|
||||
#define STRINGID_POISONHEALHPUP 453
|
||||
|
||||
#define BATTLESTRINGS_COUNT 438
|
||||
#define BATTLESTRINGS_COUNT 442
|
||||
|
||||
#endif // GUARD_CONSTANTS_BATTLE_STRING_IDS_H
|
||||
|
@ -431,7 +431,7 @@ static const u8 sText_FoePkmnPrefix3[] = _("Foe");
|
||||
static const u8 sText_AllyPkmnPrefix2[] = _("Ally");
|
||||
static const u8 sText_FoePkmnPrefix4[] = _("Foe");
|
||||
static const u8 sText_AllyPkmnPrefix3[] = _("Ally");
|
||||
static const u8 sText_AttackerUsedX[] = _("{B_ATK_NAME_WITH_PREFIX} used\n{B_BUFF2}");
|
||||
static const u8 sText_AttackerUsedX[] = _("{B_ATK_NAME_WITH_PREFIX} used\n{B_BUFF3}!");
|
||||
static const u8 sText_ExclamationMark[] = _("!");
|
||||
static const u8 sText_ExclamationMark2[] = _("!");
|
||||
static const u8 sText_ExclamationMark3[] = _("!");
|
||||
@ -586,6 +586,8 @@ static const u8 sText_MudSportEnds[] = _("The effects of Mud Sport have faded.")
|
||||
static const u8 sText_WaterSportEnds[] = _("The effects of Water Sport have faded.");
|
||||
static const u8 sText_GravityEnds[] = _("Gravity returned to normal!");
|
||||
static const u8 sText_AquaRingHeal[] = _("Aqua Ring restored\n{B_ATK_NAME_WITH_PREFIX}’s HP!");
|
||||
static const u8 sText_TargetAbilityRaisedStat[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_ATK_ABILITY}\n raised its {B_BUFF1}!");
|
||||
static const u8 sText_AttackerAbilityRaisedStat[] = _("{B_ATK_NAME_WITH_PREFIX}’s {B_ATK_ABILITY}\n raised its {B_BUFF1}!");
|
||||
|
||||
// These strings are currently placeholders, to be fixed.
|
||||
static const u8 sText_AuroraVeilEnds[] = _("");
|
||||
@ -593,6 +595,8 @@ static const u8 sText_ElectricTerrainEnds[] = _("");
|
||||
static const u8 sText_MistyTerrainEnds[] = _("");
|
||||
static const u8 sText_PsychicTerrainEnds[] = _("");
|
||||
static const u8 sText_GrassyTerrainEnds[] = _("");
|
||||
static const u8 sText_AngryPointActivates[] = _("");
|
||||
static const u8 sText_PoisonHealHpUp[] = _("");
|
||||
|
||||
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
{
|
||||
@ -1035,6 +1039,10 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
sText_MistyTerrainEnds, // 447
|
||||
sText_PsychicTerrainEnds, // 448
|
||||
sText_GrassyTerrainEnds, // 449
|
||||
sText_TargetAbilityRaisedStat, // 450
|
||||
sText_AngryPointActivates, // 451
|
||||
sText_AttackerAbilityRaisedStat, // 452
|
||||
sText_PoisonHealHpUp, // 453
|
||||
};
|
||||
|
||||
const u16 gMissStringIds[] =
|
||||
@ -2297,14 +2305,11 @@ void BufferStringBattle(u16 stringID)
|
||||
}
|
||||
break;
|
||||
case STRINGID_USEDMOVE: // pokemon used a move msg
|
||||
ChooseMoveUsedParticle(gBattleTextBuff1); // buff1 doesn't appear in the string, leftover from japanese move names
|
||||
|
||||
if (gBattleMsgDataPtr->currentMove >= MOVES_COUNT)
|
||||
StringCopy(gBattleTextBuff2, sATypeMove_Table[*(&gBattleStruct->stringMoveType)]);
|
||||
StringCopy(gBattleTextBuff3, sATypeMove_Table[*(&gBattleStruct->stringMoveType)]);
|
||||
else
|
||||
StringCopy(gBattleTextBuff2, gMoveNames[gBattleMsgDataPtr->currentMove]);
|
||||
StringCopy(gBattleTextBuff3, gMoveNames[gBattleMsgDataPtr->currentMove]);
|
||||
|
||||
ChooseTypeOfMoveUsedString(gBattleTextBuff2);
|
||||
stringPtr = sText_AttackerUsedX;
|
||||
break;
|
||||
case STRINGID_BATTLEEND: // battle end
|
||||
|
@ -203,7 +203,7 @@ static void atk6C_drawlvlupbox(void);
|
||||
static void atk6D_resetsentmonsvalue(void);
|
||||
static void atk6E_setatktoplayer0(void);
|
||||
static void atk6F_makevisible(void);
|
||||
static void atk70_recordlastability(void);
|
||||
static void atk70_recordability(void);
|
||||
static void atk71_buffermovetolearn(void);
|
||||
static void atk72_jumpifplayerran(void);
|
||||
static void atk73_hpthresholds(void);
|
||||
@ -459,7 +459,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
|
||||
atk6D_resetsentmonsvalue,
|
||||
atk6E_setatktoplayer0,
|
||||
atk6F_makevisible,
|
||||
atk70_recordlastability,
|
||||
atk70_recordability,
|
||||
atk71_buffermovetolearn,
|
||||
atk72_jumpifplayerran,
|
||||
atk73_hpthresholds,
|
||||
@ -1013,22 +1013,23 @@ static void atk00_attackcanceler(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void JumpIfMoveFailed(u8 adder, u16 move)
|
||||
static bool32 JumpIfMoveFailed(u8 adder, u16 move)
|
||||
{
|
||||
const u8 *BS_ptr = gBattlescriptCurrInstr + adder;
|
||||
if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
{
|
||||
gLastLandedMoves[gBattlerTarget] = 0;
|
||||
gLastHitByType[gBattlerTarget] = 0;
|
||||
BS_ptr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
TrySetDestinyBondToHappen();
|
||||
if (AbilityBattleEffects(ABILITYEFFECT_ABSORBING, gBattlerTarget, 0, 0, move))
|
||||
return;
|
||||
return TRUE;
|
||||
}
|
||||
gBattlescriptCurrInstr = BS_ptr;
|
||||
gBattlescriptCurrInstr += adder;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void atk40_jumpifaffectedbyprotect(void)
|
||||
@ -1058,7 +1059,7 @@ bool8 JumpIfMoveAffectedByProtect(u16 move)
|
||||
return affected;
|
||||
}
|
||||
|
||||
static bool8 AccuracyCalcHelper(u16 move)
|
||||
static bool32 AccuracyCalcHelper(u16 move)
|
||||
{
|
||||
if (gStatuses3[gBattlerTarget] & STATUS3_ALWAYS_HITS && gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker)
|
||||
{
|
||||
@ -1070,6 +1071,18 @@ static bool8 AccuracyCalcHelper(u16 move)
|
||||
JumpIfMoveFailed(7, move);
|
||||
return TRUE;
|
||||
}
|
||||
else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD)
|
||||
{
|
||||
if (!JumpIfMoveFailed(7, move))
|
||||
RecordAbilityBattle(gBattlerAttacker, ABILITY_NO_GUARD);
|
||||
return TRUE;
|
||||
}
|
||||
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD)
|
||||
{
|
||||
if (!JumpIfMoveFailed(7, move))
|
||||
RecordAbilityBattle(gBattlerTarget, ABILITY_NO_GUARD);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!(gHitMarker & HITMARKER_IGNORE_ON_AIR) && gStatuses3[gBattlerTarget] & STATUS3_ON_AIR)
|
||||
{
|
||||
@ -6242,11 +6255,11 @@ static void atk6F_makevisible(void)
|
||||
gBattlescriptCurrInstr += 2;
|
||||
}
|
||||
|
||||
static void atk70_recordlastability(void)
|
||||
static void atk70_recordability(void)
|
||||
{
|
||||
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
|
||||
RecordAbilityBattle(gActiveBattler, gLastUsedAbility);
|
||||
gBattlescriptCurrInstr += 1; // UB: Should be + 2, one byte for command and one byte for battlerId argument.
|
||||
u8 battler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
|
||||
RecordAbilityBattle(battler, gBattleMons[battler].ability);
|
||||
gBattlescriptCurrInstr += 2;
|
||||
}
|
||||
|
||||
void BufferMoveToLearnIntoBattleTextBuff2(void)
|
||||
@ -6502,6 +6515,13 @@ static void atk76_various(void)
|
||||
BtlController_EmitPlayFanfareOrBGM(0, MUS_KACHI1, TRUE);
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
break;
|
||||
case VARIOUS_STAT_TEXT_BUFFER:
|
||||
PREPARE_STAT_BUFFER(gBattleTextBuff1, gBattleCommunication[0]);
|
||||
break;
|
||||
case VARIOUS_SWITCHIN_ABILITIES:
|
||||
gBattlescriptCurrInstr += 3;
|
||||
AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gActiveBattler, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr += 3;
|
||||
@ -7158,6 +7178,9 @@ static void atk8D_setmultihitcounter(void)
|
||||
gMultiHitCounter = (Random() & 3) + 2;
|
||||
else
|
||||
gMultiHitCounter += 2;
|
||||
|
||||
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SKILL_LINK)
|
||||
gMultiHitCounter = 5;
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr += 2;
|
||||
|
@ -1230,6 +1230,7 @@ u8 DoBattlerEndTurnEffects(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
u8 ability = GetBattlerAbility(gActiveBattler);
|
||||
switch (gBattleStruct->turnEffectsTracker)
|
||||
{
|
||||
case ENDTURN_INGRAIN: // ingrain
|
||||
@ -1294,7 +1295,23 @@ u8 DoBattlerEndTurnEffects(void)
|
||||
gBattleStruct->turnEffectsTracker++;
|
||||
break;
|
||||
case ENDTURN_POISON: // poison
|
||||
if ((gBattleMons[gActiveBattler].status1 & STATUS1_POISON) && gBattleMons[gActiveBattler].hp != 0)
|
||||
if ((gBattleMons[gActiveBattler].status1 & STATUS1_POISON)
|
||||
&& gBattleMons[gActiveBattler].hp != 0
|
||||
&& ability != ABILITY_MAGIC_GUARD)
|
||||
{
|
||||
if (ability == ABILITY_POISON_HEAL)
|
||||
{
|
||||
if (!BATTLER_MAX_HP(gActiveBattler))
|
||||
{
|
||||
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 8;
|
||||
if (gBattleMoveDamage == 0)
|
||||
gBattleMoveDamage = 1;
|
||||
gBattleMoveDamage *= -1;
|
||||
BattleScriptExecute(BattleScript_PoisonHealActivates);
|
||||
effect++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 8;
|
||||
if (gBattleMoveDamage == 0)
|
||||
@ -1302,24 +1319,44 @@ u8 DoBattlerEndTurnEffects(void)
|
||||
BattleScriptExecute(BattleScript_PoisonTurnDmg);
|
||||
effect++;
|
||||
}
|
||||
}
|
||||
gBattleStruct->turnEffectsTracker++;
|
||||
break;
|
||||
case ENDTURN_BAD_POISON: // toxic poison
|
||||
if ((gBattleMons[gActiveBattler].status1 & STATUS1_TOXIC_POISON) && gBattleMons[gActiveBattler].hp != 0)
|
||||
if ((gBattleMons[gActiveBattler].status1 & STATUS1_TOXIC_POISON)
|
||||
&& gBattleMons[gActiveBattler].hp != 0
|
||||
&& ability != ABILITY_MAGIC_GUARD)
|
||||
{
|
||||
if (ability == ABILITY_POISON_HEAL)
|
||||
{
|
||||
if (!BATTLER_MAX_HP(gActiveBattler))
|
||||
{
|
||||
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 8;
|
||||
if (gBattleMoveDamage == 0)
|
||||
gBattleMoveDamage = 1;
|
||||
gBattleMoveDamage *= -1;
|
||||
BattleScriptExecute(BattleScript_PoisonHealActivates);
|
||||
effect++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 16;
|
||||
if (gBattleMoveDamage == 0)
|
||||
gBattleMoveDamage = 1;
|
||||
if ((gBattleMons[gActiveBattler].status1 & 0xF00) != 0xF00) // not 16 turns
|
||||
if ((gBattleMons[gActiveBattler].status1 & STATUS1_TOXIC_COUNTER) != STATUS1_TOXIC_COUNTER) // not 16 turns
|
||||
gBattleMons[gActiveBattler].status1 += 0x100;
|
||||
gBattleMoveDamage *= (gBattleMons[gActiveBattler].status1 & 0xF00) >> 8;
|
||||
gBattleMoveDamage *= (gBattleMons[gActiveBattler].status1 & STATUS1_TOXIC_COUNTER) >> 8;
|
||||
BattleScriptExecute(BattleScript_PoisonTurnDmg);
|
||||
effect++;
|
||||
}
|
||||
}
|
||||
gBattleStruct->turnEffectsTracker++;
|
||||
break;
|
||||
case ENDTURN_BURN: // burn
|
||||
if ((gBattleMons[gActiveBattler].status1 & STATUS1_BURN) && gBattleMons[gActiveBattler].hp != 0)
|
||||
if ((gBattleMons[gActiveBattler].status1 & STATUS1_BURN)
|
||||
&& gBattleMons[gActiveBattler].hp != 0
|
||||
&& ability != ABILITY_MAGIC_GUARD)
|
||||
{
|
||||
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 8;
|
||||
if (gBattleMoveDamage == 0)
|
||||
@ -1330,7 +1367,9 @@ u8 DoBattlerEndTurnEffects(void)
|
||||
gBattleStruct->turnEffectsTracker++;
|
||||
break;
|
||||
case ENDTURN_NIGHTMARES: // spooky nightmares
|
||||
if ((gBattleMons[gActiveBattler].status2 & STATUS2_NIGHTMARE) && gBattleMons[gActiveBattler].hp != 0)
|
||||
if ((gBattleMons[gActiveBattler].status2 & STATUS2_NIGHTMARE)
|
||||
&& gBattleMons[gActiveBattler].hp != 0
|
||||
&& ability != ABILITY_MAGIC_GUARD)
|
||||
{
|
||||
// R/S does not perform this sleep check, which causes the nightmare effect to
|
||||
// persist even after the affected Pokemon has been awakened by Shed Skin.
|
||||
@ -1350,7 +1389,9 @@ u8 DoBattlerEndTurnEffects(void)
|
||||
gBattleStruct->turnEffectsTracker++;
|
||||
break;
|
||||
case ENDTURN_CURSE: // curse
|
||||
if ((gBattleMons[gActiveBattler].status2 & STATUS2_CURSED) && gBattleMons[gActiveBattler].hp != 0)
|
||||
if ((gBattleMons[gActiveBattler].status2 & STATUS2_CURSED)
|
||||
&& gBattleMons[gActiveBattler].hp != 0
|
||||
&& ability != ABILITY_MAGIC_GUARD)
|
||||
{
|
||||
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 4;
|
||||
if (gBattleMoveDamage == 0)
|
||||
@ -2263,47 +2304,27 @@ u8 CastformDataTypeChange(u8 battler)
|
||||
u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveArg)
|
||||
{
|
||||
u8 effect = 0;
|
||||
struct Pokemon *pokeAtk;
|
||||
struct Pokemon *pokeDef;
|
||||
u16 speciesAtk;
|
||||
u16 speciesDef;
|
||||
u32 pidAtk;
|
||||
u32 pidDef;
|
||||
u32 speciesAtk, speciesDef;
|
||||
u32 pidAtk, pidDef;
|
||||
u32 moveType;
|
||||
u32 i;
|
||||
u32 move;
|
||||
u8 side;
|
||||
u8 target1;
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
|
||||
return;
|
||||
|
||||
if (gBattlerAttacker >= gBattlersCount)
|
||||
gBattlerAttacker = battler;
|
||||
|
||||
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
|
||||
pokeAtk = &gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]];
|
||||
else
|
||||
pokeAtk = &gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker]];
|
||||
speciesAtk = gBattleMons[gBattlerAttacker].species;
|
||||
pidAtk = gBattleMons[gBattlerAttacker].personality;
|
||||
|
||||
if (gBattlerTarget >= gBattlersCount)
|
||||
gBattlerTarget = battler;
|
||||
speciesDef = gBattleMons[gBattlerTarget].species;
|
||||
pidDef = gBattleMons[gBattlerTarget].personality;
|
||||
|
||||
if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
|
||||
pokeDef = &gPlayerParty[gBattlerPartyIndexes[gBattlerTarget]];
|
||||
else
|
||||
pokeDef = &gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]];
|
||||
|
||||
speciesAtk = GetMonData(pokeAtk, MON_DATA_SPECIES);
|
||||
pidAtk = GetMonData(pokeAtk, MON_DATA_PERSONALITY);
|
||||
|
||||
speciesDef = GetMonData(pokeDef, MON_DATA_SPECIES);
|
||||
pidDef = GetMonData(pokeDef, MON_DATA_PERSONALITY);
|
||||
|
||||
if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI)) // Why isn't that check done at the beginning?
|
||||
{
|
||||
u8 moveType;
|
||||
s32 i;
|
||||
u16 move;
|
||||
u8 side;
|
||||
u8 target1;
|
||||
|
||||
if (special)
|
||||
gLastUsedAbility = special;
|
||||
else
|
||||
gLastUsedAbility = gBattleMons[battler].ability;
|
||||
gLastUsedAbility = GetBattlerAbility(battler);
|
||||
|
||||
if (moveArg)
|
||||
move = moveArg;
|
||||
@ -2315,8 +2336,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
|
||||
switch (caseID)
|
||||
{
|
||||
case ABILITYEFFECT_ON_SWITCHIN: // 0
|
||||
if (gBattlerAttacker >= gBattlersCount)
|
||||
gBattlerAttacker = battler;
|
||||
switch (gLastUsedAbility)
|
||||
{
|
||||
case ABILITYEFFECT_SWITCH_IN_WEATHER:
|
||||
@ -2361,6 +2380,43 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
|
||||
BattleScriptPushCursorAndCallback(BattleScript_OverworldWeatherStarts);
|
||||
}
|
||||
break;
|
||||
case ABILITY_DOWNLOAD:
|
||||
{
|
||||
u8 statId;
|
||||
u32 opposingBattler = BATTLE_OPPOSITE(battler);
|
||||
u32 opposingDef = gBattleMons[opposingBattler].defense
|
||||
* gStatStageRatios[gBattleMons[opposingBattler].statStages[STAT_DEF]][0]
|
||||
/ gStatStageRatios[gBattleMons[opposingBattler].statStages[STAT_DEF]][1];
|
||||
u32 opposingSpDef = gBattleMons[opposingBattler].spDefense
|
||||
* gStatStageRatios[gBattleMons[opposingBattler].statStages[STAT_SPDEF]][0]
|
||||
/ gStatStageRatios[gBattleMons[opposingBattler].statStages[STAT_SPDEF]][1];
|
||||
|
||||
opposingBattler = BATTLE_PARTNER(opposingBattler);
|
||||
if (IsBattlerAlive(opposingBattler))
|
||||
{
|
||||
opposingDef += gBattleMons[opposingBattler].defense
|
||||
* gStatStageRatios[gBattleMons[opposingBattler].statStages[STAT_DEF]][0]
|
||||
/ gStatStageRatios[gBattleMons[opposingBattler].statStages[STAT_DEF]][1];
|
||||
opposingSpDef += gBattleMons[opposingBattler].spDefense
|
||||
* gStatStageRatios[gBattleMons[opposingBattler].statStages[STAT_SPDEF]][0]
|
||||
/ gStatStageRatios[gBattleMons[opposingBattler].statStages[STAT_SPDEF]][1];
|
||||
}
|
||||
|
||||
if (opposingSpDef > opposingDef)
|
||||
statId = STAT_SPATK;
|
||||
else
|
||||
statId = STAT_ATK;
|
||||
|
||||
if (gBattleMons[battler].statStages[statId] != 0xC)
|
||||
{
|
||||
gBattleMons[battler].statStages[statId]++;
|
||||
SET_STATCHANGER(statId, 1, FALSE);
|
||||
PREPARE_STAT_BUFFER(gBattleTextBuff1, statId);
|
||||
BattleScriptPushCursorAndCallback(BattleScript_AttackerAbilityStatRaiseEnd3);
|
||||
effect++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ABILITY_DRIZZLE:
|
||||
if (!(gBattleWeather & WEATHER_RAIN_PERMANENT))
|
||||
{
|
||||
@ -2508,29 +2564,33 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
|
||||
case ABILITYEFFECT_ABSORBING: // 3
|
||||
if (move)
|
||||
{
|
||||
u8 statId;
|
||||
switch (gLastUsedAbility)
|
||||
{
|
||||
case ABILITY_VOLT_ABSORB:
|
||||
if (moveType == TYPE_ELECTRIC && gBattleMoves[move].power != 0)
|
||||
{
|
||||
if (gProtectStructs[gBattlerAttacker].notFirstStrike)
|
||||
gBattlescriptCurrInstr = BattleScript_MoveHPDrain;
|
||||
else
|
||||
gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss;
|
||||
|
||||
if (moveType == TYPE_ELECTRIC)
|
||||
effect = 1;
|
||||
}
|
||||
break;
|
||||
case ABILITY_WATER_ABSORB:
|
||||
if (moveType == TYPE_WATER && gBattleMoves[move].power != 0)
|
||||
{
|
||||
if (gProtectStructs[gBattlerAttacker].notFirstStrike)
|
||||
gBattlescriptCurrInstr = BattleScript_MoveHPDrain;
|
||||
else
|
||||
gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss;
|
||||
|
||||
case ABILITY_DRY_SKIN:
|
||||
if (moveType == TYPE_WATER)
|
||||
effect = 1;
|
||||
}
|
||||
break;
|
||||
case ABILITY_MOTOR_DRIVE:
|
||||
if (moveType == TYPE_ELECTRIC)
|
||||
effect = 2, statId = STAT_SPEED;
|
||||
break;
|
||||
case ABILITY_LIGHTNING_ROD:
|
||||
if (moveType == TYPE_ELECTRIC)
|
||||
effect = 2, statId = STAT_SPATK;
|
||||
break;
|
||||
case ABILITY_STORM_DRAIN:
|
||||
if (moveType == TYPE_WATER)
|
||||
effect = 2, statId = STAT_SPATK;
|
||||
break;
|
||||
case ABILITY_SAP_SIPPER:
|
||||
if (moveArg == TYPE_GRASS)
|
||||
effect = 2, statId = STAT_ATK;
|
||||
break;
|
||||
case ABILITY_FLASH_FIRE:
|
||||
if (moveType == TYPE_FIRE && !(gBattleMons[battler].status1 & STATUS1_FREEZE))
|
||||
@ -2559,7 +2619,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (effect == 1)
|
||||
if (effect == 1) // Drain Hp ability.
|
||||
{
|
||||
if (gBattleMons[battler].maxHP == gBattleMons[battler].hp)
|
||||
{
|
||||
@ -2570,17 +2630,56 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gProtectStructs[gBattlerAttacker].notFirstStrike)
|
||||
gBattlescriptCurrInstr = BattleScript_MoveHPDrain;
|
||||
else
|
||||
gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss;
|
||||
|
||||
gBattleMoveDamage = gBattleMons[battler].maxHP / 4;
|
||||
if (gBattleMoveDamage == 0)
|
||||
gBattleMoveDamage = 1;
|
||||
gBattleMoveDamage *= -1;
|
||||
}
|
||||
}
|
||||
else if (effect == 2) // Boost Stat ability;
|
||||
{
|
||||
if (gBattleMons[battler].statStages[statId] == 0xC)
|
||||
{
|
||||
if ((gProtectStructs[gBattlerAttacker].notFirstStrike))
|
||||
gBattlescriptCurrInstr = BattleScript_MonMadeMoveUseless;
|
||||
else
|
||||
gBattlescriptCurrInstr = BattleScript_MonMadeMoveUseless_PPLoss;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gProtectStructs[gBattlerAttacker].notFirstStrike)
|
||||
gBattlescriptCurrInstr = BattleScript_MoveStatDrain;
|
||||
else
|
||||
gBattlescriptCurrInstr = BattleScript_MoveStatDrain_PPLoss;
|
||||
|
||||
SET_STATCHANGER(statId, 1, FALSE);
|
||||
gBattleMons[battler].statStages[statId]++;
|
||||
PREPARE_STAT_BUFFER(gBattleTextBuff1, statId);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ABILITYEFFECT_CONTACT: // 4
|
||||
switch (gLastUsedAbility)
|
||||
{
|
||||
case ABILITY_ANGER_POINT:
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& gIsCriticalHit
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& IsBattlerAlive(battler)
|
||||
&& gBattleMons[battler].statStages[STAT_ATK] != 0xC)
|
||||
{
|
||||
gBattleMons[battler].statStages[STAT_ATK] = 0xC;
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_AngryPointActivates;
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITY_COLOR_CHANGE:
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& move != MOVE_STRUGGLE
|
||||
@ -2995,7 +3094,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
|
||||
|
||||
if (effect && caseID < ABILITYEFFECT_CHECK_OTHER_SIDE && gLastUsedAbility != 0xFF)
|
||||
RecordAbilityBattle(battler, gLastUsedAbility);
|
||||
}
|
||||
|
||||
return effect;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user