AI handling for new moves

This commit is contained in:
DizzyEggg 2018-09-02 15:50:18 +02:00
parent f9af3bec9b
commit 15b91a3c89
3 changed files with 251 additions and 57 deletions

View File

@ -315,13 +315,13 @@
.macro if_effect param0, param1
.byte 0x37
.byte \param0
.2byte \param0
.4byte \param1
.endm
.macro if_not_effect param0, param1
.byte 0x38
.byte \param0
.2byte \param0
.4byte \param1
.endm
@ -469,14 +469,14 @@
.macro if_move_flag flag jumpptr
.byte 0x52
.2byte \flag
.4byte \flag
.4byte \jumpptr
.endm
.macro if_field_status flag jumpptr
.byte 0x53
.word \flag
.word \jumpptr
.4byte \flag
.4byte \jumpptr
.endm
.macro get_move_accuracy
@ -491,7 +491,7 @@
.macro call_if_move_flag flag ptr
.byte 0x52
.2byte \flag
.4byte \flag
.4byte \ptr
.endm
@ -559,17 +559,33 @@
.4byte \param2
.endm
.macro get_ally_chosen_move bank
.macro get_ally_chosen_move
.byte 0x63
.endm
.macro if_has_no_attacking_moves bank, param1
.macro if_has_no_attacking_moves battler, param1
.byte 0x64
.byte \bank
.byte \battler
.4byte \param1
.endm
.macro get_hazards_count battler, effect
.byte 0x65
.byte \battler
.2byte \effect
.endm
.macro if_doesnt_hold_berry battler, ptr
.byte 0x66
.byte \battler
.4byte \ptr
.endm
@ useful script macros
.macro if_holds_no_item battler, ptr
if_holds_item \battler, 0, \ptr
.endm
.macro get_curr_move_type
get_type AI_TYPE_MOVE
.endm

View File

