Battle Configs: The Revenge (#363)

* Turns for Uproar

* Chances for the amount of hits with multi-hit moves.

* Electric type mon's immunity to paralysis

* (Hi) Jump Kick to always do 1/2 of maxHP when crashing

* Turns for Disable.

* Minimized mons can always be hit by moves like Stomp

* Grass types immune to powder and spore moves.

* Psywave's damage formula

* Fixed random usage.
This commit is contained in:
Eduardo Alvaro Quezada D'Ottone 2020-05-28 04:38:27 -04:00 committed by GitHub
parent 0f6b83f286
commit 8d848997c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 81 additions and 24 deletions

View File

@ -1715,7 +1715,13 @@
.endm .endm
.macro trypoisontype attacker:req, target:req, ptr:req .macro trypoisontype attacker:req, target:req, ptr:req
various \attacker, VARIOUS_HANDLE_TYPE_IMMUNITY various \attacker, VARIOUS_POISON_TYPE_IMMUNITY
.byte \target
.4byte \ptr
.endm
.macro tryparalyzetype attacker:req, target:req, ptr:req
various \attacker, VARIOUS_PARALYZE_TYPE_IMMUNITY
.byte \target .byte \target
.4byte \ptr .4byte \ptr
.endm .endm

View File

@ -2996,7 +2996,7 @@ BattleScript_EffectParalyze:
typecalc typecalc
jumpifmovehadnoeffect BattleScript_ButItFailed jumpifmovehadnoeffect BattleScript_ButItFailed
jumpifstatus BS_TARGET, STATUS1_PARALYSIS, BattleScript_AlreadyParalyzed jumpifstatus BS_TARGET, STATUS1_PARALYSIS, BattleScript_AlreadyParalyzed
jumpiftype BS_TARGET, TYPE_ELECTRIC, BattleScript_NotAffected tryparalyzetype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected jumpifsafeguard BattleScript_SafeguardProtected

View File

@ -18,6 +18,7 @@ bool8 UproarWakeUpCheck(u8 battlerId);
bool32 DoesSubstituteBlockMove(u8 battlerAtk, u8 battlerDef, u32 move); bool32 DoesSubstituteBlockMove(u8 battlerAtk, u8 battlerDef, u32 move);
bool32 DoesDisguiseBlockMove(u8 battlerAtk, u8 battlerDef, u32 move); bool32 DoesDisguiseBlockMove(u8 battlerAtk, u8 battlerDef, u32 move);
bool32 CanPoisonType(u8 battlerAttacker, u8 battlerTarget); bool32 CanPoisonType(u8 battlerAttacker, u8 battlerTarget);
bool32 CanParalyzeType(u8 battlerAttacker, u8 battlerTarget);
bool32 CanUseLastResort(u8 battlerId); bool32 CanUseLastResort(u8 battlerId);
u32 IsFlowerVeilProtected(u32 battler); u32 IsFlowerVeilProtected(u32 battler);
u32 IsLeafGuardProtected(u32 battler); u32 IsLeafGuardProtected(u32 battler);

View File

@ -64,6 +64,9 @@
#define B_TERRAIN_TYPE_BOOST GEN_6 // In Gen8+, speed is boosted by 30% instead of 50%. #define B_TERRAIN_TYPE_BOOST GEN_6 // In Gen8+, speed is boosted by 30% instead of 50%.
#define B_BINDING_DAMAGE GEN_6 // In Gen6+, binding damage is 1/8 of max HP instead of 1/16. (With Binding Band, 1/6 and 1/8 respectively.) #define B_BINDING_DAMAGE GEN_6 // In Gen6+, binding damage is 1/8 of max HP instead of 1/16. (With Binding Band, 1/6 and 1/8 respectively.)
#define B_CONFUSION_SELF_DMG_CHANCE GEN_6 // In Gen7+, confusion has a 33.3% of self-damage, instead of 50%. #define B_CONFUSION_SELF_DMG_CHANCE GEN_6 // In Gen7+, confusion has a 33.3% of self-damage, instead of 50%.
#define B_MULTI_HIT_CHANCE GEN_6 // In Gen5+, multi-hit moves have different %. See Cmd_setmultihitcounter for values.
#define B_RECOIL_IF_MISS_DMG GEN_6 // In Gen5+, Jump Kick and Hi Jump Kick will always do half of the user's max HP when missing.
#define B_PSYWAVE_DMG GEN_6 // Psywave's damage formula. See Cmd_psywavedamageeffect.
// Move settings // Move settings
#define B_FELL_STINGER_STAT_RAISE GEN_6 // In Gen7+, it raises Atk by 3 stages instead of 2 if it causes the target to faint. #define B_FELL_STINGER_STAT_RAISE GEN_6 // In Gen7+, it raises Atk by 3 stages instead of 2 if it causes the target to faint.
@ -72,7 +75,10 @@
#define B_PAYBACK_SWITCH_BOOST GEN_6 // In Gen5+, if the opponent switches out, Payback's damage will no longer be doubled. #define B_PAYBACK_SWITCH_BOOST GEN_6 // In Gen5+, if the opponent switches out, Payback's damage will no longer be doubled.
#define B_KINGS_SHIELD_LOWER_ATK GEN_6 // In Gen7+, it lowers Atk by 1 stage instead of 2 of oponents that hit it. #define B_KINGS_SHIELD_LOWER_ATK GEN_6 // In Gen7+, it lowers Atk by 1 stage instead of 2 of oponents that hit it.
#define B_BINDING_TURNS GEN_6 // In Gen5+, binding moves last for 4-5 turns instead of 2-5 turns. (With Grip Claw, 7 and 5 turns respectively.) #define B_BINDING_TURNS GEN_6 // In Gen5+, binding moves last for 4-5 turns instead of 2-5 turns. (With Grip Claw, 7 and 5 turns respectively.)
#define B_UPROAR_TURNS GEN_6 // In Gen5+, Uproar lasts for 3 turns instead of 2-5 turns.
#define B_DISABLE_TURNS GEN_6 // Disable's turns. See Cmd_disablelastusedattack.
#define B_INCINERATE_GEMS GEN_6 // In Gen6+, Incinerate can destroy Gems. #define B_INCINERATE_GEMS GEN_6 // In Gen6+, Incinerate can destroy Gems.
#define B_MINIMIZE_DMG_ACC GEN_6 // In Gen6+, moves that causes double damage to minimized Pokémon will also skip accuracy checks.
// Ability settings // Ability settings
#define B_ABILITY_POP_UP GEN_6 // In Gen5+, the Pokémon abilities are displayed in a pop-up, when they activate in battle. #define B_ABILITY_POP_UP GEN_6 // In Gen5+, the Pokémon abilities are displayed in a pop-up, when they activate in battle.
@ -87,6 +93,8 @@
// Other // Other
#define B_FAST_INTRO TRUE // If set to TRUE, battle intro texts print at the same time as animation of a Pokémon, as opposing to waiting for the animation to end. #define B_FAST_INTRO TRUE // If set to TRUE, battle intro texts print at the same time as animation of a Pokémon, as opposing to waiting for the animation to end.
#define B_SLEEP_TURNS GEN_6 // In Gen5+, sleep lasts for 1-3 turns instead of 2-5 turns. #define B_SLEEP_TURNS GEN_6 // In Gen5+, sleep lasts for 1-3 turns instead of 2-5 turns.
#define B_PARALYZE_ELECTRIC GEN_6 // In Gen6+, Electric type Pokémon can't be paralyzed.
#define B_POWDER_GRASS GEN_6 // In Gen6+, Grass type Pokémon are immune to powder and spore moves.
// Animation Settings // Animation Settings
#define NEW_SWORD_PARTICLE // update swords dance particle #define NEW_SWORD_PARTICLE // update swords dance particle

View File

@ -156,10 +156,11 @@
#define VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED 93 #define VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED 93
#define VARIOUS_TRY_FAIRY_LOCK 94 #define VARIOUS_TRY_FAIRY_LOCK 94
#define VARIOUS_JUMP_IF_NO_ALLY 95 #define VARIOUS_JUMP_IF_NO_ALLY 95
#define VARIOUS_HANDLE_TYPE_IMMUNITY 96 #define VARIOUS_POISON_TYPE_IMMUNITY 96
#define VARIOUS_JUMP_IF_NO_HOLD_EFFECT 97 #define VARIOUS_JUMP_IF_NO_HOLD_EFFECT 97
#define VARIOUS_INFATUATE_WITH_BATTLER 98 #define VARIOUS_INFATUATE_WITH_BATTLER 98
#define VARIOUS_SET_LAST_USED_ITEM 99 #define VARIOUS_SET_LAST_USED_ITEM 99
#define VARIOUS_PARALYZE_TYPE_IMMUNITY 100
// Cmd_manipulatedamage // Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0 #define DMG_CHANGE_SIGN 0

View File

@ -17,6 +17,7 @@
#include "constants/battle_frontier.h" #include "constants/battle_frontier.h"
#include "constants/frontier_util.h" #include "constants/frontier_util.h"
#include "constants/abilities.h" #include "constants/abilities.h"
#include "constants/battle_config.h"
#include "constants/easy_chat.h" #include "constants/easy_chat.h"
#include "constants/layouts.h" #include "constants/layouts.h"
#include "constants/rgb.h" #include "constants/rgb.h"
@ -856,8 +857,9 @@ static bool8 DoesTypePreventStatus(u16 species, u32 status)
ret = TRUE; ret = TRUE;
break; break;
case STATUS1_PARALYSIS: case STATUS1_PARALYSIS:
if (gBaseStats[species].type1 == TYPE_GROUND || gBaseStats[species].type1 == TYPE_ELECTRIC if (gBaseStats[species].type1 == TYPE_GROUND || gBaseStats[species].type2 == TYPE_GROUND
|| gBaseStats[species].type2 == TYPE_GROUND || gBaseStats[species].type2 == TYPE_ELECTRIC) || (B_PARALYZE_ELECTRIC >= GEN_6 &&
(gBaseStats[species].type1 == TYPE_ELECTRIC || gBaseStats[species].type2 == TYPE_ELECTRIC)))
ret = TRUE; ret = TRUE;
break; break;
case STATUS1_BURN: case STATUS1_BURN:

View File

@ -1275,7 +1275,8 @@ static bool32 AccuracyCalcHelper(u16 move)
(((gBattleWeather & WEATHER_RAIN_ANY) && (gBattleMoves[move].effect == EFFECT_THUNDER || gBattleMoves[move].effect == EFFECT_HURRICANE)) (((gBattleWeather & WEATHER_RAIN_ANY) && (gBattleMoves[move].effect == EFFECT_THUNDER || gBattleMoves[move].effect == EFFECT_HURRICANE))
|| (((gBattleWeather & WEATHER_HAIL_ANY) && move == MOVE_BLIZZARD)))) || (((gBattleWeather & WEATHER_HAIL_ANY) && move == MOVE_BLIZZARD))))
|| (gBattleMoves[move].effect == EFFECT_VITAL_THROW) || (gBattleMoves[move].effect == EFFECT_VITAL_THROW)
|| (gBattleMoves[move].accuracy == 0)) || (gBattleMoves[move].accuracy == 0)
|| ((B_MINIMIZE_DMG_ACC >= GEN_6) && (gStatuses3[gBattlerTarget] & STATUS3_MINIMIZED) && (gBattleMoves[move].flags & FLAG_DMG_MINIMIZE)))
{ {
JumpIfMoveFailed(7, move); JumpIfMoveFailed(7, move);
return TRUE; return TRUE;
@ -2369,7 +2370,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
else else
break; break;
} }
if ((IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_ELECTRIC)) if (!CanParalyzeType(gBattleScripting.battler, gEffectBattler)
&& (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && (gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
&& (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN))
{ {
@ -2379,7 +2380,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
gBattleCommunication[MULTISTRING_CHOOSER] = 2; gBattleCommunication[MULTISTRING_CHOOSER] = 2;
RESET_RETURN RESET_RETURN
} }
if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_ELECTRIC)) if (!CanParalyzeType(gBattleScripting.battler, gEffectBattler))
break; break;
if (GetBattlerAbility(gEffectBattler) == ABILITY_LIMBER if (GetBattlerAbility(gEffectBattler) == ABILITY_LIMBER
|| GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE || GetBattlerAbility(gEffectBattler) == ABILITY_COMATOSE
@ -2538,7 +2539,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
gBattleMons[gEffectBattler].status2 |= STATUS2_MULTIPLETURNS; gBattleMons[gEffectBattler].status2 |= STATUS2_MULTIPLETURNS;
gLockedMoves[gEffectBattler] = gCurrentMove; gLockedMoves[gEffectBattler] = gCurrentMove;
gBattleMons[gEffectBattler].status2 |= ((Random() & 3) + 2) << 4; gBattleMons[gEffectBattler].status2 |= (B_UPROAR_TURNS >= GEN_5 ? 3 : ((Random() & 3) + 2) ) << 4;
BattleScriptPush(gBattlescriptCurrInstr + 1); BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleScripting.moveEffect]; gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleScripting.moveEffect];
@ -6686,6 +6687,11 @@ bool32 CanPoisonType(u8 battlerAttacker, u8 battlerTarget)
|| IS_BATTLER_OF_TYPE(battlerTarget, TYPE_STEEL))); || IS_BATTLER_OF_TYPE(battlerTarget, TYPE_STEEL)));
} }
bool32 CanParalyzeType(u8 battlerAttacker, u8 battlerTarget)
{
return !(B_PARALYZE_ELECTRIC >= GEN_6 && IS_BATTLER_OF_TYPE(battlerTarget, TYPE_ELECTRIC));
}
bool32 CanUseLastResort(u8 battlerId) bool32 CanUseLastResort(u8 battlerId)
{ {
u32 i; u32 i;
@ -6913,12 +6919,18 @@ static void Cmd_various(void)
gBattleStruct->friskedBattler = 0; gBattleStruct->friskedBattler = 0;
gBattleStruct->friskedAbility = FALSE; gBattleStruct->friskedAbility = FALSE;
break; break;
case VARIOUS_HANDLE_TYPE_IMMUNITY: case VARIOUS_POISON_TYPE_IMMUNITY:
if (!CanPoisonType(gActiveBattler, GetBattlerForBattleScript(gBattlescriptCurrInstr[3]))) if (!CanPoisonType(gActiveBattler, GetBattlerForBattleScript(gBattlescriptCurrInstr[3])))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 4); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 4);
else else
gBattlescriptCurrInstr += 8; gBattlescriptCurrInstr += 8;
return; return;
case VARIOUS_PARALYZE_TYPE_IMMUNITY:
if (!CanParalyzeType(gActiveBattler, GetBattlerForBattleScript(gBattlescriptCurrInstr[3])))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 4);
else
gBattlescriptCurrInstr += 8;
return;
case VARIOUS_TRACE_ABILITY: case VARIOUS_TRACE_ABILITY:
gBattleMons[gActiveBattler].ability = gBattleStruct->tracedAbility[gActiveBattler]; gBattleMons[gActiveBattler].ability = gBattleStruct->tracedAbility[gActiveBattler];
RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability); RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability);
@ -8273,7 +8285,7 @@ static void Cmd_manipulatedamage(void)
gBattleMoveDamage /= 2; gBattleMoveDamage /= 2;
if (gBattleMoveDamage == 0) if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1; gBattleMoveDamage = 1;
if ((gBattleMons[gBattlerTarget].maxHP / 2) < gBattleMoveDamage) if (B_RECOIL_IF_MISS_DMG >= GEN_5 || ((gBattleMons[gBattlerTarget].maxHP / 2) < gBattleMoveDamage))
gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 2; gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 2;
break; break;
case DMG_DOUBLED: case DMG_DOUBLED:
@ -8780,14 +8792,36 @@ static void Cmd_setmultihitcounter(void)
} }
else else
{ {
gMultiHitCounter = Random() & 3;
if (gMultiHitCounter > 1)
gMultiHitCounter = (Random() & 3) + 2;
else
gMultiHitCounter += 2;
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SKILL_LINK) if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SKILL_LINK)
{
gMultiHitCounter = 5; gMultiHitCounter = 5;
}
else if (B_MULTI_HIT_CHANCE >= GEN_5)
{
// 2 and 3 hits: 33.3%
// 4 and 5 hits: 16.7%
gMultiHitCounter = Random() % 4;
if (gMultiHitCounter > 2)
{
gMultiHitCounter = (Random() % 3);
if (gMultiHitCounter < 2)
gMultiHitCounter = 2;
else
gMultiHitCounter = 3;
}
else
gMultiHitCounter += 3;
}
else
{
// 2 and 3 hits: 37.5%
// 4 and 5 hits: 12.5%
gMultiHitCounter = Random() % 4;
if (gMultiHitCounter > 1)
gMultiHitCounter = (Random() % 4) + 2;
else
gMultiHitCounter += 2;
}
} }
gBattlescriptCurrInstr += 2; gBattlescriptCurrInstr += 2;
@ -9486,10 +9520,10 @@ static void Cmd_dmgtolevel(void)
static void Cmd_psywavedamageeffect(void) static void Cmd_psywavedamageeffect(void)
{ {
s32 randDamage; s32 randDamage;
if (B_PSYWAVE_DMG >= GEN_6)
while ((randDamage = (Random() & 0xF)) > 10); randDamage = (Random() % 101);
else
randDamage *= 10; randDamage = (Random() % 11) * 10;
gBattleMoveDamage = gBattleMons[gBattlerAttacker].level * (randDamage + 50) / 100; gBattleMoveDamage = gBattleMons[gBattlerAttacker].level * (randDamage + 50) / 100;
gBattlescriptCurrInstr++; gBattlescriptCurrInstr++;
} }
@ -9557,7 +9591,12 @@ static void Cmd_disablelastusedattack(void)
PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerTarget].moves[i]) PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerTarget].moves[i])
gDisableStructs[gBattlerTarget].disabledMove = gBattleMons[gBattlerTarget].moves[i]; gDisableStructs[gBattlerTarget].disabledMove = gBattleMons[gBattlerTarget].moves[i];
gDisableStructs[gBattlerTarget].disableTimer = (Random() & 3) + 2; if (B_DISABLE_TURNS == GEN_3)
gDisableStructs[gBattlerTarget].disableTimer = (Random() & 3) + 2;
else if (B_DISABLE_TURNS == GEN_4)
gDisableStructs[gBattlerTarget].disableTimer = (Random() & 3) + 4;
else
gDisableStructs[gBattlerTarget].disableTimer = 4;
gDisableStructs[gBattlerTarget].disableTimerStartValue = gDisableStructs[gBattlerTarget].disableTimer; // used to save the random amount of turns? gDisableStructs[gBattlerTarget].disableTimerStartValue = gDisableStructs[gBattlerTarget].disableTimer; // used to save the random amount of turns?
gBattlescriptCurrInstr += 5; gBattlescriptCurrInstr += 5;
} }

