Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: even more sleep clause #5

Merged
merged 19 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,7 @@ struct SleepClauseData
{
u8 isActive[NUM_BATTLE_SIDES]; // Stores sleep clause state for each battle side
bool8 effectExempt; // Stores whether effect should be exempt from triggering sleep clause (Effect Spore)
bool8 isCausingSleepClause[NUM_BATTLE_SIDES][PARTY_SIZE]; // When a Pokemon falls asleep, need to know if it should deactivate sleep clause upon waking
};

struct LostItem
Expand Down
2 changes: 1 addition & 1 deletion include/config/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@
#define B_OVERWORLD_FOG GEN_LATEST // In Gen8+, overworld Fog summons Misty Terrain in battle. In Gen4 only, overworld Fog summons the unique fog weather condition in battle.
#define B_TOXIC_REVERSAL GEN_LATEST // In Gen5+, bad poison will change to regular poison at the end of battles.
#define B_TRY_CATCH_TRAINER_BALL GEN_LATEST // In Gen4+, trying to catch a Trainer's Pokémon does not consume the Poké Ball.
#define B_SLEEP_CLAUSE TRUE // If the player / AI has already put a Pokémon on the opponent's side to sleep and it is still sleeping, another one can't be put to sleep.
#define B_SLEEP_CLAUSE TRUE // If the player / AI has already put a Pokémon on the opponent's side to sleep and it is still sleeping, another one can't be put to sleep.

// Animation Settings
#define B_NEW_SWORD_PARTICLE TRUE // If set to TRUE, it updates Swords Dance's particle.
Expand Down
4 changes: 4 additions & 0 deletions src/battle_dynamax.c
Original file line number Diff line number Diff line change
Expand Up @@ -888,7 +888,11 @@ void BS_TrySetStatus1(void)
else
gBattleMons[gBattlerTarget].status1 |= STATUS1_SLEEP_TURN((Random() % 4) + 3);
if (B_SLEEP_CLAUSE)
{
gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattlerTarget)] = TRUE;
gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattlerTarget)][gBattlerPartyIndexes[gBattlerTarget]] = TRUE;
}

gBattleCommunication[MULTISTRING_CHOOSER] = 4;
effect++;
}
Expand Down
74 changes: 71 additions & 3 deletions src/battle_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -3086,6 +3086,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
if (B_SLEEP_CLAUSE && !gBattleStruct->sleepClause.effectExempt)
{
gBattleStruct->sleepClause.isActive[GetBattlerSide(gEffectBattler)] = TRUE;
gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gEffectBattler)][gBattlerPartyIndexes[gEffectBattler]] = TRUE;
gBattleStruct->sleepClause.effectExempt = FALSE;
}
}
Expand Down Expand Up @@ -4007,6 +4008,11 @@ static void Cmd_tryfaintmon(void)

PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].moves[moveIndex])
}
if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]])
{
gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = FALSE;
gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = FALSE;
}
}
else
{
Expand Down Expand Up @@ -5711,6 +5717,11 @@ static void Cmd_moveend(void)
gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal;
break;
case STATUS1_SLEEP:
if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattlerTarget)] && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattlerTarget)][gBattlerPartyIndexes[gBattlerTarget]])
{
gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattlerTarget)] = FALSE;
gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattlerTarget)][gBattlerPartyIndexes[gBattlerTarget]] = FALSE;
}
gBattlescriptCurrInstr = BattleScript_TargetWokeUp;
break;
case STATUS1_BURN:
Expand Down Expand Up @@ -10008,11 +10019,26 @@ static void Cmd_various(void)
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[battler].status1), &gBattleMons[battler].status1);
MarkBattlerForControllerExec(battler);
gBattlescriptCurrInstr = cmd->nextInstr;
if (B_SLEEP_CLAUSE)
{
gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = TRUE;
gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = TRUE;
}
return;
}
case VARIOUS_CURE_STATUS:
{
VARIOUS_ARGS();

if (B_SLEEP_CLAUSE
&& (gBattleMons[battler].status1 & STATUS1_SLEEP)
&& gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)]
&& gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]])
{
gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = FALSE;
gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = FALSE;
}

