Final ai damage calc touches

This commit is contained in:
DizzyEggg 2018-07-15 18:07:01 +02:00
parent 967117093d
commit 6f484c20ce
5 changed files with 170 additions and 45 deletions

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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();

View File

@ -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);
}