From 6f484c20ce2bd54918813bce386de97ec8246ff1 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Sun, 15 Jul 2018 18:07:01 +0200 Subject: [PATCH] Final ai damage calc touches --- include/battle.h | 9 +++ include/pokemon.h | 1 + src/battle_ai_script_commands.c | 122 +++++++++++++++++++++++++++++++- src/battle_util2.c | 2 - src/pokemon.c | 81 ++++++++++----------- 5 files changed, 170 insertions(+), 45 deletions(-) diff --git a/include/battle.h b/include/battle.h index 74b2e5095b..07ca708def 100644 --- a/include/battle.h +++ b/include/battle.h @@ -275,6 +275,14 @@ struct WishFutureKnock u8 knockedOffPokes[2]; }; +struct AI_SavedBattleMon +{ + u8 ability; + u16 moves[4]; + u16 heldItem; + u16 species; +}; + struct AI_ThinkingStruct { u8 aiState; @@ -287,6 +295,7 @@ struct AI_ThinkingStruct u8 aiLogicId; u8 filler12[6]; u8 simulatedRNG[4]; + struct AI_SavedBattleMon saved[4]; }; struct UsedMoves diff --git a/include/pokemon.h b/include/pokemon.h index 16829bdb58..5d34106c1f 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -529,6 +529,7 @@ void GetSpeciesName(u8 *name, u16 species); u8 CalculatePPWithBonus(u16 move, u8 ppBonuses, u8 moveIndex); void RemoveMonPPBonus(struct Pokemon *mon, u8 moveIndex); void RemoveBattleMonPPBonus(struct BattlePokemon *mon, u8 moveIndex); +void PokemonToBattleMon(struct Pokemon *src, struct BattlePokemon *dst); void CopyPlayerPartyMonToBattleData(u8 battlerId, u8 partyIndex); bool8 ExecuteTableBasedItemEffect(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex); bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex, u8 e); diff --git a/src/battle_ai_script_commands.c b/src/battle_ai_script_commands.c index f8169e6cfb..c76beafb39 100644 --- a/src/battle_ai_script_commands.c +++ b/src/battle_ai_script_commands.c @@ -11,6 +11,7 @@ #include "constants/battle_move_effects.h" #include "constants/moves.h" #include "util.h" +#include "malloc.h" #include "constants/battle_ai.h" #define AI_ACTION_DONE 0x0001 @@ -624,6 +625,25 @@ static void RecordLastUsedMoveByTarget(void) } } +static bool8 IsBattlerAIControlled(u8 battlerId) +{ + switch (GetBattlerPosition(battlerId)) + { + case B_POSITION_PLAYER_LEFT: + default: + return FALSE; + case B_POSITION_OPPONENT_LEFT: + return TRUE; + case B_POSITION_PLAYER_RIGHT: + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) + return FALSE; + else + return TRUE; + case B_POSITION_OPPONENT_RIGHT: + return TRUE; + } +} + void ClearBattlerMoveHistory(u8 battlerId) { s32 i; @@ -652,19 +672,115 @@ void ClearBattlerItemEffectHistory(u8 battlerId) BATTLE_HISTORY->itemEffects[battlerId] = 0; } +static void SaveBattlerData(u8 battlerId) +{ + if (!IsBattlerAIControlled(battlerId)) + { + u32 i; + + AI_THINKING_STRUCT->saved[battlerId].ability = gBattleMons[battlerId].ability; + AI_THINKING_STRUCT->saved[battlerId].heldItem = gBattleMons[battlerId].item; + AI_THINKING_STRUCT->saved[battlerId].species = gBattleMons[battlerId].species; + for (i = 0; i < 4; i++) + AI_THINKING_STRUCT->saved[battlerId].moves[i] = gBattleMons[battlerId].moves[i]; + } +} + +static void SetBattlerData(u8 battlerId) +{ + if (!IsBattlerAIControlled(battlerId)) + { + u32 i; + + // Use the known battler's ability. + if (BATTLE_HISTORY->abilities[battlerId] != ABILITY_NONE) + gBattleMons[battlerId].ability = BATTLE_HISTORY->abilities[battlerId]; + // Check if mon can only have one ability. + else if (gBaseStats[gBattleMons[battlerId].species].ability2 == ABILITY_NONE) + gBattleMons[battlerId].ability = gBaseStats[gBattleMons[battlerId].species].ability1; + else + // The ability is unknown. + gBattleMons[battlerId].ability = ABILITY_NONE; + + if (BATTLE_HISTORY->itemEffects[battlerId] == 0) + gBattleMons[battlerId].item = 0; + + for (i = 0; i < 4; i++) + { + if (BATTLE_HISTORY->usedMoves[battlerId].moves[i] == 0) + gBattleMons[battlerId].moves[i] = 0; + } + } +} + +static void RestoreBattlerData(u8 battlerId) +{ + if (!IsBattlerAIControlled(battlerId)) + { + u32 i; + + gBattleMons[battlerId].ability = AI_THINKING_STRUCT->saved[battlerId].ability; + gBattleMons[battlerId].item = AI_THINKING_STRUCT->saved[battlerId].heldItem; + gBattleMons[battlerId].species = AI_THINKING_STRUCT->saved[battlerId].species; + for (i = 0; i < 4; i++) + gBattleMons[battlerId].moves[i] = AI_THINKING_STRUCT->saved[battlerId].moves[i]; + } +} + s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef) { - return CalculateMoveDamage(move, battlerAtk, battlerDef, gBattleMoves[move].type, 0, FALSE, FALSE); + s32 dmg; + + SaveBattlerData(battlerAtk); + SaveBattlerData(battlerDef); + + SetBattlerData(battlerAtk); + SetBattlerData(battlerDef); + + dmg = CalculateMoveDamage(move, battlerAtk, battlerDef, gBattleMoves[move].type, 0, FALSE, FALSE); + + RestoreBattlerData(battlerAtk); + RestoreBattlerData(battlerDef); + + return dmg; } s32 AI_CalcPartyMonDamage(u16 move, u8 battlerAtk, u8 battlerDef, struct Pokemon *mon) { - return 0; + s32 dmg; + u32 i; + struct BattlePokemon *battleMons = Alloc(sizeof(struct BattlePokemon) * MAX_BATTLERS_COUNT); + + for (i = 0; i < MAX_BATTLERS_COUNT; i++) + battleMons[i] = gBattleMons[i]; + + PokemonToBattleMon(mon, &gBattleMons[battlerAtk]); + dmg = AI_CalcDamage(move, battlerAtk, battlerDef); + + for (i = 0; i < MAX_BATTLERS_COUNT; i++) + gBattleMons[i] = battleMons[i]; + + Free(battleMons); + + return dmg; } u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef) { - return CalcTypeEffectivenessMultiplier(move, gBattleMoves[move].type, battlerAtk, battlerDef, FALSE); + u16 typeEffectiveness; + + SaveBattlerData(battlerAtk); + SaveBattlerData(battlerDef); + + SetBattlerData(battlerAtk); + SetBattlerData(battlerDef); + + typeEffectiveness = CalcTypeEffectivenessMultiplier(move, gBattleMoves[move].type, battlerAtk, battlerDef, FALSE); + + RestoreBattlerData(battlerAtk); + RestoreBattlerData(battlerDef); + + return typeEffectiveness; } static void BattleAICmd_if_random_less_than(void) diff --git a/src/battle_util2.c b/src/battle_util2.c index 1d2f1e95b4..a3800ffabd 100644 --- a/src/battle_util2.c +++ b/src/battle_util2.c @@ -17,8 +17,6 @@ extern void sub_81B8FB0(u8, u8); void AllocateBattleResources(void) { - gBattleResources = gBattleResources; // something dumb needed to match - if (gBattleTypeFlags & BATTLE_TYPE_x4000000) sub_81D55D0(); diff --git a/src/pokemon.c b/src/pokemon.c index f3b1b1fb3b..32ac2ea1dc 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -3420,57 +3420,58 @@ void RemoveBattleMonPPBonus(struct BattlePokemon *mon, u8 moveIndex) mon->ppBonuses &= gUnknown_08329D26[moveIndex]; } -void CopyPlayerPartyMonToBattleData(u8 battlerId, u8 partyIndex) +void PokemonToBattleMon(struct Pokemon *src, struct BattlePokemon *dst) { - u16* hpSwitchout; s32 i; u8 nickname[POKEMON_NAME_LENGTH * 2]; - gBattleMons[battlerId].species = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPECIES, NULL); - gBattleMons[battlerId].item = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HELD_ITEM, NULL); - for (i = 0; i < 4; i++) { - gBattleMons[battlerId].moves[i] = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MOVE1 + i, NULL); - gBattleMons[battlerId].pp[i] = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PP1 + i, NULL); + dst->moves[i] = GetMonData(src, MON_DATA_MOVE1 + i, NULL); + dst->pp[i] = GetMonData(src, MON_DATA_PP1 + i, NULL); } - gBattleMons[battlerId].ppBonuses = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PP_BONUSES, NULL); - gBattleMons[battlerId].friendship = GetMonData(&gPlayerParty[partyIndex], MON_DATA_FRIENDSHIP, NULL); - gBattleMons[battlerId].experience = GetMonData(&gPlayerParty[partyIndex], MON_DATA_EXP, NULL); - gBattleMons[battlerId].hpIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP_IV, NULL); - gBattleMons[battlerId].attackIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ATK_IV, NULL); - gBattleMons[battlerId].defenseIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_DEF_IV, NULL); - gBattleMons[battlerId].speedIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPEED_IV, NULL); - gBattleMons[battlerId].spAttackIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPATK_IV, NULL); - gBattleMons[battlerId].spDefenseIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPDEF_IV, NULL); - gBattleMons[battlerId].personality = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PERSONALITY, NULL); - gBattleMons[battlerId].status1 = GetMonData(&gPlayerParty[partyIndex], MON_DATA_STATUS, NULL); - gBattleMons[battlerId].level = GetMonData(&gPlayerParty[partyIndex], MON_DATA_LEVEL, NULL); - gBattleMons[battlerId].hp = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP, NULL); - gBattleMons[battlerId].maxHP = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MAX_HP, NULL); - gBattleMons[battlerId].attack = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ATK, NULL); - gBattleMons[battlerId].defense = GetMonData(&gPlayerParty[partyIndex], MON_DATA_DEF, NULL); - gBattleMons[battlerId].speed = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPEED, NULL); - gBattleMons[battlerId].spAttack = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPATK, NULL); - gBattleMons[battlerId].spDefense = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPDEF, NULL); - gBattleMons[battlerId].isEgg = GetMonData(&gPlayerParty[partyIndex], MON_DATA_IS_EGG, NULL); - gBattleMons[battlerId].altAbility = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ALT_ABILITY, NULL); - gBattleMons[battlerId].otId = GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_ID, NULL); - gBattleMons[battlerId].type1 = gBaseStats[gBattleMons[battlerId].species].type1; - gBattleMons[battlerId].type2 = gBaseStats[gBattleMons[battlerId].species].type2; - gBattleMons[battlerId].ability = GetAbilityBySpecies(gBattleMons[battlerId].species, gBattleMons[battlerId].altAbility); - GetMonData(&gPlayerParty[partyIndex], MON_DATA_NICKNAME, nickname); - StringCopy10(gBattleMons[battlerId].nickname, nickname); - GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_NAME, gBattleMons[battlerId].otName); + dst->species = GetMonData(src, MON_DATA_SPECIES, NULL); + dst->item = GetMonData(src, MON_DATA_HELD_ITEM, NULL); + dst->ppBonuses = GetMonData(src, MON_DATA_PP_BONUSES, NULL); + dst->friendship = GetMonData(src, MON_DATA_FRIENDSHIP, NULL); + dst->experience = GetMonData(src, MON_DATA_EXP, NULL); + dst->hpIV = GetMonData(src, MON_DATA_HP_IV, NULL); + dst->attackIV = GetMonData(src, MON_DATA_ATK_IV, NULL); + dst->defenseIV = GetMonData(src, MON_DATA_DEF_IV, NULL); + dst->speedIV = GetMonData(src, MON_DATA_SPEED_IV, NULL); + dst->spAttackIV = GetMonData(src, MON_DATA_SPATK_IV, NULL); + dst->spDefenseIV = GetMonData(src, MON_DATA_SPDEF_IV, NULL); + dst->personality = GetMonData(src, MON_DATA_PERSONALITY, NULL); + dst->status1 = GetMonData(src, MON_DATA_STATUS, NULL); + dst->level = GetMonData(src, MON_DATA_LEVEL, NULL); + dst->hp = GetMonData(src, MON_DATA_HP, NULL); + dst->maxHP = GetMonData(src, MON_DATA_MAX_HP, NULL); + dst->attack = GetMonData(src, MON_DATA_ATK, NULL); + dst->defense = GetMonData(src, MON_DATA_DEF, NULL); + dst->speed = GetMonData(src, MON_DATA_SPEED, NULL); + dst->spAttack = GetMonData(src, MON_DATA_SPATK, NULL); + dst->spDefense = GetMonData(src, MON_DATA_SPDEF, NULL); + dst->isEgg = GetMonData(src, MON_DATA_IS_EGG, NULL); + dst->altAbility = GetMonData(src, MON_DATA_ALT_ABILITY, NULL); + dst->otId = GetMonData(src, MON_DATA_OT_ID, NULL); + dst->type1 = gBaseStats[dst->species].type1; + dst->type2 = gBaseStats[dst->species].type2; + dst->ability = GetAbilityBySpecies(dst->species, dst->altAbility); + GetMonData(src, MON_DATA_NICKNAME, nickname); + StringCopy10(dst->nickname, nickname); + GetMonData(src, MON_DATA_OT_NAME, dst->otName); - hpSwitchout = &gBattleStruct->hpOnSwitchout[GetBattlerSide(battlerId)]; - *hpSwitchout = gBattleMons[battlerId].hp; + for (i = 0; i < BATTLE_STATS_NO; i++) + dst->statStages[i] = 6; - for (i = 0; i < 8; i++) - gBattleMons[battlerId].statStages[i] = 6; + dst->status2 = 0; +} - gBattleMons[battlerId].status2 = 0; +void CopyPlayerPartyMonToBattleData(u8 battlerId, u8 partyIndex) +{ + PokemonToBattleMon(&gPlayerParty[partyIndex], &gBattleMons[battlerId]); + gBattleStruct->hpOnSwitchout[GetBattlerSide(battlerId)] = gBattleMons[battlerId].hp; sub_803FA70(battlerId); ClearTemporarySpeciesSpriteData(battlerId, FALSE); }