gBattleMons[battler].status1 = 0;
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[battler].status1), &gBattleMons[battler].status1);
MarkBattlerForControllerExec(battler);
Expand Down Expand Up @@ -13178,12 +13204,11 @@ static void Cmd_healpartystatus(void)
u32 zero = 0;
u32 partner = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerAttacker)));
u8 toHeal = 0;
struct Pokemon *party = GetBattlerParty(gBattlerAttacker);
s32 i;

if (gCurrentMove == MOVE_HEAL_BELL)
{
struct Pokemon *party = GetBattlerParty(gBattlerAttacker);
s32 i;

gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_BELL;

if (GetBattlerAbility(gBattlerAttacker) != ABILITY_SOUNDPROOF
Expand Down Expand Up @@ -13249,7 +13274,25 @@ static void Cmd_healpartystatus(void)
}

if (ability != ABILITY_SOUNDPROOF)
{
toHeal |= (1 << i);

if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isCausingSleepClause[gBattlerAttacker][i])
{
gBattleStruct->sleepClause.isActive[gBattlerAttacker] = FALSE;
gBattleStruct->sleepClause.isCausingSleepClause[gBattlerAttacker][i] = FALSE;
}

if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
&& !(gAbsentBattlerFlags & gBitTable[partner]))
{
if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isCausingSleepClause[partner][i])
{
gBattleStruct->sleepClause.isActive[partner] = FALSE;
gBattleStruct->sleepClause.isCausingSleepClause[partner][i] = FALSE;
}
}
}
}
}
}
Expand All @@ -13258,12 +13301,29 @@ static void Cmd_healpartystatus(void)
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SOOTHING_AROMA;
toHeal = (1 << PARTY_SIZE) - 1;

if (B_SLEEP_CLAUSE)
{
gBattleStruct->sleepClause.isActive[gBattlerAttacker] = FALSE;
for (i = 0; i < PARTY_SIZE; i++)
{
gBattleStruct->sleepClause.isCausingSleepClause[gBattlerAttacker][i] = FALSE;
}
}

gBattleMons[gBattlerAttacker].status1 = 0;
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE;

if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
&& !(gAbsentBattlerFlags & gBitTable[partner]))
{
if (B_SLEEP_CLAUSE)
{
gBattleStruct->sleepClause.isActive[partner] = FALSE;
for (i = 0; i < PARTY_SIZE; i++)
{
gBattleStruct->sleepClause.isCausingSleepClause[partner][i] = FALSE;
}
}
gBattleMons[partner].status1 = 0;
gBattleMons[partner].status2 &= ~STATUS2_NIGHTMARE;
}
Expand Down Expand Up @@ -14629,6 +14689,14 @@ static void Cmd_switchoutabilities(void)
switch (GetBattlerAbility(battler))
{
case ABILITY_NATURAL_CURE:
if (B_SLEEP_CLAUSE
&& (gBattleMons[battler].status1 & STATUS1_SLEEP )
&& gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)]
&& gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]])
{
gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = FALSE;
gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = FALSE;
}
gBattleMons[battler].status1 = 0;
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE,
gBitTable[*(gBattleStruct->battlerPartyIndexes + battler)],
Expand Down
54 changes: 52 additions & 2 deletions src/battle_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -2826,7 +2826,11 @@ u8 DoBattlerEndTurnEffects(void)
gBattleMons[battler].status1 |= ((Random() % 4) + 3);

if (B_SLEEP_CLAUSE)
{
gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattlerTarget)] = TRUE;
gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattlerTarget)][gBattlerPartyIndexes[gBattlerTarget]] = TRUE;
}

BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[battler].status1);
MarkBattlerForControllerExec(battler);
BattleScriptExecute(BattleScript_YawnMakesAsleep);
Expand Down Expand Up @@ -3269,6 +3273,12 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType)
{
if (UproarWakeUpCheck(gBattlerAttacker))
{
if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattlerAttacker)] && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattlerAttacker)][gBattlerPartyIndexes[gBattlerAttacker]])
{
gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattlerAttacker)] = FALSE;
gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattlerAttacker)][gBattlerPartyIndexes[gBattlerAttacker]] = FALSE;
}

gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_SLEEP;
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE;
BattleScriptPushCursor();
Expand Down Expand Up @@ -3298,8 +3308,12 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType)
}
else
{
if (B_SLEEP_CLAUSE)
if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattlerAttacker)][gBattlerPartyIndexes[gBattlerAttacker]])
{
gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattlerAttacker)] = FALSE;
gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattlerAttacker)][gBattlerPartyIndexes[gBattlerAttacker]] = FALSE;
}

gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE;
BattleScriptPushCursor();
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP;
Expand Down Expand Up @@ -4969,7 +4983,15 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
if (gBattleMons[battler].status1 & (STATUS1_POISON | STATUS1_TOXIC_POISON))
StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn);
if (gBattleMons[battler].status1 & STATUS1_SLEEP)
{
StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn);
if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]])
{
gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = FALSE;
gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = FALSE;
}
}

if (gBattleMons[battler].status1 & STATUS1_PARALYSIS)
StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn);
if (gBattleMons[battler].status1 & STATUS1_BURN)
Expand Down Expand Up @@ -5056,8 +5078,16 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
gBattleScripting.battler = BATTLE_PARTNER(battler);
if (IsBattlerAlive(gBattleScripting.battler)
&& gBattleMons[gBattleScripting.battler].status1 & STATUS1_ANY
&& (Random() % 100) < 30)
&& (Random() % 100) < 90)
{
if (B_SLEEP_CLAUSE
&& (gBattleMons[gBattleScripting.battler].status1 & STATUS1_SLEEP )
&& gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattleScripting.battler)]
&& gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[gBattleScripting.battler]])
{
gBattleStruct->sleepClause.isActive[GetBattlerSide(gBattleScripting.battler)] = FALSE;
gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(gBattleScripting.battler)][gBattlerPartyIndexes[gBattleScripting.battler]] = FALSE;
}
BattleScriptPushCursorAndCallback(BattleScript_HealerActivates);
effect++;
}
Expand Down Expand Up @@ -6103,6 +6133,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_VITAL_SPIRIT:
if (gBattleMons[battler].status1 & STATUS1_SLEEP)
{
if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]])
{
gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = FALSE;
gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = FALSE;
}
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn);
effect = 1;
Expand Down Expand Up @@ -7214,6 +7249,11 @@ static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect)
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BerryCureSlpRet;
effect = ITEM_STATUS_CHANGE;
if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]])
{
gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = FALSE;
gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = FALSE;
}
}
break;
case HOLD_EFFECT_CURE_CONFUSION:
Expand Down Expand Up @@ -7455,6 +7495,11 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
BattleScriptExecute(BattleScript_BerryCureSlpEnd2);
effect = ITEM_STATUS_CHANGE;
if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]])
{
gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = FALSE;
gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = FALSE;
}
}
break;
case HOLD_EFFECT_CURE_STATUS:
Expand Down Expand Up @@ -7761,6 +7806,11 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
BattleScriptExecute(BattleScript_BerryCureSlpEnd2);
effect = ITEM_STATUS_CHANGE;
if (B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] && gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]])
{
gBattleStruct->sleepClause.isActive[GetBattlerSide(battler)] = FALSE;
gBattleStruct->sleepClause.isCausingSleepClause[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = FALSE;
}
}
break;
case HOLD_EFFECT_CURE_CONFUSION:
Expand Down
24 changes: 23 additions & 1 deletion src/pokemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -4184,13 +4184,35 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
bool8 HealStatusConditions(struct Pokemon *mon, u32 healMask, u8 battlerId)
{
u32 status = GetMonData(mon, MON_DATA_STATUS, 0);

u32 i = 0;
u32 battlerSide = GetBattlerSide(battlerId);

if (status & healMask)
{
status &= ~healMask;
SetMonData(mon, MON_DATA_STATUS, &status);
if (gMain.inBattle && battlerId != MAX_BATTLERS_COUNT)
{
gBattleMons[battlerId].status1 &= ~healMask;
if((healMask & STATUS1_SLEEP) && B_SLEEP_CLAUSE && gBattleStruct->sleepClause.isActive[battlerSide])
{
struct Pokemon *party;
if (battlerSide == B_SIDE_PLAYER)
party = gPlayerParty;
else
party = gEnemyParty;

for (i = 0; i < PARTY_SIZE; i++)
{
if (&party[i] == mon && gBattleStruct->sleepClause.isCausingSleepClause[battlerSide][i])
{
gBattleStruct->sleepClause.isActive[battlerSide] = FALSE;
gBattleStruct->sleepClause.isCausingSleepClause[battlerSide][i] = FALSE;
break;
}
}
}
}
return FALSE;
}
else
Expand Down
Loading
Loading