Skip to content

Commit

Permalink
Merge pull request #5 from iriv24/even-more-sleep-clause
Browse files Browse the repository at this point in the history
WIP: even more sleep clause
  • Loading branch information
Pawkkie authored Oct 22, 2024
2 parents 81dd174 + 954f411 commit 3c48bca
Show file tree
Hide file tree
Showing 7 changed files with 696 additions and 91 deletions.
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

0 comments on commit 3c48bca

Please sign in to comment.