diff options
author | AnonymousRandomPerson <chenghanngan.us@gmail.com> | 2022-02-22 22:38:57 -0500 |
---|---|---|
committer | AnonymousRandomPerson <chenghanngan.us@gmail.com> | 2022-02-22 22:38:57 -0500 |
commit | 40a34fafd685b7df6d1777ec335374ea081adad0 (patch) | |
tree | e54c5947527efdcd4bfb74bee51d7d2bff65b19c /src | |
parent | 598a588589cb581b269f2e46373c657ec897a3a3 (diff) |
Decomped WeightMoveIfUsable()
Diffstat (limited to 'src')
-rw-r--r-- | src/dungeon_ai_attack.c | 20 | ||||
-rw-r--r-- | src/dungeon_ai_attack_1.c | 194 | ||||
-rw-r--r-- | src/dungeon_ai_attack_2.c | 76 | ||||
-rw-r--r-- | src/dungeon_ai_items.c | 10 | ||||
-rw-r--r-- | src/moves.c | 2 | ||||
-rw-r--r-- | src/targeting_flags.c | 2 |
6 files changed, 224 insertions, 80 deletions
diff --git a/src/dungeon_ai_attack.c b/src/dungeon_ai_attack.c index 7368e66..65973a1 100644 --- a/src/dungeon_ai_attack.c +++ b/src/dungeon_ai_attack.c @@ -13,6 +13,7 @@ #include "dungeon_ai_targeting.h" #include "dungeon_ai_targeting_1.h" #include "dungeon_ai_attack_1.h" +#include "dungeon_ai_attack_2.h" #include "dungeon_capabilities_1.h" #include "dungeon_global_data.h" #include "dungeon_map_access.h" @@ -34,13 +35,12 @@ const s16 gRegularAttackWeights[] = {100, 20, 30, 40, 50}; extern bool8 gCanAttackInDirection[NUM_DIRECTIONS]; extern s32 gNumPotentialTargets; -extern s32 gPotentialTargetWeights_2[NUM_DIRECTIONS]; +extern s32 gPotentialAttackTargetWeights[NUM_DIRECTIONS]; extern u8 gPotentialAttackTargetDirections[NUM_DIRECTIONS]; extern struct DungeonEntity *gPotentialTargets[NUM_DIRECTIONS]; extern bool8 IsMoveUsable_1(struct DungeonEntity*, s32, bool8); extern bool8 TargetRegularAttack(struct DungeonEntity*, u32*, bool8); -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); extern s32 WeightMove(struct DungeonEntity*, s32, struct DungeonEntity*, u8); @@ -366,7 +366,7 @@ s32 FindMoveTarget(struct MoveTargetResults *moveTargetResults, struct DungeonEn { gCanAttackInDirection[i] = TRUE; gPotentialAttackTargetDirections[numPotentialTargets] = i; - gPotentialTargetWeights_2[numPotentialTargets] = 99; + gPotentialAttackTargetWeights[numPotentialTargets] = 99; gPotentialTargets[numPotentialTargets] = NULL; numPotentialTargets++; } @@ -457,7 +457,7 @@ s32 FindMoveTarget(struct MoveTargetResults *moveTargetResults, struct DungeonEn { gCanAttackInDirection[facingDir] = TRUE; gPotentialAttackTargetDirections[numPotentialTargets] = facingDir; - gPotentialTargetWeights_2[numPotentialTargets] = WeightMove(pokemon, targetingFlags, target, GetMoveTypeForPokemon(pokemon, move)); + gPotentialAttackTargetWeights[numPotentialTargets] = WeightMove(pokemon, targetingFlags, target, GetMoveTypeForPokemon(pokemon, move)); gPotentialTargets[numPotentialTargets] = target; numPotentialTargets++; } @@ -492,27 +492,27 @@ s32 FindMoveTarget(struct MoveTargetResults *moveTargetResults, struct DungeonEn s32 i; for (i = 0; i < numPotentialTargets; i++) { - if (maxWeight < gPotentialTargetWeights_2[i]) + if (maxWeight < gPotentialAttackTargetWeights[i]) { - maxWeight = gPotentialTargetWeights_2[i]; + maxWeight = gPotentialAttackTargetWeights[i]; } } for (i = 0; i < numPotentialTargets; i++) { - if (maxWeight != gPotentialTargetWeights_2[i]) + if (maxWeight != gPotentialAttackTargetWeights[i]) { - gPotentialTargetWeights_2[i] = 0; + gPotentialAttackTargetWeights[i] = 0; } } moveWeight = maxWeight; for (i = 0; i < numPotentialTargets; i++) { - totalWeight += gPotentialTargetWeights_2[i]; + totalWeight += gPotentialAttackTargetWeights[i]; } weightCounter = DungeonRandomCapped(totalWeight); for (i = 0; i < numPotentialTargets; i++) { - weightCounter -= gPotentialTargetWeights_2[i]; + weightCounter -= gPotentialAttackTargetWeights[i]; if (weightCounter < 0) { break; diff --git a/src/dungeon_ai_attack_1.c b/src/dungeon_ai_attack_1.c index 641bc8c..fb088fb 100644 --- a/src/dungeon_ai_attack_1.c +++ b/src/dungeon_ai_attack_1.c @@ -1,76 +1,144 @@ #include "global.h" #include "dungeon_ai_attack_1.h" -#include "constants/iq_skill.h" -#include "dungeon_global_data.h" -#include "dungeon_map_access.h" +#include "constants/direction.h" #include "dungeon_pokemon_attributes.h" -#include "dungeon_util.h" +#include "position_util.h" -bool8 IsTargetStraightAhead(struct DungeonEntity *pokemon, struct DungeonEntity *targetPokemon, s32 facingDir, s32 maxRange) +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); + +s32 WeightMoveIfUsable(s32 numPotentialTargets, s32 targetingFlags, struct DungeonEntity *user, struct DungeonEntity *target, struct PokemonMove *move, bool32 hasStatusChecker) { - s32 posDiffX = pokemon->posWorld.x - targetPokemon->posWorld.x; - s32 effectiveMaxRange; - if (posDiffX < 0) - { - posDiffX = -posDiffX; - } - effectiveMaxRange = pokemon->posWorld.y - targetPokemon->posWorld.y; - if (effectiveMaxRange < 0) - { - effectiveMaxRange = -effectiveMaxRange; - } - if (effectiveMaxRange < posDiffX) + s32 facingDir; + s32 targetingFlags2 = (s16) targetingFlags; + bool8 hasStatusChecker2 = hasStatusChecker; + struct DungeonEntityData *userData = user->entityData; + if ((user->posWorld.x == target->posWorld.x && user->posWorld.y == target->posWorld.y) || + (targetingFlags2 & 0xF0) == TARGETING_FLAG_TARGET_ROOM || + (targetingFlags2 & 0xF0) == TARGETING_FLAG_TARGET_FLOOR || + (targetingFlags2 & 0xF0) == TARGETING_FLAG_TARGET_SELF) { - effectiveMaxRange = posDiffX; + facingDir = userData->action.facingDir; } - if (effectiveMaxRange > maxRange) + else { - effectiveMaxRange = maxRange; + facingDir = CalculateFacingDir(&user->posWorld, &target->posWorld); } - if (!HasIQSkill(pokemon, IQ_SKILL_COURSE_CHECKER)) + if (!gCanAttackInDirection[facingDir] && + CanUseStatusMove(targetingFlags2, user, target, move, hasStatusChecker2)) { - // BUG: effectiveMaxRange is already capped at maxRange, so this condition always evaluates to TRUE. - // The AI also has range checks elsewhere, so this doesn't become an issue in most cases. - // If the AI has the Long Toss or Pierce statuses and Course Checker is disabled, - // this incorrect check causes the AI to throw items at targets further than 10 tiles away. - if (effectiveMaxRange <= maxRange) - { - return TRUE; - } + gCanAttackInDirection[facingDir] = TRUE; + do { gPotentialAttackTargetDirections[numPotentialTargets] = facingDir; } while (0); + gPotentialAttackTargetWeights[numPotentialTargets] = WeightMove(user, targetingFlags2, target, GetMoveTypeForPokemon(user, move)); + gPotentialTargets[numPotentialTargets] = target; + numPotentialTargets++; } - else - { - s32 currentPosX = pokemon->posWorld.x; - s32 currentPosY = pokemon->posWorld.y; - s32 adjacentTileOffsetX = gAdjacentTileOffsets[facingDir].x; - s32 adjacentTileOffsetY = gAdjacentTileOffsets[facingDir].y; - s32 i; - for (i = 0; i <= effectiveMaxRange; i++) - { - struct MapTile *mapTile; - currentPosX += adjacentTileOffsetX; - currentPosY += adjacentTileOffsetY; - if (currentPosX <= 0 || currentPosY <= 0 || - currentPosX >= DUNGEON_MAX_SIZE_X - 1 || currentPosY >= DUNGEON_MAX_SIZE_Y - 1) - { - break; - } - while (0); // Extra label needed to swap branch locations in ASM. - mapTile = GetMapTile_1(currentPosX, currentPosY); - if (!(mapTile->tileType & (TILE_TYPE_FLOOR | TILE_TYPE_LIQUID))) - { - break; - } - if (mapTile->pokemon == targetPokemon) - { - return TRUE; - } - if (mapTile->pokemon != NULL) - { - break; - } - } - } - return FALSE; + 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"); +// } diff --git a/src/dungeon_ai_attack_2.c b/src/dungeon_ai_attack_2.c new file mode 100644 index 0000000..41e924a --- /dev/null +++ b/src/dungeon_ai_attack_2.c @@ -0,0 +1,76 @@ +#include "global.h" +#include "dungeon_ai_attack_2.h" + +#include "constants/iq_skill.h" +#include "dungeon_global_data.h" +#include "dungeon_map_access.h" +#include "dungeon_pokemon_attributes.h" +#include "dungeon_util.h" + +bool8 IsTargetStraightAhead(struct DungeonEntity *pokemon, struct DungeonEntity *targetPokemon, s32 facingDir, s32 maxRange) +{ + s32 posDiffX = pokemon->posWorld.x - targetPokemon->posWorld.x; + s32 effectiveMaxRange; + if (posDiffX < 0) + { + posDiffX = -posDiffX; + } + effectiveMaxRange = pokemon->posWorld.y - targetPokemon->posWorld.y; + if (effectiveMaxRange < 0) + { + effectiveMaxRange = -effectiveMaxRange; + } + if (effectiveMaxRange < posDiffX) + { + effectiveMaxRange = posDiffX; + } + if (effectiveMaxRange > maxRange) + { + effectiveMaxRange = maxRange; + } + if (!HasIQSkill(pokemon, IQ_SKILL_COURSE_CHECKER)) + { + // BUG: effectiveMaxRange is already capped at maxRange, so this condition always evaluates to TRUE. + // The AI also has range checks elsewhere, so this doesn't become an issue in most cases. + // If the AI has the Long Toss or Pierce statuses and Course Checker is disabled, + // this incorrect check causes the AI to throw items at targets further than 10 tiles away. + if (effectiveMaxRange <= maxRange) + { + return TRUE; + } + } + else + { + s32 currentPosX = pokemon->posWorld.x; + s32 currentPosY = pokemon->posWorld.y; + s32 adjacentTileOffsetX = gAdjacentTileOffsets[facingDir].x; + s32 adjacentTileOffsetY = gAdjacentTileOffsets[facingDir].y; + s32 i; + for (i = 0; i <= effectiveMaxRange; i++) + { + struct MapTile *mapTile; + currentPosX += adjacentTileOffsetX; + currentPosY += adjacentTileOffsetY; + if (currentPosX <= 0 || currentPosY <= 0 || + currentPosX >= DUNGEON_MAX_SIZE_X - 1 || currentPosY >= DUNGEON_MAX_SIZE_Y - 1) + { + break; + } + while (0); // Extra label needed to swap branch locations in ASM. + mapTile = GetMapTile_1(currentPosX, currentPosY); + if (!(mapTile->tileType & (TILE_TYPE_FLOOR | TILE_TYPE_LIQUID))) + { + break; + } + if (mapTile->pokemon == targetPokemon) + { + return TRUE; + } + if (mapTile->pokemon != NULL) + { + break; + } + } + } + return FALSE; +} diff --git a/src/dungeon_ai_items.c b/src/dungeon_ai_items.c index 0135c62..31d57ff 100644 --- a/src/dungeon_ai_items.c +++ b/src/dungeon_ai_items.c @@ -6,7 +6,7 @@ #include "constants/status.h" #include "constants/targeting.h" #include "dungeon_action.h" -#include "dungeon_ai_attack_1.h" +#include "dungeon_ai_attack_2.h" #include "dungeon_ai_item_weight.h" #include "dungeon_ai_items.h" #include "dungeon_ai_targeting_2.h" @@ -39,7 +39,7 @@ enum ItemTargetFlag extern void sub_8077274(struct DungeonEntity *, struct DungeonEntity *); extern s32 gNumPotentialTargets; -extern u32 gPotentialTargetWeights[NUM_DIRECTIONS]; +extern u32 gPotentialItemTargetWeights[NUM_DIRECTIONS]; extern u32 gPotentialItemTargetDirections[NUM_DIRECTIONS]; extern bool8 gTargetAhead[NUM_DIRECTIONS]; extern struct TeamInventory *gTeamInventory_203B460; @@ -95,7 +95,7 @@ void DecideUseItem(struct DungeonEntity *pokemon) FindStraightThrowableTargets(pokemon, 2, item, 1); for (targetIndex = 0; targetIndex < gNumPotentialTargets; targetIndex++) { - if (RollPercentChance(gPotentialTargetWeights[targetIndex])) + if (RollPercentChance(gPotentialItemTargetWeights[targetIndex])) { SetAction(&pokemonData->action, DUNGEON_ACTION_THROW_ITEM_AI); pokemonData->action.actionUseIndex = selectedToolboxIndex; @@ -229,7 +229,7 @@ void DecideUseItem(struct DungeonEntity *pokemon) s32 thrownAIFlag; for (thrownAIFlag = ITEM_AI_FLAG_TARGET_ALLY; thrownAIFlag <= ITEM_AI_FLAG_TARGET_ENEMY; thrownAIFlag++) { - potentialTargetWeights = gPotentialTargetWeights; + potentialTargetWeights = gPotentialItemTargetWeights; if (GetItemAIFlag(item->itemIndex, thrownAIFlag)) { u8 itemType = GetItemType(item->itemIndex); @@ -422,7 +422,7 @@ void TargetThrownItem(struct DungeonEntity *pokemon, struct DungeonEntity *targe u32 *targetWeight; gTargetAhead[targetDirection] = TRUE; gPotentialItemTargetDirections[gNumPotentialTargets] = targetDirection; - targetWeight = &gPotentialTargetWeights[gNumPotentialTargets]; + targetWeight = &gPotentialItemTargetWeights[gNumPotentialTargets]; itemWeight = !ignoreRollChance ? EvaluateItem(targetPokemon, item, targetingFlags) : 100; *targetWeight = itemWeight; gNumPotentialTargets++; diff --git a/src/moves.c b/src/moves.c index 0874f00..a7caed6 100644 --- a/src/moves.c +++ b/src/moves.c @@ -158,7 +158,7 @@ void InitZeroedPPPokemonMove(struct PokemonMove *move, u16 moveID) move->PP = 0; } -s16 GetMoveTargetingFlags(struct PokemonMove *move, u32 isAI) +s16 GetMoveTargetingFlags(struct PokemonMove *move, bool32 isAI) { return gMovesData[move->moveID].targetingFlags[isAI]; } diff --git a/src/targeting_flags.c b/src/targeting_flags.c index f315cdf..bc6010b 100644 --- a/src/targeting_flags.c +++ b/src/targeting_flags.c @@ -6,7 +6,7 @@ #include "dungeon_pokemon_attributes.h" #include "moves.h" -s16 GetMoveTargetingFlagsForPokemon(struct DungeonEntity *pokemon, struct PokemonMove *move, u32 isAI) +s16 GetMoveTargetingFlagsForPokemon(struct DungeonEntity *pokemon, struct PokemonMove *move, bool32 isAI) { if (move->moveID == MOVE_CURSE && !isAI && !HasType(pokemon, TYPE_GHOST)) { |