From c2f81cd5f52a7a0da113b33d4b5e4029b04c1d01 Mon Sep 17 00:00:00 2001 From: W1serV1ser <1prefertheaircauseimanairnomad@gmail.com> Date: Sat, 20 Nov 2021 11:44:48 -0800 Subject: [PATCH 01/27] Added Sky Drop --- asm/macros/battle_script.inc | 22 +++ data/battle_scripts_1.s | 65 ++++++++- include/battle.h | 1 + include/constants/battle.h | 5 +- include/constants/battle_move_effects.h | 3 +- include/constants/battle_script_commands.h | 29 ++-- include/constants/battle_string_ids.h | 39 +++--- src/battle_ai_switch_items.c | 4 +- src/battle_main.c | 66 ++++++++- src/battle_message.c | 5 + src/battle_script_commands.c | 154 +++++++++++++++++++-- src/battle_util.c | 140 ++++++++++++++++++- src/data/battle_moves.h | 2 +- 13 files changed, 484 insertions(+), 51 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 6ba63f916f..4ef2168fbf 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -2055,3 +2055,25 @@ 1: .endm + @ Will jump to script pointer if the target weighs less than 200 kg, or 441 lbs. + .macro jumpifunder200 battler:req, ptr:req + various \battler, VARIOUS_JUMP_IF_UNDER_200 + .4byte \ptr + .endm + + @ Sets the sky drop status and does all other necessary operations + .macro setskydrop + various 0, VARIOUS_SET_SKY_DROP + .endm + + @ Clears the sky drop status and does all other necessary operations. + @ If the target fainted in before this script is called, it goes to the given script. + .macro clearskydrop ptr:req + various 0, VARIOUS_CLEAR_SKY_DROP + .4byte \ptr + .endm + + @ Accounts for if the target of Sky Drop was in confuse_lock when the attacker falls asleep due to Yawn. + .macro skydropyawn + various 0, VARIOUS_SKY_DROP_YAWN + .endm diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index e9d019e430..39f184ed8d 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -374,7 +374,7 @@ gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectJungleHealing @ EFFECT_JUNGLE_HEALING .4byte BattleScript_EffectCoaching @ EFFECT_COACHING .4byte BattleScript_EffectHit @ EFFECT_LASH_OUT - .4byte BattleScript_EffectHit @ EFFECT_GRASSY_GLIDE + .4byte BattleScript_EffectHit @ EFFECT_GRASSY_GLIDE .4byte BattleScript_EffectRemoveTerrain @ EFFECT_REMOVE_TERRAIN .4byte BattleScript_EffectHit @ EFFECT_DYNAMAX_DOUBLE_DMG .4byte BattleScript_EffectDecorate @ EFFECT_DECORATE @@ -403,6 +403,65 @@ gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectOctolock @ EFFECT_OCTOLOCK .4byte BattleScript_EffectClangorousSoul @ EFFECT_CLANGOROUS_SOUL .4byte BattleScript_EffectHit @ EFFECT_BOLT_BEAK + .4byte BattleScript_EffectSkyDrop @ EFFECT_SKY_DROP + +BattleScript_EffectSkyDrop: + jumpifstatus2 BS_ATTACKER, STATUS2_MULTIPLETURNS, BattleScript_SkyDropTurn2 + attackcanceler + ppreduce + accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE + attackstring + jumpifsubstituteblocks BattleScript_ButItFailed + jumpiftargetally BattleScript_ButItFailed + jumpifunder200 BS_TARGET, BattleScript_SkyDropWork + pause B_WAIT_TIME_SHORT + printstring STRINGID_TARGETTOOHEAVY + waitmessage B_WAIT_TIME_LONG + goto BattleScript_MoveEnd + +BattleScript_SkyDropWork: + setskydrop + setbyte sTWOTURN_STRINGID, B_MSG_TURN1_SKY_DROP + setsemiinvulnerablebit + call BattleScriptFirstChargingTurnAfterAttackString + goto BattleScript_MoveEnd +BattleScript_SkyDropTurn2: + attackcanceler + setmoveeffect MOVE_EFFECT_CHARGING + setbyte sB_ANIM_TURN, 0x1 + clearstatusfromeffect BS_ATTACKER + orword gHitMarker, HITMARKER_NO_PPDEDUCT + argumenttomoveeffect + clearsemiinvulnerablebit + attackstring + clearskydrop BattleScript_SkyDropChangedTarget + jumpiftype BS_TARGET, TYPE_FLYING, BattleScript_SkyDropFlyingType + goto BattleScript_HitFromCritCalc +BattleScript_SkyDropFlyingType: + makevisible BS_TARGET + printstring STRINGID_ITDOESNTAFFECT + waitmessage B_WAIT_TIME_LONG + makevisible BS_ATTACKER + jumpifstatus2 BS_TARGET, STATUS2_CONFUSION, BattleScript_SkyDropFlyingAlreadyConfused + jumpifstatus2 BS_TARGET, STATUS2_LOCK_CONFUSE, BattleScript_SkyDropFlyingConfuseLock + goto BattleScript_MoveEnd +BattleScript_SkyDropChangedTarget: + pause B_WAIT_TIME_SHORT + orhalfword gMoveResultFlags, MOVE_RESULT_FAILED + resultmessage + waitmessage B_WAIT_TIME_LONG + makevisible BS_ATTACKER + goto BattleScript_MoveEnd + +BattleScript_SkyDropFlyingConfuseLock: + setmoveeffect MOVE_EFFECT_CONFUSION + seteffectprimary +BattleScript_SkyDropFlyingAlreadyConfused: + setmoveeffect MOVE_EFFECT_THRASH + clearstatusfromeffect BS_TARGET + jumpifstatus2 BS_TARGET, STATUS2_CONFUSION, BattleScript_MoveEnd + setbyte BS_ATTACKER, BS_TARGET + goto BattleScript_ThrashConfuses BattleScript_EffectShellSideArm: shellsidearmcheck @@ -3400,6 +3459,7 @@ BattleScriptFirstChargingTurn:: printstring STRINGID_EMPTYSTRING3 ppreduce attackstring +BattleScriptFirstChargingTurnAfterAttackString: pause B_WAIT_TIME_LONG copybyte cMULTISTRING_CHOOSER, sTWOTURN_STRINGID printfromtable gFirstTurnOfTwoStringIds @@ -7511,7 +7571,10 @@ BattleScript_YawnMakesAsleep:: waitmessage B_WAIT_TIME_LONG updatestatusicon BS_EFFECT_BATTLER waitstate + jumpifstatus3 BS_EFFECT_BATTLER, STATUS3_SKY_DROPPED, BattleScript_YawnEnd makevisible BS_EFFECT_BATTLER + skydropyawn +BattleScript_YawnEnd: end2 BattleScript_EmbargoEndTurn:: diff --git a/include/battle.h b/include/battle.h index b587e482db..4cb7e7e02c 100644 --- a/include/battle.h +++ b/include/battle.h @@ -616,6 +616,7 @@ struct BattleStruct u8 blunderPolicy:1; // should blunder policy activate u8 ballSpriteIds[2]; // item gfx, window gfx u8 stickyWebUser; + u8 skyDropTargets[MAX_BATTLERS_COUNT]; // For Sky Drop, to account for if multiple Pokemon use Sky Drop in a double battle. }; #define GET_MOVE_TYPE(move, typeArg) \ diff --git a/include/constants/battle.h b/include/constants/battle.h index 28934abc25..86e5d14c9a 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -170,6 +170,7 @@ #define STATUS3_AQUA_RING (1 << 28) #define STATUS3_LASER_FOCUS (1 << 29) #define STATUS3_POWER_TRICK (1 << 30) +#define STATUS3_SKY_DROPPED (1 << 31) // Target of Sky Drop #define STATUS3_SEMI_INVULNERABLE (STATUS3_UNDERGROUND | STATUS3_ON_AIR | STATUS3_UNDERWATER | STATUS3_PHANTOM_FORCE) #define STATUS4_ELECTRIFIED (1 << 0) @@ -359,7 +360,9 @@ #define MOVE_EFFECT_RECOIL_HP_25 0x46 #define MOVE_EFFECT_RELIC_SONG 0x47 #define MOVE_EFFECT_TRAP_BOTH 0x48 -#define NUM_MOVE_EFFECTS 0x49 +#define MOVE_EFFECT_SKY_DROP 0x49 + +#define NUM_MOVE_EFFECTS 0x50 #define MOVE_EFFECT_AFFECTS_USER 0x4000 #define MOVE_EFFECT_CERTAIN 0x8000 diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 3f24caf5e5..82fc381a6a 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -386,7 +386,8 @@ #define EFFECT_OCTOLOCK 380 #define EFFECT_CLANGOROUS_SOUL 381 #define EFFECT_BOLT_BEAK 382 +#define EFFECT_SKY_DROP 383 -#define NUM_BATTLE_MOVE_EFFECTS 383 +#define NUM_BATTLE_MOVE_EFFECTS 384 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index bd16f741be..c191bc5e54 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -208,6 +208,10 @@ #define VARIOUS_SET_OCTOLOCK 135 #define VARIOUS_CUT_1_3_HP_RAISE_STATS 136 #define VARIOUS_TRY_END_NEUTRALIZING_GAS 137 +#define VARIOUS_JUMP_IF_UNDER_200 138 +#define VARIOUS_SET_SKY_DROP 139 +#define VARIOUS_CLEAR_SKY_DROP 140 +#define VARIOUS_SKY_DROP_YAWN 141 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 @@ -265,18 +269,19 @@ #define MOVEEND_ITEM_EFFECTS_ALL 15 #define MOVEEND_KINGSROCK 16 // These item effects will occur each strike of a multi-hit move #define MOVEEND_SUBSTITUTE 17 -#define MOVEEND_UPDATE_LAST_MOVES 18 -#define MOVEEND_MIRROR_MOVE 19 -#define MOVEEND_NEXT_TARGET 20 // Everything up until here is handled for each strike of a multi-hit move -#define MOVEEND_EJECT_BUTTON 21 -#define MOVEEND_RED_CARD 22 -#define MOVEEND_EJECT_PACK 23 -#define MOVEEND_LIFEORB_SHELLBELL 24 // Includes shell bell, throat spray, etc -#define MOVEEND_PICKPOCKET 25 -#define MOVEEND_DANCER 26 -#define MOVEEND_EMERGENCY_EXIT 27 -#define MOVEEND_CLEAR_BITS 28 -#define MOVEEND_COUNT 29 +#define MOVEEND_SKY_DROP_CONFUSE 18 +#define MOVEEND_UPDATE_LAST_MOVES 19 +#define MOVEEND_MIRROR_MOVE 20 +#define MOVEEND_NEXT_TARGET 21 // Everything up until here is handled for each strike of a multi-hit move +#define MOVEEND_EJECT_BUTTON 22 +#define MOVEEND_RED_CARD 23 +#define MOVEEND_EJECT_PACK 24 +#define MOVEEND_LIFEORB_SHELLBELL 25 // Includes shell bell, throat spray, etc +#define MOVEEND_PICKPOCKET 26 +#define MOVEEND_DANCER 27 +#define MOVEEND_EMERGENCY_EXIT 28 +#define MOVEEND_CLEAR_BITS 29 +#define MOVEEND_COUNT 30 // switch cases #define B_SWITCH_NORMAL 0 diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 7846fa5218..83e931c2ca 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -592,25 +592,27 @@ #define STRINGID_STRONGWINDSDISSIPATED 588 #define STRINGID_MYSTERIOUSAIRCURRENTBLOWSON 589 #define STRINGID_ATTACKWEAKENEDBSTRONGWINDS 590 -#define STRINGID_STUFFCHEEKSCANTSELECT 592 -#define STRINGID_PKMNREVERTEDTOPRIMAL 593 -#define STRINGID_BUTPOKEMONCANTUSETHEMOVE 594 -#define STRINGID_BUTHOOPACANTUSEIT 595 -#define STRINGID_BROKETHROUGHPROTECTION 596 -#define STRINGID_ABILITYALLOWSONLYMOVE 597 -#define STRINGID_SWAPPEDABILITIES 598 -#define STRINGID_PASTELVEILPROTECTED 599 -#define STRINGID_PASTELVEILENTERS 600 -#define STRINGID_BATTLERTYPECHANGEDTO 601 -#define STRINGID_BOTHCANNOLONGERESCAPE 602 -#define STRINGID_CANTESCAPEDUETOUSEDMOVE 603 -#define STRINGID_PKMNBECAMEWEAKERTOFIRE 604 -#define STRINGID_ABOUTTOUSEPOLTERGEIST 605 -#define STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE 606 -#define STRINGID_NEUTRALIZINGGASENTERS 607 -#define STRINGID_NEUTRALIZINGGASOVER 608 +#define STRINGID_STUFFCHEEKSCANTSELECT 591 +#define STRINGID_PKMNREVERTEDTOPRIMAL 592 +#define STRINGID_BUTPOKEMONCANTUSETHEMOVE 593 +#define STRINGID_BUTHOOPACANTUSEIT 594 +#define STRINGID_BROKETHROUGHPROTECTION 595 +#define STRINGID_ABILITYALLOWSONLYMOVE 596 +#define STRINGID_SWAPPEDABILITIES 597 +#define STRINGID_PASTELVEILPROTECTED 598 +#define STRINGID_PASTELVEILENTERS 599 +#define STRINGID_BATTLERTYPECHANGEDTO 600 +#define STRINGID_BOTHCANNOLONGERESCAPE 601 +#define STRINGID_CANTESCAPEDUETOUSEDMOVE 602 +#define STRINGID_PKMNBECAMEWEAKERTOFIRE 603 +#define STRINGID_ABOUTTOUSEPOLTERGEIST 604 +#define STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE 605 +#define STRINGID_NEUTRALIZINGGASENTERS 606 +#define STRINGID_NEUTRALIZINGGASOVER 607 +#define STRINGID_TARGETTOOHEAVY 608 +#define STRINGID_PKMNTOOKTARGETHIGH 609 -#define BATTLESTRINGS_COUNT 609 +#define BATTLESTRINGS_COUNT 610 // The below IDs are all indexes into battle message tables, // used to determine which of a set of messages to print. @@ -661,6 +663,7 @@ #define B_MSG_TURN1_PHANTOM_FORCE 8 #define B_MSG_TURN1_GEOMANCY 9 #define B_MSG_TURN1_FREEZE_SHOCK 10 +#define B_MSG_TURN1_SKY_DROP 11 // gMoveWeatherChangeStringIds #define B_MSG_STARTED_RAIN 0 diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 400876cc9b..f5d8901404 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -793,7 +793,9 @@ static bool8 ShouldUseItem(void) u8 validMons = 0; bool8 shouldUse = FALSE; - if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_RIGHT) + // If teaming up with player and Pokemon is on the right, or Pokemon is currently held by Sky Drop + if ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_RIGHT) + || gStatuses3[gActiveBattler] & STATUS3_SKY_DROPPED) return FALSE; if (gStatuses3[gActiveBattler] & STATUS3_EMBARGO) diff --git a/src/battle_main.c b/src/battle_main.c index 5277ade1ea..c22a3f6133 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -2945,6 +2945,12 @@ static void BattleStartClearSetData(void) } gSwapDamageCategory = FALSE; // Photon Geyser, Shell Side Arm, Light That Burns the Sky + + // Clear skyDropTargets data + for (i = 0; i < 4; i++) + { + gBattleStruct->skyDropTargets[i] = 0xFF; + } } void SwitchInClearSetData(void) @@ -3081,6 +3087,56 @@ void FaintClearSetData(void) gBattleMons[i].status2 &= ~(STATUS2_INFATUATED_WITH(gActiveBattler)); if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && *(gBattleStruct->wrappedBy + i) == gActiveBattler) gBattleMons[i].status2 &= ~(STATUS2_WRAPPED); + + // If the fainted mon was holding another Pokemon in Sky Drop, release the mon and clear Sky Drop data + if (gActiveBattler == gBattleStruct->skyDropTargets[0] && i == gBattleStruct->skyDropTargets[1]) + { + gBattleStruct->skyDropTargets[0] = 0xFF; + gBattleStruct->skyDropTargets[1] = 0xFF; + + gStatuses3[i] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); + gSprites[gBattlerSpriteIds[i]].invisible = FALSE; + + // If the target was sky dropped in the middle of using Outrage/Petal Dance/Thrash, + // confuse them upon release and print "confused via fatigue" message and animation. + if (gBattleMons[i].status2 & STATUS2_LOCK_CONFUSE) + { + gBattleMons[i].status2 &= ~(STATUS2_LOCK_CONFUSE); + + // If the released mon can be confused, do so. + // Don't use CanBeConfused here, since it can cause issues in edge cases. + if (!(GetBattlerAbility(i) == ABILITY_OWN_TEMPO + || gBattleMons[i].status2 & STATUS2_CONFUSION + || IsBattlerTerrainAffected(i, STATUS_FIELD_MISTY_TERRAIN))) + { + gBattleMons[i].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); + gBattlerAttacker = i; + gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 2; + } + } + } + else if (gActiveBattler == gBattleStruct->skyDropTargets[2] && i == gBattleStruct->skyDropTargets[3]) + { + gBattleStruct->skyDropTargets[2] = 0xFF; + gBattleStruct->skyDropTargets[3] = 0xFF; + + gStatuses3[i] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); + gSprites[gBattlerSpriteIds[i]].invisible = FALSE; + + if (gBattleMons[i].status2 & STATUS2_LOCK_CONFUSE) + { + gBattleMons[i].status2 &= ~(STATUS2_LOCK_CONFUSE); + gEffectBattler = i; + if (!(GetBattlerAbility(i) == ABILITY_OWN_TEMPO + || gBattleMons[i].status2 & STATUS2_CONFUSION + || IsBattlerTerrainAffected(i, STATUS_FIELD_MISTY_TERRAIN))) + { + gBattleMons[i].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); + gBattlerAttacker = i; + gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 2; + } + } + } } gActionSelectionCursor[gActiveBattler] = 0; @@ -3160,6 +3216,12 @@ void FaintClearSetData(void) UndoFormChange(gBattlerPartyIndexes[gActiveBattler], GET_BATTLER_SIDE(gActiveBattler), FALSE); if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) UndoMegaEvolution(gBattlerPartyIndexes[gActiveBattler]); + + // If the fainted Pokemon was being held by Sky Drop, clear their Sky Drop data. + if (gActiveBattler == gBattleStruct->skyDropTargets[1]) + gBattleStruct->skyDropTargets[1] = 0xFF; + else if (gActiveBattler == gBattleStruct->skyDropTargets[3]) + gBattleStruct->skyDropTargets[3] = 0xFF; } static void DoBattleIntro(void) @@ -3897,10 +3959,12 @@ static void HandleTurnActionSelectionState(void) } break; case B_ACTION_USE_ITEM: - if (gBattleTypeFlags & (BATTLE_TYPE_LINK + if ((gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_FRONTIER_NO_PYRAMID | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_RECORDED_LINK)) + // Or if currently held by Sky Drop + || gStatuses3[gActiveBattler] & STATUS3_SKY_DROPPED) { RecordedBattle_ClearBattlerAction(gActiveBattler, 1); gSelectionBattleScripts[gActiveBattler] = BattleScript_ActionSelectionItemsCantBeUsed; diff --git a/src/battle_message.c b/src/battle_message.c index d64d02f902..9174d7c3bc 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -431,6 +431,8 @@ static const u8 sText_ExclamationMark4[] = _("!"); static const u8 sText_ExclamationMark5[] = _("!"); static const u8 sText_Accuracy[] = _("accuracy"); static const u8 sText_Evasiveness[] = _("evasiveness"); +static const u8 sText_PkmnTookTargetHigh[] = _("{B_ATK_NAME_WITH_PREFIX} took {B_DEF_NAME_WITH_PREFIX}\ninto the air!"); +static const u8 sText_TargetTooHeavy[] = _("But the target\nwas too heavy!"); const u8 * const gStatNamesTable[NUM_BATTLE_STATS] = { @@ -1334,6 +1336,8 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_PKMNBECAMEWEAKERTOFIRE - 12] = sText_PkmnBecameWeakerToFire, [STRINGID_ABOUTTOUSEPOLTERGEIST - 12] = sText_PkmnAboutToBeAttackedByItsItem, [STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE - 12] = sText_CantEscapeBecauseOfCurrentMove, + [STRINGID_PKMNTOOKTARGETHIGH - 12] = sText_PkmnTookTargetHigh, + [STRINGID_TARGETTOOHEAVY - 12] = sText_TargetTooHeavy, }; const u16 gMentalHerbCureStringIds[] = @@ -1548,6 +1552,7 @@ const u16 gFirstTurnOfTwoStringIds[] = [B_MSG_TURN1_PHANTOM_FORCE] = STRINGID_VANISHEDINSTANTLY, [B_MSG_TURN1_GEOMANCY] = STRINGID_PKNMABSORBINGPOWER, [B_MSG_TURN1_FREEZE_SHOCK] = STRINGID_CLOAKEDINAFREEZINGLIGHT, + [B_MSG_TURN1_SKY_DROP] = STRINGID_PKMNTOOKTARGETHIGH, }; // Index copied from move's index in sTrappingMoves diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 7923a67395..1b08f86a86 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1089,7 +1089,7 @@ static const u16 sMoveEffectsForbiddenToInstruct[] = EFFECT_SEMI_INVULNERABLE, //EFFECT_SHELL_TRAP, EFFECT_SKETCH, - //EFFECT_SKY_DROP, + EFFECT_SKY_DROP, EFFECT_SKULL_BASH, EFFECT_SLEEP_TALK, EFFECT_SOLARBEAM, @@ -1609,13 +1609,15 @@ static bool32 AccuracyCalcHelper(u16 move) JumpIfMoveFailed(7, move); return TRUE; } - else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD) + // If the attacker has the ability No Guard and they aren't targeting a Pokemon involved in a Sky Drop with the move Sky Drop, move hits. + else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || (gBattlerTarget != gBattleStruct->skyDropTargets[0] && gBattlerTarget != gBattleStruct->skyDropTargets[1] && gBattlerTarget != gBattleStruct->skyDropTargets[2] && gBattlerTarget != gBattleStruct->skyDropTargets[3]))) { if (!JumpIfMoveFailed(7, move)) RecordAbilityBattle(gBattlerAttacker, ABILITY_NO_GUARD); return TRUE; } - else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD) + // If the target has the ability No Guard and they aren't involved in a Sky Drop or the current move isn't Sky Drop, move hits. + else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || (gBattlerTarget != gBattleStruct->skyDropTargets[0] && gBattlerTarget != gBattleStruct->skyDropTargets[1] && gBattlerTarget != gBattleStruct->skyDropTargets[2] && gBattlerTarget != gBattleStruct->skyDropTargets[3]))) { if (!JumpIfMoveFailed(7, move)) RecordAbilityBattle(gBattlerTarget, ABILITY_NO_GUARD); @@ -1623,8 +1625,7 @@ static bool32 AccuracyCalcHelper(u16 move) } if ((gStatuses3[gBattlerTarget] & STATUS3_PHANTOM_FORCE) - || (!(gBattleMoves[move].flags & FLAG_DMG_IN_AIR) && gStatuses3[gBattlerTarget] & STATUS3_ON_AIR) - || (!(gBattleMoves[move].flags & FLAG_DMG_2X_IN_AIR) && gStatuses3[gBattlerTarget] & STATUS3_ON_AIR) + || (!(gBattleMoves[move].flags & FLAG_DMG_IN_AIR || gBattleMoves[move].flags & FLAG_DMG_2X_IN_AIR) && gStatuses3[gBattlerTarget] & STATUS3_ON_AIR) || (!(gBattleMoves[move].flags & FLAG_DMG_UNDERGROUND) && gStatuses3[gBattlerTarget] & STATUS3_UNDERGROUND) || (!(gBattleMoves[move].flags & FLAG_DMG_UNDERWATER) && gStatuses3[gBattlerTarget] & STATUS3_UNDERWATER)) { @@ -2929,9 +2930,20 @@ void SetMoveEffect(bool32 primary, u32 certain) else { gBattleMons[gEffectBattler].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); // 2-5 turns - - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleScripting.moveEffect]; + + // If the confusion is activating due to being released from Sky Drop, go to "confused due to fatigue" script. + // Otherwise, do normal confusion script. + if(gCurrentMove == MOVE_SKY_DROP) + { + gBattleMons[gEffectBattler].status2 &= ~(STATUS2_LOCK_CONFUSE); + gBattlerAttacker = gEffectBattler; + gBattlescriptCurrInstr = BattleScript_ThrashConfuses; + } + else + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleScripting.moveEffect]; + } } break; case MOVE_EFFECT_FLINCH: @@ -5141,6 +5153,28 @@ static void Cmd_moveend(void) } gBattleScripting.moveendState++; break; + case MOVEEND_SKY_DROP_CONFUSE: // If a Pokemon was released from Sky Drop and was in LOCK_CONFUSE, go to "confused due to fatigue scripts and clear Sky Drop data. + for (i = 0; i < gBattlersCount; i++) + { + if (gBattleStruct->skyDropTargets[0] == 0xFE - i) + { + gBattlerAttacker = gBattleStruct->skyDropTargets[1]; + gBattlescriptCurrInstr = BattleScript_ThrashConfuses; + gBattleStruct->skyDropTargets[0] = 0xFF; + gBattleStruct->skyDropTargets[1] = 0xFF; + return; + } + else if (gBattleStruct->skyDropTargets[2] == 0xFE - i) + { + gBattlerAttacker = gBattleStruct->skyDropTargets[3]; + gBattlescriptCurrInstr = BattleScript_ThrashConfuses; + gBattleStruct->skyDropTargets[2] = 0xFF; + gBattleStruct->skyDropTargets[3] = 0xFF; + return; + } + } + gBattleScripting.moveendState++; + break; case MOVEEND_UPDATE_LAST_MOVES: if (gMoveResultFlags & (MOVE_RESULT_FAILED | MOVE_RESULT_DOESNT_AFFECT_FOE)) gBattleStruct->lastMoveFailed |= gBitTable[gBattlerAttacker]; @@ -7680,7 +7714,8 @@ static void Cmd_various(void) } return; case VARIOUS_GRAVITY_ON_AIRBORNE_MONS: - if (gStatuses3[gActiveBattler] & STATUS3_ON_AIR) + // Cancel all multiturn moves of IN_AIR Pokemon except those being targeted by Sky Drop. + if (gStatuses3[gActiveBattler] & STATUS3_ON_AIR && !(gActiveBattler == gBattleStruct->skyDropTargets[1] || gActiveBattler == gBattleStruct->skyDropTargets[3])) CancelMultiTurnMoves(gActiveBattler); gStatuses3[gActiveBattler] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR); @@ -8892,7 +8927,7 @@ static void Cmd_various(void) MarkBattlerForControllerExec(gActiveBattler); } - if (gBattleMons[gActiveBattler].pp[i] == 0) + if (gBattleMons[gActiveBattler].pp[i] == 0 && !(gActiveBattler == gBattleStruct->skyDropTargets[0] || gActiveBattler == gBattleStruct->skyDropTargets[2])) CancelMultiTurnMoves(gActiveBattler); gBattlescriptCurrInstr += 7; // continue @@ -8959,6 +8994,101 @@ static void Cmd_various(void) gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain TryToRevertMimicry(); // restore the types of Pokémon with Mimicry break; + case VARIOUS_JUMP_IF_UNDER_200: + // If the Pokemon is less than 200 kg, or weighing less than 441 lbs, then Sky Drop will work. Otherwise, it will fail. + if (GetPokedexHeightWeight(SpeciesToNationalPokedexNum(gBattleMons[gBattlerTarget].species), 1) < 441) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + else + gBattlescriptCurrInstr += 7; + return; + case VARIOUS_SET_SKY_DROP: + gStatuses3[gBattlerTarget] |= (STATUS3_SKY_DROPPED | STATUS3_ON_AIR); + /* skyDropTargets holds the information of who is the attacker and the target of Sky Drop. + This is needed in the case that multiple Pokemon use Sky Drop in the same turn or if + the target of a Sky Drop faints while in the air.*/ + if (gBattleStruct->skyDropTargets[0] == 0xFF) + { + gBattleStruct->skyDropTargets[0] = gBattlerAttacker; + gBattleStruct->skyDropTargets[1] = gBattlerTarget; + } + else + { + gBattleStruct->skyDropTargets[2] = gBattlerAttacker; + gBattleStruct->skyDropTargets[3] = gBattlerTarget; + } + + // End any multiturn effects caused by the target + gBattleMons[gBattlerTarget].status2 &= ~(STATUS2_MULTIPLETURNS); + gBattleMons[gBattlerTarget].status2 &= ~(STATUS2_UPROAR); + gBattleMons[gBattlerTarget].status2 &= ~(STATUS2_BIDE); + gDisableStructs[gBattlerTarget].rolloutTimer = 0; + gDisableStructs[gBattlerTarget].furyCutterCounter = 0; + break; + case VARIOUS_CLEAR_SKY_DROP: + if (gBattleStruct->skyDropTargets[0] == gBattlerAttacker) + { + // Check to see if the initial target of this Sky Drop fainted before the 2nd turn of Sky Drop. + // If so, make the move fail. If not, clear all of the statuses and continue the move. + if (gBattleStruct->skyDropTargets[1] == 0xFF) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + else + { + gStatuses3[gBattlerTarget] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); + gBattlescriptCurrInstr += 7; + } + + // Clear skyDropTargets data + gBattleStruct->skyDropTargets[0] = 0xFF; + gBattleStruct->skyDropTargets[1] = 0xFF; + } + else + { + if (gBattleStruct->skyDropTargets[3] == 0xFF) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + else + { + gStatuses3[gBattlerTarget] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); + gBattlescriptCurrInstr += 7; + } + + gBattleStruct->skyDropTargets[2] = 0xFF; + gBattleStruct->skyDropTargets[3] = 0xFF; + } + + // Confuse target if they were in the middle of Petal Dance/Outrage/Thrash when targeted. + if (gBattleMons[gBattlerTarget].status2 & STATUS2_LOCK_CONFUSE) + gBattleScripting.moveEffect = (MOVE_EFFECT_CONFUSION | MOVE_EFFECT_CERTAIN); + return; + case VARIOUS_SKY_DROP_YAWN: // If the mon that's sleeping due to Yawn was holding a Pokemon in Sky Drop, release the target and clear Sky Drop data. + if (gEffectBattler == gBattleStruct->skyDropTargets[0]) + { + gEffectBattler = gBattleStruct->skyDropTargets[1]; + gBattleStruct->skyDropTargets[0] = 0xFF; + gBattleStruct->skyDropTargets[1] = 0xFF; + gBattleMons[gEffectBattler].status2 &= ~(STATUS2_LOCK_CONFUSE); + if (CanBeConfused(gEffectBattler)) + { + gBattlerAttacker = gEffectBattler; + gBattleMons[gBattlerTarget].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); + gBattlescriptCurrInstr = BattleScript_ThrashConfuses; + return; + } + } + else if (gEffectBattler == gBattleStruct->skyDropTargets[2]) + { + gEffectBattler = gBattleStruct->skyDropTargets[3]; + gBattleStruct->skyDropTargets[2] = 0xFF; + gBattleStruct->skyDropTargets[3] = 0xFF; + gBattleMons[gEffectBattler].status2 &= ~(STATUS2_LOCK_CONFUSE); + if (CanBeConfused(gEffectBattler)) + { + gBattlerAttacker = gEffectBattler; + gBattleMons[gBattlerTarget].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); + gBattlescriptCurrInstr = BattleScript_ThrashConfuses; + return; + } + } + break; case VARIOUS_JUMP_IF_PRANKSTER_BLOCKED: if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gActiveBattler, TRUE)) gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); @@ -11351,7 +11481,8 @@ static void Cmd_tryspiteppreduce(void) gBattlescriptCurrInstr += 5; - if (gBattleMons[gBattlerTarget].pp[i] == 0) + // Don't cut off Sky Drop if pp is brought to zero. + if (gBattleMons[gBattlerTarget].pp[i] == 0 && !(gBattlerTarget == gBattleStruct->skyDropTargets[0] || gBattlerTarget == gBattleStruct->skyDropTargets[2])) CancelMultiTurnMoves(gBattlerTarget); } else @@ -11997,6 +12128,7 @@ static void Cmd_setsemiinvulnerablebit(void) { case MOVE_FLY: case MOVE_BOUNCE: + case MOVE_SKY_DROP: gStatuses3[gBattlerAttacker] |= STATUS3_ON_AIR; break; case MOVE_DIG: diff --git a/src/battle_util.c b/src/battle_util.c index cc619decf8..7cd7254d7d 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -224,6 +224,7 @@ bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move) if (gSideTimers[defSide].followmeTimer == 0 || gBattleMons[gSideTimers[defSide].followmeTarget].hp == 0 || gBattleMoves[move].effect == EFFECT_SNIPE_SHOT + || gBattleMoves[move].effect == EFFECT_SKY_DROP || ability == ABILITY_PROPELLER_TAIL || ability == ABILITY_STALWART) return FALSE; @@ -1420,12 +1421,123 @@ void MarkBattlerReceivedLinkData(u8 battlerId) void CancelMultiTurnMoves(u8 battler) { + u8 i; gBattleMons[battler].status2 &= ~(STATUS2_MULTIPLETURNS); gBattleMons[battler].status2 &= ~(STATUS2_LOCK_CONFUSE); gBattleMons[battler].status2 &= ~(STATUS2_UPROAR); gBattleMons[battler].status2 &= ~(STATUS2_BIDE); - gStatuses3[battler] &= ~(STATUS3_SEMI_INVULNERABLE); + // Don't clear battler's semi-invulnerable bits if they are held by Sky Drop. + if (gBattleStruct->skyDropTargets[1] != battler && gBattleStruct->skyDropTargets[3] != battler) + gStatuses3[battler] &= ~(STATUS3_SEMI_INVULNERABLE); + + // Check to see if this Pokemon was in the middle of using Sky Drop. If so, release the target. + if (gBattleStruct->skyDropTargets[0] == battler) + { + // Sets skyDropTargets[1] to be the battler id for the target + for(i = 0; i < MAX_BATTLERS_COUNT; i++) + { + if(gBattleStruct->skyDropTargets[1] == i) + { + // Clears sky dropped and on_air statuses + gStatuses3[i] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); + + // Makes both attacker and target's sprites visible + gSprites[gBattlerSpriteIds[battler]].invisible = FALSE; + gSprites[gBattlerSpriteIds[i]].invisible = FALSE; + + // If target was sky dropped in the middle of Outrage/Thrash/Petal Dance, + // confuse them upon release and display "confused by fatigue" message & animation. + // Don't do this if this CancelMultiTurnMoves is caused by falling asleep via Yawn. + if (gBattleMons[i].status2 & STATUS2_LOCK_CONFUSE && gBattleStruct->turnEffectsTracker != 24) + { + gBattleMons[i].status2 &= ~(STATUS2_LOCK_CONFUSE); + + // If the target can be confused, confuse them. + // Don't use CanBeConfused, can cause issues in edge cases. + if (!(GetBattlerAbility(i) == ABILITY_OWN_TEMPO + || gBattleMons[i].status2 & STATUS2_CONFUSION + || IsBattlerTerrainAffected(i, STATUS_FIELD_MISTY_TERRAIN))) + { + gBattleMons[i].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); + + // If this CancelMultiTurnMoves is occuring due to attackcanceller or VARIOUS_GRAVITY_ON_AIRBORNE_MONS + if (gBattlescriptCurrInstr[0] == 0x0 || (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 76)) + gBattleStruct->skyDropTargets[0] = 0xFE - battler; + + // If this CancelMultiTurnMoves is occuring due to cancelmultiturnmoves script + else if (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 0) + { + gBattlerAttacker = i; + gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 3; + } + + // If this CancelMultiTurnMoves is occuring due to receiving Sleep/Freeze status + else if (gBattleScripting.moveEffect <= PRIMARY_STATUS_MOVE_EFFECT) + { + gBattlerAttacker = i; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 1; + } + } + + } + break; + } + } + + // Clear skyDropTargets data, unless this CancelMultiTurnMoves is caused by Yawn, attackcanceler, or VARIOUS_GRAVITY_ON_AIRBORNE_MONS + if (!(gBattleMons[gBattleStruct->skyDropTargets[1]].status2 & STATUS2_LOCK_CONFUSE) && gBattleStruct->skyDropTargets[0] < 4) + { + gBattleStruct->skyDropTargets[0] = 0xFF; + gBattleStruct->skyDropTargets[1] = 0xFF; + } + } + else if (gBattleStruct->skyDropTargets[2] == battler) + { + for(i = 0; i < MAX_BATTLERS_COUNT; i++) + { + if(gBattleStruct->skyDropTargets[3] == i) + { + gStatuses3[i] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); + + gSprites[gBattlerSpriteIds[battler]].invisible = FALSE; + gSprites[gBattlerSpriteIds[i]].invisible = FALSE; + + if (gBattleMons[i].status2 & STATUS2_LOCK_CONFUSE && gBattleStruct->turnEffectsTracker != 24) + { + gBattleMons[i].status2 &= ~(STATUS2_LOCK_CONFUSE); + if (!(GetBattlerAbility(i) == ABILITY_OWN_TEMPO + || gBattleMons[i].status2 & STATUS2_CONFUSION + || IsBattlerTerrainAffected(i, STATUS_FIELD_MISTY_TERRAIN))) + { + gBattleMons[i].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); + + if (gBattlescriptCurrInstr[0] == 0x0 || (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 76)) + gBattleStruct->skyDropTargets[2] = 0xFE - battler; + else if (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 0) + { + gBattlerAttacker = i; + gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 3; + } + else if (gBattleScripting.moveEffect <= PRIMARY_STATUS_MOVE_EFFECT) + { + gBattlerAttacker = i; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 1; + } + } + } + break; + } + } + + if (!(gBattleMons[gBattleStruct->skyDropTargets[3]].status2 & STATUS2_LOCK_CONFUSE) && gBattleStruct->skyDropTargets[2] < 4) + { + gBattleStruct->skyDropTargets[2] = 0xFF; + gBattleStruct->skyDropTargets[3] = 0xFF; + } + } gDisableStructs[battler].rolloutTimer = 0; gDisableStructs[battler].furyCutterCounter = 0; @@ -2771,7 +2883,8 @@ u8 DoBattlerEndTurnEffects(void) gBattleStruct->turnEffectsTracker++; break; case ENDTURN_THRASH: // thrash - if (gBattleMons[gActiveBattler].status2 & STATUS2_LOCK_CONFUSE) + // Don't decrement STATUS2_LOCK_CONFUSE if the target is held by Sky Drop + if (gBattleMons[gActiveBattler].status2 & STATUS2_LOCK_CONFUSE && !(gStatuses3[gActiveBattler] & STATUS3_SKY_DROPPED)) { gBattleMons[gActiveBattler].status2 -= STATUS2_LOCK_CONFUSE_TURN(1); if (WasUnableToUseMove(gActiveBattler)) @@ -3211,6 +3324,7 @@ void TryClearRageAndFuryCutter(void) enum { CANCELLER_FLAGS, + CANCELLER_SKY_DROP, CANCELLER_ASLEEP, CANCELLER_FROZEN, CANCELLER_TRUANT, @@ -3247,6 +3361,16 @@ u8 AtkCanceller_UnableToUseMove(void) gStatuses3[gBattlerAttacker] &= ~(STATUS3_GRUDGE); gBattleStruct->atkCancellerTracker++; break; + case CANCELLER_SKY_DROP: + // If Pokemon is being held in Sky Drop + if (gStatuses3[gBattlerAttacker] & STATUS3_SKY_DROPPED) + { + gBattlescriptCurrInstr = BattleScript_MoveEnd; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; case CANCELLER_ASLEEP: // check being asleep if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) { @@ -3438,7 +3562,7 @@ u8 AtkCanceller_UnableToUseMove(void) if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS) && (Random() % 4) == 0) { gProtectStructs[gBattlerAttacker].prlzImmobility = TRUE; - // This is removed in Emerald for some reason + // This is removed in Emerald because it is called in BattleScript_MoveUsedIsParalyzed. //CancelMultiTurnMoves(gBattlerAttacker); gBattlescriptCurrInstr = BattleScript_MoveUsedIsParalyzed; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; @@ -4886,7 +5010,9 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move && !(TestSheerForceFlag(gBattlerAttacker, gCurrentMove)) && (CanBattlerSwitch(battler) || !(gBattleTypeFlags & BATTLE_TYPE_TRAINER)) && !(gBattleTypeFlags & BATTLE_TYPE_ARENA) - && CountUsablePartyMons(battler) > 0) + && CountUsablePartyMons(battler) > 0 + // Not currently held by Sky Drop + && !(gStatuses3[battler] & STATUS3_SKY_DROPPED)) { gBattleResources->flags->flags[battler] |= RESOURCE_FLAG_EMERGENCY_EXIT; effect++; @@ -5748,6 +5874,8 @@ bool32 CanBattlerEscape(u32 battlerId) // no ability check return FALSE; else if (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK) return FALSE; + else if (gStatuses3[battlerId] & STATUS3_SKY_DROPPED) + return FALSE; else return TRUE; } @@ -9128,6 +9256,10 @@ bool32 CanMegaEvolve(u8 battlerId) && (mega->alreadyEvolved[partnerPosition] || (mega->toEvolve & gBitTable[BATTLE_PARTNER(battlerId)]))) return FALSE; } + + // Check if mon is currently held by Sky Drop + if (gStatuses3[battlerId] & STATUS3_SKY_DROPPED) + return FALSE; // Gets mon data. if (GetBattlerSide(battlerId) == B_SIDE_OPPONENT) diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index a49cf5fd87..adcc40b82c 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -8009,7 +8009,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_SKY_DROP] = { - .effect = EFFECT_PLACEHOLDER, // Needs a custom move effect + .effect = EFFECT_SKY_DROP, .power = 60, .type = TYPE_FLYING, .accuracy = 100, From 844a0217f75e790f41d44aa25ba2987e0d68d391 Mon Sep 17 00:00:00 2001 From: W1serV1ser <1prefertheaircauseimanairnomad@gmail.com> Date: Sat, 20 Nov 2021 12:04:21 -0800 Subject: [PATCH 02/27] Fixed spacing, added braces, and reverted comment --- src/battle_util.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index 7cd7254d7d..6bf0ee248d 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1435,9 +1435,9 @@ void CancelMultiTurnMoves(u8 battler) if (gBattleStruct->skyDropTargets[0] == battler) { // Sets skyDropTargets[1] to be the battler id for the target - for(i = 0; i < MAX_BATTLERS_COUNT; i++) + for (i = 0; i < MAX_BATTLERS_COUNT; i++) { - if(gBattleStruct->skyDropTargets[1] == i) + if (gBattleStruct->skyDropTargets[1] == i) { // Clears sky dropped and on_air statuses gStatuses3[i] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); @@ -1463,7 +1463,9 @@ void CancelMultiTurnMoves(u8 battler) // If this CancelMultiTurnMoves is occuring due to attackcanceller or VARIOUS_GRAVITY_ON_AIRBORNE_MONS if (gBattlescriptCurrInstr[0] == 0x0 || (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 76)) + { gBattleStruct->skyDropTargets[0] = 0xFE - battler; + } // If this CancelMultiTurnMoves is occuring due to cancelmultiturnmoves script else if (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 0) @@ -1472,7 +1474,7 @@ void CancelMultiTurnMoves(u8 battler) gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 3; } - // If this CancelMultiTurnMoves is occuring due to receiving Sleep/Freeze status + // If this CancelMultiTurnMoves is occuring due to receiving Sleep/Freeze status else if (gBattleScripting.moveEffect <= PRIMARY_STATUS_MOVE_EFFECT) { gBattlerAttacker = i; @@ -1495,9 +1497,9 @@ void CancelMultiTurnMoves(u8 battler) } else if (gBattleStruct->skyDropTargets[2] == battler) { - for(i = 0; i < MAX_BATTLERS_COUNT; i++) + for (i = 0; i < MAX_BATTLERS_COUNT; i++) { - if(gBattleStruct->skyDropTargets[3] == i) + if (gBattleStruct->skyDropTargets[3] == i) { gStatuses3[i] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); @@ -1514,7 +1516,9 @@ void CancelMultiTurnMoves(u8 battler) gBattleMons[i].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); if (gBattlescriptCurrInstr[0] == 0x0 || (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 76)) + { gBattleStruct->skyDropTargets[2] = 0xFE - battler; + } else if (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 0) { gBattlerAttacker = i; @@ -3562,7 +3566,7 @@ u8 AtkCanceller_UnableToUseMove(void) if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS) && (Random() % 4) == 0) { gProtectStructs[gBattlerAttacker].prlzImmobility = TRUE; - // This is removed in Emerald because it is called in BattleScript_MoveUsedIsParalyzed. + // This is removed in Emerald for some reason //CancelMultiTurnMoves(gBattlerAttacker); gBattlescriptCurrInstr = BattleScript_MoveUsedIsParalyzed; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; @@ -9257,9 +9261,9 @@ bool32 CanMegaEvolve(u8 battlerId) return FALSE; } - // Check if mon is currently held by Sky Drop - if (gStatuses3[battlerId] & STATUS3_SKY_DROPPED) - return FALSE; + // Check if mon is currently held by Sky Drop + if (gStatuses3[battlerId] & STATUS3_SKY_DROPPED) + return FALSE; // Gets mon data. if (GetBattlerSide(battlerId) == B_SIDE_OPPONENT) From 5d1228fc2ea920dfb628a0d7540c44d4fb8e3540 Mon Sep 17 00:00:00 2001 From: W1serV1ser <1prefertheaircauseimanairnomad@gmail.com> Date: Sun, 21 Nov 2021 15:42:31 -0800 Subject: [PATCH 03/27] More spacing and format fixes --- src/battle_script_commands.c | 10 +++++----- src/battle_util.c | 18 ++++++++---------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 1b08f86a86..90ae0b1199 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1609,14 +1609,14 @@ static bool32 AccuracyCalcHelper(u16 move) JumpIfMoveFailed(7, move); return TRUE; } - // If the attacker has the ability No Guard and they aren't targeting a Pokemon involved in a Sky Drop with the move Sky Drop, move hits. + // If the attacker has the ability No Guard and they aren't targeting a Pokemon involved in a Sky Drop with the move Sky Drop, move hits. else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || (gBattlerTarget != gBattleStruct->skyDropTargets[0] && gBattlerTarget != gBattleStruct->skyDropTargets[1] && gBattlerTarget != gBattleStruct->skyDropTargets[2] && gBattlerTarget != gBattleStruct->skyDropTargets[3]))) { if (!JumpIfMoveFailed(7, move)) RecordAbilityBattle(gBattlerAttacker, ABILITY_NO_GUARD); return TRUE; } - // If the target has the ability No Guard and they aren't involved in a Sky Drop or the current move isn't Sky Drop, move hits. + // If the target has the ability No Guard and they aren't involved in a Sky Drop or the current move isn't Sky Drop, move hits. else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || (gBattlerTarget != gBattleStruct->skyDropTargets[0] && gBattlerTarget != gBattleStruct->skyDropTargets[1] && gBattlerTarget != gBattleStruct->skyDropTargets[2] && gBattlerTarget != gBattleStruct->skyDropTargets[3]))) { if (!JumpIfMoveFailed(7, move)) @@ -2931,8 +2931,8 @@ void SetMoveEffect(bool32 primary, u32 certain) { gBattleMons[gEffectBattler].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); // 2-5 turns - // If the confusion is activating due to being released from Sky Drop, go to "confused due to fatigue" script. - // Otherwise, do normal confusion script. + // If the confusion is activating due to being released from Sky Drop, go to "confused due to fatigue" script. + // Otherwise, do normal confusion script. if(gCurrentMove == MOVE_SKY_DROP) { gBattleMons[gEffectBattler].status2 &= ~(STATUS2_LOCK_CONFUSE); @@ -9061,7 +9061,7 @@ static void Cmd_various(void) return; case VARIOUS_SKY_DROP_YAWN: // If the mon that's sleeping due to Yawn was holding a Pokemon in Sky Drop, release the target and clear Sky Drop data. if (gEffectBattler == gBattleStruct->skyDropTargets[0]) - { + { gEffectBattler = gBattleStruct->skyDropTargets[1]; gBattleStruct->skyDropTargets[0] = 0xFF; gBattleStruct->skyDropTargets[1] = 0xFF; diff --git a/src/battle_util.c b/src/battle_util.c index 6bf0ee248d..7e40315492 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1460,20 +1460,18 @@ void CancelMultiTurnMoves(u8 battler) || IsBattlerTerrainAffected(i, STATUS_FIELD_MISTY_TERRAIN))) { gBattleMons[i].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); - + // If this CancelMultiTurnMoves is occuring due to attackcanceller or VARIOUS_GRAVITY_ON_AIRBORNE_MONS if (gBattlescriptCurrInstr[0] == 0x0 || (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 76)) { gBattleStruct->skyDropTargets[0] = 0xFE - battler; } - // If this CancelMultiTurnMoves is occuring due to cancelmultiturnmoves script else if (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 0) { gBattlerAttacker = i; gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 3; } - // If this CancelMultiTurnMoves is occuring due to receiving Sleep/Freeze status else if (gBattleScripting.moveEffect <= PRIMARY_STATUS_MOVE_EFFECT) { @@ -1482,12 +1480,11 @@ void CancelMultiTurnMoves(u8 battler) gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 1; } } - } break; } } - + // Clear skyDropTargets data, unless this CancelMultiTurnMoves is caused by Yawn, attackcanceler, or VARIOUS_GRAVITY_ON_AIRBORNE_MONS if (!(gBattleMons[gBattleStruct->skyDropTargets[1]].status2 & STATUS2_LOCK_CONFUSE) && gBattleStruct->skyDropTargets[0] < 4) { @@ -1502,19 +1499,20 @@ void CancelMultiTurnMoves(u8 battler) if (gBattleStruct->skyDropTargets[3] == i) { gStatuses3[i] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); - + gSprites[gBattlerSpriteIds[battler]].invisible = FALSE; gSprites[gBattlerSpriteIds[i]].invisible = FALSE; - + if (gBattleMons[i].status2 & STATUS2_LOCK_CONFUSE && gBattleStruct->turnEffectsTracker != 24) { gBattleMons[i].status2 &= ~(STATUS2_LOCK_CONFUSE); + if (!(GetBattlerAbility(i) == ABILITY_OWN_TEMPO || gBattleMons[i].status2 & STATUS2_CONFUSION || IsBattlerTerrainAffected(i, STATUS_FIELD_MISTY_TERRAIN))) { gBattleMons[i].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); - + if (gBattlescriptCurrInstr[0] == 0x0 || (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 76)) { gBattleStruct->skyDropTargets[2] = 0xFE - battler; @@ -1535,7 +1533,7 @@ void CancelMultiTurnMoves(u8 battler) break; } } - + if (!(gBattleMons[gBattleStruct->skyDropTargets[3]].status2 & STATUS2_LOCK_CONFUSE) && gBattleStruct->skyDropTargets[2] < 4) { gBattleStruct->skyDropTargets[2] = 0xFF; @@ -9260,7 +9258,7 @@ bool32 CanMegaEvolve(u8 battlerId) && (mega->alreadyEvolved[partnerPosition] || (mega->toEvolve & gBitTable[BATTLE_PARTNER(battlerId)]))) return FALSE; } - + // Check if mon is currently held by Sky Drop if (gStatuses3[battlerId] & STATUS3_SKY_DROPPED) return FALSE; From 7a7c6afc39796f4d056ca81a7539aff5fa542e8c Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 29 Nov 2021 12:42:01 -0500 Subject: [PATCH 04/27] larger ability popup, fix ability name printing/clearing, and config for longer ability names --- graphics/battle_interface/ability_pop_up.png | Bin 365 -> 275 bytes include/battle_main.h | 5 + include/constants/battle_config.h | 1 + src/battle_interface.c | 296 ++++++++++--------- src/data/text/abilities.h | 274 +++++++++++++++++ 5 files changed, 441 insertions(+), 135 deletions(-) diff --git a/graphics/battle_interface/ability_pop_up.png b/graphics/battle_interface/ability_pop_up.png index 4b549b1b5380aa3dae7759e635044ff58ea47d3d..92971a7a51f0a79e0b4ef940ed09c3960cdc35e0 100644 GIT binary patch delta 190 zcmV;v073ul0+RxeB$0kRf1XK1K~zYIV_;wqQo;v-@+L0$00X0mksv<6z~mH)7cdB$ z5>TL`N=Sj|$WVYcpn*ZHl7=5JsFdReqY7XO(g`R~HX{(!1o90qpK spo~yZCmUf?;6f`sfBTiW^2Cl1>6E86^Fo>79MwA5SrUO>lu^0-Ch1K zW&d;(C_B;9#WAE}&f6c- z_dV-LW2QF_E)hJ8EazrUY1pZhVDgGnVn4$d?gI|*g_!rgk+)&CUR||PaYK&fFV+VS a_b90U*7V=+nkCi)@`I 0) - { - do - { - if (arg3) - CpuCopy32(windowTileData + 16, dest + 16, 16); - else - CpuCopy32(windowTileData + 20, dest + 20, 12); - dest += 32, windowTileData += 32; - arg2--; - } while (arg2 != 0); - } + CpuCopy32(windowTileData + 256, dest + 256, arg2 * 32); + if (arg2 > 0) + { + do + { + if (arg3) + CpuCopy32(windowTileData + 16, dest + 16, 16); + else + CpuCopy32(windowTileData + 20, dest + 20, 12); + dest += 32, windowTileData += 32; + arg2--; + } while (arg2 != 0); + } } #define MAX_CHARS_PRINTED 12 static void PrintOnAbilityPopUp(const u8 *str, u8 *spriteTileData1, u8 *spriteTileData2, u32 x1, u32 x2, u32 y, u32 color1, u32 color2, u32 color3) { - u32 windowId, i; - u8 *windowTileData; - u8 text1[MAX_CHARS_PRINTED + 2]; - u8 text2[MAX_CHARS_PRINTED + 2]; + u32 windowId, i; + u8 *windowTileData; + u8 text1[MAX_CHARS_PRINTED]; + u8 text2[MAX_CHARS_PRINTED]; - for (i = 0; i < MAX_CHARS_PRINTED + 1; i++) - { - text1[i] = str[i]; - if (text1[i] == EOS) - break; - } - text1[i] = EOS; + for (i = 0; i < MAX_CHARS_PRINTED; i++) + { + text1[i] = str[i]; + if (text1[i] == EOS) + break; + } + text1[i] = EOS; - windowTileData = AddTextPrinterAndCreateWindowOnAbilityPopUp(text1, x1, y, color1, color2, color3, &windowId); - TextIntoAbilityPopUp(spriteTileData1, windowTileData, 8, (y == 0)); - RemoveWindow(windowId); + windowTileData = AddTextPrinterAndCreateWindowOnAbilityPopUp(text1, x1, y, color1, color2, color3, &windowId); + TextIntoAbilityPopUp(spriteTileData1, windowTileData, 8, (y == 0)); + RemoveWindow(windowId); - if (i == MAX_CHARS_PRINTED + 1) - { - for (i = 0; i < MAX_CHARS_PRINTED; i++) - { - text2[i] = str[MAX_CHARS_PRINTED + i]; - if (text2[i] == EOS) - break; - } - text2[i] = EOS; + if (i == MAX_CHARS_PRINTED) + { + for (i = 0; i < MAX_CHARS_PRINTED; i++) + { + text2[i] = str[MAX_CHARS_PRINTED + i]; + if (text2[i] == EOS) + break; + } + text2[i] = EOS; - windowTileData = AddTextPrinterAndCreateWindowOnAbilityPopUp(text2, x2, y, color1, color2, color3, &windowId); - TextIntoAbilityPopUp(spriteTileData2, windowTileData, 1, (y == 0)); - RemoveWindow(windowId); - } + windowTileData = AddTextPrinterAndCreateWindowOnAbilityPopUp(text2, x2, y, color1, color2, color3, &windowId); + TextIntoAbilityPopUp(spriteTileData2, windowTileData, 3, (y == 0)); + RemoveWindow(windowId); + } +} + +static const u8 sText_Space16[]= _(" "); +static void ClearAbilityName(u8 spriteId1, u8 spriteId2) +{ + PrintOnAbilityPopUp(sText_Space16, + (void*)(OBJ_VRAM0) + (gSprites[spriteId1].oam.tileNum * 32) + 256, + (void*)(OBJ_VRAM0) + (gSprites[spriteId2].oam.tileNum * 32) + 256, + 6, 1, + 4, + 7, 9, 1); } static void PrintBattlerOnAbilityPopUp(u8 battlerId, u8 spriteId1, u8 spriteId2) @@ -2976,111 +2987,125 @@ static void PrintAbilityOnAbilityPopUp(u32 ability, u8 spriteId1, u8 spriteId2) PrintOnAbilityPopUp(gAbilityNames[ability], (void*)(OBJ_VRAM0) + (gSprites[spriteId1].oam.tileNum * 32) + 256, (void*)(OBJ_VRAM0) + (gSprites[spriteId2].oam.tileNum * 32) + 256, - 7, 1, + 6, 1, 4, 7, 9, 1); } -#define PIXEL_COORDS_TO_OFFSET(x, y)( \ -/*Add tiles by X*/ \ -((y / 8) * 32 * 8) \ -/*Add tiles by X*/ \ -+ ((x / 8) * 32) \ -/*Add pixels by Y*/ \ -+ ((((y) - ((y / 8) * 8))) * 4) \ -/*Add pixels by X*/ \ +#define PIXEL_COORDS_TO_OFFSET(x, y)( \ +/*Add tiles by X*/ \ +((y / 8) * 32 * 8) \ +/*Add tiles by X*/ \ ++ ((x / 8) * 32) \ +/*Add pixels by Y*/ \ ++ ((((y) - ((y / 8) * 8))) * 4) \ +/*Add pixels by X*/ \ + ((((x) - ((x / 8) * 8)) / 2))) static const u16 sOverwrittenPixelsTable[][2] = { - {PIXEL_COORDS_TO_OFFSET(0, 0), 5}, - {PIXEL_COORDS_TO_OFFSET(0, 1), 5}, - {PIXEL_COORDS_TO_OFFSET(0, 2), 5}, - {PIXEL_COORDS_TO_OFFSET(0, 3), 5}, - {PIXEL_COORDS_TO_OFFSET(0, 4), 5}, - {PIXEL_COORDS_TO_OFFSET(0, 5), 5}, - {PIXEL_COORDS_TO_OFFSET(0, 6), 5}, - {PIXEL_COORDS_TO_OFFSET(0, 7), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 8), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 9), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 10), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 11), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 12), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 13), 8}, + {PIXEL_COORDS_TO_OFFSET(0, 0), 5}, + {PIXEL_COORDS_TO_OFFSET(0, 1), 5}, + {PIXEL_COORDS_TO_OFFSET(0, 2), 5}, + {PIXEL_COORDS_TO_OFFSET(0, 3), 5}, + {PIXEL_COORDS_TO_OFFSET(0, 4), 5}, + {PIXEL_COORDS_TO_OFFSET(0, 5), 5}, + {PIXEL_COORDS_TO_OFFSET(0, 6), 5}, + {PIXEL_COORDS_TO_OFFSET(0, 7), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 8), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 9), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 10), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 11), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 12), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 13), 8}, - {PIXEL_COORDS_TO_OFFSET(8, 13), 8}, - {PIXEL_COORDS_TO_OFFSET(16, 13), 8}, - {PIXEL_COORDS_TO_OFFSET(24, 13), 8}, - {PIXEL_COORDS_TO_OFFSET(32, 13), 8}, - {PIXEL_COORDS_TO_OFFSET(40, 13), 8}, - {PIXEL_COORDS_TO_OFFSET(48, 13), 8}, - {PIXEL_COORDS_TO_OFFSET(56, 13), 8}, + {PIXEL_COORDS_TO_OFFSET(8, 13), 8}, + {PIXEL_COORDS_TO_OFFSET(16, 13), 8}, + {PIXEL_COORDS_TO_OFFSET(24, 13), 8}, + {PIXEL_COORDS_TO_OFFSET(32, 13), 8}, + {PIXEL_COORDS_TO_OFFSET(40, 13), 8}, + {PIXEL_COORDS_TO_OFFSET(48, 13), 8}, + {PIXEL_COORDS_TO_OFFSET(56, 13), 8}, - {PIXEL_COORDS_TO_OFFSET(0, 14), 8}, - {PIXEL_COORDS_TO_OFFSET(8, 14), 8}, - {PIXEL_COORDS_TO_OFFSET(16, 14), 8}, - {PIXEL_COORDS_TO_OFFSET(24, 14), 8}, - {PIXEL_COORDS_TO_OFFSET(32, 14), 8}, - {PIXEL_COORDS_TO_OFFSET(40, 14), 8}, - {PIXEL_COORDS_TO_OFFSET(48, 14), 8}, - {PIXEL_COORDS_TO_OFFSET(56, 14), 8}, + {PIXEL_COORDS_TO_OFFSET(0, 14), 8}, + {PIXEL_COORDS_TO_OFFSET(8, 14), 8}, + {PIXEL_COORDS_TO_OFFSET(16, 14), 8}, + {PIXEL_COORDS_TO_OFFSET(24, 14), 8}, + {PIXEL_COORDS_TO_OFFSET(32, 14), 8}, + {PIXEL_COORDS_TO_OFFSET(40, 14), 8}, + {PIXEL_COORDS_TO_OFFSET(48, 14), 8}, + {PIXEL_COORDS_TO_OFFSET(56, 14), 8}, - {PIXEL_COORDS_TO_OFFSET(0, 15), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 16), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 17), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 18), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 19), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 20), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 21), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 22), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 23), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 24), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 25), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 26), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 15), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 16), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 17), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 18), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 19), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 20), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 21), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 22), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 23), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 24), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 25), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 26), 3}, + +//Second Row Of Image + {PIXEL_COORDS_TO_OFFSET(0, 45), 8}, + {PIXEL_COORDS_TO_OFFSET(0, 46), 8}, + {PIXEL_COORDS_TO_OFFSET(0, 47), 8}, + //{PIXEL_COORDS_TO_OFFSET(0, 48), 8}, // cuts off the top of the 'G' in Neutralizing Gas + {PIXEL_COORDS_TO_OFFSET(8, 45), 8}, + {PIXEL_COORDS_TO_OFFSET(8, 46), 8}, + {PIXEL_COORDS_TO_OFFSET(8, 47), 8}, + {PIXEL_COORDS_TO_OFFSET(8, 48), 8}, + {PIXEL_COORDS_TO_OFFSET(16, 45), 8}, + {PIXEL_COORDS_TO_OFFSET(16, 46), 8}, + {PIXEL_COORDS_TO_OFFSET(16, 47), 8}, + {PIXEL_COORDS_TO_OFFSET(16, 48), 8}, }; static inline void CopyPixels(u8 *dest, const u8 *src, u32 pixelCount) { - u32 i = 0; + u32 i = 0; - if (pixelCount & 1) - { - while (pixelCount != 0) - { - dest[i] &= ~(0xF); - dest[i] |= (src[i] & 0xF); - if (--pixelCount != 0) - { - dest[i] &= ~(0xF0); - dest[i] |= (src[i] & 0xF0); - pixelCount--; - } - i++; - } - } - else - { - for (i = 0; i < pixelCount / 2; i++) - dest[i] = src[i]; - } + if (pixelCount & 1) + { + while (pixelCount != 0) + { + dest[i] &= ~(0xF); + dest[i] |= (src[i] & 0xF); + if (--pixelCount != 0) + { + dest[i] &= ~(0xF0); + dest[i] |= (src[i] & 0xF0); + pixelCount--; + } + i++; + } + } + else + { + for (i = 0; i < pixelCount / 2; i++) + dest[i] = src[i]; + } } static void RestoreOverwrittenPixels(u8 *tiles) { - u32 i; - u8 *buffer = Alloc(sizeof(sAbilityPopUpGfx) * 2); + u32 i; + u8 *buffer = Alloc(sizeof(sAbilityPopUpGfx) * 2); - CpuCopy32(tiles, buffer, sizeof(sAbilityPopUpGfx)); + CpuCopy32(tiles, buffer, sizeof(sAbilityPopUpGfx)); - for (i = 0; i < ARRAY_COUNT(sOverwrittenPixelsTable); i++) - { - CopyPixels(buffer + sOverwrittenPixelsTable[i][0], - sAbilityPopUpGfx + sOverwrittenPixelsTable[i][0], - sOverwrittenPixelsTable[i][1]); - } + for (i = 0; i < ARRAY_COUNT(sOverwrittenPixelsTable); i++) + { + CopyPixels(buffer + sOverwrittenPixelsTable[i][0], + sAbilityPopUpGfx + sOverwrittenPixelsTable[i][0], + sOverwrittenPixelsTable[i][1]); + } - CpuCopy32(buffer, tiles, sizeof(sAbilityPopUpGfx)); - Free(buffer); + CpuCopy32(buffer, tiles, sizeof(sAbilityPopUpGfx)); + Free(buffer); } void CreateAbilityPopUp(u8 battlerId, u32 ability, bool32 isDoubleBattle) @@ -3163,6 +3188,7 @@ void UpdateAbilityPopup(u8 battlerId) u8 spriteId2 = gBattleStruct->abilityPopUpSpriteIds[battlerId][1]; u16 ability = (gBattleScripting.abilityPopupOverwrite != 0) ? gBattleScripting.abilityPopupOverwrite : gBattleMons[battlerId].ability; + ClearAbilityName(spriteId1, spriteId2); PrintAbilityOnAbilityPopUp(ability, spriteId1, spriteId2); RestoreOverwrittenPixels((void*)(OBJ_VRAM0) + (gSprites[spriteId1].oam.tileNum * 32)); } diff --git a/src/data/text/abilities.h b/src/data/text/abilities.h index c2c17b7371..76fad45982 100644 --- a/src/data/text/abilities.h +++ b/src/data/text/abilities.h @@ -255,6 +255,279 @@ static const u8 sGrimNeighDescription[] = _("KOs boost Sp. Atk stat."); static const u8 sAsOneIceRiderDescription[] = _("Unnerve and Chilling Neigh."); static const u8 sAsOneShadowRiderDescription[] = _("Unnerve and Grim Neigh."); +#if B_EXPANDED_ABILITY_NAMES == TRUE +const u8 gAbilityNames[ABILITIES_COUNT][ABILITY_NAME_LENGTH + 1] = +{ + [ABILITY_NONE] = _("-------"), + [ABILITY_STENCH] = _("Stench"), + [ABILITY_DRIZZLE] = _("Drizzle"), + [ABILITY_SPEED_BOOST] = _("Speed Boost"), + [ABILITY_BATTLE_ARMOR] = _("Battle Armor"), + [ABILITY_STURDY] = _("Sturdy"), + [ABILITY_DAMP] = _("Damp"), + [ABILITY_LIMBER] = _("Limber"), + [ABILITY_SAND_VEIL] = _("Sand Veil"), + [ABILITY_STATIC] = _("Static"), + [ABILITY_VOLT_ABSORB] = _("Volt Absorb"), + [ABILITY_WATER_ABSORB] = _("Water Absorb"), + [ABILITY_OBLIVIOUS] = _("Oblivious"), + [ABILITY_CLOUD_NINE] = _("Cloud Nine"), + [ABILITY_COMPOUND_EYES] = _("CompoundEyes"), + [ABILITY_INSOMNIA] = _("Insomnia"), + [ABILITY_COLOR_CHANGE] = _("Color Change"), + [ABILITY_IMMUNITY] = _("Immunity"), + [ABILITY_FLASH_FIRE] = _("Flash Fire"), + [ABILITY_SHIELD_DUST] = _("Shield Dust"), + [ABILITY_OWN_TEMPO] = _("Own Tempo"), + [ABILITY_SUCTION_CUPS] = _("Suction Cups"), + [ABILITY_INTIMIDATE] = _("Intimidate"), + [ABILITY_SHADOW_TAG] = _("Shadow Tag"), + [ABILITY_ROUGH_SKIN] = _("Rough Skin"), + [ABILITY_WONDER_GUARD] = _("Wonder Guard"), + [ABILITY_LEVITATE] = _("Levitate"), + [ABILITY_EFFECT_SPORE] = _("Effect Spore"), + [ABILITY_SYNCHRONIZE] = _("Synchronize"), + [ABILITY_CLEAR_BODY] = _("Clear Body"), + [ABILITY_NATURAL_CURE] = _("Natural Cure"), + [ABILITY_LIGHTNING_ROD] = _("LightningRod"), + [ABILITY_SERENE_GRACE] = _("Serene Grace"), + [ABILITY_SWIFT_SWIM] = _("Swift Swim"), + [ABILITY_CHLOROPHYLL] = _("Chlorophyll"), + [ABILITY_ILLUMINATE] = _("Illuminate"), + [ABILITY_TRACE] = _("Trace"), + [ABILITY_HUGE_POWER] = _("Huge Power"), + [ABILITY_POISON_POINT] = _("Poison Point"), + [ABILITY_INNER_FOCUS] = _("Inner Focus"), + [ABILITY_MAGMA_ARMOR] = _("Magma Armor"), + [ABILITY_WATER_VEIL] = _("Water Veil"), + [ABILITY_MAGNET_PULL] = _("Magnet Pull"), + [ABILITY_SOUNDPROOF] = _("Soundproof"), + [ABILITY_RAIN_DISH] = _("Rain Dish"), + [ABILITY_SAND_STREAM] = _("Sand Stream"), + [ABILITY_PRESSURE] = _("Pressure"), + [ABILITY_THICK_FAT] = _("Thick Fat"), + [ABILITY_EARLY_BIRD] = _("Early Bird"), + [ABILITY_FLAME_BODY] = _("Flame Body"), + [ABILITY_RUN_AWAY] = _("Run Away"), + [ABILITY_KEEN_EYE] = _("Keen Eye"), + [ABILITY_HYPER_CUTTER] = _("Hyper Cutter"), + [ABILITY_PICKUP] = _("Pickup"), + [ABILITY_TRUANT] = _("Truant"), + [ABILITY_HUSTLE] = _("Hustle"), + [ABILITY_CUTE_CHARM] = _("Cute Charm"), + [ABILITY_PLUS] = _("Plus"), + [ABILITY_MINUS] = _("Minus"), + [ABILITY_FORECAST] = _("Forecast"), + [ABILITY_STICKY_HOLD] = _("Sticky Hold"), + [ABILITY_SHED_SKIN] = _("Shed Skin"), + [ABILITY_GUTS] = _("Guts"), + [ABILITY_MARVEL_SCALE] = _("Marvel Scale"), + [ABILITY_LIQUID_OOZE] = _("Liquid Ooze"), + [ABILITY_OVERGROW] = _("Overgrow"), + [ABILITY_BLAZE] = _("Blaze"), + [ABILITY_TORRENT] = _("Torrent"), + [ABILITY_SWARM] = _("Swarm"), + [ABILITY_ROCK_HEAD] = _("Rock Head"), + [ABILITY_DROUGHT] = _("Drought"), + [ABILITY_ARENA_TRAP] = _("Arena Trap"), + [ABILITY_VITAL_SPIRIT] = _("Vital Spirit"), + [ABILITY_WHITE_SMOKE] = _("White Smoke"), + [ABILITY_PURE_POWER] = _("Pure Power"), + [ABILITY_SHELL_ARMOR] = _("Shell Armor"), + [ABILITY_AIR_LOCK] = _("Air Lock"), + [ABILITY_TANGLED_FEET] = _("Tangled Feet"), + [ABILITY_MOTOR_DRIVE] = _("Motor Drive"), + [ABILITY_RIVALRY] = _("Rivalry"), + [ABILITY_STEADFAST] = _("Steadfast"), + [ABILITY_SNOW_CLOAK] = _("Snow Cloak"), + [ABILITY_GLUTTONY] = _("Gluttony"), + [ABILITY_ANGER_POINT] = _("Anger Point"), + [ABILITY_UNBURDEN] = _("Unburden"), + [ABILITY_HEATPROOF] = _("Heatproof"), + [ABILITY_SIMPLE] = _("Simple"), + [ABILITY_DRY_SKIN] = _("Dry Skin"), + [ABILITY_DOWNLOAD] = _("Download"), + [ABILITY_IRON_FIST] = _("Iron Fist"), + [ABILITY_POISON_HEAL] = _("Poison Heal"), + [ABILITY_ADAPTABILITY] = _("Adaptability"), + [ABILITY_SKILL_LINK] = _("Skill Link"), + [ABILITY_HYDRATION] = _("Hydration"), + [ABILITY_SOLAR_POWER] = _("Solar Power"), + [ABILITY_QUICK_FEET] = _("Quick Feet"), + [ABILITY_NORMALIZE] = _("Normalize"), + [ABILITY_SNIPER] = _("Sniper"), + [ABILITY_MAGIC_GUARD] = _("Magic Guard"), + [ABILITY_NO_GUARD] = _("No Guard"), + [ABILITY_STALL] = _("Stall"), + [ABILITY_TECHNICIAN] = _("Technician"), + [ABILITY_LEAF_GUARD] = _("Leaf Guard"), + [ABILITY_KLUTZ] = _("Klutz"), + [ABILITY_MOLD_BREAKER] = _("Mold Breaker"), + [ABILITY_SUPER_LUCK] = _("Super Luck"), + [ABILITY_AFTERMATH] = _("Aftermath"), + [ABILITY_ANTICIPATION] = _("Anticipation"), + [ABILITY_FOREWARN] = _("Forewarn"), + [ABILITY_UNAWARE] = _("Unaware"), + [ABILITY_TINTED_LENS] = _("Tinted Lens"), + [ABILITY_FILTER] = _("Filter"), + [ABILITY_SLOW_START] = _("Slow Start"), + [ABILITY_SCRAPPY] = _("Scrappy"), + [ABILITY_STORM_DRAIN] = _("Storm Drain"), + [ABILITY_ICE_BODY] = _("Ice Body"), + [ABILITY_SOLID_ROCK] = _("Solid Rock"), + [ABILITY_SNOW_WARNING] = _("Snow Warning"), + [ABILITY_HONEY_GATHER] = _("Honey Gather"), + [ABILITY_FRISK] = _("Frisk"), + [ABILITY_RECKLESS] = _("Reckless"), + [ABILITY_MULTITYPE] = _("Multitype"), + [ABILITY_FLOWER_GIFT] = _("Flower Gift"), + [ABILITY_BAD_DREAMS] = _("Bad Dreams"), + [ABILITY_PICKPOCKET] = _("Pickpocket"), + [ABILITY_SHEER_FORCE] = _("Sheer Force"), + [ABILITY_CONTRARY] = _("Contrary"), + [ABILITY_UNNERVE] = _("Unnerve"), + [ABILITY_DEFIANT] = _("Defiant"), + [ABILITY_DEFEATIST] = _("Defeatist"), + [ABILITY_CURSED_BODY] = _("Cursed Body"), + [ABILITY_HEALER] = _("Healer"), + [ABILITY_FRIEND_GUARD] = _("Friend Guard"), + [ABILITY_WEAK_ARMOR] = _("Weak Armor"), + [ABILITY_HEAVY_METAL] = _("Heavy Metal"), + [ABILITY_LIGHT_METAL] = _("Light Metal"), + [ABILITY_MULTISCALE] = _("Multiscale"), + [ABILITY_TOXIC_BOOST] = _("Toxic Boost"), + [ABILITY_FLARE_BOOST] = _("Flare Boost"), + [ABILITY_HARVEST] = _("Harvest"), + [ABILITY_TELEPATHY] = _("Telepathy"), + [ABILITY_MOODY] = _("Moody"), + [ABILITY_OVERCOAT] = _("Overcoat"), + [ABILITY_POISON_TOUCH] = _("Poison Touch"), + [ABILITY_REGENERATOR] = _("Regenerator"), + [ABILITY_BIG_PECKS] = _("Big Pecks"), + [ABILITY_SAND_RUSH] = _("Sand Rush"), + [ABILITY_WONDER_SKIN] = _("Wonder Skin"), + [ABILITY_ANALYTIC] = _("Analytic"), + [ABILITY_ILLUSION] = _("Illusion"), + [ABILITY_IMPOSTER] = _("Imposter"), + [ABILITY_INFILTRATOR] = _("Infiltrator"), + [ABILITY_MUMMY] = _("Mummy"), + [ABILITY_MOXIE] = _("Moxie"), + [ABILITY_JUSTIFIED] = _("Justified"), + [ABILITY_RATTLED] = _("Rattled"), + [ABILITY_MAGIC_BOUNCE] = _("Magic Bounce"), + [ABILITY_SAP_SIPPER] = _("Sap Sipper"), + [ABILITY_PRANKSTER] = _("Prankster"), + [ABILITY_SAND_FORCE] = _("Sand Force"), + [ABILITY_IRON_BARBS] = _("Iron Barbs"), + [ABILITY_ZEN_MODE] = _("Zen Mode"), + [ABILITY_VICTORY_STAR] = _("Victory Star"), + [ABILITY_TURBOBLAZE] = _("Turboblaze"), + [ABILITY_TERAVOLT] = _("Teravolt"), + [ABILITY_AROMA_VEIL] = _("Aroma Veil"), + [ABILITY_FLOWER_VEIL] = _("Flower Veil"), + [ABILITY_CHEEK_POUCH] = _("Cheek Pouch"), + [ABILITY_PROTEAN] = _("Protean"), + [ABILITY_FUR_COAT] = _("Fur Coat"), + [ABILITY_MAGICIAN] = _("Magician"), + [ABILITY_BULLETPROOF] = _("Bulletproof"), + [ABILITY_COMPETITIVE] = _("Competitive"), + [ABILITY_STRONG_JAW] = _("Strong Jaw"), + [ABILITY_REFRIGERATE] = _("Refrigerate"), + [ABILITY_SWEET_VEIL] = _("Sweet Veil"), + [ABILITY_STANCE_CHANGE] = _("Stance Change"), + [ABILITY_GALE_WINGS] = _("Gale Wings"), + [ABILITY_MEGA_LAUNCHER] = _("Mega Launcher"), + [ABILITY_GRASS_PELT] = _("Grass Pelt"), + [ABILITY_SYMBIOSIS] = _("Symbiosis"), + [ABILITY_TOUGH_CLAWS] = _("Tough Claws"), + [ABILITY_PIXILATE] = _("Pixilate"), + [ABILITY_GOOEY] = _("Gooey"), + [ABILITY_AERILATE] = _("Aerilate"), + [ABILITY_PARENTAL_BOND] = _("Parental Bond"), + [ABILITY_DARK_AURA] = _("Dark Aura"), + [ABILITY_FAIRY_AURA] = _("Fairy Aura"), + [ABILITY_AURA_BREAK] = _("Aura Break"), + [ABILITY_PRIMORDIAL_SEA] = _("Primordial Sea"), + [ABILITY_DESOLATE_LAND] = _("Desolate Land"), + [ABILITY_DELTA_STREAM] = _("Delta Stream"), + [ABILITY_STAMINA] = _("Stamina"), + [ABILITY_WIMP_OUT] = _("Wimp Out"), + [ABILITY_EMERGENCY_EXIT] = _("Emergency Exit"), + [ABILITY_WATER_COMPACTION] = _("Water Compaction"), + [ABILITY_MERCILESS] = _("Merciless"), + [ABILITY_SHIELDS_DOWN] = _("Shields Down"), + [ABILITY_STAKEOUT] = _("Stakeout"), + [ABILITY_WATER_BUBBLE] = _("Water Bubble"), + [ABILITY_STEELWORKER] = _("Steelworker"), + [ABILITY_BERSERK] = _("Berserk"), + [ABILITY_SLUSH_RUSH] = _("Slush Rush"), + [ABILITY_LONG_REACH] = _("Long Reach"), + [ABILITY_LIQUID_VOICE] = _("Liquid Voice"), + [ABILITY_TRIAGE] = _("Triage"), + [ABILITY_GALVANIZE] = _("Galvanize"), + [ABILITY_SURGE_SURFER] = _("Surge Surfer"), + [ABILITY_SCHOOLING] = _("Schooling"), + [ABILITY_DISGUISE] = _("Disguise"), + [ABILITY_BATTLE_BOND] = _("Battle Bond"), + [ABILITY_POWER_CONSTRUCT] = _("Power Construct"), + [ABILITY_CORROSION] = _("Corrosion"), + [ABILITY_COMATOSE] = _("Comatose"), + [ABILITY_QUEENLY_MAJESTY] = _("Queenly Majesty"), + [ABILITY_INNARDS_OUT] = _("Innards Out"), + [ABILITY_DANCER] = _("Dancer"), + [ABILITY_BATTERY] = _("Battery"), + [ABILITY_FLUFFY] = _("Fluffy"), + [ABILITY_DAZZLING] = _("Dazzling"), + [ABILITY_SOUL_HEART] = _("Soul-Heart"), + [ABILITY_TANGLING_HAIR] = _("Tangling Hair"), + [ABILITY_RECEIVER] = _("Receiver"), + [ABILITY_POWER_OF_ALCHEMY] = _("Power Of Alchemy"), + [ABILITY_BEAST_BOOST] = _("Beast Boost"), + [ABILITY_RKS_SYSTEM] = _("RKS System"), + [ABILITY_ELECTRIC_SURGE] = _("Electric Surge"), + [ABILITY_PSYCHIC_SURGE] = _("Psychic Surge"), + [ABILITY_MISTY_SURGE] = _("Misty Surge"), + [ABILITY_GRASSY_SURGE] = _("Grassy Surge"), + [ABILITY_FULL_METAL_BODY] = _("Full Metal Body"), + [ABILITY_SHADOW_SHIELD] = _("Shadow Shield"), + [ABILITY_PRISM_ARMOR] = _("Prism Armor"), + [ABILITY_NEUROFORCE] = _("Neuroforce"), + [ABILITY_INTREPID_SWORD] = _("Intrepid Sword"), + [ABILITY_DAUNTLESS_SHIELD] = _("Dauntless Shield"), + [ABILITY_LIBERO] = _("Libero"), + [ABILITY_BALL_FETCH] = _("Ball Fetch"), + [ABILITY_COTTON_DOWN] = _("Cotton Down"), + [ABILITY_PROPELLER_TAIL] = _("Propeller Tail"), + [ABILITY_MIRROR_ARMOR] = _("Mirror Armor"), + [ABILITY_GULP_MISSILE] = _("Gulp Missile"), + [ABILITY_STALWART] = _("Stalwart"), + [ABILITY_STEAM_ENGINE] = _("Steam Engine"), + [ABILITY_PUNK_ROCK] = _("Punk Rock"), + [ABILITY_SAND_SPIT] = _("Sand Spit"), + [ABILITY_ICE_SCALES] = _("Ice Scales"), + [ABILITY_RIPEN] = _("Ripen"), + [ABILITY_ICE_FACE] = _("Ice Face"), + [ABILITY_POWER_SPOT] = _("Power Spot"), + [ABILITY_MIMICRY] = _("Mimicry"), + [ABILITY_SCREEN_CLEANER] = _("Screen Cleaner"), + [ABILITY_STEELY_SPIRIT] = _("Steely Spirit"), + [ABILITY_PERISH_BODY] = _("Perish Body"), + [ABILITY_WANDERING_SPIRIT] = _("Wandering Spirit"), + [ABILITY_GORILLA_TACTICS] = _("Gorilla Tactics"), + [ABILITY_NEUTRALIZING_GAS] = _("Neutralizing Gas"), + [ABILITY_PASTEL_VEIL] = _("Pastel Veil"), + [ABILITY_HUNGER_SWITCH] = _("Hunger Switch"), + [ABILITY_QUICK_DRAW] = _("Quick Draw"), + [ABILITY_UNSEEN_FIST] = _("Unseen Fist"), + [ABILITY_CURIOUS_MEDICINE] = _("Curious Medicine"), + [ABILITY_TRANSISTOR] = _("Transistor"), + [ABILITY_DRAGONS_MAW] = _("Dragon's Maw"), + [ABILITY_CHILLING_NEIGH] = _("Chilling Neigh"), + [ABILITY_GRIM_NEIGH] = _("Grim Neigh"), + [ABILITY_AS_ONE_ICE_RIDER] = _("As One"), + [ABILITY_AS_ONE_SHADOW_RIDER] = _("As One"), +}; +#else // 12 characters const u8 gAbilityNames[ABILITIES_COUNT][ABILITY_NAME_LENGTH + 1] = { [ABILITY_NONE] = _("-------"), @@ -526,6 +799,7 @@ const u8 gAbilityNames[ABILITIES_COUNT][ABILITY_NAME_LENGTH + 1] = [ABILITY_AS_ONE_ICE_RIDER] = _("As One"), [ABILITY_AS_ONE_SHADOW_RIDER] = _("As One"), }; +#endif const u8 *const gAbilityDescriptionPointers[ABILITIES_COUNT] = { From e731d93c0b54ea71ebfa5bd9ab8b4e8fb7e2fb3b Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 29 Nov 2021 12:46:14 -0500 Subject: [PATCH 05/27] update a couple gen 3 ability names --- src/data/text/abilities.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/data/text/abilities.h b/src/data/text/abilities.h index 76fad45982..cdc3276082 100644 --- a/src/data/text/abilities.h +++ b/src/data/text/abilities.h @@ -272,7 +272,7 @@ const u8 gAbilityNames[ABILITIES_COUNT][ABILITY_NAME_LENGTH + 1] = [ABILITY_WATER_ABSORB] = _("Water Absorb"), [ABILITY_OBLIVIOUS] = _("Oblivious"), [ABILITY_CLOUD_NINE] = _("Cloud Nine"), - [ABILITY_COMPOUND_EYES] = _("CompoundEyes"), + [ABILITY_COMPOUND_EYES] = _("Compound Eyes"), [ABILITY_INSOMNIA] = _("Insomnia"), [ABILITY_COLOR_CHANGE] = _("Color Change"), [ABILITY_IMMUNITY] = _("Immunity"), @@ -289,7 +289,7 @@ const u8 gAbilityNames[ABILITIES_COUNT][ABILITY_NAME_LENGTH + 1] = [ABILITY_SYNCHRONIZE] = _("Synchronize"), [ABILITY_CLEAR_BODY] = _("Clear Body"), [ABILITY_NATURAL_CURE] = _("Natural Cure"), - [ABILITY_LIGHTNING_ROD] = _("LightningRod"), + [ABILITY_LIGHTNING_ROD] = _("Lightning Rod"), [ABILITY_SERENE_GRACE] = _("Serene Grace"), [ABILITY_SWIFT_SWIM] = _("Swift Swim"), [ABILITY_CHLOROPHYLL] = _("Chlorophyll"), From a5659f3339e0836ba90ff4f05bcdd0462f684521 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Sat, 4 Dec 2021 23:00:57 -0300 Subject: [PATCH 06/27] AI partners no longer get exp. --- src/battle_script_commands.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index fcac028945..f5fb72e687 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3920,7 +3920,8 @@ static void Cmd_getexp(void) gBattleScripting.getexpState = 5; gBattleMoveDamage = 0; // used for exp } - else if (GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_LEVEL) == MAX_LEVEL) + else if ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gBattleStruct->expGetterMonId >= 3) + || GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_LEVEL) == MAX_LEVEL) { *(&gBattleStruct->sentInPokes) >>= 1; gBattleScripting.getexpState = 5; From ffe35fbb069c4afe7789a31b83a59a2c839487ee Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Sun, 5 Dec 2021 10:34:18 -0300 Subject: [PATCH 07/27] Updated defeat condition on multi battles --- data/battle_scripts_1.s | 1 + include/constants/battle_config.h | 5 +++-- src/battle_script_commands.c | 28 +++++++++++++++++++++++++++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index e9d019e430..e4c628d76c 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -5925,6 +5925,7 @@ BattleScript_PayDayMoneyAndPickUpItems:: end2 BattleScript_LocalBattleLost:: + jumpifbattletype BATTLE_TYPE_INGAME_PARTNER, BattleScript_LocalBattleLostPrintWhiteOut jumpifbattletype BATTLE_TYPE_DOME, BattleScript_CheckDomeDrew jumpifbattletype BATTLE_TYPE_FRONTIER, BattleScript_LocalBattleLostPrintTrainersWinText jumpifbattletype BATTLE_TYPE_TRAINER_HILL, BattleScript_LocalBattleLostPrintTrainersWinText diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 29b7b57503..65f85af957 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -226,8 +226,9 @@ #define B_LAST_USED_BALL TRUE // If TRUE, the "last used ball" feature from Gen 7 will be implemented #define B_LAST_USED_BALL_BUTTON R_BUTTON // If last used ball is implemented, this button (or button combo) will trigger throwing the last used ball. -// Other -#define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter. +// Other settings +#define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter. +#define B_NEW_MULTI_BATTLE_DEFEAT_CONDITION TRUE // In Gen5+, multi battles end when the Player and also their Partner don't have any more Pokémon to fight. // Animation Settings #define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle. diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index f5fb72e687..6b1f5a6ff2 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4113,6 +4113,28 @@ static void Cmd_getexp(void) } } +#ifdef B_NEW_MULTI_BATTLE_DEFEAT_CONDITION == TRUE +static bool32 NoAliveMonsForPlayerAndPartner(void) +{ + u32 i; + u32 HP_count = 0; + + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && (gPartnerTrainerId == TRAINER_STEVEN_PARTNER || gPartnerTrainerId >= TRAINER_CUSTOM_PARTNER)) + { + for (i = 0; i < PARTY_SIZE; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG) + && (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || !(gBattleStruct->arenaLostPlayerMons & gBitTable[i]))) + { + HP_count += GetMonData(&gPlayerParty[i], MON_DATA_HP); + } + } + } + + return (HP_count == 0); +} +#endif + static bool32 NoAliveMonsForPlayer(void) { u32 i; @@ -4168,7 +4190,11 @@ static void Cmd_unknown_24(void) if (gBattleControllerExecFlags) return; - if (NoAliveMonsForPlayer()) + #ifdef B_NEW_MULTI_BATTLE_DEFEAT_CONDITION == TRUE + if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER) && NoAliveMonsForPlayerAndPartner()) + gBattleOutcome |= B_OUTCOME_LOST; + #endif + if (!(gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER)) && NoAliveMonsForPlayer()) gBattleOutcome |= B_OUTCOME_LOST; if (NoAliveMonsForOpponent()) gBattleOutcome |= B_OUTCOME_WON; From cb44de13b3a524ee054730a6f1f322d8610d30c5 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Sun, 19 Dec 2021 20:53:57 -0300 Subject: [PATCH 08/27] B_NEW_MULTI_BATTLE_DEFEAT_CONDITION -> B_MULTI_BATTLE_WHITEOUT --- include/constants/battle_config.h | 4 ++-- src/battle_script_commands.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 65f85af957..f68646bb81 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -227,8 +227,8 @@ #define B_LAST_USED_BALL_BUTTON R_BUTTON // If last used ball is implemented, this button (or button combo) will trigger throwing the last used ball. // Other settings -#define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter. -#define B_NEW_MULTI_BATTLE_DEFEAT_CONDITION TRUE // In Gen5+, multi battles end when the Player and also their Partner don't have any more Pokémon to fight. +#define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter. +#define B_MULTI_BATTLE_WHITEOUT GEN_8 // In Gen4+, multi battles end when the Player and also their Partner don't have any more Pokémon to fight. // Animation Settings #define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle. diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 6b1f5a6ff2..d41084ca7a 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4113,7 +4113,7 @@ static void Cmd_getexp(void) } } -#ifdef B_NEW_MULTI_BATTLE_DEFEAT_CONDITION == TRUE +#ifdef B_MULTI_BATTLE_WHITEOUT >= GEN_4 static bool32 NoAliveMonsForPlayerAndPartner(void) { u32 i; @@ -4190,7 +4190,7 @@ static void Cmd_unknown_24(void) if (gBattleControllerExecFlags) return; - #ifdef B_NEW_MULTI_BATTLE_DEFEAT_CONDITION == TRUE + #ifdef B_MULTI_BATTLE_WHITEOUT >= GEN_4 if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER) && NoAliveMonsForPlayerAndPartner()) gBattleOutcome |= B_OUTCOME_LOST; #endif From 713d97891f4db7ac06959192e552cacbdaf7970d Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Wed, 22 Dec 2021 21:32:10 -0300 Subject: [PATCH 09/27] Update include/constants/battle_config.h Co-authored-by: Eduardo Quezada D'Ottone --- include/constants/battle_config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index f68646bb81..041a3ddc84 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -227,8 +227,8 @@ #define B_LAST_USED_BALL_BUTTON R_BUTTON // If last used ball is implemented, this button (or button combo) will trigger throwing the last used ball. // Other settings -#define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter. -#define B_MULTI_BATTLE_WHITEOUT GEN_8 // In Gen4+, multi battles end when the Player and also their Partner don't have any more Pokémon to fight. +#define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter. +#define B_MULTI_BATTLE_WHITEOUT GEN_8 // In Gen4+, multi battles end when the Player and also their Partner don't have any more Pokémon to fight. // Animation Settings #define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle. From 0a95a31ee9ac550d5e5b0c2ca514fb7f3b214e68 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Thu, 23 Dec 2021 08:44:54 -0500 Subject: [PATCH 10/27] fix formatting --- include/battle_main.h | 2 +- src/battle_interface.c | 316 ++++++++++++++++++++--------------------- 2 files changed, 159 insertions(+), 159 deletions(-) diff --git a/include/battle_main.h b/include/battle_main.h index 759774888a..d0d3e38fb9 100644 --- a/include/battle_main.h +++ b/include/battle_main.h @@ -29,7 +29,7 @@ struct ChooseMoveStruct; #define ABILITY_NAME_LENGTH 16 #else #define ABILITY_NAME_LENGTH 12 -#endif +#endif // defines for the 'DoBounceEffect' function #define BOUNCE_MON 0x0 diff --git a/src/battle_interface.c b/src/battle_interface.c index 265349f2e6..e512e8d177 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -2855,83 +2855,83 @@ static const struct SpriteTemplate sSpriteTemplate_AbilityPopUp2 = static const s16 sAbilityPopUpCoordsDoubles[MAX_BATTLERS_COUNT][2] = { {29, 80}, // player left - {186, 19}, // opponent left - {29, 97}, // player right - {186, 36}, // opponent right + {186, 19}, // opponent left + {29, 97}, // player right + {186, 36}, // opponent right }; static const s16 sAbilityPopUpCoordsSingles[MAX_BATTLERS_COUNT][2] = { {29, 97}, // player - {186, 57}, // opponent + {186, 57}, // opponent }; static u8* AddTextPrinterAndCreateWindowOnAbilityPopUp(const u8 *str, u32 x, u32 y, u32 color1, u32 color2, u32 color3, u32 *windowId) { - u8 color[3] = {color1, color2, color3}; - struct WindowTemplate winTemplate = {0}; - winTemplate.width = 8; - winTemplate.height = 2; + u8 color[3] = {color1, color2, color3}; + struct WindowTemplate winTemplate = {0}; + winTemplate.width = 8; + winTemplate.height = 2; - *windowId = AddWindow(&winTemplate); - FillWindowPixelBuffer(*windowId, PIXEL_FILL(color1)); + *windowId = AddWindow(&winTemplate); + FillWindowPixelBuffer(*windowId, PIXEL_FILL(color1)); - AddTextPrinterParameterized4(*windowId, 0, x, y, 0, 0, color, -1, str); - return (u8*)(GetWindowAttribute(*windowId, WINDOW_TILE_DATA)); + AddTextPrinterParameterized4(*windowId, 0, x, y, 0, 0, color, -1, str); + return (u8*)(GetWindowAttribute(*windowId, WINDOW_TILE_DATA)); } static void TextIntoAbilityPopUp(void *dest, u8 *windowTileData, s32 arg2, bool32 arg3) { - CpuCopy32(windowTileData + 256, dest + 256, arg2 * 32); - if (arg2 > 0) - { - do - { - if (arg3) - CpuCopy32(windowTileData + 16, dest + 16, 16); - else - CpuCopy32(windowTileData + 20, dest + 20, 12); - dest += 32, windowTileData += 32; - arg2--; - } while (arg2 != 0); - } + CpuCopy32(windowTileData + 256, dest + 256, arg2 * 32); + if (arg2 > 0) + { + do + { + if (arg3) + CpuCopy32(windowTileData + 16, dest + 16, 16); + else + CpuCopy32(windowTileData + 20, dest + 20, 12); + dest += 32, windowTileData += 32; + arg2--; + } while (arg2 != 0); + } } #define MAX_CHARS_PRINTED 12 static void PrintOnAbilityPopUp(const u8 *str, u8 *spriteTileData1, u8 *spriteTileData2, u32 x1, u32 x2, u32 y, u32 color1, u32 color2, u32 color3) { - u32 windowId, i; - u8 *windowTileData; - u8 text1[MAX_CHARS_PRINTED]; - u8 text2[MAX_CHARS_PRINTED]; + u32 windowId, i; + u8 *windowTileData; + u8 text1[MAX_CHARS_PRINTED]; + u8 text2[MAX_CHARS_PRINTED]; - for (i = 0; i < MAX_CHARS_PRINTED; i++) - { - text1[i] = str[i]; - if (text1[i] == EOS) - break; - } - text1[i] = EOS; + for (i = 0; i < MAX_CHARS_PRINTED; i++) + { + text1[i] = str[i]; + if (text1[i] == EOS) + break; + } + text1[i] = EOS; - windowTileData = AddTextPrinterAndCreateWindowOnAbilityPopUp(text1, x1, y, color1, color2, color3, &windowId); - TextIntoAbilityPopUp(spriteTileData1, windowTileData, 8, (y == 0)); - RemoveWindow(windowId); + windowTileData = AddTextPrinterAndCreateWindowOnAbilityPopUp(text1, x1, y, color1, color2, color3, &windowId); + TextIntoAbilityPopUp(spriteTileData1, windowTileData, 8, (y == 0)); + RemoveWindow(windowId); - if (i == MAX_CHARS_PRINTED) - { - for (i = 0; i < MAX_CHARS_PRINTED; i++) - { - text2[i] = str[MAX_CHARS_PRINTED + i]; - if (text2[i] == EOS) - break; - } - text2[i] = EOS; + if (i == MAX_CHARS_PRINTED) + { + for (i = 0; i < MAX_CHARS_PRINTED; i++) + { + text2[i] = str[MAX_CHARS_PRINTED + i]; + if (text2[i] == EOS) + break; + } + text2[i] = EOS; - windowTileData = AddTextPrinterAndCreateWindowOnAbilityPopUp(text2, x2, y, color1, color2, color3, &windowId); - TextIntoAbilityPopUp(spriteTileData2, windowTileData, 3, (y == 0)); - RemoveWindow(windowId); - } + windowTileData = AddTextPrinterAndCreateWindowOnAbilityPopUp(text2, x2, y, color1, color2, color3, &windowId); + TextIntoAbilityPopUp(spriteTileData2, windowTileData, 3, (y == 0)); + RemoveWindow(windowId); + } } static const u8 sText_Space16[]= _(" "); @@ -2992,120 +2992,120 @@ static void PrintAbilityOnAbilityPopUp(u32 ability, u8 spriteId1, u8 spriteId2) 7, 9, 1); } -#define PIXEL_COORDS_TO_OFFSET(x, y)( \ -/*Add tiles by X*/ \ -((y / 8) * 32 * 8) \ -/*Add tiles by X*/ \ -+ ((x / 8) * 32) \ -/*Add pixels by Y*/ \ -+ ((((y) - ((y / 8) * 8))) * 4) \ -/*Add pixels by X*/ \ +#define PIXEL_COORDS_TO_OFFSET(x, y)( \ +/*Add tiles by X*/ \ +((y / 8) * 32 * 8) \ +/*Add tiles by X*/ \ ++ ((x / 8) * 32) \ +/*Add pixels by Y*/ \ ++ ((((y) - ((y / 8) * 8))) * 4) \ +/*Add pixels by X*/ \ + ((((x) - ((x / 8) * 8)) / 2))) static const u16 sOverwrittenPixelsTable[][2] = { - {PIXEL_COORDS_TO_OFFSET(0, 0), 5}, - {PIXEL_COORDS_TO_OFFSET(0, 1), 5}, - {PIXEL_COORDS_TO_OFFSET(0, 2), 5}, - {PIXEL_COORDS_TO_OFFSET(0, 3), 5}, - {PIXEL_COORDS_TO_OFFSET(0, 4), 5}, - {PIXEL_COORDS_TO_OFFSET(0, 5), 5}, - {PIXEL_COORDS_TO_OFFSET(0, 6), 5}, - {PIXEL_COORDS_TO_OFFSET(0, 7), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 8), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 9), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 10), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 11), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 12), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 13), 8}, + {PIXEL_COORDS_TO_OFFSET(0, 0), 5}, + {PIXEL_COORDS_TO_OFFSET(0, 1), 5}, + {PIXEL_COORDS_TO_OFFSET(0, 2), 5}, + {PIXEL_COORDS_TO_OFFSET(0, 3), 5}, + {PIXEL_COORDS_TO_OFFSET(0, 4), 5}, + {PIXEL_COORDS_TO_OFFSET(0, 5), 5}, + {PIXEL_COORDS_TO_OFFSET(0, 6), 5}, + {PIXEL_COORDS_TO_OFFSET(0, 7), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 8), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 9), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 10), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 11), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 12), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 13), 8}, - {PIXEL_COORDS_TO_OFFSET(8, 13), 8}, - {PIXEL_COORDS_TO_OFFSET(16, 13), 8}, - {PIXEL_COORDS_TO_OFFSET(24, 13), 8}, - {PIXEL_COORDS_TO_OFFSET(32, 13), 8}, - {PIXEL_COORDS_TO_OFFSET(40, 13), 8}, - {PIXEL_COORDS_TO_OFFSET(48, 13), 8}, - {PIXEL_COORDS_TO_OFFSET(56, 13), 8}, + {PIXEL_COORDS_TO_OFFSET(8, 13), 8}, + {PIXEL_COORDS_TO_OFFSET(16, 13), 8}, + {PIXEL_COORDS_TO_OFFSET(24, 13), 8}, + {PIXEL_COORDS_TO_OFFSET(32, 13), 8}, + {PIXEL_COORDS_TO_OFFSET(40, 13), 8}, + {PIXEL_COORDS_TO_OFFSET(48, 13), 8}, + {PIXEL_COORDS_TO_OFFSET(56, 13), 8}, - {PIXEL_COORDS_TO_OFFSET(0, 14), 8}, - {PIXEL_COORDS_TO_OFFSET(8, 14), 8}, - {PIXEL_COORDS_TO_OFFSET(16, 14), 8}, - {PIXEL_COORDS_TO_OFFSET(24, 14), 8}, - {PIXEL_COORDS_TO_OFFSET(32, 14), 8}, - {PIXEL_COORDS_TO_OFFSET(40, 14), 8}, - {PIXEL_COORDS_TO_OFFSET(48, 14), 8}, - {PIXEL_COORDS_TO_OFFSET(56, 14), 8}, + {PIXEL_COORDS_TO_OFFSET(0, 14), 8}, + {PIXEL_COORDS_TO_OFFSET(8, 14), 8}, + {PIXEL_COORDS_TO_OFFSET(16, 14), 8}, + {PIXEL_COORDS_TO_OFFSET(24, 14), 8}, + {PIXEL_COORDS_TO_OFFSET(32, 14), 8}, + {PIXEL_COORDS_TO_OFFSET(40, 14), 8}, + {PIXEL_COORDS_TO_OFFSET(48, 14), 8}, + {PIXEL_COORDS_TO_OFFSET(56, 14), 8}, - {PIXEL_COORDS_TO_OFFSET(0, 15), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 16), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 17), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 18), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 19), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 20), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 21), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 22), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 23), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 24), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 25), 3}, - {PIXEL_COORDS_TO_OFFSET(0, 26), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 15), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 16), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 17), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 18), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 19), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 20), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 21), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 22), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 23), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 24), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 25), 3}, + {PIXEL_COORDS_TO_OFFSET(0, 26), 3}, //Second Row Of Image - {PIXEL_COORDS_TO_OFFSET(0, 45), 8}, - {PIXEL_COORDS_TO_OFFSET(0, 46), 8}, - {PIXEL_COORDS_TO_OFFSET(0, 47), 8}, - //{PIXEL_COORDS_TO_OFFSET(0, 48), 8}, // cuts off the top of the 'G' in Neutralizing Gas - {PIXEL_COORDS_TO_OFFSET(8, 45), 8}, - {PIXEL_COORDS_TO_OFFSET(8, 46), 8}, - {PIXEL_COORDS_TO_OFFSET(8, 47), 8}, - {PIXEL_COORDS_TO_OFFSET(8, 48), 8}, - {PIXEL_COORDS_TO_OFFSET(16, 45), 8}, - {PIXEL_COORDS_TO_OFFSET(16, 46), 8}, - {PIXEL_COORDS_TO_OFFSET(16, 47), 8}, - {PIXEL_COORDS_TO_OFFSET(16, 48), 8}, + {PIXEL_COORDS_TO_OFFSET(0, 45), 8}, + {PIXEL_COORDS_TO_OFFSET(0, 46), 8}, + {PIXEL_COORDS_TO_OFFSET(0, 47), 8}, + //{PIXEL_COORDS_TO_OFFSET(0, 48), 8}, // cuts off the top of the 'G' in Neutralizing Gas + {PIXEL_COORDS_TO_OFFSET(8, 45), 8}, + {PIXEL_COORDS_TO_OFFSET(8, 46), 8}, + {PIXEL_COORDS_TO_OFFSET(8, 47), 8}, + {PIXEL_COORDS_TO_OFFSET(8, 48), 8}, + {PIXEL_COORDS_TO_OFFSET(16, 45), 8}, + {PIXEL_COORDS_TO_OFFSET(16, 46), 8}, + {PIXEL_COORDS_TO_OFFSET(16, 47), 8}, + {PIXEL_COORDS_TO_OFFSET(16, 48), 8}, }; static inline void CopyPixels(u8 *dest, const u8 *src, u32 pixelCount) { - u32 i = 0; + u32 i = 0; - if (pixelCount & 1) - { - while (pixelCount != 0) - { - dest[i] &= ~(0xF); - dest[i] |= (src[i] & 0xF); - if (--pixelCount != 0) - { - dest[i] &= ~(0xF0); - dest[i] |= (src[i] & 0xF0); - pixelCount--; - } - i++; - } - } - else - { - for (i = 0; i < pixelCount / 2; i++) - dest[i] = src[i]; - } + if (pixelCount & 1) + { + while (pixelCount != 0) + { + dest[i] &= ~(0xF); + dest[i] |= (src[i] & 0xF); + if (--pixelCount != 0) + { + dest[i] &= ~(0xF0); + dest[i] |= (src[i] & 0xF0); + pixelCount--; + } + i++; + } + } + else + { + for (i = 0; i < pixelCount / 2; i++) + dest[i] = src[i]; + } } static void RestoreOverwrittenPixels(u8 *tiles) { - u32 i; - u8 *buffer = Alloc(sizeof(sAbilityPopUpGfx) * 2); + u32 i; + u8 *buffer = Alloc(sizeof(sAbilityPopUpGfx) * 2); - CpuCopy32(tiles, buffer, sizeof(sAbilityPopUpGfx)); + CpuCopy32(tiles, buffer, sizeof(sAbilityPopUpGfx)); - for (i = 0; i < ARRAY_COUNT(sOverwrittenPixelsTable); i++) - { - CopyPixels(buffer + sOverwrittenPixelsTable[i][0], - sAbilityPopUpGfx + sOverwrittenPixelsTable[i][0], - sOverwrittenPixelsTable[i][1]); - } + for (i = 0; i < ARRAY_COUNT(sOverwrittenPixelsTable); i++) + { + CopyPixels(buffer + sOverwrittenPixelsTable[i][0], + sAbilityPopUpGfx + sOverwrittenPixelsTable[i][0], + sOverwrittenPixelsTable[i][1]); + } - CpuCopy32(buffer, tiles, sizeof(sAbilityPopUpGfx)); - Free(buffer); + CpuCopy32(buffer, tiles, sizeof(sAbilityPopUpGfx)); + Free(buffer); } void CreateAbilityPopUp(u8 battlerId, u32 ability, bool32 isDoubleBattle) @@ -3254,19 +3254,19 @@ static void Task_FreeAbilityPopUpGfx(u8 taskId) static const struct OamData sOamData_LastUsedBall = { - .y = 0, - .affineMode = 0, - .objMode = 0, - .mosaic = 0, - .bpp = 0, - .shape = SPRITE_SHAPE(32x32), - .x = 0, - .matrixNum = 0, - .size = SPRITE_SIZE(32x32), - .tileNum = 0, - .priority = 1, - .paletteNum = 0, - .affineParam = 0, + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = SPRITE_SHAPE(32x32), + .x = 0, + .matrixNum = 0, + .size = SPRITE_SIZE(32x32), + .tileNum = 0, + .priority = 1, + .paletteNum = 0, + .affineParam = 0, }; static const struct SpriteTemplate sSpriteTemplate_LastUsedBallWindow = From 58a5a9cbec6a7324089b3307743fab514efcaaa2 Mon Sep 17 00:00:00 2001 From: W1serV1ser <1prefertheaircauseimanairnomad@gmail.com> Date: Thu, 23 Dec 2021 15:27:11 -0800 Subject: [PATCH 11/27] Simplified skyDropTargets storage and made other minor improvements A lot of these changes are based on ghoulslash's version of Sky Drop. --- src/battle_main.c | 102 ++++++++++------------- src/battle_script_commands.c | 125 +++++++++++------------------ src/battle_util.c | 151 ++++++++++++----------------------- 3 files changed, 140 insertions(+), 238 deletions(-) diff --git a/src/battle_main.c b/src/battle_main.c index c22a3f6133..c9ee8b724b 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -2871,6 +2871,7 @@ static void BattleStartClearSetData(void) gBattleStruct->lastTakenMoveFrom[i][2] = 0; gBattleStruct->lastTakenMoveFrom[i][3] = 0; gBattleStruct->AI_monToSwitchIntoId[i] = PARTY_SIZE; + gBattleStruct->skyDropTargets[i] = 0xFF; } gLastUsedMove = 0; @@ -2945,12 +2946,6 @@ static void BattleStartClearSetData(void) } gSwapDamageCategory = FALSE; // Photon Geyser, Shell Side Arm, Light That Burns the Sky - - // Clear skyDropTargets data - for (i = 0; i < 4; i++) - { - gBattleStruct->skyDropTargets[i] = 0xFF; - } } void SwitchInClearSetData(void) @@ -3087,56 +3082,6 @@ void FaintClearSetData(void) gBattleMons[i].status2 &= ~(STATUS2_INFATUATED_WITH(gActiveBattler)); if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && *(gBattleStruct->wrappedBy + i) == gActiveBattler) gBattleMons[i].status2 &= ~(STATUS2_WRAPPED); - - // If the fainted mon was holding another Pokemon in Sky Drop, release the mon and clear Sky Drop data - if (gActiveBattler == gBattleStruct->skyDropTargets[0] && i == gBattleStruct->skyDropTargets[1]) - { - gBattleStruct->skyDropTargets[0] = 0xFF; - gBattleStruct->skyDropTargets[1] = 0xFF; - - gStatuses3[i] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); - gSprites[gBattlerSpriteIds[i]].invisible = FALSE; - - // If the target was sky dropped in the middle of using Outrage/Petal Dance/Thrash, - // confuse them upon release and print "confused via fatigue" message and animation. - if (gBattleMons[i].status2 & STATUS2_LOCK_CONFUSE) - { - gBattleMons[i].status2 &= ~(STATUS2_LOCK_CONFUSE); - - // If the released mon can be confused, do so. - // Don't use CanBeConfused here, since it can cause issues in edge cases. - if (!(GetBattlerAbility(i) == ABILITY_OWN_TEMPO - || gBattleMons[i].status2 & STATUS2_CONFUSION - || IsBattlerTerrainAffected(i, STATUS_FIELD_MISTY_TERRAIN))) - { - gBattleMons[i].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); - gBattlerAttacker = i; - gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 2; - } - } - } - else if (gActiveBattler == gBattleStruct->skyDropTargets[2] && i == gBattleStruct->skyDropTargets[3]) - { - gBattleStruct->skyDropTargets[2] = 0xFF; - gBattleStruct->skyDropTargets[3] = 0xFF; - - gStatuses3[i] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); - gSprites[gBattlerSpriteIds[i]].invisible = FALSE; - - if (gBattleMons[i].status2 & STATUS2_LOCK_CONFUSE) - { - gBattleMons[i].status2 &= ~(STATUS2_LOCK_CONFUSE); - gEffectBattler = i; - if (!(GetBattlerAbility(i) == ABILITY_OWN_TEMPO - || gBattleMons[i].status2 & STATUS2_CONFUSION - || IsBattlerTerrainAffected(i, STATUS_FIELD_MISTY_TERRAIN))) - { - gBattleMons[i].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); - gBattlerAttacker = i; - gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 2; - } - } - } } gActionSelectionCursor[gActiveBattler] = 0; @@ -3216,12 +3161,45 @@ void FaintClearSetData(void) UndoFormChange(gBattlerPartyIndexes[gActiveBattler], GET_BATTLER_SIDE(gActiveBattler), FALSE); if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) UndoMegaEvolution(gBattlerPartyIndexes[gActiveBattler]); - - // If the fainted Pokemon was being held by Sky Drop, clear their Sky Drop data. - if (gActiveBattler == gBattleStruct->skyDropTargets[1]) - gBattleStruct->skyDropTargets[1] = 0xFF; - else if (gActiveBattler == gBattleStruct->skyDropTargets[3]) - gBattleStruct->skyDropTargets[3] = 0xFF; + + // If the fainted mon was involved in a Sky Drop + if (gBattleStruct->skyDropTargets[gActiveBattler] != 0xFF) + { + // Get battler id of the other Pokemon involved in this Sky Drop + u8 otherSkyDropper = gBattleStruct->skyDropTargets[gActiveBattler]; + + // Clear Sky Drop data + gBattleStruct->skyDropTargets[gActiveBattler] = 0xFF; + gBattleStruct->skyDropTargets[otherSkyDropper] = 0xFF; + + // If the other Pokemon involved in this Sky Drop was the target, not the attacker + if (gStatuses3[otherSkyDropper] & STATUS3_SKY_DROPPED) + { + // Release the target and take them out of the semi-invulnerable state + gStatuses3[otherSkyDropper] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); + + // Make the target's sprite visible + gSprites[gBattlerSpriteIds[otherSkyDropper]].invisible = FALSE; + + // If the target was sky dropped in the middle of using Outrage/Petal Dance/Thrash, + // confuse them upon release and print "confused via fatigue" message and animation. + if (gBattleMons[otherSkyDropper].status2 & STATUS2_LOCK_CONFUSE) + { + gBattleMons[otherSkyDropper].status2 &= ~(STATUS2_LOCK_CONFUSE); + + // If the released mon can be confused, do so. + // Don't use CanBeConfused here, since it can cause issues in edge cases. + if (!(GetBattlerAbility(otherSkyDropper) == ABILITY_OWN_TEMPO + || gBattleMons[otherSkyDropper].status2 & STATUS2_CONFUSION + || IsBattlerTerrainAffected(otherSkyDropper, STATUS_FIELD_MISTY_TERRAIN))) + { + gBattleMons[otherSkyDropper].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); + gBattlerAttacker = otherSkyDropper; + gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 2; + } + } + } + } } static void DoBattleIntro(void) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 90ae0b1199..9663afa9c2 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1610,14 +1610,14 @@ static bool32 AccuracyCalcHelper(u16 move) return TRUE; } // If the attacker has the ability No Guard and they aren't targeting a Pokemon involved in a Sky Drop with the move Sky Drop, move hits. - else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || (gBattlerTarget != gBattleStruct->skyDropTargets[0] && gBattlerTarget != gBattleStruct->skyDropTargets[1] && gBattlerTarget != gBattleStruct->skyDropTargets[2] && gBattlerTarget != gBattleStruct->skyDropTargets[3]))) + else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF)) { if (!JumpIfMoveFailed(7, move)) RecordAbilityBattle(gBattlerAttacker, ABILITY_NO_GUARD); return TRUE; } // If the target has the ability No Guard and they aren't involved in a Sky Drop or the current move isn't Sky Drop, move hits. - else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || (gBattlerTarget != gBattleStruct->skyDropTargets[0] && gBattlerTarget != gBattleStruct->skyDropTargets[1] && gBattlerTarget != gBattleStruct->skyDropTargets[2] && gBattlerTarget != gBattleStruct->skyDropTargets[3]))) + else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF)) { if (!JumpIfMoveFailed(7, move)) RecordAbilityBattle(gBattlerTarget, ABILITY_NO_GUARD); @@ -1625,7 +1625,7 @@ static bool32 AccuracyCalcHelper(u16 move) } if ((gStatuses3[gBattlerTarget] & STATUS3_PHANTOM_FORCE) - || (!(gBattleMoves[move].flags & FLAG_DMG_IN_AIR || gBattleMoves[move].flags & FLAG_DMG_2X_IN_AIR) && gStatuses3[gBattlerTarget] & STATUS3_ON_AIR) + || (!(gBattleMoves[move].flags & (FLAG_DMG_IN_AIR | FLAG_DMG_2X_IN_AIR)) && gStatuses3[gBattlerTarget] & STATUS3_ON_AIR) || (!(gBattleMoves[move].flags & FLAG_DMG_UNDERGROUND) && gStatuses3[gBattlerTarget] & STATUS3_UNDERGROUND) || (!(gBattleMoves[move].flags & FLAG_DMG_UNDERWATER) && gStatuses3[gBattlerTarget] & STATUS3_UNDERWATER)) { @@ -5153,23 +5153,27 @@ static void Cmd_moveend(void) } gBattleScripting.moveendState++; break; - case MOVEEND_SKY_DROP_CONFUSE: // If a Pokemon was released from Sky Drop and was in LOCK_CONFUSE, go to "confused due to fatigue scripts and clear Sky Drop data. + case MOVEEND_SKY_DROP_CONFUSE: // If a Pokemon was released from Sky Drop and was in LOCK_CONFUSE, go to "confused due to fatigue" scripts and clear Sky Drop data. for (i = 0; i < gBattlersCount; i++) { - if (gBattleStruct->skyDropTargets[0] == 0xFE - i) + if (gBattleStruct->skyDropTargets[i] == 0xFE) { - gBattlerAttacker = gBattleStruct->skyDropTargets[1]; + // Find the battler id of the Pokemon that was held by Sky Drop + for (arg1 = 0; arg1 < gBattlersCount; arg1++) + { + if (gBattleStruct->skyDropTargets[arg1] == i) + break; + } + + // Set gBattlerAttacker to the battler id of the target + gBattlerAttacker = arg1; + + // Jump to "confused due to fatigue" script gBattlescriptCurrInstr = BattleScript_ThrashConfuses; - gBattleStruct->skyDropTargets[0] = 0xFF; - gBattleStruct->skyDropTargets[1] = 0xFF; - return; - } - else if (gBattleStruct->skyDropTargets[2] == 0xFE - i) - { - gBattlerAttacker = gBattleStruct->skyDropTargets[3]; - gBattlescriptCurrInstr = BattleScript_ThrashConfuses; - gBattleStruct->skyDropTargets[2] = 0xFF; - gBattleStruct->skyDropTargets[3] = 0xFF; + + // Clear skyDropTargets data + gBattleStruct->skyDropTargets[i] = 0xFF; + gBattleStruct->skyDropTargets[arg1] = 0xFF; return; } } @@ -7715,10 +7719,10 @@ static void Cmd_various(void) return; case VARIOUS_GRAVITY_ON_AIRBORNE_MONS: // Cancel all multiturn moves of IN_AIR Pokemon except those being targeted by Sky Drop. - if (gStatuses3[gActiveBattler] & STATUS3_ON_AIR && !(gActiveBattler == gBattleStruct->skyDropTargets[1] || gActiveBattler == gBattleStruct->skyDropTargets[3])) + if (gStatuses3[gActiveBattler] & STATUS3_ON_AIR && !(gStatuses3[gActiveBattler] & STATUS3_SKY_DROPPED)) CancelMultiTurnMoves(gActiveBattler); - gStatuses3[gActiveBattler] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR); + gStatuses3[gActiveBattler] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR | STATUS3_SKY_DROPPED); break; case VARIOUS_SPECTRAL_THIEF: // Raise stats @@ -8927,7 +8931,7 @@ static void Cmd_various(void) MarkBattlerForControllerExec(gActiveBattler); } - if (gBattleMons[gActiveBattler].pp[i] == 0 && !(gActiveBattler == gBattleStruct->skyDropTargets[0] || gActiveBattler == gBattleStruct->skyDropTargets[2])) + if (gBattleMons[gActiveBattler].pp[i] == 0 && gBattleStruct->skyDropTargets[gActiveBattler] == 0xFF) CancelMultiTurnMoves(gActiveBattler); gBattlescriptCurrInstr += 7; // continue @@ -9003,21 +9007,13 @@ static void Cmd_various(void) return; case VARIOUS_SET_SKY_DROP: gStatuses3[gBattlerTarget] |= (STATUS3_SKY_DROPPED | STATUS3_ON_AIR); - /* skyDropTargets holds the information of who is the attacker and the target of Sky Drop. + /* skyDropTargets holds the information of who is in a particular instance of Sky Drop. This is needed in the case that multiple Pokemon use Sky Drop in the same turn or if the target of a Sky Drop faints while in the air.*/ - if (gBattleStruct->skyDropTargets[0] == 0xFF) - { - gBattleStruct->skyDropTargets[0] = gBattlerAttacker; - gBattleStruct->skyDropTargets[1] = gBattlerTarget; - } - else - { - gBattleStruct->skyDropTargets[2] = gBattlerAttacker; - gBattleStruct->skyDropTargets[3] = gBattlerTarget; - } + gBattleStruct->skyDropTargets[gBattlerAttacker] = gBattlerTarget; + gBattleStruct->skyDropTargets[gBattlerTarget] = gBattlerAttacker; - // End any multiturn effects caused by the target + // End any multiturn effects caused by the target except STATUS2_LOCK_CONFUSE gBattleMons[gBattlerTarget].status2 &= ~(STATUS2_MULTIPLETURNS); gBattleMons[gBattlerTarget].status2 &= ~(STATUS2_UPROAR); gBattleMons[gBattlerTarget].status2 &= ~(STATUS2_BIDE); @@ -9025,34 +9021,16 @@ static void Cmd_various(void) gDisableStructs[gBattlerTarget].furyCutterCounter = 0; break; case VARIOUS_CLEAR_SKY_DROP: - if (gBattleStruct->skyDropTargets[0] == gBattlerAttacker) - { - // Check to see if the initial target of this Sky Drop fainted before the 2nd turn of Sky Drop. - // If so, make the move fail. If not, clear all of the statuses and continue the move. - if (gBattleStruct->skyDropTargets[1] == 0xFF) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); - else - { - gStatuses3[gBattlerTarget] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); - gBattlescriptCurrInstr += 7; - } - - // Clear skyDropTargets data - gBattleStruct->skyDropTargets[0] = 0xFF; - gBattleStruct->skyDropTargets[1] = 0xFF; - } + // Check to see if the initial target of this Sky Drop fainted before the 2nd turn of Sky Drop. + // If so, make the move fail. If not, clear all of the statuses and continue the move. + if (gBattleStruct->skyDropTargets[gBattlerAttacker] == 0xFF) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); else { - if (gBattleStruct->skyDropTargets[3] == 0xFF) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); - else - { - gStatuses3[gBattlerTarget] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); - gBattlescriptCurrInstr += 7; - } - - gBattleStruct->skyDropTargets[2] = 0xFF; - gBattleStruct->skyDropTargets[3] = 0xFF; + gBattleStruct->skyDropTargets[gBattlerAttacker] = 0xFF; + gBattleStruct->skyDropTargets[gBattlerTarget] = 0xFF; + gStatuses3[gBattlerTarget] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); + gBattlescriptCurrInstr += 7; } // Confuse target if they were in the middle of Petal Dance/Outrage/Thrash when targeted. @@ -9060,28 +9038,19 @@ static void Cmd_various(void) gBattleScripting.moveEffect = (MOVE_EFFECT_CONFUSION | MOVE_EFFECT_CERTAIN); return; case VARIOUS_SKY_DROP_YAWN: // If the mon that's sleeping due to Yawn was holding a Pokemon in Sky Drop, release the target and clear Sky Drop data. - if (gEffectBattler == gBattleStruct->skyDropTargets[0]) + if (gBattleStruct->skyDropTargets[gEffectBattler] != 0xFF && !(gStatuses3[gEffectBattler] & STATUS3_SKY_DROPPED)) { - gEffectBattler = gBattleStruct->skyDropTargets[1]; - gBattleStruct->skyDropTargets[0] = 0xFF; - gBattleStruct->skyDropTargets[1] = 0xFF; - gBattleMons[gEffectBattler].status2 &= ~(STATUS2_LOCK_CONFUSE); - if (CanBeConfused(gEffectBattler)) - { - gBattlerAttacker = gEffectBattler; - gBattleMons[gBattlerTarget].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); - gBattlescriptCurrInstr = BattleScript_ThrashConfuses; - return; - } - } - else if (gEffectBattler == gBattleStruct->skyDropTargets[2]) - { - gEffectBattler = gBattleStruct->skyDropTargets[3]; - gBattleStruct->skyDropTargets[2] = 0xFF; - gBattleStruct->skyDropTargets[3] = 0xFF; - gBattleMons[gEffectBattler].status2 &= ~(STATUS2_LOCK_CONFUSE); - if (CanBeConfused(gEffectBattler)) + // Set the target of Sky Drop as gEffectBattler + gEffectBattler = gBattleStruct->skyDropTargets[gEffectBattler]; + + // Clear skyDropTargets data + gBattleStruct->skyDropTargets[gBattleStruct->skyDropTargets[gEffectBattler]] = 0xFF; + gBattleStruct->skyDropTargets[gEffectBattler] = 0xFF; + + // If the target was in the middle of Outrage/Thrash/etc. when targeted by Sky Drop, confuse them on release and do proper animation + if (gBattleMons[gEffectBattler].status2 & STATUS2_LOCK_CONFUSE && CanBeConfused(gEffectBattler)) { + gBattleMons[gEffectBattler].status2 &= ~(STATUS2_LOCK_CONFUSE); gBattlerAttacker = gEffectBattler; gBattleMons[gBattlerTarget].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); gBattlescriptCurrInstr = BattleScript_ThrashConfuses; @@ -11482,7 +11451,7 @@ static void Cmd_tryspiteppreduce(void) gBattlescriptCurrInstr += 5; // Don't cut off Sky Drop if pp is brought to zero. - if (gBattleMons[gBattlerTarget].pp[i] == 0 && !(gBattlerTarget == gBattleStruct->skyDropTargets[0] || gBattlerTarget == gBattleStruct->skyDropTargets[2])) + if (gBattleMons[gBattlerTarget].pp[i] == 0 && gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF) CancelMultiTurnMoves(gBattlerTarget); } else diff --git a/src/battle_util.c b/src/battle_util.c index 7e40315492..c223f3ec7e 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1427,117 +1427,72 @@ void CancelMultiTurnMoves(u8 battler) gBattleMons[battler].status2 &= ~(STATUS2_UPROAR); gBattleMons[battler].status2 &= ~(STATUS2_BIDE); - // Don't clear battler's semi-invulnerable bits if they are held by Sky Drop. - if (gBattleStruct->skyDropTargets[1] != battler && gBattleStruct->skyDropTargets[3] != battler) + // Clear battler's semi-invulnerable bits if they are not held by Sky Drop. + if (!(gStatuses3[battler] & STATUS3_SKY_DROPPED)) gStatuses3[battler] &= ~(STATUS3_SEMI_INVULNERABLE); // Check to see if this Pokemon was in the middle of using Sky Drop. If so, release the target. - if (gBattleStruct->skyDropTargets[0] == battler) + if (gBattleStruct->skyDropTargets[battler] != 0xFF && !(gStatuses3[battler] & STATUS3_SKY_DROPPED)) { - // Sets skyDropTargets[1] to be the battler id for the target - for (i = 0; i < MAX_BATTLERS_COUNT; i++) + // Get the target's battler id + u8 otherSkyDropper = gBattleStruct->skyDropTargets[battler]; + + // Clears sky_dropped and on_air statuses + gStatuses3[otherSkyDropper] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); + + // Makes both attacker and target's sprites visible + gSprites[gBattlerSpriteIds[battler]].invisible = FALSE; + gSprites[gBattlerSpriteIds[otherSkyDropper]].invisible = FALSE; + + // If target was sky dropped in the middle of Outrage/Thrash/Petal Dance, + // confuse them upon release and display "confused by fatigue" message & animation. + // Don't do this if this CancelMultiTurnMoves is caused by falling asleep via Yawn. + if (gBattleMons[otherSkyDropper].status2 & STATUS2_LOCK_CONFUSE && gBattleStruct->turnEffectsTracker != 24) { - if (gBattleStruct->skyDropTargets[1] == i) + gBattleMons[otherSkyDropper].status2 &= ~(STATUS2_LOCK_CONFUSE); + + // If the target can be confused, confuse them. + // Don't use CanBeConfused, can cause issues in edge cases. + if (!(GetBattlerAbility(otherSkyDropper) == ABILITY_OWN_TEMPO + || gBattleMons[otherSkyDropper].status2 & STATUS2_CONFUSION + || IsBattlerTerrainAffected(otherSkyDropper, STATUS_FIELD_MISTY_TERRAIN))) { - // Clears sky dropped and on_air statuses - gStatuses3[i] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); - - // Makes both attacker and target's sprites visible - gSprites[gBattlerSpriteIds[battler]].invisible = FALSE; - gSprites[gBattlerSpriteIds[i]].invisible = FALSE; - - // If target was sky dropped in the middle of Outrage/Thrash/Petal Dance, - // confuse them upon release and display "confused by fatigue" message & animation. - // Don't do this if this CancelMultiTurnMoves is caused by falling asleep via Yawn. - if (gBattleMons[i].status2 & STATUS2_LOCK_CONFUSE && gBattleStruct->turnEffectsTracker != 24) + // Set confused status + gBattleMons[otherSkyDropper].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); + + // If this CancelMultiTurnMoves is occuring due to attackcanceller + if (gBattlescriptCurrInstr[0] == 0x0) { - gBattleMons[i].status2 &= ~(STATUS2_LOCK_CONFUSE); - - // If the target can be confused, confuse them. - // Don't use CanBeConfused, can cause issues in edge cases. - if (!(GetBattlerAbility(i) == ABILITY_OWN_TEMPO - || gBattleMons[i].status2 & STATUS2_CONFUSION - || IsBattlerTerrainAffected(i, STATUS_FIELD_MISTY_TERRAIN))) - { - gBattleMons[i].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); - - // If this CancelMultiTurnMoves is occuring due to attackcanceller or VARIOUS_GRAVITY_ON_AIRBORNE_MONS - if (gBattlescriptCurrInstr[0] == 0x0 || (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 76)) - { - gBattleStruct->skyDropTargets[0] = 0xFE - battler; - } - // If this CancelMultiTurnMoves is occuring due to cancelmultiturnmoves script - else if (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 0) - { - gBattlerAttacker = i; - gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 3; - } - // If this CancelMultiTurnMoves is occuring due to receiving Sleep/Freeze status - else if (gBattleScripting.moveEffect <= PRIMARY_STATUS_MOVE_EFFECT) - { - gBattlerAttacker = i; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 1; - } - } + gBattleStruct->skyDropTargets[battler] = 0xFE; + } + // If this CancelMultiTurnMoves is occuring due to VARIOUS_GRAVITY_ON_AIRBORNE_MONS + // Reapplying STATUS3_SKY_DROPPED allows for avoiding unecessary messages when Gravity is applied to the target. + else if (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 76) + { + gBattleStruct->skyDropTargets[battler] = 0xFE; + gStatuses3[otherSkyDropper] |= STATUS3_SKY_DROPPED; + } + // If this CancelMultiTurnMoves is occuring due to cancelmultiturnmoves script + else if (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 0) + { + gBattlerAttacker = otherSkyDropper; + gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 3; + } + // If this CancelMultiTurnMoves is occuring due to receiving Sleep/Freeze status + else if (gBattleScripting.moveEffect <= PRIMARY_STATUS_MOVE_EFFECT) + { + gBattlerAttacker = otherSkyDropper; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 1; } - break; } } // Clear skyDropTargets data, unless this CancelMultiTurnMoves is caused by Yawn, attackcanceler, or VARIOUS_GRAVITY_ON_AIRBORNE_MONS - if (!(gBattleMons[gBattleStruct->skyDropTargets[1]].status2 & STATUS2_LOCK_CONFUSE) && gBattleStruct->skyDropTargets[0] < 4) + if (!(gBattleMons[otherSkyDropper].status2 & STATUS2_LOCK_CONFUSE) && gBattleStruct->skyDropTargets[battler] < 4) { - gBattleStruct->skyDropTargets[0] = 0xFF; - gBattleStruct->skyDropTargets[1] = 0xFF; - } - } - else if (gBattleStruct->skyDropTargets[2] == battler) - { - for (i = 0; i < MAX_BATTLERS_COUNT; i++) - { - if (gBattleStruct->skyDropTargets[3] == i) - { - gStatuses3[i] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); - - gSprites[gBattlerSpriteIds[battler]].invisible = FALSE; - gSprites[gBattlerSpriteIds[i]].invisible = FALSE; - - if (gBattleMons[i].status2 & STATUS2_LOCK_CONFUSE && gBattleStruct->turnEffectsTracker != 24) - { - gBattleMons[i].status2 &= ~(STATUS2_LOCK_CONFUSE); - - if (!(GetBattlerAbility(i) == ABILITY_OWN_TEMPO - || gBattleMons[i].status2 & STATUS2_CONFUSION - || IsBattlerTerrainAffected(i, STATUS_FIELD_MISTY_TERRAIN))) - { - gBattleMons[i].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); - - if (gBattlescriptCurrInstr[0] == 0x0 || (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 76)) - { - gBattleStruct->skyDropTargets[2] = 0xFE - battler; - } - else if (gBattlescriptCurrInstr[0] == 0x76 && gBattlescriptCurrInstr[2] == 0) - { - gBattlerAttacker = i; - gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 3; - } - else if (gBattleScripting.moveEffect <= PRIMARY_STATUS_MOVE_EFFECT) - { - gBattlerAttacker = i; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_ThrashConfuses - 1; - } - } - } - break; - } - } - - if (!(gBattleMons[gBattleStruct->skyDropTargets[3]].status2 & STATUS2_LOCK_CONFUSE) && gBattleStruct->skyDropTargets[2] < 4) - { - gBattleStruct->skyDropTargets[2] = 0xFF; - gBattleStruct->skyDropTargets[3] = 0xFF; + gBattleStruct->skyDropTargets[battler] = 0xFF; + gBattleStruct->skyDropTargets[otherSkyDropper] = 0xFF; } } From 770224d34129c7a2bb0561a5012757e1b2630a11 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Thu, 23 Dec 2021 18:58:15 -0500 Subject: [PATCH 12/27] increase TEXT_BUFF_ARRAY_COUNT for expanded ability names --- include/battle_message.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/battle_message.h b/include/battle_message.h index 5c10f9e04a..09ee27c081 100644 --- a/include/battle_message.h +++ b/include/battle_message.h @@ -1,7 +1,13 @@ #ifndef GUARD_BATTLE_MESSAGE_H #define GUARD_BATTLE_MESSAGE_H -#define TEXT_BUFF_ARRAY_COUNT 16 +#include "constants/battle_config.h" + +#if B_EXPANDED_ABILITY_NAMES == TRUE + #define TEXT_BUFF_ARRAY_COUNT 17 +#else + #define TEXT_BUFF_ARRAY_COUNT 16 +#endif // for 0xFD #define B_TXT_BUFF1 0x0 From e0f7e7a2d970df7e28884f9e8c73b2771355312e Mon Sep 17 00:00:00 2001 From: W1serV1ser <1prefertheaircauseimanairnomad@gmail.com> Date: Mon, 27 Dec 2021 12:10:38 -0800 Subject: [PATCH 13/27] Updated variable name in MOVEEND_SKY_DROP_CONFUSE --- src/battle_script_commands.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 47d5b4fa26..d71c93bcaa 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -5179,22 +5179,23 @@ static void Cmd_moveend(void) { if (gBattleStruct->skyDropTargets[i] == 0xFE) { + u8 targetId; // Find the battler id of the Pokemon that was held by Sky Drop - for (arg1 = 0; arg1 < gBattlersCount; arg1++) + for (targetId = 0; targetId < gBattlersCount; targetId++) { - if (gBattleStruct->skyDropTargets[arg1] == i) + if (gBattleStruct->skyDropTargets[targetId] == i) break; } // Set gBattlerAttacker to the battler id of the target - gBattlerAttacker = arg1; + gBattlerAttacker = targetId; // Jump to "confused due to fatigue" script gBattlescriptCurrInstr = BattleScript_ThrashConfuses; // Clear skyDropTargets data gBattleStruct->skyDropTargets[i] = 0xFF; - gBattleStruct->skyDropTargets[arg1] = 0xFF; + gBattleStruct->skyDropTargets[targetId] = 0xFF; return; } } From cc1a2431452403d36f6997d96092c14cfc7b233a Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Tue, 28 Dec 2021 12:18:44 -0300 Subject: [PATCH 14/27] Update src/battle_script_commands.c Co-authored-by: Eduardo Quezada D'Ottone --- src/battle_script_commands.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index d41084ca7a..07e68e5bc3 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4190,12 +4190,21 @@ static void Cmd_unknown_24(void) if (gBattleControllerExecFlags) return; - #ifdef B_MULTI_BATTLE_WHITEOUT >= GEN_4 - if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER) && NoAliveMonsForPlayerAndPartner()) - gBattleOutcome |= B_OUTCOME_LOST; - #endif - if (!(gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER)) && NoAliveMonsForPlayer()) +#ifdef B_MULTI_BATTLE_WHITEOUT >= GEN_4 + if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER)) + { + if (NoAliveMonsForPlayerAndPartner()) + gBattleOutcome |= B_OUTCOME_LOST; + } + else + { + if (NoAliveMonsForPlayer()) + gBattleOutcome |= B_OUTCOME_LOST; + } +#else + if (NoAliveMonsForPlayer()) gBattleOutcome |= B_OUTCOME_LOST; +#endif if (NoAliveMonsForOpponent()) gBattleOutcome |= B_OUTCOME_WON; From 34c6e6ca3175f4491671ded55d3aa144b1de43c9 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Thu, 30 Dec 2021 01:48:56 -0300 Subject: [PATCH 15/27] Update battle_ai_util.c --- src/battle_ai_util.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 63f5385fd2..fb53bb8013 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -157,7 +157,6 @@ static const s8 sAiAbilityRatings[ABILITIES_COUNT] = [ABILITY_POISON_HEAL] = 8, [ABILITY_POISON_POINT] = 4, [ABILITY_POISON_TOUCH] = 4, - //[ABILITY_PORTAL_POWER] = 8, [ABILITY_POWER_CONSTRUCT] = 10, [ABILITY_POWER_OF_ALCHEMY] = 0, [ABILITY_PRANKSTER] = 8, From d433d6755874a27285eaafd7f1f3fab3eb1f6adc Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sat, 1 Jan 2022 20:21:29 -0300 Subject: [PATCH 16/27] Extrapolated Assist forbidden flags to Gen 8 moves --- src/battle_script_commands.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index eee5ccf03f..c170f7be46 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -939,8 +939,8 @@ static const u8 sForbiddenMoves[MOVES_COUNT] = [MOVE_BADDY_BAD] = FORBIDDEN_METRONOME, [MOVE_BANEFUL_BUNKER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_BEAK_BLAST] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, - [MOVE_BEHEMOTH_BASH] = FORBIDDEN_METRONOME | FORBIDDEN_COPYCAT, - [MOVE_BEHEMOTH_BLADE] = FORBIDDEN_METRONOME | FORBIDDEN_COPYCAT, + [MOVE_BEHEMOTH_BASH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, + [MOVE_BEHEMOTH_BLADE] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_BELCH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, [MOVE_BESTOW] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_BIDE] = FORBIDDEN_SLEEP_TALK, @@ -969,7 +969,7 @@ static const u8 sForbiddenMoves[MOVES_COUNT] = [MOVE_DRAGON_ENERGY] = FORBIDDEN_METRONOME, [MOVE_DRAGON_TAIL] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_DRUM_BEATING] = FORBIDDEN_METRONOME, - [MOVE_DYNAMAX_CANNON] = FORBIDDEN_METRONOME | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, + [MOVE_DYNAMAX_CANNON] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, [MOVE_ENDURE] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_ETERNABEAM] = FORBIDDEN_METRONOME, [MOVE_FALSE_SURRENDER] = FORBIDDEN_METRONOME, @@ -1008,7 +1008,7 @@ static const u8 sForbiddenMoves[MOVES_COUNT] = [MOVE_MOONGEIST_BEAM] = FORBIDDEN_METRONOME, [MOVE_NATURE_POWER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, [MOVE_NATURES_MADNESS] = FORBIDDEN_METRONOME, - [MOVE_OBSTRUCT] = FORBIDDEN_METRONOME | FORBIDDEN_COPYCAT, + [MOVE_OBSTRUCT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_ORIGIN_PULSE] = FORBIDDEN_METRONOME, [MOVE_OVERDRIVE] = FORBIDDEN_METRONOME, [MOVE_PHANTOM_FORCE] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK, From 66faa6aa1575736cfd91b4a33a0f4d92322001c9 Mon Sep 17 00:00:00 2001 From: W1serV1ser <1prefertheaircauseimanairnomad@gmail.com> Date: Tue, 4 Jan 2022 12:33:31 -0800 Subject: [PATCH 17/27] Follow Me/Rage Powder effect on target goes away once affected by Sky Drop --- src/battle_script_commands.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index d71c93bcaa..748d6d9822 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9060,6 +9060,11 @@ static void Cmd_various(void) gBattleMons[gBattlerTarget].status2 &= ~(STATUS2_BIDE); gDisableStructs[gBattlerTarget].rolloutTimer = 0; gDisableStructs[gBattlerTarget].furyCutterCounter = 0; + + // End any Follow Me/Rage Powder effects caused by the target + if (gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTimer != 0 && gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTarget == gBattlerTarget) + SideTimers[GetBattlerSide(gBattlerTarget)].followmeTimer = 0; + break; case VARIOUS_CLEAR_SKY_DROP: // Check to see if the initial target of this Sky Drop fainted before the 2nd turn of Sky Drop. From 178c4c66bab600e9d5650c42cc7f01fecc51ca25 Mon Sep 17 00:00:00 2001 From: W1serV1ser <1prefertheaircauseimanairnomad@gmail.com> Date: Tue, 4 Jan 2022 12:38:50 -0800 Subject: [PATCH 18/27] Fixed gSideTimers typo --- src/battle_script_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 748d6d9822..5243c0029b 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9063,7 +9063,7 @@ static void Cmd_various(void) // End any Follow Me/Rage Powder effects caused by the target if (gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTimer != 0 && gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTarget == gBattlerTarget) - SideTimers[GetBattlerSide(gBattlerTarget)].followmeTimer = 0; + gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTimer = 0; break; case VARIOUS_CLEAR_SKY_DROP: From 9733f92c7f9a52761e716fc723bbf2d27ae59e85 Mon Sep 17 00:00:00 2001 From: TheXaman <48356183+TheXaman@users.noreply.github.com> Date: Wed, 5 Jan 2022 18:48:01 +0100 Subject: [PATCH 19/27] Yawn now uses B_SLEEP_TURNS, resolves #1873 --- src/battle_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_util.c b/src/battle_util.c index fd32cefaa2..36e8b0a126 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2892,7 +2892,7 @@ u8 DoBattlerEndTurnEffects(void) } else { - gBattleMons[gActiveBattler].status1 |= (Random() & 3) + 2; + gBattleMons[gEffectBattler].status1 |= (B_SLEEP_TURNS >= GEN_5) ? ((Random() % 3) + 2) : ((Random() % 4) + 3); BtlController_EmitSetMonData(BUFFER_A, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); MarkBattlerForControllerExec(gActiveBattler); BattleScriptExecute(BattleScript_YawnMakesAsleep); From 328b5013946a76c06f8ae42323bf9d40ae04e9c4 Mon Sep 17 00:00:00 2001 From: TheXaman <48356183+TheXaman@users.noreply.github.com> Date: Wed, 5 Jan 2022 18:54:42 +0100 Subject: [PATCH 20/27] Update src/battle_util.c Co-authored-by: LOuroboros --- src/battle_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_util.c b/src/battle_util.c index 36e8b0a126..e76a4fba55 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2892,7 +2892,7 @@ u8 DoBattlerEndTurnEffects(void) } else { - gBattleMons[gEffectBattler].status1 |= (B_SLEEP_TURNS >= GEN_5) ? ((Random() % 3) + 2) : ((Random() % 4) + 3); + gBattleMons[gActiveBattler].status1 |= (B_SLEEP_TURNS >= GEN_5) ? ((Random() % 3) + 2) : ((Random() % 4) + 3); BtlController_EmitSetMonData(BUFFER_A, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); MarkBattlerForControllerExec(gActiveBattler); BattleScriptExecute(BattleScript_YawnMakesAsleep); From f6b32c8d176ddac0538a8f5ee78e9eb328bc10e1 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Sat, 8 Jan 2022 20:19:53 -0300 Subject: [PATCH 21/27] Fixed Anchor Shot description. --- src/data/text/move_descriptions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/text/move_descriptions.h b/src/data/text/move_descriptions.h index 037261e321..2678062e82 100644 --- a/src/data/text/move_descriptions.h +++ b/src/data/text/move_descriptions.h @@ -2479,7 +2479,7 @@ static const u8 sPOLLEN_PUFFDescription[] = _( static const u8 sANCHOR_SHOTDescription[] = _( "Strangles the foe with a\n" - "chain. The foe can't flinch."); + "chain. The foe can't escape."); static const u8 sPSYCHIC_TERRAINDescription[] = _( "The ground turns weird for\n" From 352523403a78a46d7caf5483384106a2d30911b4 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Sun, 9 Jan 2022 14:57:45 -0300 Subject: [PATCH 22/27] Fixed usage of B_MULTI_BATTLE_WHITEOUT --- src/battle_script_commands.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 35c7cfeb9e..c624130a6c 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4147,7 +4147,7 @@ static void Cmd_getexp(void) } } -#ifdef B_MULTI_BATTLE_WHITEOUT >= GEN_4 +#if B_MULTI_BATTLE_WHITEOUT >= GEN_4 static bool32 NoAliveMonsForPlayerAndPartner(void) { u32 i; @@ -4230,7 +4230,7 @@ static void Cmd_checkteamslost(void) if (gBattleControllerExecFlags) return; -#ifdef B_MULTI_BATTLE_WHITEOUT >= GEN_4 +#if B_MULTI_BATTLE_WHITEOUT >= GEN_4 if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER)) { if (NoAliveMonsForPlayerAndPartner()) From 24b5a5709a999facdfd7e10cd97f737fd1a72905 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Mon, 10 Jan 2022 23:01:18 -0300 Subject: [PATCH 23/27] Allow Galarian Darmanitan's Zen Mode to work --- include/constants/battle_config.h | 96 ++++++++++++++++--------------- src/battle_util.c | 36 ++++++------ 2 files changed, 68 insertions(+), 64 deletions(-) diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 6662f261f4..8f56ac8719 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -5,53 +5,55 @@ // Species with peculiar battle effects. #ifndef POKEMON_EXPANSION - #define SPECIES_DIALGA 0 - #define SPECIES_PALKIA 0 - #define SPECIES_GIRATINA 0 - #define SPECIES_CHERRIM 0 - #define SPECIES_ARCEUS 0 - #define SPECIES_SILVALLY 0 - #define SPECIES_GENESECT 0 - #define SPECIES_AEGISLASH 0 - #define SPECIES_AEGISLASH_BLADE 10000 - #define SPECIES_MIMIKYU 0 - #define SPECIES_MIMIKYU_BUSTED 10001 - #define SPECIES_DARMANITAN 0 - #define SPECIES_DARMANITAN_ZEN_MODE 10002 - #define SPECIES_MINIOR_CORE_RED 0 - #define SPECIES_MINIOR 10003 - #define SPECIES_MINIOR_CORE_BLUE 0 - #define SPECIES_MINIOR_METEOR_BLUE 10004 - #define SPECIES_MINIOR_CORE_GREEN 0 - #define SPECIES_MINIOR_METEOR_GREEN 10005 - #define SPECIES_MINIOR_CORE_INDIGO 0 - #define SPECIES_MINIOR_METEOR_INDIGO 10006 - #define SPECIES_MINIOR_CORE_ORANGE 0 - #define SPECIES_MINIOR_METEOR_ORANGE 10007 - #define SPECIES_MINIOR_CORE_VIOLET 0 - #define SPECIES_MINIOR_METEOR_VIOLET 10008 - #define SPECIES_MINIOR_CORE_YELLOW 0 - #define SPECIES_MINIOR_METEOR_YELLOW 10009 - #define SPECIES_WISHIWASHI 0 - #define SPECIES_WISHIWASHI_SCHOOL 10010 - #define SPECIES_ZYGARDE 0 // 50% - #define SPECIES_ZYGARDE_10 10011 // 10 % - #define SPECIES_ZYGARDE_COMPLETE 10012 // 100 % - #define SPECIES_BURMY 0 - #define SPECIES_BURMY_SANDY_CLOAK 10013 - #define SPECIES_BURMY_TRASH_CLOAK 10014 - #define SPECIES_CRAMORANT 0 - #define SPECIES_CRAMORANT_GORGING 10015 - #define SPECIES_CRAMORANT_GULPING 10016 - #define SPECIES_GRENINJA_BATTLE_BOND 0 - #define SPECIES_GRENINJA_ASH 10017 - #define SPECIES_HOOPA 0 - #define SPECIES_HOOPA_UNBOUND 10018 - #define SPECIES_MELOETTA 0 - #define SPECIES_MELOETTA_PIROUETTE 10019 - #define SPECIES_MORPEKO 0 - #define SPECIES_MORPEKO_HANGRY 10020 - #define SPECIES_SIRFETCHD 10021 + #define SPECIES_DIALGA 0 + #define SPECIES_PALKIA 0 + #define SPECIES_GIRATINA 0 + #define SPECIES_CHERRIM 0 + #define SPECIES_ARCEUS 0 + #define SPECIES_SILVALLY 0 + #define SPECIES_GENESECT 0 + #define SPECIES_AEGISLASH 0 + #define SPECIES_AEGISLASH_BLADE 10000 + #define SPECIES_MIMIKYU 0 + #define SPECIES_MIMIKYU_BUSTED 10001 + #define SPECIES_DARMANITAN 0 + #define SPECIES_DARMANITAN_ZEN_MODE 10002 + #define SPECIES_MINIOR_CORE_RED 0 + #define SPECIES_MINIOR 10003 + #define SPECIES_MINIOR_CORE_BLUE 0 + #define SPECIES_MINIOR_METEOR_BLUE 10004 + #define SPECIES_MINIOR_CORE_GREEN 0 + #define SPECIES_MINIOR_METEOR_GREEN 10005 + #define SPECIES_MINIOR_CORE_INDIGO 0 + #define SPECIES_MINIOR_METEOR_INDIGO 10006 + #define SPECIES_MINIOR_CORE_ORANGE 0 + #define SPECIES_MINIOR_METEOR_ORANGE 10007 + #define SPECIES_MINIOR_CORE_VIOLET 0 + #define SPECIES_MINIOR_METEOR_VIOLET 10008 + #define SPECIES_MINIOR_CORE_YELLOW 0 + #define SPECIES_MINIOR_METEOR_YELLOW 10009 + #define SPECIES_WISHIWASHI 0 + #define SPECIES_WISHIWASHI_SCHOOL 10010 + #define SPECIES_ZYGARDE 0 // 50% + #define SPECIES_ZYGARDE_10 10011 // 10 % + #define SPECIES_ZYGARDE_COMPLETE 10012 // 100 % + #define SPECIES_BURMY 0 + #define SPECIES_BURMY_SANDY_CLOAK 10013 + #define SPECIES_BURMY_TRASH_CLOAK 10014 + #define SPECIES_CRAMORANT 0 + #define SPECIES_CRAMORANT_GORGING 10015 + #define SPECIES_CRAMORANT_GULPING 10016 + #define SPECIES_GRENINJA_BATTLE_BOND 0 + #define SPECIES_GRENINJA_ASH 10017 + #define SPECIES_HOOPA 0 + #define SPECIES_HOOPA_UNBOUND 10018 + #define SPECIES_MELOETTA 0 + #define SPECIES_MELOETTA_PIROUETTE 10019 + #define SPECIES_MORPEKO 0 + #define SPECIES_MORPEKO_HANGRY 10020 + #define SPECIES_SIRFETCHD 10021 + #define SPECIES_DARMANITAN_GALARIAN 0 + #define SPECIES_DARMANITAN_ZEN_MODE_GALARIAN 10022 #endif // Items with peculiar battle effects. diff --git a/src/battle_util.c b/src/battle_util.c index b293b9a5e6..491c117aba 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -3969,6 +3969,7 @@ static bool32 ShouldChangeFormHpBased(u32 battler) {ABILITY_SCHOOLING, SPECIES_WISHIWASHI_SCHOOL, SPECIES_WISHIWASHI, 4}, {ABILITY_GULP_MISSILE, SPECIES_CRAMORANT, SPECIES_CRAMORANT_GORGING, 2}, {ABILITY_GULP_MISSILE, SPECIES_CRAMORANT, SPECIES_CRAMORANT_GULPING, 1}, + {ABILITY_ZEN_MODE, SPECIES_DARMANITAN_GALARIAN, SPECIES_DARMANITAN_ZEN_MODE_GALARIAN, 2}, }; u32 i; @@ -9350,23 +9351,24 @@ void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut) struct Pokemon *party = (side == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty; static const u16 species[][3] = { - // Changed Form ID Default Form ID Should change on switch - {SPECIES_MIMIKYU_BUSTED, SPECIES_MIMIKYU, FALSE}, - {SPECIES_GRENINJA_ASH, SPECIES_GRENINJA_BATTLE_BOND, FALSE}, - {SPECIES_MELOETTA_PIROUETTE, SPECIES_MELOETTA, FALSE}, - {SPECIES_AEGISLASH_BLADE, SPECIES_AEGISLASH, TRUE}, - {SPECIES_DARMANITAN_ZEN_MODE, SPECIES_DARMANITAN, TRUE}, - {SPECIES_MINIOR, SPECIES_MINIOR_CORE_RED, TRUE}, - {SPECIES_MINIOR_METEOR_BLUE, SPECIES_MINIOR_CORE_BLUE, TRUE}, - {SPECIES_MINIOR_METEOR_GREEN, SPECIES_MINIOR_CORE_GREEN, TRUE}, - {SPECIES_MINIOR_METEOR_INDIGO, SPECIES_MINIOR_CORE_INDIGO, TRUE}, - {SPECIES_MINIOR_METEOR_ORANGE, SPECIES_MINIOR_CORE_ORANGE, TRUE}, - {SPECIES_MINIOR_METEOR_VIOLET, SPECIES_MINIOR_CORE_VIOLET, TRUE}, - {SPECIES_MINIOR_METEOR_YELLOW, SPECIES_MINIOR_CORE_YELLOW, TRUE}, - {SPECIES_WISHIWASHI_SCHOOL, SPECIES_WISHIWASHI, TRUE}, - {SPECIES_CRAMORANT_GORGING, SPECIES_CRAMORANT, TRUE}, - {SPECIES_CRAMORANT_GULPING, SPECIES_CRAMORANT, TRUE}, - {SPECIES_MORPEKO_HANGRY, SPECIES_MORPEKO, TRUE}, + // Changed Form ID Default Form ID Should change on switch + {SPECIES_MIMIKYU_BUSTED, SPECIES_MIMIKYU, FALSE}, + {SPECIES_GRENINJA_ASH, SPECIES_GRENINJA_BATTLE_BOND, FALSE}, + {SPECIES_MELOETTA_PIROUETTE, SPECIES_MELOETTA, FALSE}, + {SPECIES_AEGISLASH_BLADE, SPECIES_AEGISLASH, TRUE}, + {SPECIES_DARMANITAN_ZEN_MODE, SPECIES_DARMANITAN, TRUE}, + {SPECIES_MINIOR, SPECIES_MINIOR_CORE_RED, TRUE}, + {SPECIES_MINIOR_METEOR_BLUE, SPECIES_MINIOR_CORE_BLUE, TRUE}, + {SPECIES_MINIOR_METEOR_GREEN, SPECIES_MINIOR_CORE_GREEN, TRUE}, + {SPECIES_MINIOR_METEOR_INDIGO, SPECIES_MINIOR_CORE_INDIGO, TRUE}, + {SPECIES_MINIOR_METEOR_ORANGE, SPECIES_MINIOR_CORE_ORANGE, TRUE}, + {SPECIES_MINIOR_METEOR_VIOLET, SPECIES_MINIOR_CORE_VIOLET, TRUE}, + {SPECIES_MINIOR_METEOR_YELLOW, SPECIES_MINIOR_CORE_YELLOW, TRUE}, + {SPECIES_WISHIWASHI_SCHOOL, SPECIES_WISHIWASHI, TRUE}, + {SPECIES_CRAMORANT_GORGING, SPECIES_CRAMORANT, TRUE}, + {SPECIES_CRAMORANT_GULPING, SPECIES_CRAMORANT, TRUE}, + {SPECIES_MORPEKO_HANGRY, SPECIES_MORPEKO, TRUE}, + {SPECIES_DARMANITAN_ZEN_MODE_GALARIAN, SPECIES_DARMANITAN_GALARIAN, TRUE}, }; currSpecies = GetMonData(&party[monId], MON_DATA_SPECIES, NULL); From bee4019d224f2139538b0787375bfc339cc5b809 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Tue, 11 Jan 2022 19:52:51 -0300 Subject: [PATCH 24/27] Tweaked Protean's effect's InGame appearance --- src/battle_script_commands.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index c624130a6c..3230e2ec5d 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1428,6 +1428,8 @@ static void Cmd_attackcanceler(void) SET_BATTLER_TYPE(gBattlerAttacker, moveType); gBattlerAbility = gBattlerAttacker; BattleScriptPushCursor(); + PrepareStringBattle(STRINGID_EMPTYSTRING3, gBattlerAttacker); + gBattleCommunication[MSG_DISPLAY] = 1; gBattlescriptCurrInstr = BattleScript_ProteanActivates; return; } From b2965e5522d14f2aa17f265d1447f76c16af4141 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Tue, 11 Jan 2022 20:15:47 -0300 Subject: [PATCH 25/27] Added a pause to BattleScript_ProteanActivates --- data/battle_scripts_1.s | 1 + include/constants/battle.h | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index ba775a1a06..eb8d53a157 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -8299,6 +8299,7 @@ BattleScript_MimicryActivatesEnd3:: end3 BattleScript_ProteanActivates:: + pause B_WAIT_TIME_SHORTEST call BattleScript_AbilityPopUp printstring STRINGID_PKMNCHANGEDTYPE waitmessage B_WAIT_TIME_LONG diff --git a/include/constants/battle.h b/include/constants/battle.h index bdb570b7ca..3eaa79a402 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -396,9 +396,10 @@ #define BATTLE_TERRAIN_COUNT 22 -#define B_WAIT_TIME_LONG 64 -#define B_WAIT_TIME_MED 48 -#define B_WAIT_TIME_SHORT 32 +#define B_WAIT_TIME_LONG 64 +#define B_WAIT_TIME_MED 48 +#define B_WAIT_TIME_SHORT 32 +#define B_WAIT_TIME_SHORTEST 16 #define CHERRIM_OVERCAST 0 #define CHERRIM_SUNSHINE 1 From 69f678b3fca25ac1ff87c3bcf133d1b144680226 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Tue, 11 Jan 2022 20:21:12 -0300 Subject: [PATCH 26/27] Put the new B_WAIT_TIME_SHORTEST to use --- data/battle_scripts_1.s | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index eb8d53a157..f4735f7792 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -1251,7 +1251,7 @@ BattleScript_EffectAromaticMistWorks: setstatchanger STAT_SPDEF, 1, FALSE statbuffchange STAT_BUFF_ALLOW_PTR, BattleScript_EffectAromaticMistEnd jumpifbyte CMP_NOT_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_AromaticMistAnim - pause 16 + pause B_WAIT_TIME_SHORTEST printstring STRINGID_TARGETSTATWONTGOHIGHER waitmessage B_WAIT_TIME_LONG goto BattleScript_EffectAromaticMistEnd @@ -7147,7 +7147,7 @@ BattleScript_EnduredMsg:: BattleScript_SturdiedMsg:: copybyte gBattlerAbility, gBattlerTarget - pause 16 + pause B_WAIT_TIME_SHORTEST call BattleScript_AbilityPopUp printstring STRINGID_ENDUREDSTURDY waitmessage B_WAIT_TIME_LONG @@ -8395,7 +8395,7 @@ BattleScript_WeakArmorActivates:: statbuffchange STAT_BUFF_ALLOW_PTR, BattleScript_WeakArmorActivatesSpeed jumpifbyte CMP_LESS_THAN, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_WeakArmorDefAnim jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_FELL_EMPTY, BattleScript_WeakArmorActivatesSpeed - pause 16 + pause B_WAIT_TIME_SHORTEST printfromtable gStatDownStringIds waitmessage B_WAIT_TIME_LONG goto BattleScript_WeakArmorActivatesSpeed @@ -8409,7 +8409,7 @@ BattleScript_WeakArmorActivatesSpeed: statbuffchange STAT_BUFF_ALLOW_PTR, BattleScript_WeakArmorActivatesEnd jumpifbyte CMP_LESS_THAN, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_WeakArmorSpeedAnim jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_ROSE_EMPTY, BattleScript_WeakArmorActivatesEnd - pause 16 + pause B_WAIT_TIME_SHORTEST printstring STRINGID_TARGETSTATWONTGOHIGHER waitmessage B_WAIT_TIME_LONG goto BattleScript_WeakArmorActivatesEnd From a4f0de5106d24e4bf945a722efdc448acc7bae26 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Wed, 12 Jan 2022 01:54:29 -0300 Subject: [PATCH 27/27] Removed the last bits of HOLD_EFFECT_GRACIDEA --- include/constants/hold_effects.h | 2 +- src/battle_debug.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/constants/hold_effects.h b/include/constants/hold_effects.h index d15e50d5ff..e0361795d7 100644 --- a/include/constants/hold_effects.h +++ b/include/constants/hold_effects.h @@ -100,7 +100,7 @@ #define HOLD_EFFECT_ADAMANT_ORB 94 #define HOLD_EFFECT_LUSTROUS_ORB 95 #define HOLD_EFFECT_GRISEOUS_ORB 96 -#define HOLD_EFFECT_GRACIDEA 97 +#define HOLD_EFFECT_ENIGMA_BERRY 97 #define HOLD_EFFECT_RESIST_BERRY 98 #define HOLD_EFFECT_POWER_ITEM 99 #define HOLD_EFFECT_RESTORE_PCT_HP 100 diff --git a/src/battle_debug.c b/src/battle_debug.c index e672145c51..2ea46321df 100644 --- a/src/battle_debug.c +++ b/src/battle_debug.c @@ -1996,7 +1996,7 @@ static const u8 sText_HoldEffectQuickPowder[] = _("Quick Powder"); static const u8 sText_HoldEffectAdamantOrb[] = _("Adamant Orb"); static const u8 sText_HoldEffectLustrousOrb[] = _("Lustrous Orb"); static const u8 sText_HoldEffectGriseousOrb[] = _("Griseous Orb"); -static const u8 sText_HoldEffectGracidea[] = _("Gracidea"); +static const u8 sText_HoldEffectEnigmaBerry[] = _("Enigma Berry"); static const u8 sText_HoldEffectResistBerry[] = _("Resist Berry"); static const u8 sText_HoldEffectPowerItem[] = _("Power Item"); static const u8 sText_HoldEffectRestorePctHp[] = _("Restore Pct Hp"); @@ -2138,7 +2138,7 @@ static const u8 *const sHoldEffectNames[] = [HOLD_EFFECT_ADAMANT_ORB] = sText_HoldEffectAdamantOrb, [HOLD_EFFECT_LUSTROUS_ORB] = sText_HoldEffectLustrousOrb, [HOLD_EFFECT_GRISEOUS_ORB] = sText_HoldEffectGriseousOrb, - [HOLD_EFFECT_GRACIDEA] = sText_HoldEffectGracidea, + [HOLD_EFFECT_ENIGMA_BERRY] = sText_HoldEffectEnigmaBerry, [HOLD_EFFECT_RESIST_BERRY] = sText_HoldEffectResistBerry, [HOLD_EFFECT_POWER_ITEM] = sText_HoldEffectPowerItem, [HOLD_EFFECT_RESTORE_PCT_HP] = sText_HoldEffectRestorePctHp,