Introduce battle config; Snow Warning Done.
This commit is contained in:
parent
0c6d30e3da
commit
9088c0bdb5
@ -4609,6 +4609,14 @@ BattleScript_DroughtActivates::
|
||||
call BattleScript_WeatherFormChanges
|
||||
end3
|
||||
|
||||
BattleScript_SnowWarningActivates::
|
||||
pause 0x20
|
||||
printstring STRINGID_SNOWWARNINGHAIL
|
||||
waitstate
|
||||
playanimation BS_BATTLER_0, B_ANIM_HAIL_CONTINUES, NULL
|
||||
call BattleScript_WeatherFormChanges
|
||||
end3
|
||||
|
||||
BattleScript_BadDreamsActivates::
|
||||
setbyte gBattlerTarget, 0
|
||||
BattleScript_BadDreamsLoop:
|
||||
|
||||
@ -322,5 +322,6 @@ extern const u8 BattleScript_CursedBodyActivates[];
|
||||
extern const u8 BattleScript_MummyActivates[];
|
||||
extern const u8 BattleScript_WeakArmorActivates[];
|
||||
extern const u8 BattleScript_FellStingerRaisesStat[];
|
||||
extern const u8 BattleScript_SnowWarningActivates[];
|
||||
|
||||
#endif // GUARD_BATTLE_SCRIPTS_H
|
||||
|
||||
@ -64,6 +64,7 @@ void TryClearRageStatuses(void);
|
||||
u8 AtkCanceller_UnableToUseMove(void);
|
||||
bool8 HasNoMonsToSwitch(u8 battlerId, u8 r1, u8 r2);
|
||||
u8 CastformDataTypeChange(u8 battlerId);
|
||||
bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility);
|
||||
u8 AbilityBattleEffects(u8 caseID, u8 battlerId, u8 ability, u8 special, u16 moveArg);
|
||||
void BattleScriptExecute(const u8* BS_ptr);
|
||||
void BattleScriptPushCursorAndCallback(const u8* BS_ptr);
|
||||
|
||||
@ -240,10 +240,18 @@
|
||||
#define WEATHER_SUN_TEMPORARY (1 << 5)
|
||||
#define WEATHER_SUN_PERMANENT (1 << 6)
|
||||
#define WEATHER_SUN_ANY (WEATHER_SUN_TEMPORARY | WEATHER_SUN_PERMANENT)
|
||||
#define WEATHER_HAIL (1 << 7)
|
||||
#define WEATHER_HAIL_ANY (WEATHER_HAIL)
|
||||
#define WEATHER_HAIL_TEMPORARY (1 << 7)
|
||||
#define WEATHER_HAIL_PERMANENT (1 << 8)
|
||||
#define WEATHER_HAIL_ANY (WEATHER_HAIL_TEMPORARY | WEATHER_HAIL_PERMANENT)
|
||||
#define WEATHER_ANY (WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_SUN_ANY | WEATHER_HAIL_ANY)
|
||||
|
||||
// Battle Weather as enum
|
||||
#define ENUM_WEATHER_NONE 0
|
||||
#define ENUM_WEATHER_RAIN 1
|
||||
#define ENUM_WEATHER_SUN 2
|
||||
#define ENUM_WEATHER_SANDSTORM 3
|
||||
#define ENUM_WEATHER_HAIL 4
|
||||
|
||||
// Move Effects
|
||||
#define MOVE_EFFECT_SLEEP 0x1
|
||||
#define MOVE_EFFECT_POISON 0x2
|
||||
|
||||
14
include/constants/battle_config.h
Normal file
14
include/constants/battle_config.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef GUARD_CONSTANTS_BATTLE_CONFIG_H
|
||||
#define GUARD_CONSTANTS_BATTLE_CONFIG_H
|
||||
|
||||
#define GEN_3 0
|
||||
#define GEN_4 1
|
||||
#define GEN_5 2
|
||||
#define GEN_6 3
|
||||
#define GEN_7 4
|
||||
|
||||
#define B_CRIT_CHANCE GEN_6 // Chances of a critical hit landing. See atk04_critcalc.
|
||||
#define B_FELL_STINGER_STAT_RAISE GEN_6 // Gen6 Atk+2, Gen7 Atk+3.
|
||||
#define B_ABILITY_WEATHER GEN_6 // Up to gen5 - weather induced by abilities such as Drought or Drizzle lasted till the battle's end or weather change by a move. From Gen6 onwards, weather caused by abilities lasts the same amount of turns as induced from a move.
|
||||
|
||||
#endif // GUARD_CONSTANTS_BATTLE_CONFIG_H
|
||||
@ -1162,7 +1162,7 @@ static void SetUpModifyArrows(struct BattleDebugMenu *data)
|
||||
{
|
||||
case LIST_ITEM_ABILITY:
|
||||
data->modifyArrows.minValue = 0;
|
||||
data->modifyArrows.maxValue = ABILITIES_COUNT_GEN5 - 1;
|
||||
data->modifyArrows.maxValue = ABILITIES_COUNT_GEN6 - 1;
|
||||
data->modifyArrows.maxDigits = 3;
|
||||
data->modifyArrows.modifiedValPtr = &gBattleMons[data->battlerId].ability;
|
||||
data->modifyArrows.typeOfVal = VAL_U8;
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
#include "battle_setup.h"
|
||||
#include "overworld.h"
|
||||
#include "party_menu.h"
|
||||
#include "constants/battle_config.h"
|
||||
|
||||
extern u16 gBattle_BG1_X;
|
||||
extern u16 gBattle_BG1_Y;
|
||||
@ -1342,9 +1343,13 @@ s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbi
|
||||
}
|
||||
|
||||
// The chance is 1/N for each stage.
|
||||
static const u8 sCriticalHitChanceGen3[] = {16, 8, 4, 3, 2}; // Gens 2,3,4,5
|
||||
static const u8 sCriticalHitChanceGen6[] = {16, 8, 2, 1, 1};
|
||||
static const u8 sCriticalHitChanceGen7[] = {24, 8, 2, 1, 1};
|
||||
#if B_CRIT_CHANCE == GEN_7
|
||||
static const u8 sCriticalHitChance[] = {24, 8, 2, 1, 1};
|
||||
#elif B_CRIT_CHANCE == GEN_6
|
||||
static const u8 sCriticalHitChance[] = {16, 8, 2, 1, 1};
|
||||
#else
|
||||
static const u8 sCriticalHitChance[] = {16, 8, 4, 3, 2}; // Gens 2,3,4,5
|
||||
#endif // B_CRIT_CHANCE
|
||||
|
||||
static void atk04_critcalc(void)
|
||||
{
|
||||
@ -1357,7 +1362,7 @@ static void atk04_critcalc(void)
|
||||
gIsCriticalHit = FALSE;
|
||||
else if (critChance == -2)
|
||||
gIsCriticalHit = TRUE;
|
||||
else if (Random() % sCriticalHitChanceGen3[critChance] == 0)
|
||||
else if (Random() % sCriticalHitChance[critChance] == 0)
|
||||
gIsCriticalHit = TRUE;
|
||||
else
|
||||
gIsCriticalHit = FALSE;
|
||||
@ -6390,7 +6395,7 @@ static void atk76_various(void)
|
||||
&& HasAttackerFaintedTarget()
|
||||
&& !IsBattleLostForPlayer()
|
||||
&& !IsBattleWonForPlayer()
|
||||
&& gBattleMons[gBattlerAttacker].statStages[STAT_ATK] != 0xC)
|
||||
&& gBattleMons[gBattlerAttacker].statStages[STAT_ATK] != 12)
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].statStages[STAT_ATK]++;
|
||||
SET_STATCHANGER(STAT_ATK, 1, FALSE);
|
||||
@ -6405,10 +6410,12 @@ static void atk76_various(void)
|
||||
&& HasAttackerFaintedTarget()
|
||||
&& !IsBattleLostForPlayer()
|
||||
&& !IsBattleWonForPlayer()
|
||||
&& gBattleMons[gBattlerAttacker].statStages[STAT_ATK] != 0xC)
|
||||
&& gBattleMons[gBattlerAttacker].statStages[STAT_ATK] != 12)
|
||||
{
|
||||
if (gBattleMons[gBattlerAttacker].statStages[STAT_ATK] >= 0xB)
|
||||
if (gBattleMons[gBattlerAttacker].statStages[STAT_ATK] >= 11)
|
||||
SET_STATCHANGER(STAT_ATK, 1, FALSE);
|
||||
else if (gBattleMons[gBattlerAttacker].statStages[STAT_ATK] <= 9 && B_FELL_STINGER_STAT_RAISE == GEN_7)
|
||||
SET_STATCHANGER(STAT_ATK, 3, FALSE);
|
||||
else
|
||||
SET_STATCHANGER(STAT_ATK, 2, FALSE);
|
||||
|
||||
@ -6601,16 +6608,14 @@ static void atk7C_trymirrormove(void)
|
||||
|
||||
static void atk7D_setrain(void)
|
||||
{
|
||||
if (gBattleWeather & WEATHER_RAIN_ANY)
|
||||
if (!TryChangeBattleWeather(gBattlerAttacker, ENUM_WEATHER_RAIN, FALSE))
|
||||
{
|
||||
gMoveResultFlags |= MOVE_RESULT_MISSED;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleWeather = WEATHER_RAIN_TEMPORARY;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||
gWishFutureKnock.weatherDuration = 5;
|
||||
}
|
||||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
@ -7478,16 +7483,14 @@ static void atk94_damagetohalftargethp(void) // super fang
|
||||
|
||||
static void atk95_setsandstorm(void)
|
||||
{
|
||||
if (gBattleWeather & WEATHER_SANDSTORM_ANY)
|
||||
if (!TryChangeBattleWeather(gBattlerAttacker, ENUM_WEATHER_SANDSTORM, FALSE))
|
||||
{
|
||||
gMoveResultFlags |= MOVE_RESULT_MISSED;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleWeather = WEATHER_SANDSTORM_TEMPORARY;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
|
||||
gWishFutureKnock.weatherDuration = 5;
|
||||
}
|
||||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
@ -8645,16 +8648,14 @@ static void atkBA_jumpifnopursuitswitchdmg(void)
|
||||
|
||||
static void atkBB_setsunny(void)
|
||||
{
|
||||
if (gBattleWeather & WEATHER_SUN_ANY)
|
||||
if (!TryChangeBattleWeather(gBattlerAttacker, ENUM_WEATHER_SUN, FALSE))
|
||||
{
|
||||
gMoveResultFlags |= MOVE_RESULT_MISSED;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleWeather = WEATHER_SUN_TEMPORARY;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
|
||||
gWishFutureKnock.weatherDuration = 5;
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr++;
|
||||
@ -8911,16 +8912,14 @@ static void atkC7_setminimize(void)
|
||||
|
||||
static void atkC8_sethail(void)
|
||||
{
|
||||
if (gBattleWeather & WEATHER_HAIL_ANY)
|
||||
if (!TryChangeBattleWeather(gBattlerAttacker, ENUM_WEATHER_HAIL, FALSE))
|
||||
{
|
||||
gMoveResultFlags |= MOVE_RESULT_MISSED;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleWeather = WEATHER_HAIL;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 5;
|
||||
gWishFutureKnock.weatherDuration = 5;
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr++;
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include "link.h"
|
||||
#include "berry.h"
|
||||
#include "pokedex.h"
|
||||
#include "constants/battle_config.h"
|
||||
|
||||
extern u8 weather_get_current(void);
|
||||
|
||||
@ -1070,9 +1071,9 @@ u8 DoFieldEndTurnEffects(void)
|
||||
case ENDTURN_HAIL:
|
||||
if (gBattleWeather & WEATHER_HAIL_ANY)
|
||||
{
|
||||
if (--gWishFutureKnock.weatherDuration == 0)
|
||||
if (!(gBattleWeather & WEATHER_HAIL_PERMANENT) && --gWishFutureKnock.weatherDuration == 0)
|
||||
{
|
||||
gBattleWeather &= ~WEATHER_HAIL;
|
||||
gBattleWeather &= ~WEATHER_HAIL_TEMPORARY;
|
||||
gBattlescriptCurrInstr = BattleScript_SandStormHailEnds;
|
||||
}
|
||||
else
|
||||
@ -2311,7 +2312,39 @@ u8 CastformDataTypeChange(u8 battler)
|
||||
return formChange;
|
||||
}
|
||||
|
||||
// The largest function in the game, but even it could not save itself from decompiling.
|
||||
static const u16 sWeatherFlagsInfo[][3] =
|
||||
{
|
||||
[ENUM_WEATHER_RAIN] = {WEATHER_RAIN_TEMPORARY, WEATHER_RAIN_PERMANENT, HOLD_EFFECT_DAMP_ROCK},
|
||||
[ENUM_WEATHER_SUN] = {WEATHER_SUN_TEMPORARY, WEATHER_SUN_PERMANENT, HOLD_EFFECT_HEAT_ROCK},
|
||||
[ENUM_WEATHER_SANDSTORM] = {WEATHER_SANDSTORM_TEMPORARY, WEATHER_SANDSTORM_PERMANENT, HOLD_EFFECT_SMOOTH_ROCK},
|
||||
[ENUM_WEATHER_HAIL] = {WEATHER_HAIL_TEMPORARY, WEATHER_HAIL_PERMANENT, HOLD_EFFECT_ICY_ROCK},
|
||||
};
|
||||
|
||||
bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility)
|
||||
{
|
||||
if (viaAbility && B_ABILITY_WEATHER <= GEN_5
|
||||
&& !(gBattleWeather & sWeatherFlagsInfo[weatherEnumId][1]))
|
||||
{
|
||||
gBattleWeather = (sWeatherFlagsInfo[weatherEnumId][0] | sWeatherFlagsInfo[weatherEnumId][1]);
|
||||
return TRUE;
|
||||
}
|
||||
else if (B_ABILITY_WEATHER > GEN_5
|
||||
&& !(gBattleWeather & (sWeatherFlagsInfo[weatherEnumId][0] | sWeatherFlagsInfo[weatherEnumId][1])))
|
||||
{
|
||||
gBattleWeather = (sWeatherFlagsInfo[weatherEnumId][0]);
|
||||
if (GetBattlerHoldEffect(battler, TRUE) == sWeatherFlagsInfo[weatherEnumId][2])
|
||||
gWishFutureKnock.weatherDuration = 8;
|
||||
else
|
||||
gWishFutureKnock.weatherDuration = 5;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveArg)
|
||||
{
|
||||
u8 effect = 0;
|
||||
@ -2477,32 +2510,37 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
|
||||
}
|
||||
break;
|
||||
case ABILITY_DRIZZLE:
|
||||
if (!(gBattleWeather & WEATHER_RAIN_PERMANENT))
|
||||
if (TryChangeBattleWeather(battler, ENUM_WEATHER_RAIN, TRUE))
|
||||
{
|
||||
gBattleWeather = (WEATHER_RAIN_PERMANENT | WEATHER_RAIN_TEMPORARY);
|
||||
BattleScriptPushCursorAndCallback(BattleScript_DrizzleActivates);
|
||||
gBattleScripting.battler = battler;
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITY_SAND_STREAM:
|
||||
if (!(gBattleWeather & WEATHER_SANDSTORM_PERMANENT))
|
||||
if (TryChangeBattleWeather(battler, ENUM_WEATHER_SANDSTORM, TRUE))
|
||||
{
|
||||
gBattleWeather = (WEATHER_SANDSTORM_PERMANENT | WEATHER_SANDSTORM_TEMPORARY);
|
||||
BattleScriptPushCursorAndCallback(BattleScript_SandstreamActivates);
|
||||
BattleScriptPushCursorAndCallback(BattleScript_DrizzleActivates);
|
||||
gBattleScripting.battler = battler;
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITY_DROUGHT:
|
||||
if (!(gBattleWeather & WEATHER_SUN_PERMANENT))
|
||||
if (TryChangeBattleWeather(battler, ENUM_WEATHER_SUN, TRUE))
|
||||
{
|
||||
gBattleWeather = (WEATHER_SUN_PERMANENT | WEATHER_SUN_TEMPORARY);
|
||||
BattleScriptPushCursorAndCallback(BattleScript_DroughtActivates);
|
||||
gBattleScripting.battler = battler;
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITY_SNOW_WARNING:
|
||||
if (TryChangeBattleWeather(battler, ENUM_WEATHER_HAIL, TRUE))
|
||||
{
|
||||
BattleScriptPushCursorAndCallback(BattleScript_SnowWarningActivates);
|
||||
gBattleScripting.battler = battler;
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITY_INTIMIDATE:
|
||||
if (!(gSpecialStatuses[battler].intimidatedMon))
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user