diff options
Diffstat (limited to 'src/dungeon_ai_attack_1.c')
-rw-r--r-- | src/dungeon_ai_attack_1.c | 233 |
1 files changed, 132 insertions, 101 deletions
diff --git a/src/dungeon_ai_attack_1.c b/src/dungeon_ai_attack_1.c index fb088fb..023df14 100644 --- a/src/dungeon_ai_attack_1.c +++ b/src/dungeon_ai_attack_1.c @@ -2,16 +2,22 @@ #include "dungeon_ai_attack_1.h" #include "constants/direction.h" +#include "constants/targeting.h" +#include "constants/type.h" +#include "dungeon_ai_targeting_2.h" #include "dungeon_pokemon_attributes.h" +#include "dungeon_random.h" +#include "moves.h" #include "position_util.h" +#include "status_checks_1.h" extern bool8 gCanAttackInDirection[NUM_DIRECTIONS]; extern s32 gPotentialAttackTargetWeights[NUM_DIRECTIONS]; extern u8 gPotentialAttackTargetDirections[NUM_DIRECTIONS]; extern struct DungeonEntity *gPotentialTargets[NUM_DIRECTIONS]; -extern bool8 CanUseStatusMove(s32, struct DungeonEntity*, struct DungeonEntity*, struct PokemonMove*, bool8); extern s32 WeightMove(struct DungeonEntity*, s32, struct DungeonEntity*, u8); +extern bool8 CanUseOnTargetWithStatusChecker(struct DungeonEntity*, struct DungeonEntity*, struct PokemonMove*); s32 WeightMoveIfUsable(s32 numPotentialTargets, s32 targetingFlags, struct DungeonEntity *user, struct DungeonEntity *target, struct PokemonMove *move, bool32 hasStatusChecker) { @@ -42,103 +48,128 @@ s32 WeightMoveIfUsable(s32 numPotentialTargets, s32 targetingFlags, struct Dunge return numPotentialTargets; } -// NAKED -// s32 WeightMoveIfUsable(s32 numPotentialTargets, s32 targetingFlags, struct DungeonEntity *user, struct DungeonEntity *target, struct PokemonMove *move, bool8 hasStatusChecker) -// { -// asm_unified("push {r4-r7,lr}\n" -// "mov r7, r10\n" -// "mov r6, r9\n" -// "mov r5, r8\n" -// "push {r5-r7}\n" -// "sub sp, 0x4\n" -// "adds r6, r0, 0\n" -// "adds r5, r2, 0\n" -// "adds r7, r3, 0\n" -// "ldr r0, [sp, 0x28]\n" -// "lsls r1, 16\n" -// "asrs r1, 16\n" -// "mov r9, r1\n" -// "lsls r0, 24\n" -// "lsrs r0, 24\n" -// "mov r10, r0\n" -// "ldr r2, [r5, 0x70]\n" -// "ldr r1, [r5, 0x4]\n" -// "ldr r0, [r7, 0x4]\n" -// "cmp r1, r0\n" -// "beq _0807C5BC\n" -// "movs r0, 0xF0\n" -// "mov r1, r9\n" -// "ands r0, r1\n" -// "cmp r0, 0x30\n" -// "beq _0807C5BC\n" -// "cmp r0, 0x60\n" -// "beq _0807C5BC\n" -// "cmp r0, 0x70\n" -// "bne _0807C5C4\n" -// "_0807C5BC:\n" -// "adds r0, r2, 0\n" -// "adds r0, 0x46\n" -// "ldrb r4, [r0]\n" -// "b _0807C5CE\n" -// "_0807C5C4:\n" -// "adds r0, r5, 0x4\n" -// "adds r1, r7, 0x4\n" -// "bl CalculateFacingDir\n" -// "adds r4, r0, 0\n" -// "_0807C5CE:\n" -// "ldr r0, _0807C638\n" -// "adds r0, r4\n" -// "mov r8, r0\n" -// "ldrb r0, [r0]\n" -// "cmp r0, 0\n" -// "bne _0807C624\n" -// "mov r0, r10\n" -// "str r0, [sp]\n" -// "mov r0, r9\n" -// "adds r1, r5, 0\n" -// "adds r2, r7, 0\n" -// "ldr r3, [sp, 0x24]\n" -// "bl CanUseStatusMove\n" -// "lsls r0, 24\n" -// "cmp r0, 0\n" -// "beq _0807C624\n" -// "movs r0, 0x1\n" -// "mov r1, r8\n" -// "strb r0, [r1]\n" -// "ldr r0, _0807C63C\n" -// "adds r0, r6, r0\n" -// "strb r4, [r0]\n" -// "adds r0, r5, 0\n" -// "ldr r1, [sp, 0x24]\n" -// "bl GetMoveTypeForPokemon\n" -// "adds r3, r0, 0\n" -// "lsls r3, 24\n" -// "lsrs r3, 24\n" -// "adds r0, r5, 0\n" -// "mov r1, r9\n" -// "adds r2, r7, 0\n" -// "bl WeightMove\n" -// "ldr r1, _0807C640\n" -// "lsls r2, r6, 2\n" -// "adds r1, r2, r1\n" -// "str r0, [r1]\n" -// "ldr r0, _0807C644\n" -// "adds r2, r0\n" -// "str r7, [r2]\n" -// "adds r6, 0x1\n" -// "_0807C624:\n" -// "adds r0, r6, 0\n" -// "add sp, 0x4\n" -// "pop {r3-r5}\n" -// "mov r8, r3\n" -// "mov r9, r4\n" -// "mov r10, r5\n" -// "pop {r4-r7}\n" -// "pop {r1}\n" -// "bx r1\n" -// ".align 2, 0\n" -// "_0807C638: .4byte gCanAttackInDirection\n" -// "_0807C63C: .4byte gPotentialAttackTargetDirections\n" -// "_0807C640: .4byte gPotentialAttackTargetWeights\n" -// "_0807C644: .4byte gPotentialTargets"); -// } +bool8 CanUseStatusMove(s32 targetingFlags, struct DungeonEntity *user, struct DungeonEntity *target, struct PokemonMove *move, bool32 hasStatusChecker) +{ + struct DungeonEntityData *targetData; + s32 targetingFlags2 = (s16) targetingFlags; + bool8 hasStatusChecker2 = hasStatusChecker; + bool8 hasTarget = FALSE; + u32 categoryTargetingFlags = targetingFlags2 & 0xF; + u32 *categoryTargetingFlags2 = &categoryTargetingFlags; // Fixes a regswap. + if (*categoryTargetingFlags2 == TARGETING_FLAG_TARGET_OTHER) + { + if (CanTarget(user, target, FALSE, TRUE) == TARGET_CAPABILITY_CAN_TARGET) + { + hasTarget = TRUE; + } + } + else if (categoryTargetingFlags == TARGETING_FLAG_HEAL_TEAM) + { + goto checkCanTarget; + } + else if (categoryTargetingFlags == TARGETING_FLAG_LONG_RANGE) + { + targetData = target->entityData; + goto checkThirdParty; + } + else if (categoryTargetingFlags == TARGETING_FLAG_ATTACK_ALL) + { + targetData = target->entityData; + if (user == target) + { + goto returnFalse; + } + checkThirdParty: + hasTarget = TRUE; + if (targetData->shopkeeperMode == SHOPKEEPER_FRIENDLY || + targetData->clientType == CLIENT_TYPE_DONT_MOVE || + targetData->clientType == CLIENT_TYPE_CLIENT) + { + returnFalse: + return FALSE; + } + } + else if (categoryTargetingFlags == TARGETING_FLAG_BOOST_TEAM) + { + if (user == target) + { + goto returnFalse; + } + checkCanTarget: + if (CanTarget(user, target, FALSE, TRUE) == TARGET_CAPABILITY_CANNOT_ATTACK) + { + hasTarget = TRUE; + } + } + else if ((u16) (categoryTargetingFlags - 3) <= 1) // categoryTargetingFlags == TARGETING_FLAG_ITEM + { + hasTarget = TRUE; + } + + if (hasTarget) + { + if (hasStatusChecker2) + { + if (!CanUseOnTargetWithStatusChecker(user, target, move)) + { + goto returnFalse; + } + if ((targetingFlags2 & 0xF00) == TARGETING_FLAG_SET_TRAP) + { + goto rollMoveUseChance; + } + else if ((targetingFlags2 & 0xF00) == TARGETING_FLAG_HEAL_HP) + { + if (!HasQuarterHPOrLess(target)) + { + if (*categoryTargetingFlags2); + goto returnFalse; + } + } + else if ((targetingFlags2 & 0xF00) == TARGETING_FLAG_HEAL_STATUS) + { + if (!HasNegativeStatus(target)) + { + if (*categoryTargetingFlags2); // Flips the conditional. + goto returnFalse; + } + } + else if ((targetingFlags2 & 0xF00) == TARGETING_FLAG_DREAM_EATER) + { + if (!IsSleeping(target)) + { + if (*categoryTargetingFlags2); // Flips the conditional. + goto returnFalse; + } + } + else if ((targetingFlags2 & 0xF00) == TARGETING_FLAG_EXPOSE) + { + targetData = target->entityData; + if ((targetData->type1 != TYPE_GHOST && targetData->type2 != TYPE_GHOST) || targetData->exposedStatus) + { + if (*categoryTargetingFlags2); // Flips the conditional. + goto returnFalse; + } + } + else if ((targetingFlags2 & 0xF00) == TARGETING_FLAG_HEAL_ALL) + { + if (!HasNegativeStatus(target) && !HasQuarterHPOrLess(target)) + { + if (*categoryTargetingFlags2); // Flips the conditional. + goto returnFalse; + } + } + } + else if ((targetingFlags2 & 0xF00) == TARGETING_FLAG_SET_TRAP) + { + s32 useChance; + rollMoveUseChance: + useChance = GetMoveAccuracy(move, ACCURACY_TYPE_USE_CHANCE); + if (DungeonRandomCapped(100) >= useChance) + { + goto returnFalse; + } + } + } + return hasTarget; +} |