Introduce battle config; Snow Warning Done.

This commit is contained in:
DizzyEggg 2018-07-27 23:40:10 +02:00
parent 0c6d30e3da
commit 9088c0bdb5
8 changed files with 101 additions and 32 deletions

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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