From fdd8765256cb38819e696d2c799be03e304ba78d Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Sun, 22 Jul 2018 19:34:13 +0200 Subject: [PATCH] Add Storm Drain redirection --- include/battle.h | 1 + src/battle_main.c | 18 ++++++++++++------ src/battle_script_commands.c | 8 ++++++++ src/battle_util.c | 37 ++++++++++++++++++++++++++++-------- 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/include/battle.h b/include/battle.h index 1753c9a3eb..7ad418626c 100644 --- a/include/battle.h +++ b/include/battle.h @@ -230,6 +230,7 @@ struct SpecialStatus u8 focusBanded:1; u8 focusSashed:1; u8 sturdied:1; + u8 stormDrainRedirected:1; s32 dmg; s32 physicalDmg; s32 specialDmg; diff --git a/src/battle_main.c b/src/battle_main.c index fb851aac75..d0ce224313 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -5365,17 +5365,20 @@ static void HandleAction_UseMove(void) } else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gSideTimers[side].followmeTimer == 0 - && (gBattleMoves[gCurrentMove].power != 0 - || gBattleMoves[gCurrentMove].target != MOVE_TARGET_USER) - && gBattleMons[*(gBattleStruct->moveTarget + gBattlerAttacker)].ability != ABILITY_LIGHTNING_ROD - && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) + && (gBattleMoves[gCurrentMove].power != 0 || gBattleMoves[gCurrentMove].target != MOVE_TARGET_USER) + && ((gBattleMons[*(gBattleStruct->moveTarget + gBattlerAttacker)].ability != ABILITY_LIGHTNING_ROD && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) + || (gBattleMons[*(gBattleStruct->moveTarget + gBattlerAttacker)].ability != ABILITY_STORM_DRAIN && gBattleMoves[gCurrentMove].type == TYPE_WATER) + ) + ) { side = GetBattlerSide(gBattlerAttacker); for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) { if (side != GetBattlerSide(gActiveBattler) && *(gBattleStruct->moveTarget + gBattlerAttacker) != gActiveBattler - && gBattleMons[gActiveBattler].ability == ABILITY_LIGHTNING_ROD + && ((gBattleMons[gActiveBattler].ability == ABILITY_LIGHTNING_ROD && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) + || (gBattleMons[gActiveBattler].ability == ABILITY_STORM_DRAIN && gBattleMoves[gCurrentMove].type == TYPE_WATER) + ) && GetBattlerTurnOrderNum(gActiveBattler) < var) { var = GetBattlerTurnOrderNum(gActiveBattler); @@ -5423,7 +5426,10 @@ static void HandleAction_UseMove(void) { gActiveBattler = gBattlerByTurnOrder[var]; RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability); - gSpecialStatuses[gActiveBattler].lightningRodRedirected = 1; + if (gBattleMons[gActiveBattler].ability == ABILITY_LIGHTNING_ROD) + gSpecialStatuses[gActiveBattler].lightningRodRedirected = 1; + else if (gBattleMons[gActiveBattler].ability == ABILITY_STORM_DRAIN) + gSpecialStatuses[gActiveBattler].stormDrainRedirected = 1; gBattlerTarget = gActiveBattler; } } diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index fd95bbb280..a43f58b0be 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -996,6 +996,14 @@ static void atk00_attackcanceler(void) gBattlescriptCurrInstr = BattleScript_TookAttack; RecordAbilityBattle(gBattlerTarget, gLastUsedAbility); } + else if (gSpecialStatuses[gBattlerTarget].stormDrainRedirected) + { + gSpecialStatuses[gBattlerTarget].stormDrainRedirected = 0; + gLastUsedAbility = ABILITY_STORM_DRAIN; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_TookAttack; + RecordAbilityBattle(gBattlerTarget, gLastUsedAbility); + } else if (DEFENDER_IS_PROTECTED && (gCurrentMove != MOVE_CURSE || IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST)) && ((!IsTwoTurnsMove(gCurrentMove) || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)))) diff --git a/src/battle_util.c b/src/battle_util.c index f90f08bd6c..caa9bdd380 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2493,10 +2493,10 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA switch (gLastUsedAbility) { case ABILITY_RAIN_DISH: - if (WEATHER_HAS_EFFECT && (gBattleWeather & WEATHER_RAIN_ANY) + if (WEATHER_HAS_EFFECT + && (gBattleWeather & WEATHER_RAIN_ANY) && gBattleMons[battler].maxHP > gBattleMons[battler].hp) { - gLastUsedAbility = ABILITY_RAIN_DISH; // why BattleScriptPushCursorAndCallback(BattleScript_RainDishActivates); gBattleMoveDamage = gBattleMons[battler].maxHP / 16; if (gBattleMoveDamage == 0) @@ -2505,9 +2505,18 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA effect++; } break; + case ABILITY_HYDRATION: + if (WEATHER_HAS_EFFECT + && (gBattleWeather & WEATHER_RAIN_ANY) + && gBattleMons[battler].status1 & STATUS1_ANY) + { + goto ABILITY_HEAL_MON_STATUS; + } + break; case ABILITY_SHED_SKIN: if ((gBattleMons[battler].status1 & STATUS1_ANY) && (Random() % 3) == 0) { + ABILITY_HEAL_MON_STATUS: if (gBattleMons[battler].status1 & (STATUS1_POISON | STATUS1_TOXIC_POISON)) StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn); if (gBattleMons[battler].status1 & STATUS1_SLEEP) @@ -2518,8 +2527,9 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn); if (gBattleMons[battler].status1 & STATUS1_FREEZE) StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn); + gBattleMons[battler].status1 = 0; - gBattleMons[battler].status2 &= ~(STATUS2_NIGHTMARE); // fix nightmare glitch + gBattleMons[battler].status2 &= ~(STATUS2_NIGHTMARE); gBattleScripting.battler = gActiveBattler = battler; BattleScriptPushCursorAndCallback(BattleScript_ShedSkinActivates); BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[battler].status1); @@ -3847,6 +3857,14 @@ u8 GetMoveTarget(u16 move, u8 setTarget) RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability); gSpecialStatuses[targetBattler].lightningRodRedirected = 1; } + else if (gBattleMoves[move].type == TYPE_WATER + && AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIDE, gBattlerAttacker, ABILITY_STORM_DRAIN, 0, 0) + && gBattleMons[targetBattler].ability != ABILITY_STORM_DRAIN) + { + targetBattler ^= BIT_FLANK; + RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability); + gSpecialStatuses[targetBattler].stormDrainRedirected = 1; + } } break; case MOVE_TARGET_DEPENDS: @@ -5043,12 +5061,14 @@ s32 CalculateMoveDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, s32 return dmg; } -static inline void MulByTypeEffectiveness(u16 *modifier, u16 move, u8 moveType, u8 battlerDef, u8 defType) +static inline void MulByTypeEffectiveness(u16 *modifier, u16 move, u8 moveType, u8 battlerDef, u8 defType, u8 atkAblity) { u16 mod = sTypeEffectivenessTable[moveType][defType]; if ((moveType == TYPE_FIGHTING || moveType == TYPE_NORMAL) && defType == TYPE_GHOST && gBattleMons[battlerDef].status2 & STATUS2_FORESIGHT) mod = UQ_4_12(1.0); + if ((moveType == TYPE_FIGHTING || moveType == TYPE_NORMAL) && defType == TYPE_GHOST && atkAblity == ABILITY_SCRAPPY) + mod = UQ_4_12(1.0); if (moveType == TYPE_PSYCHIC && defType == TYPE_DARK && gStatuses3[battlerDef] & STATUS3_MIRACLE_EYED) mod = UQ_4_12(1.0); if (move == MOVE_FREEZE_DRY && defType == TYPE_WATER) @@ -5086,9 +5106,10 @@ u16 CalcTypeEffectivenessMultiplier(u16 move, u8 moveType, u8 battlerAtk, u8 bat if (move != MOVE_STRUGGLE && moveType != TYPE_MYSTERY) { - MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, gBattleMons[battlerDef].type1); + u32 atkAbility = GetBattlerAbility(battlerAtk); + MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, gBattleMons[battlerDef].type1, atkAbility); if (gBattleMons[battlerDef].type2 != gBattleMons[battlerDef].type1) - MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, gBattleMons[battlerDef].type2); + MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, gBattleMons[battlerDef].type2, atkAbility); if (moveType == TYPE_GROUND && !IsBattlerGrounded(battlerDef)) { @@ -5127,9 +5148,9 @@ u16 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u8 ability if (move != MOVE_STRUGGLE && moveType != TYPE_MYSTERY) { - MulByTypeEffectiveness(&modifier, move, moveType, 0, gBaseStats[speciesDef].type1); + MulByTypeEffectiveness(&modifier, move, moveType, 0, gBaseStats[speciesDef].type1, ABILITY_NONE); if (gBaseStats[speciesDef].type2 != gBaseStats[speciesDef].type1) - MulByTypeEffectiveness(&modifier, move, moveType, 0, gBaseStats[speciesDef].type2); + MulByTypeEffectiveness(&modifier, move, moveType, 0, gBaseStats[speciesDef].type2, ABILITY_NONE); if (moveType == TYPE_GROUND && abilityDef == ABILITY_LEVITATE && !(gFieldStatuses & STATUS_FIELD_GRAVITY)) modifier = UQ_4_12(0.0);