mirror of
https://github.com/rh-hideout/pokeemerald-expansion
synced 2025-10-06 03:32:43 +02:00
Improved logic for Guard Split and Power Split. (#7298)
This commit is contained in:
@@ -79,4 +79,10 @@
|
||||
#define FRIENDLY_FIRE_NORMAL_THRESHOLD 3
|
||||
#define FRIENDLY_FIRE_CONSERVATIVE_THRESHOLD 4
|
||||
|
||||
// AI's desired stat changes for Guard Split and Power Split, treated as %
|
||||
#define GUARD_SPLIT_ALLY_PERCENTAGE 200
|
||||
#define GUARD_SPLIT_ENEMY_PERCENTAGE 50
|
||||
#define POWER_SPLIT_ALLY_PERCENTAGE 150
|
||||
#define POWER_SPLIT_ENEMY_PERCENTAGE 50
|
||||
|
||||
#endif // GUARD_CONFIG_AI_H
|
||||
|
@@ -2455,11 +2455,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
}
|
||||
break;
|
||||
case EFFECT_POWER_SPLIT:
|
||||
if (IsTargetingPartner(battlerAtk, battlerDef))
|
||||
{
|
||||
ADJUST_SCORE(-10);
|
||||
}
|
||||
else
|
||||
if (!IsTargetingPartner(battlerAtk, battlerDef))
|
||||
{
|
||||
u32 atkAttack = gBattleMons[battlerAtk].attack;
|
||||
u32 defAttack = gBattleMons[battlerDef].attack;
|
||||
@@ -2472,11 +2468,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
}
|
||||
break;
|
||||
case EFFECT_GUARD_SPLIT:
|
||||
if (IsTargetingPartner(battlerAtk, battlerDef))
|
||||
{
|
||||
ADJUST_SCORE(-10);
|
||||
}
|
||||
else
|
||||
if (!IsTargetingPartner(battlerAtk, battlerDef))
|
||||
{
|
||||
u32 atkDefense = gBattleMons[battlerAtk].defense;
|
||||
u32 defDefense = gBattleMons[battlerDef].defense;
|
||||
@@ -3530,6 +3522,55 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
&& gBattleMons[battlerAtkPartner].hp < gBattleMons[battlerAtkPartner].maxHP / 2)
|
||||
RETURN_SCORE_PLUS(WEAK_EFFECT);
|
||||
break;
|
||||
case EFFECT_SPEED_SWAP:
|
||||
break;
|
||||
case EFFECT_GUARD_SPLIT:
|
||||
{
|
||||
u32 atkDefense = gBattleMons[battlerAtk].defense;
|
||||
u32 defDefense = gBattleMons[battlerDef].defense;
|
||||
u32 atkSpDefense = gBattleMons[battlerAtk].spDefense;
|
||||
u32 defSpDefense = gBattleMons[battlerDef].spDefense;
|
||||
|
||||
// It's actually * 100 and / 2
|
||||
u32 newDefense = (atkDefense + defDefense) * 50;
|
||||
u32 newSpDefense = (atkSpDefense + defSpDefense) * 50;
|
||||
|
||||
// We want to massively raise our defense.
|
||||
if (newDefense > atkDefense * GUARD_SPLIT_ALLY_PERCENTAGE)
|
||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||
if (newSpDefense > atkSpDefense * GUARD_SPLIT_ALLY_PERCENTAGE)
|
||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||
if (newDefense > defDefense * GUARD_SPLIT_ALLY_PERCENTAGE)
|
||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||
if (newSpDefense > defSpDefense * GUARD_SPLIT_ALLY_PERCENTAGE)
|
||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||
|
||||
ADJUST_SCORE(WORST_EFFECT);
|
||||
break;
|
||||
}
|
||||
case EFFECT_POWER_SPLIT:
|
||||
{
|
||||
u32 atkAttack = gBattleMons[battlerAtk].attack;
|
||||
u32 defAttack = gBattleMons[battlerDef].attack;
|
||||
u32 atkSpAttack = gBattleMons[battlerAtk].spAttack;
|
||||
u32 defSpAttack = gBattleMons[battlerDef].spAttack;
|
||||
|
||||
// * 100 and / 2
|
||||
u32 newAttack = (atkAttack + defAttack) * 50;
|
||||
u32 newSpAtk = (atkSpAttack + defSpAttack) * 50;
|
||||
|
||||
if (HasMoveWithCategory(battlerAtk, DAMAGE_CATEGORY_PHYSICAL) && newAttack > atkAttack * POWER_SPLIT_ALLY_PERCENTAGE)
|
||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||
if (HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_PHYSICAL) && newAttack > defAttack * POWER_SPLIT_ALLY_PERCENTAGE)
|
||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||
if (HasMoveWithCategory(battlerAtk, DAMAGE_CATEGORY_SPECIAL) && newSpAtk > atkSpAttack * POWER_SPLIT_ALLY_PERCENTAGE)
|
||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||
if (HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_SPECIAL) && newSpAtk > defSpAttack * POWER_SPLIT_ALLY_PERCENTAGE)
|
||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||
|
||||
ADJUST_SCORE(WORST_EFFECT);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
} // attacker move effects
|
||||
@@ -4721,26 +4762,54 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
if (gBattleMons[battlerDef].speed > gBattleMons[battlerAtk].speed)
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
case EFFECT_GUARD_SPLIT:
|
||||
{
|
||||
u32 newDefense = (gBattleMons[battlerAtk].defense + gBattleMons[battlerDef].defense) / 2;
|
||||
u32 newSpDef = (gBattleMons[battlerAtk].spDefense + gBattleMons[battlerDef].spDefense) / 2;
|
||||
case EFFECT_GUARD_SPLIT:
|
||||
{
|
||||
u32 atkDefense = gBattleMons[battlerAtk].defense;
|
||||
u32 defDefense = gBattleMons[battlerDef].defense;
|
||||
u32 atkSpDefense = gBattleMons[battlerAtk].spDefense;
|
||||
u32 defSpDefense = gBattleMons[battlerDef].spDefense;
|
||||
|
||||
if ((newDefense > gBattleMons[battlerAtk].defense && newSpDef >= gBattleMons[battlerAtk].spDefense)
|
||||
|| (newSpDef > gBattleMons[battlerAtk].spDefense && newDefense >= gBattleMons[battlerAtk].defense))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
}
|
||||
// It's actually * 100 and / 2;
|
||||
u32 newDefense = (atkDefense + defDefense) * 50;
|
||||
u32 newSpDefense = (atkSpDefense + defSpDefense) * 50;
|
||||
|
||||
// We want to massively raise our defense.
|
||||
if (newDefense > atkDefense * GUARD_SPLIT_ALLY_PERCENTAGE)
|
||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||
if (newSpDefense > atkSpDefense * GUARD_SPLIT_ALLY_PERCENTAGE)
|
||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||
|
||||
// We also want to massively lower theirs.
|
||||
if (newDefense < defDefense * GUARD_SPLIT_ENEMY_PERCENTAGE)
|
||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||
if (newSpDefense < defSpDefense * GUARD_SPLIT_ENEMY_PERCENTAGE)
|
||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||
|
||||
ADJUST_SCORE(WORST_EFFECT);
|
||||
break;
|
||||
}
|
||||
case EFFECT_POWER_SPLIT:
|
||||
{
|
||||
u32 newAttack = (gBattleMons[battlerAtk].attack + gBattleMons[battlerDef].attack) / 2;
|
||||
u32 newSpAtk = (gBattleMons[battlerAtk].spAttack + gBattleMons[battlerDef].spAttack) / 2;
|
||||
{
|
||||
u32 atkAttack = gBattleMons[battlerAtk].attack;
|
||||
u32 defAttack = gBattleMons[battlerDef].attack;
|
||||
u32 atkSpAttack = gBattleMons[battlerAtk].spAttack;
|
||||
u32 defSpAttack = gBattleMons[battlerDef].spAttack;
|
||||
|
||||
if ((newAttack > gBattleMons[battlerAtk].attack && newSpAtk >= gBattleMons[battlerAtk].spAttack)
|
||||
|| (newSpAtk > gBattleMons[battlerAtk].spAttack && newAttack >= gBattleMons[battlerAtk].attack))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
}
|
||||
break;
|
||||
// It's actually * 100 and / 2
|
||||
u32 newAttack = (atkAttack + defAttack) * 50;
|
||||
u32 newSpAtk = (atkSpAttack + defSpAttack) * 50;
|
||||
|
||||
if (HasMoveWithCategory(battlerAtk, DAMAGE_CATEGORY_PHYSICAL) && newAttack > atkAttack * POWER_SPLIT_ALLY_PERCENTAGE)
|
||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||
if (HasMoveWithCategory(battlerAtk, DAMAGE_CATEGORY_SPECIAL) && newSpAtk > atkSpAttack * POWER_SPLIT_ALLY_PERCENTAGE)
|
||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||
if (newAttack < defAttack * POWER_SPLIT_ENEMY_PERCENTAGE)
|
||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||
if (newSpAtk < defSpAttack * POWER_SPLIT_ENEMY_PERCENTAGE)
|
||||
ADJUST_AND_RETURN_SCORE(GOOD_EFFECT);
|
||||
|
||||
ADJUST_SCORE(WORST_EFFECT);
|
||||
}
|
||||
case EFFECT_ELECTRIC_TERRAIN:
|
||||
case EFFECT_MISTY_TERRAIN:
|
||||
if (gStatuses3[battlerAtk] & STATUS3_YAWN && IsBattlerGrounded(battlerAtk))
|
||||
|
@@ -410,3 +410,57 @@ AI_DOUBLE_BATTLE_TEST("AI prioritizes Skill Swapping Contrary to allied mons tha
|
||||
}
|
||||
}
|
||||
|
||||
AI_DOUBLE_BATTLE_TEST("AI uses Guard Split to improve its stats")
|
||||
{
|
||||
|
||||
u32 player, opponent;
|
||||
|
||||
PARAMETRIZE { player = SPECIES_SHUCKLE; opponent = SPECIES_PHEROMOSA; }
|
||||
PARAMETRIZE { player = SPECIES_PHEROMOSA; opponent = SPECIES_SHUCKLE; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_GUARD_SPLIT) == EFFECT_GUARD_SPLIT);
|
||||
ASSUME(gSpeciesInfo[SPECIES_PHEROMOSA].baseDefense < gSpeciesInfo[SPECIES_WOBBUFFET].baseDefense);
|
||||
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].baseDefense < gSpeciesInfo[SPECIES_SHUCKLE].baseDefense);
|
||||
ASSUME(gSpeciesInfo[SPECIES_PHEROMOSA].baseSpDefense < gSpeciesInfo[SPECIES_WOBBUFFET].baseSpDefense);
|
||||
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].baseSpDefense < gSpeciesInfo[SPECIES_SHUCKLE].baseSpDefense);
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_DOUBLE_BATTLE);
|
||||
PLAYER(player);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_GUARD_SPLIT, MOVE_NIGHT_SHADE); }
|
||||
OPPONENT(opponent);
|
||||
} WHEN {
|
||||
if (player == SPECIES_SHUCKLE)
|
||||
TURN { EXPECT_MOVE(opponentLeft, MOVE_GUARD_SPLIT, target:playerLeft); }
|
||||
else
|
||||
TURN { EXPECT_MOVE(opponentLeft, MOVE_GUARD_SPLIT, target:opponentRight); }
|
||||
}
|
||||
}
|
||||
|
||||
AI_DOUBLE_BATTLE_TEST("AI uses Power Split to improve its stats")
|
||||
{
|
||||
|
||||
u32 player, opponent;
|
||||
|
||||
PARAMETRIZE { player = SPECIES_SHUCKLE; opponent = SPECIES_PHEROMOSA; }
|
||||
PARAMETRIZE { player = SPECIES_PHEROMOSA; opponent = SPECIES_SHUCKLE; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_POWER_SPLIT) == EFFECT_POWER_SPLIT);
|
||||
ASSUME(gSpeciesInfo[SPECIES_PHEROMOSA].baseAttack > gSpeciesInfo[SPECIES_WOBBUFFET].baseAttack);
|
||||
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].baseAttack > gSpeciesInfo[SPECIES_SHUCKLE].baseAttack);
|
||||
ASSUME(gSpeciesInfo[SPECIES_PHEROMOSA].baseSpAttack > gSpeciesInfo[SPECIES_WOBBUFFET].baseSpAttack);
|
||||
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].baseSpAttack > gSpeciesInfo[SPECIES_SHUCKLE].baseSpAttack);
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_DOUBLE_BATTLE);
|
||||
PLAYER(player);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_POWER_SPLIT, MOVE_TACKLE, MOVE_ROUND); }
|
||||
OPPONENT(opponent) { Moves(MOVE_TACKLE, MOVE_ROUND); }
|
||||
} WHEN {
|
||||
if (player == SPECIES_PHEROMOSA)
|
||||
TURN { EXPECT_MOVE(opponentLeft, MOVE_POWER_SPLIT, target:playerLeft); }
|
||||
else
|
||||
TURN { EXPECT_MOVE(opponentLeft, MOVE_POWER_SPLIT, target:opponentRight); }
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user