Remove powerfulMoveEffects array (#3515)
* Remove powerfulMoveEffects array * Solar Beam test
This commit is contained in:
parent
244ca0be95
commit
53b7e4bf66
4 changed files with 84 additions and 87 deletions
|
@ -91,7 +91,6 @@ bool32 AI_IsDamagedByRecoil(u32 battler);
|
|||
u32 GetNoOfHitsToKO(u32 dmg, s32 hp);
|
||||
u32 GetNoOfHitsToKOBattlerDmg(u32 dmg, u32 battlerDef);
|
||||
u32 GetNoOfHitsToKOBattler(u32 battlerAtk, u32 battlerDef, u32 moveIndex);
|
||||
bool32 IsInIgnoredPowerfulMoveEffects(u32 effect);
|
||||
void SetMovesDamageResults(u32 battlerAtk, u16 *moves);
|
||||
u32 GetMoveDamageResult(u32 battlerAtk, u32 battlerDef, u32 moveIndex);
|
||||
u32 GetCurrDamageHpPercent(u32 battlerAtk, u32 battlerDef);
|
||||
|
@ -113,6 +112,7 @@ bool32 IsMoveRedirectionPrevented(u32 move, u32 atkAbility);
|
|||
bool32 IsMoveEncouragedToHit(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
bool32 IsHazardMoveEffect(u32 moveEffect);
|
||||
bool32 IsEncoreEncouragedEffect(u32 moveEffect);
|
||||
bool32 IsChargingMove(u32 battlerAtk, u32 effect);
|
||||
void ProtectChecks(u32 battlerAtk, u32 battlerDef, u32 move, u32 predictedMove, s32 *score);
|
||||
bool32 ShouldSetSandstorm(u32 battler, u32 ability, u32 holdEffect);
|
||||
bool32 ShouldSetHail(u32 battler, u32 ability, u32 holdEffect);
|
||||
|
|
|
@ -760,6 +760,9 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
if (IsSemiInvulnerable(battlerDef, move) && moveEffect != EFFECT_SEMI_INVULNERABLE && AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_FASTER)
|
||||
RETURN_SCORE_MINUS(20); // if target off screen and we go first, don't use move
|
||||
|
||||
if (IsChargingMove(battlerAtk, moveEffect) && CanTargetFaintAi(battlerDef, battlerAtk))
|
||||
RETURN_SCORE_MINUS(10);
|
||||
|
||||
// check if negates type
|
||||
switch (effectiveness)
|
||||
{
|
||||
|
@ -1356,22 +1359,13 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
}
|
||||
break;
|
||||
//case EFFECT_BIDE:
|
||||
//case EFFECT_SUPER_FANG:
|
||||
//case EFFECT_RECHARGE:
|
||||
case EFFECT_LEVEL_DAMAGE:
|
||||
case EFFECT_PSYWAVE:
|
||||
//case EFFECT_COUNTER:
|
||||
//case EFFECT_FLAIL:
|
||||
case EFFECT_RETURN:
|
||||
case EFFECT_PRESENT:
|
||||
case EFFECT_FRUSTRATION:
|
||||
case EFFECT_SONICBOOM:
|
||||
//case EFFECT_MIRROR_COAT:
|
||||
case EFFECT_SKULL_BASH:
|
||||
case EFFECT_FOCUS_PUNCH:
|
||||
case EFFECT_SUPERPOWER:
|
||||
//case EFFECT_ENDEAVOR:
|
||||
case EFFECT_LOW_KICK:
|
||||
// AI_CBM_HighRiskForDamage
|
||||
if (aiData->abilities[battlerDef] == ABILITY_WONDER_GUARD && effectiveness < AI_EFFECTIVENESS_x2)
|
||||
ADJUST_SCORE(-10);
|
||||
|
@ -1906,17 +1900,6 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
|| (gBattleMons[battlerDef].status2 & (STATUS2_TRANSFORMED | STATUS2_SUBSTITUTE))) //Leave out Illusion b/c AI is supposed to be fooled
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_TWO_TURNS_ATTACK:
|
||||
if (aiData->holdEffects[battlerAtk] != HOLD_EFFECT_POWER_HERB && CanTargetFaintAi(battlerDef, battlerAtk))
|
||||
ADJUST_SCORE(-6);
|
||||
break;
|
||||
case EFFECT_RECHARGE:
|
||||
if (aiData->abilities[battlerDef] == ABILITY_WONDER_GUARD && effectiveness < AI_EFFECTIVENESS_x2)
|
||||
ADJUST_SCORE(-10);
|
||||
else if (aiData->abilities[battlerAtk] != ABILITY_TRUANT
|
||||
&& !CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
|
||||
ADJUST_SCORE(-2);
|
||||
break;
|
||||
case EFFECT_SPITE:
|
||||
case EFFECT_MIMIC:
|
||||
if (AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_FASTER) // Attacker should go first
|
||||
|
@ -2109,13 +2092,6 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
break;
|
||||
case EFFECT_SPECTRAL_THIEF:
|
||||
break;
|
||||
case EFFECT_SOLAR_BEAM:
|
||||
if (aiData->holdEffects[battlerAtk] == HOLD_EFFECT_POWER_HERB
|
||||
|| ((AI_GetWeather(aiData) & B_WEATHER_SUN) && aiData->holdEffects[battlerAtk] != HOLD_EFFECT_UTILITY_UMBRELLA))
|
||||
break;
|
||||
if (CanTargetFaintAi(battlerDef, battlerAtk)) //Attacker can be knocked out
|
||||
ADJUST_SCORE(-4);
|
||||
break;
|
||||
case EFFECT_SEMI_INVULNERABLE:
|
||||
if (predictedMove != MOVE_NONE
|
||||
&& AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_SLOWER
|
||||
|
@ -2674,6 +2650,10 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
&& !BattlerStatCanRise(battlerAtk, aiData->abilities[battlerAtk], STAT_SPDEF))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_LOW_KICK:
|
||||
if (IsDynamaxed(battlerDef))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_PLACEHOLDER:
|
||||
return 0; // cannot even select
|
||||
} // move effect checks
|
||||
|
@ -3151,7 +3131,7 @@ static s32 AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef, u32 currId)
|
|||
s32 score = 0;
|
||||
s32 leastHits = 1000;
|
||||
u16 *moves = GetMovesArray(battlerAtk);
|
||||
bool8 isPowerfulIgnoredEffect[MAX_MON_MOVES];
|
||||
bool8 isChargingMoveEffect[MAX_MON_MOVES];
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
|
@ -3163,13 +3143,13 @@ static s32 AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef, u32 currId)
|
|||
leastHits = noOfHits[i];
|
||||
}
|
||||
viableMoveScores[i] = AI_SCORE_DEFAULT;
|
||||
isPowerfulIgnoredEffect[i] = IsInIgnoredPowerfulMoveEffects(gBattleMoves[moves[i]].effect);
|
||||
isChargingMoveEffect[i] = IsChargingMove(battlerAtk, gBattleMoves[moves[i]].effect);
|
||||
}
|
||||
else
|
||||
{
|
||||
noOfHits[i] = -1;
|
||||
viableMoveScores[i] = 0;
|
||||
isPowerfulIgnoredEffect[i] = FALSE;
|
||||
isChargingMoveEffect[i] = FALSE;
|
||||
}
|
||||
/*
|
||||
MgbaPrintf_("%S: required hits: %d Dmg: %d", gMoveNames[moves[i]], noOfHits[i], AI_DATA->simulatedDmg[battlerAtk][battlerDef][i]);
|
||||
|
@ -3178,7 +3158,7 @@ static s32 AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef, u32 currId)
|
|||
|
||||
// Priority list:
|
||||
// 1. Less no of hits to ko
|
||||
// 2. Not in the powerful but ignored move effects table
|
||||
// 2. Not charging
|
||||
// 3. More accuracy
|
||||
// 4. Better effect
|
||||
|
||||
|
@ -3193,9 +3173,9 @@ static s32 AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef, u32 currId)
|
|||
{
|
||||
multipleBestMoves = TRUE;
|
||||
// We need to make sure it's the current move which is objectively better.
|
||||
if (isPowerfulIgnoredEffect[i] && !isPowerfulIgnoredEffect[currId])
|
||||
if (isChargingMoveEffect[i] && !isChargingMoveEffect[currId])
|
||||
viableMoveScores[i] -= 3;
|
||||
else if (!isPowerfulIgnoredEffect[i] && isPowerfulIgnoredEffect[currId])
|
||||
else if (!isChargingMoveEffect[i] && isChargingMoveEffect[currId])
|
||||
viableMoveScores[currId] -= 3;
|
||||
|
||||
switch (CompareMoveAccuracies(battlerAtk, battlerDef, currId, i))
|
||||
|
@ -4847,15 +4827,6 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score
|
|||
IncreasePoisonScore(battlerAtk, battlerDef, move, &score);
|
||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPEED, &score);
|
||||
break;
|
||||
case EFFECT_SOLAR_BEAM:
|
||||
if (GetNoOfHitsToKOBattler(battlerAtk, battlerDef, movesetIndex) >= 2
|
||||
&& HasMoveEffect(battlerAtk, EFFECT_SUNNY_DAY) && (AI_GetWeather(aiData) & B_WEATHER_SUN)) // Use Sunny Day to boost damage.
|
||||
ADJUST_SCORE(-3);
|
||||
case EFFECT_TWO_TURNS_ATTACK:
|
||||
case EFFECT_SKULL_BASH:
|
||||
if (aiData->holdEffects[battlerAtk] == HOLD_EFFECT_POWER_HERB)
|
||||
ADJUST_SCORE(2);
|
||||
break;
|
||||
case EFFECT_COUNTER:
|
||||
if (!IsBattlerIncapacitated(battlerDef, aiData->abilities[battlerDef]) && predictedMove != MOVE_NONE)
|
||||
{
|
||||
|
@ -5246,9 +5217,6 @@ static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
case EFFECT_BELLY_DRUM:
|
||||
case EFFECT_PSYCH_UP:
|
||||
case EFFECT_MIRROR_COAT:
|
||||
case EFFECT_SOLAR_BEAM:
|
||||
case EFFECT_TWO_TURNS_ATTACK:
|
||||
case EFFECT_ERUPTION:
|
||||
case EFFECT_TICKLE:
|
||||
case EFFECT_SUNNY_DAY:
|
||||
case EFFECT_SANDSTORM:
|
||||
|
|
|
@ -363,25 +363,6 @@ static const u16 sEncouragedEncoreEffects[] =
|
|||
EFFECT_CAMOUFLAGE,
|
||||
};
|
||||
|
||||
// For the purposes of determining the most powerful move in a moveset, these
|
||||
// moves are treated the same as having a power of 0 or 1
|
||||
#define IGNORED_MOVES_END 0xFFFF
|
||||
static const u16 sIgnoredPowerfulMoveEffects[] =
|
||||
{
|
||||
EFFECT_EXPLOSION,
|
||||
EFFECT_DREAM_EATER,
|
||||
EFFECT_RECHARGE,
|
||||
EFFECT_SKULL_BASH,
|
||||
EFFECT_SOLAR_BEAM,
|
||||
EFFECT_FOCUS_PUNCH,
|
||||
EFFECT_SUPERPOWER,
|
||||
EFFECT_ERUPTION,
|
||||
EFFECT_OVERHEAT,
|
||||
EFFECT_MIND_BLOWN,
|
||||
EFFECT_MAKE_IT_RAIN,
|
||||
IGNORED_MOVES_END
|
||||
};
|
||||
|
||||
// Functions
|
||||
u32 GetAIChosenMove(u32 battlerId)
|
||||
{
|
||||
|
@ -980,6 +961,11 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
|
|||
switch (gBattleMoves[move].effect)
|
||||
{
|
||||
case EFFECT_RECHARGE:
|
||||
case EFFECT_SUPERPOWER:
|
||||
case EFFECT_OVERHEAT:
|
||||
case EFFECT_MAKE_IT_RAIN:
|
||||
case EFFECT_MIND_BLOWN:
|
||||
case EFFECT_STEEL_BEAM:
|
||||
return TRUE;
|
||||
case EFFECT_RECOIL_25:
|
||||
case EFFECT_RECOIL_IF_MISS:
|
||||
|
@ -1054,22 +1040,6 @@ u32 GetNoOfHitsToKOBattler(u32 battlerAtk, u32 battlerDef, u32 moveIndex)
|
|||
return GetNoOfHitsToKOBattlerDmg(AI_DATA->simulatedDmg[battlerAtk][battlerDef][moveIndex], battlerDef);
|
||||
}
|
||||
|
||||
bool32 IsInIgnoredPowerfulMoveEffects(u32 effect)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; sIgnoredPowerfulMoveEffects[i] != IGNORED_MOVES_END; i++)
|
||||
{
|
||||
if (effect == sIgnoredPowerfulMoveEffects[i])
|
||||
{
|
||||
// Don't ingore Solar Beam if doesn't have a charging turn.
|
||||
if (effect == EFFECT_SOLAR_BEAM && (AI_GetWeather(AI_DATA) & B_WEATHER_SUN))
|
||||
break;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void SetMovesDamageResults(u32 battlerAtk, u16 *moves)
|
||||
{
|
||||
s32 i, j, battlerDef, bestId, currId, hp, result;
|
||||
|
@ -1079,7 +1049,7 @@ void SetMovesDamageResults(u32 battlerAtk, u16 *moves)
|
|||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
u32 move = moves[i];
|
||||
if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || gBattleMoves[move].power == 0 || IsInIgnoredPowerfulMoveEffects(gBattleMoves[move].effect))
|
||||
if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || gBattleMoves[move].power == 0)
|
||||
isNotConsidered[i] = TRUE;
|
||||
else
|
||||
isNotConsidered[i] = FALSE;
|
||||
|
@ -1094,11 +1064,10 @@ void SetMovesDamageResults(u32 battlerAtk, u16 *moves)
|
|||
|
||||
if (isNotConsidered[i])
|
||||
{
|
||||
result = MOVE_POWER_OTHER; // Move has a power of 0/1, or is in the group sIgnoredPowerfulMoveEffects
|
||||
result = MOVE_POWER_OTHER; // Move has a power of 0/1
|
||||
}
|
||||
else
|
||||
{
|
||||
// Considered move has power and is not in sIgnoredPowerfulMoveEffects
|
||||
// Check all other moves and calculate their power
|
||||
for (j = 0; j < MAX_MON_MOVES; j++)
|
||||
{
|
||||
|
@ -2394,6 +2363,24 @@ bool32 IsEncoreEncouragedEffect(u32 moveEffect)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsChargingMove(u32 battlerAtk, u32 effect)
|
||||
{
|
||||
switch (effect)
|
||||
{
|
||||
case EFFECT_SOLAR_BEAM:
|
||||
if (AI_GetWeather(AI_DATA) & B_WEATHER_SUN)
|
||||
return FALSE;
|
||||
case EFFECT_SKULL_BASH:
|
||||
case EFFECT_METEOR_BEAM:
|
||||
case EFFECT_TWO_TURNS_ATTACK:
|
||||
if (AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_POWER_HERB)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static u32 GetLeechSeedDamage(u32 battlerId)
|
||||
{
|
||||
u32 damage = 0;
|
||||
|
|
|
@ -260,8 +260,8 @@ AI_SINGLE_BATTLE_TEST("AI can choose a status move that boosts the attack by two
|
|||
AI_SINGLE_BATTLE_TEST("AI chooses the safest option to faint the target, taking into account accuracy and move effect")
|
||||
{
|
||||
u16 move1 = MOVE_NONE, move2 = MOVE_NONE, move3 = MOVE_NONE, move4 = MOVE_NONE;
|
||||
u16 expectedMove, abilityAtk = ABILITY_NONE;
|
||||
u16 expectedMove2 = MOVE_NONE;
|
||||
u16 expectedMove, expectedMove2 = MOVE_NONE;
|
||||
u16 abilityAtk = ABILITY_NONE, holdItemAtk = ITEM_NONE;
|
||||
|
||||
// Psychic is not very effective, but always hits. Solarbeam requires a charging turn, Double Edge has recoil and Focus Blast can miss;
|
||||
PARAMETRIZE { abilityAtk = ABILITY_STURDY; move1 = MOVE_FOCUS_BLAST; move2 = MOVE_SOLAR_BEAM; move3 = MOVE_PSYCHIC; move4 = MOVE_DOUBLE_EDGE; expectedMove = MOVE_PSYCHIC; }
|
||||
|
@ -272,12 +272,24 @@ AI_SINGLE_BATTLE_TEST("AI chooses the safest option to faint the target, taking
|
|||
// This time it's Solarbeam + Psychic, because the weather is sunny.
|
||||
PARAMETRIZE { abilityAtk = ABILITY_DROUGHT; move1 = MOVE_FOCUS_BLAST; move2 = MOVE_SOLAR_BEAM; move3 = MOVE_PSYCHIC; move4 = MOVE_DOUBLE_EDGE;
|
||||
expectedMove = MOVE_PSYCHIC; expectedMove2 = MOVE_SOLAR_BEAM; }
|
||||
// Psychic and Solar Beam are chosen because user is holding Power Herb
|
||||
PARAMETRIZE { abilityAtk = ABILITY_STURDY; holdItemAtk = ITEM_POWER_HERB; move1 = MOVE_FOCUS_BLAST; move2 = MOVE_SOLAR_BEAM; move3 = MOVE_PSYCHIC; move4 = MOVE_DOUBLE_EDGE;
|
||||
expectedMove = MOVE_PSYCHIC; expectedMove2 = MOVE_SOLAR_BEAM; }
|
||||
// Psychic and Skull Bash are chosen because user is holding Power Herb
|
||||
PARAMETRIZE { abilityAtk = ABILITY_STURDY; holdItemAtk = ITEM_POWER_HERB; move1 = MOVE_FOCUS_BLAST; move2 = MOVE_SKULL_BASH; move3 = MOVE_PSYCHIC; move4 = MOVE_DOUBLE_EDGE;
|
||||
expectedMove = MOVE_PSYCHIC; expectedMove2 = MOVE_SKULL_BASH; }
|
||||
// Skull Bash is chosen because it's the most accurate and is holding Power Herb
|
||||
PARAMETRIZE { abilityAtk = ABILITY_STURDY; holdItemAtk = ITEM_POWER_HERB; move1 = MOVE_FOCUS_BLAST; move2 = MOVE_SKULL_BASH; move3 = MOVE_SLAM; move4 = MOVE_DOUBLE_EDGE;
|
||||
expectedMove = MOVE_SKULL_BASH; }
|
||||
// Crabhammer is chosen even if Skull Bash is more accurate, the user has no Power Herb
|
||||
PARAMETRIZE { abilityAtk = ABILITY_STURDY; move1 = MOVE_FOCUS_BLAST; move2 = MOVE_SKULL_BASH; move3 = MOVE_SLAM; move4 = MOVE_CRABHAMMER;
|
||||
expectedMove = MOVE_CRABHAMMER; }
|
||||
|
||||
GIVEN {
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(5); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_GEODUDE) { Moves(move1, move2, move3, move4); Ability(abilityAtk); }
|
||||
OPPONENT(SPECIES_GEODUDE) { Moves(move1, move2, move3, move4); Ability(abilityAtk); Item(holdItemAtk); }
|
||||
} WHEN {
|
||||
TURN { if (expectedMove2 == MOVE_NONE) { EXPECT_MOVE(opponent, expectedMove); SEND_OUT(player, 1); }
|
||||
else {EXPECT_MOVES(opponent, expectedMove, expectedMove2); SCORE_EQ(opponent, expectedMove, expectedMove2); SEND_OUT(player, 1);}
|
||||
|
@ -288,6 +300,36 @@ AI_SINGLE_BATTLE_TEST("AI chooses the safest option to faint the target, taking
|
|||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI won't use Solar Beam if there is no Sun up or the user is not holding Power Herb")
|
||||
{
|
||||
u16 abilityAtk = ABILITY_NONE;
|
||||
u16 holdItemAtk = ITEM_NONE;
|
||||
|
||||
PARAMETRIZE { abilityAtk = ABILITY_DROUGHT; }
|
||||
PARAMETRIZE { holdItemAtk = ITEM_POWER_HERB; }
|
||||
PARAMETRIZE { }
|
||||
|
||||
GIVEN {
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(211); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_TYPHLOSION) { Moves(MOVE_SOLAR_BEAM, MOVE_GRASS_PLEDGE); Ability(abilityAtk); Item(holdItemAtk); }
|
||||
} WHEN {
|
||||
if (abilityAtk == ABILITY_DROUGHT) {
|
||||
TURN { EXPECT_MOVES(opponent, MOVE_SOLAR_BEAM, MOVE_GRASS_PLEDGE); }
|
||||
TURN { EXPECT_MOVES(opponent, MOVE_SOLAR_BEAM, MOVE_GRASS_PLEDGE); SEND_OUT(player, 1); }
|
||||
} else if (holdItemAtk == ITEM_POWER_HERB) {
|
||||
TURN { EXPECT_MOVES(opponent, MOVE_SOLAR_BEAM, MOVE_GRASS_PLEDGE); MOVE(player, MOVE_KNOCK_OFF); }
|
||||
TURN { EXPECT_MOVE(opponent, MOVE_GRASS_PLEDGE); SEND_OUT(player, 1); }
|
||||
} else {
|
||||
TURN { EXPECT_MOVE(opponent, MOVE_GRASS_PLEDGE); }
|
||||
TURN { EXPECT_MOVE(opponent, MOVE_GRASS_PLEDGE); SEND_OUT(player, 1); }
|
||||
}
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet fainted!");
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI won't use ground type attacks against flying type Pokemon unless Gravity is in effect")
|
||||
{
|
||||
GIVEN {
|
||||
|
|
Loading…
Reference in a new issue