@ -50,58 +50,53 @@ AI_CheckBadMove:
if_move MOVE_FISSURE, AI_CBM_CheckIfNegatesType
if_move MOVE_HORN_DRILL, AI_CBM_CheckIfNegatesType
get_how_powerful_move_is
if_equal 0, AI_CheckBadMove_CheckSoundproof
if_equal 0, AI_CheckBadMove_CheckEffect
AI_CBM_CheckIfNegatesType: @ 82DBF92
if_type_effectiveness AI_EFFECTIVENESS_x0, Score_Minus10
get_ability AI_USER
if_equal ABILITY_MOLD_BREAKER, AI_CheckBadMove_CheckEffect
if_equal ABILITY_TERAVOLT, AI_CheckBadMove_CheckEffect
if_equal ABILITY_TURBOBLAZE, AI_CheckBadMove_CheckEffect
get_ability AI_TARGET
if_equal ABILITY_VOLT_ABSORB, CheckIfVoltAbsorbCancelsElectric
if_equal ABILITY_LIGHTNING_ROD, CheckIfVoltAbsorbCancelsElectric
if_equal ABILITY_MOTOR_DRIVE, CheckIfVoltAbsorbCancelsElectric
if_equal ABILITY_WATER_ABSORB, CheckIfWaterAbsorbCancelsWater
if_equal ABILITY_DRY_SKIN, CheckIfWaterAbsorbCancelsWater
if_equal ABILITY_FLASH_FIRE, CheckIfFlashFireCancelsFire
if_equal ABILITY_WONDER_GUARD, CheckIfWonderGuardCancelsMove
if_equal ABILITY_LEVITATE, CheckIfLevitateCancelsGroundMove
goto AI_CheckBadMove_CheckSoundproof_
if_equal ABILITY_SOUNDPROOF, CheckIfSoundproofCancelsMove
goto AI_CheckBadMove_CheckEffect
CheckIfSoundproofCancelsMove:
if_move_flag FLAG_SOUND, Score_Minus10
goto AI_CheckBadMove_CheckEffect
CheckIfVoltAbsorbCancelsElectric: @ 82DBFBD
get_curr_move_type
if_equal_ TYPE_ELECTRIC, Score_Minus12
goto AI_CheckBadMove_CheckSoundproof_
if_equal_ TYPE_ELECTRIC, AI_CheckBadMove_CheckEffect
goto AI_CheckBadMove_CheckEffect
CheckIfWaterAbsorbCancelsWater: @ 82DBFCA
get_curr_move_type
if_equal_ TYPE_WATER, Score_Minus12
goto AI_CheckBadMove_CheckSoundproof_
goto AI_CheckBadMove_CheckEffect
CheckIfFlashFireCancelsFire: @ 82DBFD7
get_curr_move_type
if_equal_ TYPE_FIRE, Score_Minus12
goto AI_CheckBadMove_CheckSoundproof_
goto AI_CheckBadMove_CheckEffect
CheckIfWonderGuardCancelsMove: @ 82DBFE4
if_type_effectiveness AI_EFFECTIVENESS_x2, AI_CheckBadMove_CheckSoundproof_
if_type_effectiveness AI_EFFECTIVENESS_x2, AI_CheckBadMove_CheckEffect
goto Score_Minus10
CheckIfLevitateCancelsGroundMove: @ 82DBFEF
get_curr_move_type
if_equal_ TYPE_GROUND, Score_Minus10
AI_CheckBadMove_CheckSoundproof_: @ 82DBFF7
get_how_powerful_move_is
if_equal 0, AI_CheckBadMove_CheckSoundproof
AI_CheckBadMove_CheckSoundproof: @ 82DBFFE
get_ability AI_TARGET
if_not_equal ABILITY_SOUNDPROOF, AI_CheckBadMove_CheckEffect
if_move MOVE_GROWL, Score_Minus10
if_move MOVE_ROAR, Score_Minus10
if_move MOVE_SING, Score_Minus10
if_move MOVE_SUPERSONIC, Score_Minus10
if_move MOVE_SCREECH, Score_Minus10
if_move MOVE_SNORE, Score_Minus10
if_move MOVE_UPROAR, Score_Minus10
if_move MOVE_METAL_SOUND, Score_Minus10
if_move MOVE_GRASS_WHISTLE, Score_Minus10
AI_CheckBadMove_CheckEffect: @ 82DC045
if_effect EFFECT_SLEEP, AI_CBM_Sleep
if_effect EFFECT_EXPLOSION, AI_CBM_Explosion
@ -212,8 +207,156 @@ AI_CheckBadMove_CheckEffect: @ 82DC045
if_effect EFFECT_WATER_SPORT, AI_CBM_WaterSport
if_effect EFFECT_CALM_MIND, AI_CBM_CalmMind
if_effect EFFECT_DRAGON_DANCE, AI_CBM_DragonDance
if_effect EFFECT_STICKY_WEB, AI_CBM_StickyWeb
if_effect EFFECT_STEALTH_ROCK, AI_CBM_StealthRock
if_effect EFFECT_TOXIC_SPIKES, AI_CBM_ToxicSpikes
if_effect EFFECT_AQUA_RING, AI_CBM_AquaRing
if_effect EFFECT_GRAVITY, AI_CBM_Gravity
if_effect EFFECT_EMBARGO, AI_CBM_Embargo
if_effect EFFECT_LUCKY_CHANT, AI_CBM_LuckyChant
if_effect EFFECT_HEAL_PULSE, Score_Minus5
if_effect EFFECT_QUASH, AI_CBM_Quash
if_effect EFFECT_GASTRO_ACID, AI_CBM_GastroAcid
if_effect EFFECT_HEAL_BLOCK, AI_CBM_HealBlock
if_effect EFFECT_WORRY_SEED, AI_CBM_WorrySeed
if_effect EFFECT_MIRACLE_EYE, AI_CBM_MiracleEye
if_effect EFFECT_MAGNET_RISE, AI_CBM_MagnetRise
if_effect EFFECT_TELEKINESIS, AI_CBM_Telekinesis
if_effect EFFECT_MISTY_TERRAIN, AI_CBM_MistyTerrain
if_effect EFFECT_GRASSY_TERRAIN, AI_CBM_GrassyTerrain
if_effect EFFECT_ELECTRIC_TERRAIN, AI_CBM_ElectricTerrain
if_effect EFFECT_PSYCHIC_TERRAIN, AI_CBM_PsychicTerrain
if_effect EFFECT_QUIVER_DANCE, AI_CBM_QuiverDance
if_effect EFFECT_COIL, AI_CBM_Coil
if_effect EFFECT_TAILWIND, AI_CBM_Tailwind
if_effect EFFECT_SIMPLE_BEAM, AI_CBM_SimpleBeam
if_effect EFFECT_NATURAL_GIFT, AI_CBM_NaturalGift
if_effect EFFECT_FLING, AI_CBM_Fling
if_effect EFFECT_ATTACK_ACCURACY_UP, AI_CBM_AtkAccUp
if_effect EFFECT_ATTACK_SPATK_UP, AI_CBM_AtkSpAtkUp
end
AI_CBM_AtkAccUp:
if_stat_level_not_equal AI_USER, STAT_ATK, 12, AI_Ret
if_stat_level_equal AI_USER, STAT_ACC, 12, Score_Minus10
end
AI_CBM_AtkSpAtkUp:
if_stat_level_not_equal AI_USER, STAT_ATK, 12, AI_Ret
if_stat_level_equal AI_USER, STAT_SPATK, 12, Score_Minus10
end
AI_CBM_Fling:
if_holds_no_item AI_USER, Score_Minus10
if_ability AI_USER, ABILITY_KLUTZ, Score_Minus10
if_status3 AI_USER, STATUS3_EMBARGO, Score_Minus10
if_field_status STATUS_FIELD_MAGIC_ROOM, Score_Minus10
end
AI_CBM_NaturalGift:
if_doesnt_hold_berry AI_USER, Score_Minus10
if_ability AI_USER, ABILITY_KLUTZ, Score_Minus10
if_status3 AI_USER, STATUS3_EMBARGO, Score_Minus10
if_field_status STATUS_FIELD_MAGIC_ROOM, Score_Minus10
end
AI_CBM_SimpleBeam:
if_ability AI_TARGET, ABILITY_SIMPLE, Score_Minus10
end
AI_CBM_Tailwind:
if_side_affecting AI_USER, SIDE_STATUS_TAILWIND, Score_Minus10
end
AI_CBM_QuiverDance:
if_stat_level_not_equal AI_USER, STAT_SPATK, 12, AI_Ret
if_stat_level_not_equal AI_USER, STAT_SPDEF, 12, AI_Ret
if_stat_level_equal AI_USER, STAT_SPEED, 12, Score_Minus10
end
AI_CBM_Coil:
if_stat_level_not_equal AI_USER, STAT_ATK, 12, AI_Ret
if_stat_level_not_equal AI_USER, STAT_DEF, 12, AI_Ret
if_stat_level_equal AI_USER, STAT_ACC, 12, Score_Minus10
end
AI_CBM_MistyTerrain:
if_field_status STATUS_FIELD_MISTY_TERRAIN, Score_Minus10
end
AI_CBM_GrassyTerrain:
if_field_status STATUS_FIELD_GRASSY_TERRAIN, Score_Minus10
end
AI_CBM_ElectricTerrain:
if_field_status STATUS_FIELD_ELECTRIC_TERRAIN, Score_Minus10
end
AI_CBM_PsychicTerrain:
if_field_status STATUS_FIELD_PSYCHIC_TERRAIN, Score_Minus10
end
AI_CBM_Quash:
if_not_double_battle Score_Minus10
end
AI_CBM_Telekinesis:
if_status3 AI_TARGET, STATUS3_TELEKINESIS, Score_Minus10
end
AI_CBM_MagnetRise:
if_status3 AI_USER, STATUS3_MAGNET_RISE, Score_Minus10
end
AI_CBM_MiracleEye:
if_status3 AI_TARGET, STATUS3_MIRACLE_EYED, Score_Minus10
if_status2 AI_TARGET, STATUS2_FORESIGHT, Score_Minus10
end
AI_CBM_WorrySeed:
get_ability AI_TARGET
if_equal ABILITY_INSOMNIA, Score_Minus10
if_equal ABILITY_VITAL_SPIRIT, Score_Minus10
end
AI_CBM_HealBlock:
if_status3 AI_TARGET, STATUS3_HEAL_BLOCK, Score_Minus10
end
AI_CBM_GastroAcid:
if_status3 AI_TARGET, STATUS3_GASTRO_ACID, Score_Minus10
end
AI_CBM_AquaRing:
if_status3 AI_USER, STATUS3_AQUA_RING, Score_Minus10
end
AI_CBM_LuckyChant:
if_side_affecting AI_USER, SIDE_STATUS_LUCKY_CHANT, Score_Minus10
end
AI_CBM_Embargo:
if_status3 AI_TARGET, STATUS3_EMBARGO, Score_Minus10
end
AI_CBM_Gravity:
if_field_status STATUS_FIELD_GRAVITY, Score_Minus10
end
AI_CBM_ToxicSpikes:
if_not_side_affecting AI_TARGET, SIDE_STATUS_TOXIC_SPIKES, AI_Ret
get_hazards_count AI_TARGET, EFFECT_TOXIC_SPIKES
if_equal 2, Score_Minus10
end
AI_CBM_StealthRock:
if_side_affecting AI_TARGET, SIDE_STATUS_STEALTH_ROCK, Score_Minus10
end
AI_CBM_StickyWeb:
if_side_affecting AI_TARGET, SIDE_STATUS_STICKY_WEB, Score_Minus10
end
AI_CBM_Sleep: @ 82DC2D4
get_ability AI_TARGET
if_equal ABILITY_INSOMNIA, Score_Minus10
@ -441,11 +584,14 @@ AI_CBM_Curse: @ 82DC5BB
end
AI_CBM_Spikes: @ 82DC5CC
if_side_affecting AI_TARGET, SIDE_STATUS_SPIKES, Score_Minus10
if_not_side_affecting AI_TARGET, SIDE_STATUS_SPIKES, AI_Ret
get_hazards_count AI_TARGET, EFFECT_SPIKES
if_equal 3, Score_Minus10
end
AI_CBM_Foresight: @ 82DC5D7
if_status2 AI_TARGET, STATUS2_FORESIGHT, Score_Minus10
if_status3 AI_TARGET, STATUS3_MIRACLE_EYED, Score_Minus10
end
AI_CBM_PerishSong: @ 82DC5E2