View File

@ -2415,7 +2415,7 @@ u8 AtkCanceller_UnableToUseMove(void)
case CANCELLER_POWDER_MOVE: case CANCELLER_POWDER_MOVE:
if (gBattleMoves[gCurrentMove].flags & FLAG_POWDER) if (gBattleMoves[gCurrentMove].flags & FLAG_POWDER)
{ {
if (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS) if ((B_POWDER_GRASS >= GEN_6 && IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS))
|| GetBattlerAbility(gBattlerTarget) == ABILITY_OVERCOAT) || GetBattlerAbility(gBattlerTarget) == ABILITY_OVERCOAT)
{ {
gBattlerAbility = gBattlerTarget; gBattlerAbility = gBattlerTarget;
@ -3732,7 +3732,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
&& gBattleMons[gBattlerAttacker].hp != 0 && gBattleMons[gBattlerAttacker].hp != 0
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg && !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED && TARGET_TURN_DAMAGED
&& !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_ELECTRIC) && CanParalyzeType(gBattlerTarget, gBattlerAttacker)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_LIMBER && GetBattlerAbility(gBattlerAttacker) != ABILITY_LIMBER
&& !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY) && !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY)
&& !IsAbilityStatusProtected(gBattlerAttacker) && !IsAbilityStatusProtected(gBattlerAttacker)