From 598a588589cb581b269f2e46373c657ec897a3a3 Mon Sep 17 00:00:00 2001 From: AnonymousRandomPerson Date: Mon, 21 Feb 2022 15:59:34 -0500 Subject: Decomped CanAttackInFront() --- src/dungeon_ai.c | 62 ------------------------- src/dungeon_ai_1.c | 105 ------------------------------------------- src/dungeon_ai_attack.c | 8 ++-- src/dungeon_ai_item_weight.c | 2 +- src/dungeon_ai_items.c | 2 +- src/dungeon_ai_targeting.c | 62 +++++++++++++++++++++++++ src/dungeon_ai_targeting_1.c | 62 +++++++++++++++++++++++++ src/dungeon_ai_targeting_2.c | 105 +++++++++++++++++++++++++++++++++++++++++++ src/dungeon_capabilities_1.c | 6 +-- 9 files changed, 238 insertions(+), 176 deletions(-) delete mode 100644 src/dungeon_ai.c delete mode 100644 src/dungeon_ai_1.c create mode 100644 src/dungeon_ai_targeting.c create mode 100644 src/dungeon_ai_targeting_1.c create mode 100644 src/dungeon_ai_targeting_2.c (limited to 'src') diff --git a/src/dungeon_ai.c b/src/dungeon_ai.c deleted file mode 100644 index b2e3b2e..0000000 --- a/src/dungeon_ai.c +++ /dev/null @@ -1,62 +0,0 @@ -#include "global.h" -#include "dungeon_ai.h" - -#include "constants/ability.h" -#include "constants/tactic.h" -#include "dungeon_pokemon_attributes.h" -#include "dungeon_util.h" - -extern void CheckRunAwayVisualFlag(struct DungeonEntity *, bool8 showRunAwayEffect); - -bool8 ShouldAvoidFirstHit(struct DungeonEntity *pokemon, bool8 forceAvoid) -{ - if (!HasTactic(pokemon, TACTIC_AVOID_THE_FIRST_HIT)) - return FALSE; - if (!forceAvoid) - return FALSE; - return TRUE; -} - -bool8 ShouldAvoidEnemies(struct DungeonEntity *pokemon) -{ - if (!EntityExists(pokemon)) - { - return FALSE; - } - else - { - struct DungeonEntityData *pokemonData = pokemon->entityData; - if (pokemonData->terrifiedTurnsLeft != 0) - { - return TRUE; - } - if (pokemonData->isLeader) - { - return FALSE; - } - if (HasAbility(pokemon, ABILITY_RUN_AWAY)) - { - bool8 runAwayActive = pokemonData->HP < pokemonData->maxHP / 2; - if (runAwayActive) - { - return TRUE; - } - } - if (HasTactic(pokemon, TACTIC_GET_AWAY) || - (HasTactic(pokemon, TACTIC_AVOID_TROUBLE) && pokemonData->HP <= pokemonData->maxHP / 2)) - { - return TRUE; - } - return FALSE; - } -} - -bool8 ShouldAvoidEnemiesAndShowEffect(struct DungeonEntity *pokemon, bool8 showRunAwayEffect) -{ - if (ShouldAvoidEnemies(pokemon)) - { - CheckRunAwayVisualFlag(pokemon, showRunAwayEffect); - return TRUE; - } - return FALSE; -} diff --git a/src/dungeon_ai_1.c b/src/dungeon_ai_1.c deleted file mode 100644 index 78c899f..0000000 --- a/src/dungeon_ai_1.c +++ /dev/null @@ -1,105 +0,0 @@ -#include "global.h" -#include "dungeon_ai_1.h" - -#include "constants/status.h" -#include "constants/targeting.h" -#include "dungeon_pokemon_attributes.h" - -const u8 gTargetingData[3][2][2][2] = { - { - { - {TARGET_CAPABILITY_CANNOT_ATTACK, TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET}, - {TARGET_CAPABILITY_CAN_TARGET, TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET} - }, - { - {TARGET_CAPABILITY_CAN_TARGET, TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET}, - {TARGET_CAPABILITY_CANNOT_ATTACK, TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET} - } - }, - { - { - {TARGET_CAPABILITY_CANNOT_ATTACK, TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET}, - {TARGET_CAPABILITY_CAN_TARGET, TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET} - }, - { - {TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET, TARGET_CAPABILITY_CAN_TARGET}, - {TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET, TARGET_CAPABILITY_CAN_TARGET} - } - }, - { - { - {TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET, TARGET_CAPABILITY_CAN_TARGET}, - {TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET, TARGET_CAPABILITY_CAN_TARGET} - }, - { - {TARGET_CAPABILITY_CAN_TARGET, TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET}, - {TARGET_CAPABILITY_CANNOT_ATTACK, TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET} - } - } -}; - -u8 CanTarget(struct DungeonEntity *pokemon, struct DungeonEntity *targetPokemon, bool8 ignoreInvisible, bool8 checkPetrified) -{ - struct DungeonEntityData *pokemonData = pokemon->entityData; - struct DungeonEntityData *targetData = targetPokemon->entityData; - u8 targetingDecoy; - u8 pokemonTargetingDecoy; - bool8 pokemonIsEnemy; - bool8 targetIsEnemy; - bool8 targetIsDecoy; - if (pokemon == targetPokemon) - { - return TARGET_CAPABILITY_CANNOT_ATTACK; - } - if (pokemonData->shopkeeperMode == SHOPKEEPER_FRIENDLY || - targetData->shopkeeperMode == SHOPKEEPER_FRIENDLY || - pokemonData->clientType == CLIENT_TYPE_DONT_MOVE || - targetData->clientType == CLIENT_TYPE_DONT_MOVE || - pokemonData->clientType == CLIENT_TYPE_CLIENT || - targetData->clientType == CLIENT_TYPE_CLIENT || - (checkPetrified && !pokemonData->isEnemy && targetData->immobilizeStatus == IMMOBILIZE_STATUS_PETRIFIED) || - (!ignoreInvisible && targetData->transformStatus == TRANSFORM_STATUS_INVISIBLE && !CanSeeInvisible(pokemon))) - { - return TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET; - } - pokemonTargetingDecoy = pokemonData->targetingDecoy; - targetingDecoy = TARGETING_DECOY_NONE; - if (pokemonTargetingDecoy != TARGETING_DECOY_NONE) - { - targetingDecoy = TARGETING_DECOY_WILD; - if (pokemonTargetingDecoy == TARGETING_DECOY_TEAM) - { - targetingDecoy = TARGETING_DECOY_TEAM; - } - } - if (pokemonData->shopkeeperMode != SHOPKEEPER_NONE) - { - pokemonIsEnemy = FALSE; - if (pokemonData->shopkeeperMode == SHOPKEEPER_AGGRESSIVE_TO_PLAYER) - { - pokemonIsEnemy = TRUE; - } - } - else - { - pokemonIsEnemy = pokemonData->isEnemy ? TRUE : FALSE; - } - if (targetData->shopkeeperMode != SHOPKEEPER_NONE) - { - targetIsEnemy = FALSE; - if (targetData->shopkeeperMode == SHOPKEEPER_AGGRESSIVE_TO_PLAYER) - { - targetIsEnemy = TRUE; - } - } - else - { - targetIsEnemy = targetData->isEnemy ? TRUE : FALSE; - } - targetIsDecoy = FALSE; - if (targetData->waitingStatus == WAITING_STATUS_DECOY) - { - targetIsDecoy = TRUE; - } - return gTargetingData[targetingDecoy][pokemonIsEnemy][targetIsEnemy][targetIsDecoy]; -} diff --git a/src/dungeon_ai_attack.c b/src/dungeon_ai_attack.c index 092bab5..7368e66 100644 --- a/src/dungeon_ai_attack.c +++ b/src/dungeon_ai_attack.c @@ -10,7 +10,8 @@ #include "constants/type.h" #include "charge_move.h" #include "dungeon_action.h" -#include "dungeon_ai.h" +#include "dungeon_ai_targeting.h" +#include "dungeon_ai_targeting_1.h" #include "dungeon_ai_attack_1.h" #include "dungeon_capabilities_1.h" #include "dungeon_global_data.h" @@ -37,9 +38,8 @@ extern s32 gPotentialTargetWeights_2[NUM_DIRECTIONS]; extern u8 gPotentialAttackTargetDirections[NUM_DIRECTIONS]; extern struct DungeonEntity *gPotentialTargets[NUM_DIRECTIONS]; -extern bool8 IsMoveUsable(struct DungeonEntity*, s32, bool8); +extern bool8 IsMoveUsable_1(struct DungeonEntity*, s32, bool8); extern bool8 TargetRegularAttack(struct DungeonEntity*, u32*, bool8); -extern bool8 CanAttackInFront(struct DungeonEntity*, s32); extern s32 WeightMoveIfUsable(s32, s32, struct DungeonEntity*, struct DungeonEntity*, struct PokemonMove*, bool8); extern bool8 IsTargetInLineRange(struct DungeonEntity*, struct DungeonEntity*, s32); extern bool8 CanUseStatusMove(s32, struct DungeonEntity*, struct DungeonEntity*, struct PokemonMove*, bool8); @@ -182,7 +182,7 @@ void DecideAttack(struct DungeonEntity *pokemon) move = &pokemonData->moves[i]; if (move->moveFlags & MOVE_FLAG_EXISTS && willNotUnlinkMove[i] && - IsMoveUsable(pokemon, i, hasPPChecker) && + IsMoveUsable_1(pokemon, i, hasPPChecker) && move->moveFlags & MOVE_FLAG_ENABLED) { moveTargetResults[i].moveUsable = TRUE; diff --git a/src/dungeon_ai_item_weight.c b/src/dungeon_ai_item_weight.c index 08652b2..ce79ad4 100644 --- a/src/dungeon_ai_item_weight.c +++ b/src/dungeon_ai_item_weight.c @@ -3,7 +3,7 @@ #include "constants/status.h" #include "constants/targeting.h" -#include "dungeon_ai_1.h" +#include "dungeon_ai_targeting_2.h" #include "dungeon_map_access.h" #include "dungeon_pokemon_attributes.h" #include "dungeon_util.h" diff --git a/src/dungeon_ai_items.c b/src/dungeon_ai_items.c index 52aacc4..0135c62 100644 --- a/src/dungeon_ai_items.c +++ b/src/dungeon_ai_items.c @@ -6,10 +6,10 @@ #include "constants/status.h" #include "constants/targeting.h" #include "dungeon_action.h" -#include "dungeon_ai_1.h" #include "dungeon_ai_attack_1.h" #include "dungeon_ai_item_weight.h" #include "dungeon_ai_items.h" +#include "dungeon_ai_targeting_2.h" #include "dungeon_capabilities.h" #include "dungeon_capabilities_1.h" #include "dungeon_entity.h" diff --git a/src/dungeon_ai_targeting.c b/src/dungeon_ai_targeting.c new file mode 100644 index 0000000..ec5abd9 --- /dev/null +++ b/src/dungeon_ai_targeting.c @@ -0,0 +1,62 @@ +#include "global.h" +#include "dungeon_ai_targeting.h" + +#include "constants/iq_skill.h" +#include "constants/item.h" +#include "constants/status.h" +#include "dungeon_engine.h" +#include "dungeon_items.h" +#include "dungeon_map_access.h" +#include "dungeon_movement.h" +#include "dungeon_pokemon_attributes.h" +#include "dungeon_util.h" +#include "map.h" + +const u8 gDirectionBitMasks_2[] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80}; + +bool8 CanAttackInFront(struct DungeonEntity *pokemon, s32 direction) +{ + u8 crossableTerrain = GetCrossableTerrain(pokemon->entityData->entityID); + struct MapTile *tile; + if (crossableTerrain < CROSSABLE_TERRAIN_CREVICE) + { + crossableTerrain = CROSSABLE_TERRAIN_CREVICE; + } + tile = GetMapTile_1(pokemon->posWorld.x + gAdjacentTileOffsets[direction].x, + pokemon->posWorld.y + gAdjacentTileOffsets[direction].y); + if (!(tile->tileType & TILE_TYPE_MAP_EDGE) && + (tile->pokemon == NULL || GetEntityType(tile->pokemon) == ENTITY_POKEMON)) + { + if (!IsFixedDungeon()) + { + if (pokemon->entityData->transformStatus == TRANSFORM_STATUS_MOBILE || + HasItem(pokemon, ITEM_ID_MOBILE_SCARF)) + { + crossableTerrain = CROSSABLE_TERRAIN_WALL; + } + else if (HasIQSkill(pokemon, IQ_SKILL_ALL_TERRAIN_HIKER)) + { + // BUG: If the Pokémon is a Ghost type that can normally attack through walls, + // All-Terrain Hiker/Super Mobile may make the AI think it can't attack through walls. + crossableTerrain = CROSSABLE_TERRAIN_CREVICE; + } + else if (HasIQSkill(pokemon, IQ_SKILL_SUPER_MOBILE)) + { + if ((direction & 1) != 0) + { + crossableTerrain = CROSSABLE_TERRAIN_CREVICE; + } + else + { + crossableTerrain = CROSSABLE_TERRAIN_WALL; + } + } + } + tile = GetMapTile_1(pokemon->posWorld.x, pokemon->posWorld.y); + if (tile->canMoveAdjacent[crossableTerrain] & gDirectionBitMasks_2[direction & DIRECTION_MASK]) + { + return TRUE; + } + } + return FALSE; +} diff --git a/src/dungeon_ai_targeting_1.c b/src/dungeon_ai_targeting_1.c new file mode 100644 index 0000000..5ff76b0 --- /dev/null +++ b/src/dungeon_ai_targeting_1.c @@ -0,0 +1,62 @@ +#include "global.h" +#include "dungeon_ai_targeting_1.h" + +#include "constants/ability.h" +#include "constants/tactic.h" +#include "dungeon_pokemon_attributes.h" +#include "dungeon_util.h" + +extern void CheckRunAwayVisualFlag(struct DungeonEntity *, bool8 showRunAwayEffect); + +bool8 ShouldAvoidFirstHit(struct DungeonEntity *pokemon, bool8 forceAvoid) +{ + if (!HasTactic(pokemon, TACTIC_AVOID_THE_FIRST_HIT)) + return FALSE; + if (!forceAvoid) + return FALSE; + return TRUE; +} + +bool8 ShouldAvoidEnemies(struct DungeonEntity *pokemon) +{ + if (!EntityExists(pokemon)) + { + return FALSE; + } + else + { + struct DungeonEntityData *pokemonData = pokemon->entityData; + if (pokemonData->terrifiedTurnsLeft != 0) + { + return TRUE; + } + if (pokemonData->isLeader) + { + return FALSE; + } + if (HasAbility(pokemon, ABILITY_RUN_AWAY)) + { + bool8 runAwayActive = pokemonData->HP < pokemonData->maxHP / 2; + if (runAwayActive) + { + return TRUE; + } + } + if (HasTactic(pokemon, TACTIC_GET_AWAY) || + (HasTactic(pokemon, TACTIC_AVOID_TROUBLE) && pokemonData->HP <= pokemonData->maxHP / 2)) + { + return TRUE; + } + return FALSE; + } +} + +bool8 ShouldAvoidEnemiesAndShowEffect(struct DungeonEntity *pokemon, bool8 showRunAwayEffect) +{ + if (ShouldAvoidEnemies(pokemon)) + { + CheckRunAwayVisualFlag(pokemon, showRunAwayEffect); + return TRUE; + } + return FALSE; +} diff --git a/src/dungeon_ai_targeting_2.c b/src/dungeon_ai_targeting_2.c new file mode 100644 index 0000000..83319e1 --- /dev/null +++ b/src/dungeon_ai_targeting_2.c @@ -0,0 +1,105 @@ +#include "global.h" +#include "dungeon_ai_targeting_2.h" + +#include "constants/status.h" +#include "constants/targeting.h" +#include "dungeon_pokemon_attributes.h" + +const u8 gTargetingData[3][2][2][2] = { + { + { + {TARGET_CAPABILITY_CANNOT_ATTACK, TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET}, + {TARGET_CAPABILITY_CAN_TARGET, TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET} + }, + { + {TARGET_CAPABILITY_CAN_TARGET, TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET}, + {TARGET_CAPABILITY_CANNOT_ATTACK, TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET} + } + }, + { + { + {TARGET_CAPABILITY_CANNOT_ATTACK, TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET}, + {TARGET_CAPABILITY_CAN_TARGET, TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET} + }, + { + {TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET, TARGET_CAPABILITY_CAN_TARGET}, + {TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET, TARGET_CAPABILITY_CAN_TARGET} + } + }, + { + { + {TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET, TARGET_CAPABILITY_CAN_TARGET}, + {TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET, TARGET_CAPABILITY_CAN_TARGET} + }, + { + {TARGET_CAPABILITY_CAN_TARGET, TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET}, + {TARGET_CAPABILITY_CANNOT_ATTACK, TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET} + } + } +}; + +u8 CanTarget(struct DungeonEntity *pokemon, struct DungeonEntity *targetPokemon, bool8 ignoreInvisible, bool8 checkPetrified) +{ + struct DungeonEntityData *pokemonData = pokemon->entityData; + struct DungeonEntityData *targetData = targetPokemon->entityData; + u8 targetingDecoy; + u8 pokemonTargetingDecoy; + bool8 pokemonIsEnemy; + bool8 targetIsEnemy; + bool8 targetIsDecoy; + if (pokemon == targetPokemon) + { + return TARGET_CAPABILITY_CANNOT_ATTACK; + } + if (pokemonData->shopkeeperMode == SHOPKEEPER_FRIENDLY || + targetData->shopkeeperMode == SHOPKEEPER_FRIENDLY || + pokemonData->clientType == CLIENT_TYPE_DONT_MOVE || + targetData->clientType == CLIENT_TYPE_DONT_MOVE || + pokemonData->clientType == CLIENT_TYPE_CLIENT || + targetData->clientType == CLIENT_TYPE_CLIENT || + (checkPetrified && !pokemonData->isEnemy && targetData->immobilizeStatus == IMMOBILIZE_STATUS_PETRIFIED) || + (!ignoreInvisible && targetData->transformStatus == TRANSFORM_STATUS_INVISIBLE && !CanSeeInvisible(pokemon))) + { + return TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET; + } + pokemonTargetingDecoy = pokemonData->targetingDecoy; + targetingDecoy = TARGETING_DECOY_NONE; + if (pokemonTargetingDecoy != TARGETING_DECOY_NONE) + { + targetingDecoy = TARGETING_DECOY_WILD; + if (pokemonTargetingDecoy == TARGETING_DECOY_TEAM) + { + targetingDecoy = TARGETING_DECOY_TEAM; + } + } + if (pokemonData->shopkeeperMode != SHOPKEEPER_NONE) + { + pokemonIsEnemy = FALSE; + if (pokemonData->shopkeeperMode == SHOPKEEPER_AGGRESSIVE_TO_PLAYER) + { + pokemonIsEnemy = TRUE; + } + } + else + { + pokemonIsEnemy = pokemonData->isEnemy ? TRUE : FALSE; + } + if (targetData->shopkeeperMode != SHOPKEEPER_NONE) + { + targetIsEnemy = FALSE; + if (targetData->shopkeeperMode == SHOPKEEPER_AGGRESSIVE_TO_PLAYER) + { + targetIsEnemy = TRUE; + } + } + else + { + targetIsEnemy = targetData->isEnemy ? TRUE : FALSE; + } + targetIsDecoy = FALSE; + if (targetData->waitingStatus == WAITING_STATUS_DECOY) + { + targetIsDecoy = TRUE; + } + return gTargetingData[targetingDecoy][pokemonIsEnemy][targetIsEnemy][targetIsDecoy]; +} diff --git a/src/dungeon_capabilities_1.c b/src/dungeon_capabilities_1.c index 605f9e9..ef566fe 100644 --- a/src/dungeon_capabilities_1.c +++ b/src/dungeon_capabilities_1.c @@ -5,7 +5,7 @@ #include "constants/iq_skill.h" #include "constants/status.h" #include "charge_move.h" -#include "dungeon_ai.h" +#include "dungeon_ai_targeting_1.h" #include "dungeon_capabilities.h" #include "dungeon_engine.h" #include "dungeon_items.h" @@ -15,7 +15,7 @@ #include "dungeon_util.h" #include "map.h" -const u8 gDirectionBitMasks[] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80}; +const u8 gDirectionBitMasks_1[] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80}; static inline bool8 JoinLocationCannotUseItems(struct DungeonEntityData *pokemonData) { @@ -119,7 +119,7 @@ bool8 CanMoveInDirection(struct DungeonEntity *pokemon, u32 facingDir) } } currentMapTile = GetMapTile_1(pokemon->posWorld.x, pokemon->posWorld.y); - if (!(currentMapTile->canMoveAdjacent[crossableTerrain] & gDirectionBitMasks[facingDir & DIRECTION_MASK])) + if (!(currentMapTile->canMoveAdjacent[crossableTerrain] & gDirectionBitMasks_1[facingDir & DIRECTION_MASK])) { return FALSE; } -- cgit v1.2.3