diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/battle_3.c | 640 | ||||
-rw-r--r-- | src/battle_4.c | 18 |
2 files changed, 555 insertions, 103 deletions
diff --git a/src/battle_3.c b/src/battle_3.c index 5c6bc8b07..cb0812034 100644 --- a/src/battle_3.c +++ b/src/battle_3.c @@ -10,6 +10,7 @@ #include "data2.h" #include "rng.h" #include "text.h" +#include "battle_move_effects.h" extern u8* gBattlescriptCurrInstr; extern u8 gActiveBank; @@ -35,7 +36,13 @@ extern u8 gAbsentBankFlags; extern u8 gBattleCommunication[]; extern u32 gHitMarker; extern u8 gEffectBank; +extern u8 gBank1; extern s32 gBattleMoveDamage; +extern u16 gBattlePartyID[4]; +extern u16 gChosenMovesByBanks[4]; +extern s32 gTakenDmg[4]; +extern u8 gTakenDmgBanks[4]; +extern u8 gBattleMoveFlags; u8 IsImprisoned(u8 bank, u16 move); u8 GetBankByPlayerAI(u8 ID); @@ -45,6 +52,11 @@ void b_call_bc_move_exec(u8* BS_ptr); bool8 sub_8015660(u8 bank); //check if a move failed void SetMoveEffect(bool8 primary, u8 certainArg); bool8 sub_8025A44(u8 bank); //uproar wakeup check +bool8 sub_8018018(u8 bank, u8, u8); +void sub_8015740(u8 bank); +s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 a4, u16 powerOverride, u8 typeOverride, u8 bank_atk, u8 bank_def); +u8 CountTrailingZeroBits(u32 a); +u8 sub_801B5C0(u16 move, u8 targetbyte); //get target of move extern u8 BattleScript_MoveSelectionDisabledMove[]; extern u8 BattleScript_MoveSelectionTormented[]; @@ -54,6 +66,17 @@ extern u8 BattleScript_MoveSelectionChoiceBanded[]; extern u8 BattleScript_MoveSelectionNoPP[]; extern u8 BattleScript_NoMovesLeft[]; extern u8 BattleScript_WishComesTrue[]; +extern u8 BattleScript_IngrainTurnHeal[]; +extern u8 BattleScript_LeechSeedTurnDrain[]; +extern u8 BattleScript_PoisonTurnDmg[]; +extern u8 BattleScript_BurnTurnDmg[]; +extern u8 BattleScript_NightmareTurnDmg[]; +extern u8 BattleScript_CurseTurnDmg[]; +extern u8 BattleScript_WrapTurnDmg[]; +extern u8 BattleScript_WrapEnds[]; +extern u8 BattleScript_DisabledNoMore[]; +extern u8 BattleScript_EncoredNoMore[]; + extern u8 gUnknown_081D9030[]; extern u8 gUnknown_081D8F62[]; extern u8 gUnknown_081D8FFF[]; @@ -61,21 +84,34 @@ extern u8 gUnknown_081D8F7D[]; extern u8 gUnknown_081D9016[]; extern u8 gUnknown_081D9008[]; extern u8 gUnknown_081D9041[]; - -extern u8 gUnknown_081D93D1[]; //ingrain bs -extern u8 gUnknown_081D904B[]; //leech seed BS -extern u8 gUnknown_081D9518[]; //poison dmg BS -extern u8 gUnknown_081D953A[]; //burn dmg BS -extern u8 gUnknown_081D9613[]; //nightmare dmg BS -extern u8 gUnknown_081D9624[]; //curse dmg BS -extern u8 gUnknown_081D95E2[]; //wrap dmg BS -extern u8 gUnknown_081D95F4[]; //wrap ends BS extern u8 gUnknown_081D950F[]; //uproar wakeup BS extern u8 gUnknown_081D957E[]; //uproar BS extern u8 gUnknown_081D9587[]; //thrash confusion BS -extern u8 gUnknown_081D9148[]; //disabled no more BS -extern u8 gUnknown_081D914F[]; //encored no more BS extern u8 gUnknown_081D964C[]; //yawn sleep BS +extern u8 gUnknown_081D92D7[]; //future sight hit +extern u8 gUnknown_081D9202[]; //perish song hit +extern u8 gUnknown_081D921D[]; //perish song timer goes down +extern u8 gUnknown_081D8C72[]; +extern u8 gUnknown_081D8C7B[]; +extern u8 gUnknown_081D94FB[]; //uproar wakes you up when trying to use a move +extern u8 gUnknown_081D94EE[]; //poke is asleep +extern u8 gUnknown_081D94FB[]; //poke woke up +extern u8 gUnknown_081D9545[]; //poke is frozen +extern u8 gUnknown_081D9552[]; //poke is no longer frozen +extern u8 gUnknown_081D9977[]; //poke is loafing around +extern u8 gUnknown_081D7956[]; //poke must recharge +extern u8 gUnknown_081D9573[]; //poke flinched +extern u8 gUnknown_081D9139[]; //poke tries to use a disabled move +extern u8 gUnknown_081D938F[]; //taunt prevents from using the chosen move +extern u8 gUnknown_081D9459[]; //using imprisoned move +extern u8 gUnknown_081D9595[]; //poke is confused +extern u8 gUnknown_081D95D4[]; //poke is confused no more +extern u8 gUnknown_081D9566[]; //poke is paralyzed +extern u8 gUnknown_081D9608[]; //poke is infatuated, won't attack +extern u8 gUnknown_081D95FB[]; //poke is infatuated +extern u8 gUnknown_081D90A7[]; //bide storing energy +extern u8 gUnknown_081D90B2[]; //bide attack +extern u8 gUnknown_081D90F1[]; //bide no energy to attack #define CHOICED_MOVE(bank)(((u16*)(&ewram[bank * 2 + 0x160e8]))) @@ -477,9 +513,10 @@ u8 UpdateTurnCounters(void) #define TURNBASED_MAX_CASE 19 -bool8 TurnBasedEffects(void) +u8 TurnBasedEffects(void) { u8 effect = 0; + gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_x20); while (BATTLE_STRUCT->turnEffectsBank < gNoOfAllBanks && BATTLE_STRUCT->turnEffectsTracker <= TURNBASED_MAX_CASE) { @@ -490,67 +527,64 @@ bool8 TurnBasedEffects(void) } else { - int i; switch (BATTLE_STRUCT->turnEffectsTracker) { - case 0: //ingrain - if (gStatuses3[gActiveBank] & STATUS3_ROOTED && gBattleMons[gActiveBank].hp != gBattleMons[gActiveBank].maxHP && gBattleMons[gActiveBank].hp != 0) + case 0: // ingrain + if ((gStatuses3[gActiveBank] & STATUS3_ROOTED) + && gBattleMons[gActiveBank].hp != gBattleMons[gActiveBank].maxHP + && gBattleMons[gActiveBank].hp != 0) { gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 16; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; gBattleMoveDamage *= -1; - b_call_bc_move_exec(gUnknown_081D93D1); + b_call_bc_move_exec(BattleScript_IngrainTurnHeal); effect++; } BATTLE_STRUCT->turnEffectsTracker++; break; - case 1: //end turn abilities + case 1: // end turn abilities if (AbilityBattleEffects(ABILITYEFFECT_ENDTURN, gActiveBank, 0, 0, 0)) effect++; BATTLE_STRUCT->turnEffectsTracker++; break; - case 2: //item effects - if (ItemBattleEffects(0, gActiveBank, 0)) + case 2: // item effects + if (ItemBattleEffects(1, gActiveBank, 0)) effect++; BATTLE_STRUCT->turnEffectsTracker++; break; - case 18: //item effects again + case 18: // item effects again if (ItemBattleEffects(1, gActiveBank, 1)) effect++; BATTLE_STRUCT->turnEffectsTracker++; break; - case 3: //leech seed + case 3: // leech seed + if (gStatuses3[gActiveBank] & STATUS3_LEECHSEED && gBattleMons[gStatuses3[gActiveBank] & STATUS3_LEECHSEED_BANK].hp != 0 && gBattleMons[gActiveBank].hp != 0) { - u8 leecher; - if (gStatuses3[gActiveBank] & STATUS3_LEECHSEED && gBattleMons[leecher = (gStatuses3[gActiveBank] & STATUS3_LEECHSEED_BANK)].hp && gBattleMons[gActiveBank].hp) //wont match without this ugly leecher assignment - { - //u8 leecher = gStatuses3[gActiveBank] & STATUS3_LEECHSEED_BANK; - gBankTarget = leecher; //funny how the 'target' is actually the bank that receives HP - gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 8; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - BATTLE_STRUCT->animArg1 = leecher; - BATTLE_STRUCT->animArg2 = gBankAttacker; - b_call_bc_move_exec(gUnknown_081D904B); - effect++; - } - BATTLE_STRUCT->turnEffectsTracker++; + gBankTarget = gStatuses3[gActiveBank] & STATUS3_LEECHSEED_BANK; //funny how the 'target' is actually the bank that receives HP + gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 8; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + BATTLE_STRUCT->animArg1 = gBankTarget; + BATTLE_STRUCT->animArg2 = gBankAttacker; + b_call_bc_move_exec(BattleScript_LeechSeedTurnDrain); + effect++; } + BATTLE_STRUCT->turnEffectsTracker++; break; - case 4: //poison - if (gBattleMons[gActiveBank].status1 & STATUS_POISON && gBattleMons[gActiveBank].hp) + case 4: // poison + if ((gBattleMons[gActiveBank].status1 & STATUS_POISON) && gBattleMons[gActiveBank].hp != 0) { gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 8; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - b_call_bc_move_exec(gUnknown_081D9518); + b_call_bc_move_exec(BattleScript_PoisonTurnDmg); effect++; } BATTLE_STRUCT->turnEffectsTracker++; break; - case 5: //toxic poison - if (gBattleMons[gActiveBank].status1 & STATUS_TOXIC_POISON && gBattleMons[gActiveBank].hp) + case 5: // toxic poison + if ((gBattleMons[gActiveBank].status1 & STATUS_TOXIC_POISON) && gBattleMons[gActiveBank].hp != 0) { gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 16; if (gBattleMoveDamage == 0) @@ -558,50 +592,50 @@ bool8 TurnBasedEffects(void) if ((gBattleMons[gActiveBank].status1 & 0xF00) != 0xF00) //not 16 turns gBattleMons[gActiveBank].status1 += 0x100; gBattleMoveDamage *= (gBattleMons[gActiveBank].status1 & 0xF00) >> 8; - b_call_bc_move_exec(gUnknown_081D9518); + b_call_bc_move_exec(BattleScript_PoisonTurnDmg); effect++; } BATTLE_STRUCT->turnEffectsTracker++; break; - case 6: //burn - if (gBattleMons[gActiveBank].status1 & STATUS_BURN && gBattleMons[gActiveBank].hp) + case 6: // burn + if ((gBattleMons[gActiveBank].status1 & STATUS_BURN) && gBattleMons[gActiveBank].hp != 0) { gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 8; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - b_call_bc_move_exec(gUnknown_081D953A); + b_call_bc_move_exec(BattleScript_BurnTurnDmg); effect++; } BATTLE_STRUCT->turnEffectsTracker++; break; - case 7: //spooky nightmares - if (gBattleMons[gActiveBank].status2 & STATUS2_NIGHTMARE && gBattleMons[gActiveBank].hp) + case 7: // spooky nightmares + if ((gBattleMons[gActiveBank].status2 & STATUS2_NIGHTMARE) && gBattleMons[gActiveBank].hp != 0) { - //missing sleep check + // missing sleep check gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 4; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - b_call_bc_move_exec(gUnknown_081D9613); + b_call_bc_move_exec(BattleScript_NightmareTurnDmg); effect++; } BATTLE_STRUCT->turnEffectsTracker++; break; - case 8: //curse - if (gBattleMons[gActiveBank].status2 & STATUS2_CURSED && gBattleMons[gActiveBank].hp) + case 8: // curse + if ((gBattleMons[gActiveBank].status2 & STATUS2_CURSED) && gBattleMons[gActiveBank].hp != 0) { gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 4; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - b_call_bc_move_exec(gUnknown_081D9624); + b_call_bc_move_exec(BattleScript_CurseTurnDmg); effect++; } BATTLE_STRUCT->turnEffectsTracker++; break; - case 9: //wrap - if (gBattleMons[gActiveBank].status2 & STATUS2_WRAPPED && gBattleMons[gActiveBank].hp) + case 9: // wrap + if ((gBattleMons[gActiveBank].status2 & STATUS2_WRAPPED) && gBattleMons[gActiveBank].hp != 0) { - gBattleMons[gActiveBank].status2 &= 0xFFFFE000; //hmmm - if (gBattleMons[gActiveBank].status2 & STATUS2_WRAPPED) //damaged by wrap + gBattleMons[gActiveBank].status2 -= 0x2000; + if (gBattleMons[gActiveBank].status2 & STATUS2_WRAPPED) // damaged by wrap { BATTLE_STRUCT->animArg1 = ewram[gActiveBank * 2 + 0x16004]; BATTLE_STRUCT->animArg2 = ewram[gActiveBank * 2 + 0x16005]; @@ -609,52 +643,53 @@ bool8 TurnBasedEffects(void) gBattleTextBuff1[1] = 2; gBattleTextBuff1[2] = ewram[gActiveBank * 2 + 0x16004]; gBattleTextBuff1[3] = ewram[gActiveBank * 2 + 0x16005]; - gBattleTextBuff1[4] = 0xFF; - gBattlescriptCurrInstr = gUnknown_081D95E2; + gBattleTextBuff1[4] = EOS; + gBattlescriptCurrInstr = BattleScript_WrapTurnDmg; gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 16; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; } - else //broke free + else // broke free { gBattleTextBuff1[0] = 0xFD; gBattleTextBuff1[1] = 2; gBattleTextBuff1[2] = ewram[gActiveBank * 2 + 0x16004]; gBattleTextBuff1[3] = ewram[gActiveBank * 2 + 0x16005]; - gBattleTextBuff1[4] = 0xFF; - gBattlescriptCurrInstr = gUnknown_081D95F4; + gBattleTextBuff1[4] = EOS; + gBattlescriptCurrInstr = BattleScript_WrapEnds; } b_call_bc_move_exec(gBattlescriptCurrInstr); effect++; } BATTLE_STRUCT->turnEffectsTracker++; break; - case 10: //uproar + case 10: // uproar if (gBattleMons[gActiveBank].status2 & STATUS2_UPROAR) { for (gBankAttacker = 0; gBankAttacker < gNoOfAllBanks; gBankAttacker++) { - if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP && gBattleMons[gBankAttacker].ability != ABILITY_SOUNDPROOF) + if ((gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) + && gBattleMons[gBankAttacker].ability != ABILITY_SOUNDPROOF) { gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP); gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); gBattleCommunication[MULTISTRING_CHOOSER] = 1; b_call_bc_move_exec(gUnknown_081D950F); gActiveBank = gBankAttacker; - EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBankAttacker].status1); + EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); MarkBufferBankForExecution(gActiveBank); break; } } if (gBankAttacker != gNoOfAllBanks) { - effect = 2; //a pokemon was awaken + effect = 2; // a pokemon was awaken break; } else { gBankAttacker = gActiveBank; - gBattleMons[gActiveBank].status2 -= 0x10; //uproar timer goes down + gBattleMons[gActiveBank].status2 -= 0x10; // uproar timer goes down if (sub_8015660(gActiveBank)) { CancelMultiTurnMoves(gActiveBank); @@ -677,15 +712,16 @@ bool8 TurnBasedEffects(void) if (effect != 2) BATTLE_STRUCT->turnEffectsTracker++; break; - case 11: //thrash + case 11: // thrash if (gBattleMons[gActiveBank].status2 & STATUS2_LOCK_CONFUSE) { - gBattleMons[gActiveBank].status2 &= 0xFFFFFC00; + gBattleMons[gActiveBank].status2 -= 0x400; if (sub_8015660(gActiveBank)) CancelMultiTurnMoves(gActiveBank); - else if (!(gBattleMons[gActiveBank].status2 & STATUS2_LOCK_CONFUSE) && gBattleMons[gActiveBank].status2 & STATUS2_MULTIPLETURNS) + else if (!(gBattleMons[gActiveBank].status2 & STATUS2_LOCK_CONFUSE) + && (gBattleMons[gActiveBank].status2 & STATUS2_MULTIPLETURNS)) { - gBattleMons[gActiveBank].status2 &= 0xFFFFEFFF; + gBattleMons[gActiveBank].status2 &= ~(STATUS2_MULTIPLETURNS); if (!(gBattleMons[gActiveBank].status2 & STATUS2_CONFUSION)) { gBattleCommunication[MOVE_EFFECT_BYTE] = 0x47; @@ -698,67 +734,70 @@ bool8 TurnBasedEffects(void) } BATTLE_STRUCT->turnEffectsTracker++; break; - case 12: //disable - if (gDisableStructs[gActiveBank].disableTimer1) + case 12: // disable + if (gDisableStructs[gActiveBank].disableTimer1 != 0) { + int i; for (i = 0; i < 4; i++) { if (gDisableStructs[gActiveBank].disabledMove == gBattleMons[gActiveBank].moves[i]) break; } - if (i == 4) //pokemon does not have the disabled move anymore + if (i == 4) // pokemon does not have the disabled move anymore { gDisableStructs[gActiveBank].disabledMove = 0; gDisableStructs[gActiveBank].disableTimer1 = 0; } - else if (--gDisableStructs[gActiveBank].disableTimer1 == 0) //disable ends + else if (--gDisableStructs[gActiveBank].disableTimer1 == 0) // disable ends { gDisableStructs[gActiveBank].disabledMove = 0; - b_call_bc_move_exec(gUnknown_081D9148); + b_call_bc_move_exec(BattleScript_DisabledNoMore); effect++; } } BATTLE_STRUCT->turnEffectsTracker++; break; - case 13: //encore - if (gDisableStructs[gActiveBank].encoreTimer1) + case 13: // encore + if (gDisableStructs[gActiveBank].encoreTimer1 != 0) { - if (gBattleMons[gActiveBank].moves[gDisableStructs[gActiveBank].encoredMovePos] != gDisableStructs[gActiveBank].encoredMove) //pokemon does not have the encored move anymore + if (gBattleMons[gActiveBank].moves[gDisableStructs[gActiveBank].encoredMovePos] != gDisableStructs[gActiveBank].encoredMove) // pokemon does not have the encored move anymore { gDisableStructs[gActiveBank].encoredMove = 0; gDisableStructs[gActiveBank].encoreTimer1 = 0; } - else if (--gDisableStructs[gActiveBank].encoreTimer1 == 0 || gBattleMons[gActiveBank].pp[gDisableStructs[gActiveBank].encoredMovePos] == 0) + else if (--gDisableStructs[gActiveBank].encoreTimer1 == 0 + || gBattleMons[gActiveBank].pp[gDisableStructs[gActiveBank].encoredMovePos] == 0) { gDisableStructs[gActiveBank].encoredMove = 0; gDisableStructs[gActiveBank].encoreTimer1 = 0; - b_call_bc_move_exec(gUnknown_081D914F); + b_call_bc_move_exec(BattleScript_EncoredNoMore); effect++; } } BATTLE_STRUCT->turnEffectsTracker++; break; - case 14: //lock-on decrement + case 14: // lock-on decrement if (gStatuses3[gActiveBank] & STATUS3_ALWAYS_HITS) gStatuses3[gActiveBank] -= 0x8; BATTLE_STRUCT->turnEffectsTracker++; break; - case 15: //charge + case 15: // charge if (gDisableStructs[gActiveBank].chargeTimer1 && --gDisableStructs[gActiveBank].chargeTimer1 == 0) gStatuses3[gActiveBank] &= ~STATUS3_CHARGED_UP; BATTLE_STRUCT->turnEffectsTracker++; break; - case 16: //taunt + case 16: // taunt if (gDisableStructs[gActiveBank].tauntTimer1) gDisableStructs[gActiveBank].tauntTimer1--; BATTLE_STRUCT->turnEffectsTracker++; break; - case 17: //yawn + case 17: // yawn if (gStatuses3[gActiveBank] & STATUS3_YAWN) { - gStatuses3[gActiveBank] &= 0xFFFFF800; - if (!(gStatuses3[gActiveBank] & STATUS3_YAWN) && !gBattleMons[gActiveBank].status1 && gBattleMons[gActiveBank].ability != ABILITY_VITAL_SPIRIT - && gBattleMons[gActiveBank].ability != ABILITY_INSOMNIA && !sub_8025A44(gActiveBank)) + gStatuses3[gActiveBank] -= 0x800; + if (!(gStatuses3[gActiveBank] & STATUS3_YAWN) && !(gBattleMons[gActiveBank].status1 & STATUS_ANY) + && gBattleMons[gActiveBank].ability != ABILITY_VITAL_SPIRIT + && gBattleMons[gActiveBank].ability != ABILITY_INSOMNIA && !sub_8025A44(gActiveBank)) { CancelMultiTurnMoves(gActiveBank); gBattleMons[gActiveBank].status1 |= (Random() & 3) + 2; @@ -771,15 +810,440 @@ bool8 TurnBasedEffects(void) } BATTLE_STRUCT->turnEffectsTracker++; break; - case 19: //done + case 19: // done BATTLE_STRUCT->turnEffectsTracker = 0; BATTLE_STRUCT->turnEffectsBank++; break; } - if (effect) + if (effect != 0) return effect; } } gHitMarker &= ~(HITMARKER_GRUDGE | HITMARKER_x20); return 0; } + +bool8 sub_80170DC(void) // handle future sight and perish song +{ + gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_x20); + switch (BATTLE_STRUCT->sub80170DC_Tracker) + { + case 0: // future sight + while (BATTLE_STRUCT->sub80170DC_Bank < gNoOfAllBanks) + { + gActiveBank = BATTLE_STRUCT->sub80170DC_Bank; + if (gAbsentBankFlags & gBitTable[gActiveBank]) + BATTLE_STRUCT->sub80170DC_Bank++; + else + { + BATTLE_STRUCT->sub80170DC_Bank++; + if (gWishFutureKnock.futureSightCounter[gActiveBank] && --gWishFutureKnock.futureSightCounter[gActiveBank] == 0 && gBattleMons[gActiveBank].hp) + { + if (gWishFutureKnock.futureSightMove[gActiveBank] == MOVE_FUTURE_SIGHT) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + else //Doom Desire + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = gWishFutureKnock.futureSightMove[gActiveBank]; + gBattleTextBuff1[3] = gWishFutureKnock.futureSightMove[gActiveBank] >> 8; + gBattleTextBuff1[4] = 0xFF; + gBankTarget = gActiveBank; + gBankAttacker = gWishFutureKnock.futureSightAttacker[gActiveBank]; + gBattleMoveDamage = gWishFutureKnock.futureSightDmg[gActiveBank]; + gSpecialStatuses[gBankTarget].moveturnLostHP = 0xFFFF; + b_call_bc_move_exec(gUnknown_081D92D7); + return 1; + } + } + } + BATTLE_STRUCT->sub80170DC_Tracker = 1; + BATTLE_STRUCT->sub80170DC_Bank = 0; + case 1: // perish song + while (BATTLE_STRUCT->sub80170DC_Bank < gNoOfAllBanks) + { + gActiveBank = gBankAttacker = gTurnOrder[BATTLE_STRUCT->sub80170DC_Bank]; + if (gAbsentBankFlags & gBitTable[gActiveBank]) + BATTLE_STRUCT->sub80170DC_Bank++; + else + { + BATTLE_STRUCT->sub80170DC_Bank++; + if (gStatuses3[gActiveBank] & STATUS3_PERISH_SONG) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 1; + gBattleTextBuff1[2] = 1; + gBattleTextBuff1[3] = 1; + gBattleTextBuff1[4] = gDisableStructs[gActiveBank].perishSong1; + gBattleTextBuff1[5] = 0xFF; + if (gDisableStructs[gActiveBank].perishSong1 == 0) + { + gStatuses3[gActiveBank] &= ~(STATUS3_PERISH_SONG); + gBattleMoveDamage = gBattleMons[gActiveBank].hp; + gBattlescriptCurrInstr = gUnknown_081D9202; + } + else + { + gDisableStructs[gActiveBank].perishSong1--; + gBattlescriptCurrInstr = gUnknown_081D921D; + } + b_call_bc_move_exec(gBattlescriptCurrInstr); + return 1; + } + } + } + break; + } + gHitMarker &= ~(HITMARKER_GRUDGE | HITMARKER_x20); + return 0; +} + +#define sub_80173A4_MAX_CASE 7 + +bool8 sub_80173A4(void) +{ + if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) + return 0; + do + { + int i; + switch (BATTLE_STRUCT->sub80173A4_Tracker) + { + case 0: + BATTLE_STRUCT->unk1605A = 0; + BATTLE_STRUCT->sub80173A4_Tracker++; + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gAbsentBankFlags & gBitTable[i] && !sub_8018018(i, 6, 6)) + gAbsentBankFlags &= ~(gBitTable[i]); + } + case 1: + do + { + gBank1 = gBankTarget = BATTLE_STRUCT->unk1605A; + if (gBattleMons[BATTLE_STRUCT->unk1605A].hp == 0 && !(BATTLE_STRUCT->unk16113 & gBitTable[gBattlePartyID[BATTLE_STRUCT->unk1605A]]) && !(gAbsentBankFlags & gBitTable[BATTLE_STRUCT->unk1605A])) + { + b_call_bc_move_exec(gUnknown_081D8C72); + BATTLE_STRUCT->sub80173A4_Tracker = 2; + return 1; + } + } while (++BATTLE_STRUCT->unk1605A != gNoOfAllBanks); + BATTLE_STRUCT->sub80173A4_Tracker = 3; + break; + case 2: + sub_8015740(gBank1); + if (++BATTLE_STRUCT->unk1605A == gNoOfAllBanks) + BATTLE_STRUCT->sub80173A4_Tracker = 3; + else + BATTLE_STRUCT->sub80173A4_Tracker = 1; + break; + case 3: + BATTLE_STRUCT->unk1605A = 0; + BATTLE_STRUCT->sub80173A4_Tracker++; + case 4: + do + { + gBank1 = gBankTarget = BATTLE_STRUCT->unk1605A; //or should banks be switched? + if (gBattleMons[BATTLE_STRUCT->unk1605A].hp == 0 && !(gAbsentBankFlags & gBitTable[BATTLE_STRUCT->unk1605A])) + { + b_call_bc_move_exec(gUnknown_081D8C7B); + BATTLE_STRUCT->sub80173A4_Tracker = 5; + return 1; + } + } while (++BATTLE_STRUCT->unk1605A != gNoOfAllBanks); + BATTLE_STRUCT->sub80173A4_Tracker = 6; + break; + case 5: + if (++BATTLE_STRUCT->unk1605A == gNoOfAllBanks) + BATTLE_STRUCT->sub80173A4_Tracker = 6; + else + BATTLE_STRUCT->sub80173A4_Tracker = 4; + break; + case 6: + if (AbilityBattleEffects(9, 0, 0, 0, 0) || AbilityBattleEffects(0xB, 0, 0, 0, 0) || ItemBattleEffects(1, 0, 1) || AbilityBattleEffects(6, 0, 0, 0, 0)) + return 1; + BATTLE_STRUCT->sub80173A4_Tracker++; + break; + case 7: + break; + } + } while (BATTLE_STRUCT->sub80173A4_Tracker != sub_80173A4_MAX_CASE); + return 0; +} + +void b_clear_atk_up_if_hit_flag_unless_enraged(void) +{ + int i; + for (i = 0; i < gNoOfAllBanks; i++) + { + if (gBattleMons[i].status2 & STATUS2_RAGE && gChosenMovesByBanks[i] != MOVE_RAGE) + gBattleMons[i].status2 &= ~(STATUS2_RAGE); + } +} + +#define ATKCANCELLER_MAX_CASE 14 +/* +u8 AtkCanceller_UnableToUseMove(void) +{ + u8 effect = 0; + s32* bideDmg = &BATTLE_STRUCT->bideDmg; + do + { + switch (BATTLE_STRUCT->atkCancellerTracker) + { + case 0: // flags clear + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_DESTINY_BOND); + gStatuses3[gBankAttacker] &= ~(STATUS3_GRUDGE); + BATTLE_STRUCT->atkCancellerTracker++; + break; + case 1: // check being asleep + if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) + { + if (sub_8025A44(gBankAttacker)) + { + gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP); + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); + b_movescr_stack_push_cursor(); + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gBattlescriptCurrInstr = gUnknown_081D94FB; + effect = 2; + } + else + { + u8 toSub; + if (gBattleMons[gBankAttacker].ability == ABILITY_EARLY_BIRD) + toSub = 2; + else + toSub = 1; + if ((gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) < toSub) + gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP); + else + gBattleMons[gBankAttacker].status1 -= toSub; + if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) + { + if (gCurrentMove != MOVE_SNORE && gCurrentMove != MOVE_SLEEP_TALK) + { + gBattlescriptCurrInstr = gUnknown_081D94EE; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 2; + } + } + else + { + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); + b_movescr_stack_push_cursor(); + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gBattlescriptCurrInstr = gUnknown_081D94FB; + effect = 2; + } + } + } + BATTLE_STRUCT->atkCancellerTracker++; + break; + case 2: // check being frozen + if (gBattleMons[gBankAttacker].status1 & STATUS_FREEZE) + { + if (Random() % 5) + { + if (gBattleMoves[gCurrentMove].effect != EFFECT_THAW_HIT) // unfreezing via a move effect happens in case 13 + { + gBattlescriptCurrInstr = gUnknown_081D9545; + gHitMarker |= HITMARKER_NO_ATTACKSTRING; + effect = 2; + } + } + else // unfreeze + { + gBattleMons[gBankAttacker].status1 &= ~(STATUS_FREEZE); + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = gUnknown_081D9552; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + effect = 2; + } + } + BATTLE_STRUCT->atkCancellerTracker++; + break; + case 3: // truant + if (gBattleMons[gBankAttacker].ability == ABILITY_TRUANT && gDisableStructs[gBankAttacker].truantCounter) + { + CancelMultiTurnMoves(gBankAttacker); + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gBattlescriptCurrInstr = gUnknown_081D9977; + gBattleMoveFlags |= MOVESTATUS_MISSED; + effect = 1; + } + BATTLE_STRUCT->atkCancellerTracker++; + break; + case 4: // recharge + if (gBattleMons[gBankAttacker].status2 & STATUS2_RECHARGE) + { + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_RECHARGE); + gDisableStructs[gBankAttacker].rechargeCounter = 0; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = gUnknown_081D7956; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + BATTLE_STRUCT->atkCancellerTracker++; + break; + case 5: // flinch + if (gBattleMons[gBankAttacker].status2 & STATUS2_FLINCHED) + { + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_FLINCHED); + gProtectStructs[gBankAttacker].flinchImmobility = 1; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = gUnknown_081D9573; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + BATTLE_STRUCT->atkCancellerTracker++; + break; + case 6: // disabled move + if (gDisableStructs[gBankAttacker].disabledMove == gCurrentMove && gDisableStructs[gBankAttacker].disabledMove != 0) + { + gProtectStructs[gBankAttacker].usedDisabledMove = 1; + BATTLE_STRUCT->scriptingActive = gBankAttacker; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = gUnknown_081D9139; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + BATTLE_STRUCT->atkCancellerTracker++; + break; + case 7: // taunt + if (gDisableStructs[gBankAttacker].tauntTimer1 && gBattleMoves[gCurrentMove].power == 0) + { + gProtectStructs[gBankAttacker].usedTauntedMove = 1; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = gUnknown_081D938F; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + BATTLE_STRUCT->atkCancellerTracker++; + break; + case 8: // imprisoned + if (IsImprisoned(gBankAttacker, gCurrentMove)) + { + gProtectStructs[gBankAttacker].usedImprisionedMove = 1; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = gUnknown_081D9459; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + BATTLE_STRUCT->atkCancellerTracker++; + break; + case 9: // confusion + if (gBattleMons[gBankAttacker].status2 & STATUS2_CONFUSION) + { + gBattleMons[gBankAttacker].status2--; + if (gBattleMons[gBankAttacker].status2 & STATUS2_CONFUSION) + { + if (Random() & 1) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + b_movescr_stack_push_cursor(); + } + else // confusion dmg + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gBankTarget = gBankAttacker; + gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankAttacker], MOVE_POUND, 0, 40, 0, gBankAttacker, gBankAttacker); + gProtectStructs[gBankAttacker].confusionSelfDmg = 1; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + } + gBattlescriptCurrInstr = gUnknown_081D9595; + } + else // snapped out of confusion + { + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = gUnknown_081D95D4; + } + effect = 1; + } + BATTLE_STRUCT->atkCancellerTracker++; + break; + case 10: // paralysis + if (gBattleMons[gBankAttacker].status1 & STATUS_PARALYSIS && (Random() % 4) == 0) + { + gProtectStructs[gBankAttacker].prlzImmobility = 1; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = gUnknown_081D9566; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + BATTLE_STRUCT->atkCancellerTracker++; + break; + case 11: // infatuation + if (gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION) + { + BATTLE_STRUCT->scriptingActive = CountTrailingZeroBits(gBattleMons[gBankAttacker].status2 >> 0x10); + if (Random() & 1) + b_movescr_stack_push_cursor(); + else + { + b_movescr_stack_push(gUnknown_081D9608); + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + gProtectStructs[gBankAttacker].loveImmobility = 1; + CancelMultiTurnMoves(gBankAttacker); + } + gBattlescriptCurrInstr = gUnknown_081D95FB; + effect = 1; + } + BATTLE_STRUCT->atkCancellerTracker++; + break; + case 12: // bide + if (gBattleMons[gBankAttacker].status2 & STATUS2_BIDE) + { + gBattleMons[gBankAttacker].status2 -= 0x100; + if (gBattleMons[gBankAttacker].status2 & STATUS2_BIDE) + gBattlescriptCurrInstr = gUnknown_081D90A7; + else + { + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_BIDE); + if (gTakenDmg[gBankAttacker]) + { + gCurrentMove = MOVE_BIDE; + *bideDmg = gTakenDmg[gBankAttacker] * 2; + gBankTarget = gTakenDmgBanks[gBankAttacker]; + if (gAbsentBankFlags & gBitTable[gBankTarget]) + gBankTarget = sub_801B5C0(MOVE_BIDE, 1); + gBattlescriptCurrInstr = gUnknown_081D90B2; + } + else + gBattlescriptCurrInstr = gUnknown_081D90F1; + } + effect = 1; + } + BATTLE_STRUCT->atkCancellerTracker++; + break; + case 13: // move thawing + if (gBattleMons[gBankAttacker].status1 & STATUS_FREEZE) + { + if (gBattleMoves[gCurrentMove].effect == EFFECT_THAW_HIT) + { + gBattleMons[gBankAttacker].status1 &= ~(STATUS_FREEZE); + b_movescr_stack_push_cursor(); + gBattlescriptCurrInstr = gUnknown_081D9552; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + effect = 2; + } + BATTLE_STRUCT->atkCancellerTracker++; + break; + case 14: // last case + break; + } + + } while (BATTLE_STRUCT->atkCancellerTracker != ATKCANCELLER_MAX_CASE && effect == 0); + + if (effect == 2) + { + gActiveBank = gBankAttacker; + EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1); + MarkBufferBankForExecution(gActiveBank); + } + return effect; +} + +*/ diff --git a/src/battle_4.c b/src/battle_4.c index ced5b9b8c..eb21d5e0f 100644 --- a/src/battle_4.c +++ b/src/battle_4.c @@ -95,7 +95,7 @@ extern u16 gUnknown_02024C4C[4]; //last used moves by banks, another one extern u8 gCurrentMoveTurn; //extern functions -bool8 CantUseMove(void); +u8 AtkCanceller_UnableToUseMove(void); void PressurePPLose(u8 bank_atk, u8 bank_def, u16 move); void CancelMultiTurnMoves(u8 bank); void b_movescr_stack_push(u8* BS_ptr); @@ -223,18 +223,6 @@ extern u8 gUnknown_081D95DB[]; //bs payday money give #define BS2ScriptRead16(ptr) ((ptr)[0] + ((ptr)[1] << 8)) #define BS2ScriptReadPtr(ptr) ((void *)BS2ScriptRead32(ptr)) - -#define MOVESTATUS_MISSED (1 << 0) -#define MOVESTATUS_SUPEREFFECTIVE (1 << 1) -#define MOVESTATUS_NOTVERYEFFECTIVE (1 << 2) -#define MOVESTATUS_NOTAFFECTED (1 << 3) -#define MOVESTATUS_ONEHITKO (1 << 4) -#define MOVESTATUS_FAILED (1 << 5) -#define MOVESTATUS_ENDURED (1 << 6) -#define MOVESTATUS_HUNGON (1 << 7) - -#define MOVESTATUS_NOEFFECT ((MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED | MOVESTATUS_FAILED)) - #define TargetProtectAffected ((gProtectStructs[gBankTarget].protected && gBattleMoves[gCurrentMove].flags & FLAG_PROTECT_AFFECTED)) //array entries for battle communication @@ -1050,11 +1038,11 @@ static void atk00_attackcanceler(void) } if (gBattleMons[gBankAttacker].hp == 0 && !(gHitMarker & HITMARKER_NO_ATTACKSTRING)) { - gHitMarker |= HITMARKER_x80000; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; gBattlescriptCurrInstr = BattleScript_EndTurn; return; } - if (CantUseMove()) + if (AtkCanceller_UnableToUseMove()) return; if (AbilityBattleEffects(2, gBankTarget, 0, 0, 0)) return; |