View File

@ -155,6 +155,8 @@ static void BattleAICmd_if_flash_fired(void);
static void BattleAICmd_if_holds_item(void);
static void BattleAICmd_get_ally_chosen_move(void);
static void BattleAICmd_if_has_no_attacking_moves(void);
static void BattleAICmd_get_hazards_count(void);
static void BattleAICmd_if_doesnt_hold_berry(void);
// ewram
EWRAM_DATA const u8 *gAIScriptPtr = NULL;
@ -266,6 +268,8 @@ static const BattleAICmdFunc sBattleAICmdTable[] =
BattleAICmd_if_holds_item, // 0x62
BattleAICmd_get_ally_chosen_move, // 0x63
BattleAICmd_if_has_no_attacking_moves, // 0x64
BattleAICmd_get_hazards_count, // 0x65
BattleAICmd_if_doesnt_hold_berry, // 0x66
};
static const u16 sDiscouragedPowerfulMoveEffects[] =
@ -1815,18 +1819,18 @@ static void BattleAICmd_get_weather(void)
static void BattleAICmd_if_effect(void)
{
if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect == gAIScriptPtr[1])
gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect == T1_READ_16(gAIScriptPtr + 1))
gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3);
else
gAIScriptPtr += 6;
gAIScriptPtr += 7;
}
static void BattleAICmd_if_not_effect(void)
{
if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect != gAIScriptPtr[1])
gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect != T1_READ_16(gAIScriptPtr + 1))
gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3);
else
gAIScriptPtr += 6;
gAIScriptPtr += 7;
}
static void BattleAICmd_if_stat_level_less_than(void)
@ -2047,8 +2051,7 @@ static void BattleAICmd_if_has_move_with_effect(void)
case AI_TARGET_PARTNER:
for (i = 0; i < 4; i++)
{
// UB: checks sBattler_AI instead of gBattlerTarget.
if (gBattleMons[sBattler_AI].moves[i] != 0 && gBattleMoves[BATTLE_HISTORY->usedMoves[gBattlerTarget].moves[i]].effect == gAIScriptPtr[2])
if (gBattleMons[gBattlerTarget].moves[i] != 0 && gBattleMoves[BATTLE_HISTORY->usedMoves[gBattlerTarget].moves[i]].effect == gAIScriptPtr[2])
break;
}
if (i == 4)
@ -2184,18 +2187,13 @@ static void BattleAICmd_if_holds_item(void)
{
u8 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]);
u16 item;
u8 var1, var2;
if ((battlerId & BIT_SIDE) == (sBattler_AI & BIT_SIDE))
item = gBattleMons[battlerId].item;
else
item = BATTLE_HISTORY->itemEffects[battlerId];
// UB: doesn't properly read an unaligned u16
var2 = gAIScriptPtr[2];
var1 = gAIScriptPtr[3];
if ((var1 | var2) == item)
if (T1_READ_16(gAIScriptPtr + 2) == item)
gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4);
else
gAIScriptPtr += 8;
@ -2301,12 +2299,12 @@ static void BattleAICmd_get_protect_count(void)
static void BattleAICmd_if_move_flag(void)
{
u16 flag = T1_READ_16(gAIScriptPtr + 1);
u32 flag = T1_READ_32(gAIScriptPtr + 1);
if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].flags & flag)
gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3);
gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5);
else
gAIScriptPtr += 7;
gAIScriptPtr += 9;
}
static void BattleAICmd_if_field_status(void)
@ -2341,16 +2339,16 @@ static void BattleAICmd_call_if_eq(void)
static void BattleAICmd_call_if_move_flag(void)
{
u16 flag = T1_READ_16(gAIScriptPtr + 1);
u32 flag = T1_READ_32(gAIScriptPtr + 1);
if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].flags & flag)
{
AIStackPushVar(gAIScriptPtr + 7);
gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3);
AIStackPushVar(gAIScriptPtr + 9);
gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5);
}
else
{
gAIScriptPtr += 7;
gAIScriptPtr += 9;
}
}
@ -2493,7 +2491,41 @@ static void BattleAICmd_if_has_no_attacking_moves(void)
}
if (i == 4)
gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1);
gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 5;
gAIScriptPtr += 6;
}
static void BattleAICmd_get_hazards_count(void)
{
u8 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]);
u8 side = GetBattlerSide(battlerId);
switch (T1_READ_16(gAIScriptPtr + 2))
{
case EFFECT_SPIKES:
AI_THINKING_STRUCT->funcResult = gSideTimers[side].spikesAmount;
break;
case EFFECT_TOXIC_SPIKES:
AI_THINKING_STRUCT->funcResult = gSideTimers[side].toxicSpikesAmount;
break;
}
gAIScriptPtr += 4;
}
static void BattleAICmd_if_doesnt_hold_berry(void)
{
u8 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]);
u16 item;
if (IsBattlerAIControlled(battlerId))
item = gBattleMons[battlerId].item;
else
item = BATTLE_HISTORY->itemEffects[battlerId];
if (ItemId_GetPocket(item) == POCKET_BERRIES)
gAIScriptPtr += 6;
else
T1_READ_PTR(gAIScriptPtr + 2);
}