diff options
author | AnonymousRandomPerson <chenghanngan.us@gmail.com> | 2022-03-10 22:20:44 -0500 |
---|---|---|
committer | AnonymousRandomPerson <chenghanngan.us@gmail.com> | 2022-03-10 22:33:13 -0500 |
commit | cc4053130f1d9d0bb36c78bd39b0b07e96064f5e (patch) | |
tree | ef1292c42922bdb50518d3607070dff130260971 | |
parent | 83d097624b48c58ed081ccc8f2cd9e613d290128 (diff) |
Decomped TargetRegularAttack()
-rw-r--r-- | asm/code_807C854.s | 234 | ||||
-rw-r--r-- | include/dungeon_ai_attack.h | 2 | ||||
-rw-r--r-- | include/dungeon_ai_attack_1.h | 8 | ||||
-rwxr-xr-x | ld_script.txt | 2 | ||||
-rw-r--r-- | src/dungeon_ai_attack.c | 147 | ||||
-rw-r--r-- | src/dungeon_ai_attack_1.c | 76 | ||||
-rw-r--r-- | src/dungeon_ai_items.c | 1 |
7 files changed, 146 insertions, 324 deletions
diff --git a/asm/code_807C854.s b/asm/code_807C854.s deleted file mode 100644 index 40a8c49..0000000 --- a/asm/code_807C854.s +++ /dev/null @@ -1,234 +0,0 @@ - #include "asm/constants/gba_constants.inc" - #include "asm/macros.inc" - - .syntax unified - - .text - - thumb_func_start TargetRegularAttack -TargetRegularAttack: - push {r4-r7,lr} - mov r7, r10 - mov r6, r9 - mov r5, r8 - push {r5-r7} - sub sp, 0x50 - adds r7, r0, 0 - str r1, [sp, 0x40] - lsls r2, 24 - lsrs r2, 24 - str r2, [sp, 0x44] - ldr r0, [r7, 0x70] - movs r1, 0 - mov r8, r1 - adds r1, r0, 0 - adds r1, 0x46 - ldrb r6, [r1] - adds r0, 0xE8 - ldrb r0, [r0] - movs r3, 0x8 - mov r10, r3 - cmp r0, 0x1 - bne _0807C886 - movs r0, 0x1 - mov r10, r0 -_0807C886: - movs r4, 0 - adds r0, r7, 0 - movs r1, 0x9 - bl HasIQSkill - lsls r0, 24 - cmp r0, 0 - bne _0807C8A4 - adds r0, r7, 0 - movs r1, 0xA - bl HasIQSkill - lsls r0, 24 - cmp r0, 0 - beq _0807C8A6 -_0807C8A4: - movs r4, 0x1 -_0807C8A6: - str r4, [sp, 0x48] - adds r0, r7, 0 - movs r1, 0x8 - bl HasIQSkill - lsls r0, 24 - lsrs r0, 24 - str r0, [sp, 0x4C] - movs r1, 0 - mov r9, r1 - cmp r9, r10 - bge _0807C952 -_0807C8BE: - movs r0, 0x7 - ands r6, r0 - movs r3, 0x4 - ldrsh r0, [r7, r3] - ldr r1, _0807C95C - lsls r2, r6, 2 - adds r2, r1 - movs r3, 0 - ldrsh r1, [r2, r3] - adds r0, r1 - movs r3, 0x6 - ldrsh r1, [r7, r3] - movs r3, 0x2 - ldrsh r2, [r2, r3] - adds r1, r2 - bl GetMapTile_1 - ldr r5, [r0, 0x10] - cmp r5, 0 - beq _0807C948 - adds r0, r5, 0 - bl GetEntityType - cmp r0, 0x1 - bne _0807C948 - adds r0, r7, 0 - adds r1, r6, 0 - bl CanAttackInFront - lsls r0, 24 - cmp r0, 0 - beq _0807C948 - adds r0, r7, 0 - adds r1, r5, 0 - movs r2, 0 - ldr r3, [sp, 0x44] - bl CanTarget - lsls r0, 24 - lsrs r0, 24 - cmp r0, 0x1 - bne _0807C948 - ldr r0, [sp, 0x4C] - cmp r0, 0 - beq _0807C922 - ldr r0, [r5, 0x70] - adds r0, 0xB0 - ldrb r0, [r0] - cmp r0, 0x1 - beq _0807C948 -_0807C922: - mov r1, r8 - lsls r4, r1, 2 - mov r3, sp - adds r0, r3, r4 - str r6, [r0] - adds r0, r7, 0 - movs r1, 0 - adds r2, r5, 0 - movs r3, 0 - bl WeightMove - add r1, sp, 0x20 - adds r1, r4 - str r0, [r1] - ldr r0, [sp, 0x48] - cmp r0, 0 - beq _0807C960 - movs r1, 0x1 - add r8, r1 -_0807C948: - movs r3, 0x1 - add r9, r3 - adds r6, 0x1 - cmp r9, r10 - blt _0807C8BE -_0807C952: - mov r0, r8 - cmp r0, 0 - bne _0807C966 - movs r0, 0 - b _0807C9E8 - .align 2, 0 -_0807C95C: .4byte gAdjacentTileOffsets -_0807C960: - ldr r1, [sp, 0x40] - str r6, [r1] - b _0807C9E6 -_0807C966: - movs r4, 0 - movs r3, 0 - mov r0, r8 - cmp r0, 0 - ble _0807C984 - add r1, sp, 0x20 - mov r2, r8 -_0807C974: - ldr r0, [r1] - cmp r3, r0 - bge _0807C97C - adds r3, r0, 0 -_0807C97C: - adds r1, 0x4 - subs r2, 0x1 - cmp r2, 0 - bne _0807C974 -_0807C984: - mov r1, r8 - cmp r1, 0 - ble _0807C9A0 - movs r5, 0 - add r1, sp, 0x20 - mov r2, r8 -_0807C990: - ldr r0, [r1] - cmp r3, r0 - beq _0807C998 - str r5, [r1] -_0807C998: - adds r1, 0x4 - subs r2, 0x1 - cmp r2, 0 - bne _0807C990 -_0807C9A0: - mov r3, r8 - cmp r3, 0 - ble _0807C9B4 - add r1, sp, 0x20 - mov r2, r8 -_0807C9AA: - ldm r1!, {r0} - adds r4, r0 - subs r2, 0x1 - cmp r2, 0 - bne _0807C9AA -_0807C9B4: - adds r0, r4, 0 - bl DungeonRandomCapped - adds r1, r0, 0 - movs r2, 0 - cmp r2, r8 - bge _0807C9DC - ldr r0, [sp, 0x20] - subs r1, r0 - cmp r1, 0 - blt _0807C9DC - add r3, sp, 0x20 -_0807C9CC: - adds r3, 0x4 - adds r2, 0x1 - cmp r2, r8 - bge _0807C9DC - ldr r0, [r3] - subs r1, r0 - cmp r1, 0 - bge _0807C9CC -_0807C9DC: - lsls r0, r2, 2 - add r0, sp - ldr r0, [r0] - ldr r1, [sp, 0x40] - str r0, [r1] -_0807C9E6: - movs r0, 0x1 -_0807C9E8: - add sp, 0x50 - pop {r3-r5} - mov r8, r3 - mov r9, r4 - mov r10, r5 - pop {r4-r7} - pop {r1} - bx r1 - thumb_func_end TargetRegularAttack - - .align 2, 0
\ No newline at end of file diff --git a/include/dungeon_ai_attack.h b/include/dungeon_ai_attack.h index aa840fd..cd8d9d8 100644 --- a/include/dungeon_ai_attack.h +++ b/include/dungeon_ai_attack.h @@ -18,5 +18,7 @@ bool8 IsTargetInLineRange(struct DungeonEntity *user, struct DungeonEntity *targ s32 WeightMoveIfUsable(s32 numPotentialTargets, s32 targetingFlags, struct DungeonEntity *user, struct DungeonEntity *target, struct PokemonMove *move, u32 hasStatusChecker); bool8 CanUseStatusMove(s32 targetingFlags, struct DungeonEntity *user, struct DungeonEntity *target, struct PokemonMove *move, bool32 hasStatusChecker); s32 WeightMove(struct DungeonEntity *user, s32 targetingFlags, struct DungeonEntity *target, u32 moveType); +bool8 TargetRegularAttack(struct DungeonEntity *pokemon, u32 *targetDir, bool8 checkPetrified); +bool8 IsTargetStraightAhead(struct DungeonEntity *pokemon, struct DungeonEntity *targetPokemon, s32 facingDir, s32 maxRange); #endif diff --git a/include/dungeon_ai_attack_1.h b/include/dungeon_ai_attack_1.h deleted file mode 100644 index dc9e9c9..0000000 --- a/include/dungeon_ai_attack_1.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef GUARD_DUNGEON_AI_ATTACK_1_H -#define GUARD_DUNGEON_AI_ATTACK_1_H - -#include "dungeon_entity.h" - -bool8 IsTargetStraightAhead(struct DungeonEntity *pokemon, struct DungeonEntity *targetPokemon, s32 facingDir, s32 maxRange); - -#endif diff --git a/ld_script.txt b/ld_script.txt index e2cbe38..ea6c581 100755 --- a/ld_script.txt +++ b/ld_script.txt @@ -245,8 +245,6 @@ SECTIONS { src/status.o(.text); asm/code_8077274.o(.text); src/dungeon_ai_attack.o(.text); - asm/code_807C854.o(.text); - src/dungeon_ai_attack_1.o(.text); asm/code_807CABC.o(.text); src/targeting_flags.o(.text); asm/code_807CD9C.o(.text); diff --git a/src/dungeon_ai_attack.c b/src/dungeon_ai_attack.c index f55c20d..6dbefbd 100644 --- a/src/dungeon_ai_attack.c +++ b/src/dungeon_ai_attack.c @@ -14,7 +14,6 @@ #include "dungeon_ai_targeting.h" #include "dungeon_ai_targeting_1.h" #include "dungeon_ai_targeting_2.h" -#include "dungeon_ai_attack_1.h" #include "dungeon_capabilities_1.h" #include "dungeon_global_data.h" #include "dungeon_map_access.h" @@ -43,8 +42,6 @@ extern s32 gPotentialAttackTargetWeights[NUM_DIRECTIONS]; extern u8 gPotentialAttackTargetDirections[NUM_DIRECTIONS]; extern struct DungeonEntity *gPotentialTargets[NUM_DIRECTIONS]; -extern bool8 TargetRegularAttack(struct DungeonEntity*, u32*, bool8); - void DecideAttack(struct DungeonEntity *pokemon) { struct DungeonEntityData *pokemonData = pokemon->entityData; @@ -781,3 +778,147 @@ s32 WeightMove(struct DungeonEntity *user, s32 targetingFlags, struct DungeonEnt } return weight; } + +bool8 TargetRegularAttack(struct DungeonEntity *pokemon, u32 *targetDir, bool8 checkPetrified) +{ + struct DungeonEntityData *pokemonData = pokemon->entityData; + s32 numPotentialTargets = 0; + s32 facingDir = pokemonData->action.facingDir; + s32 faceTurnLimit = pokemonData->eyesightStatus == EYESIGHT_STATUS_BLINKER ? 1 : 8; + s32 i; + s32 potentialAttackTargetDirections[NUM_DIRECTIONS]; + s32 potentialAttackTargetWeights[NUM_DIRECTIONS]; + bool8 hasTargetingIQ = HasIQSkill(pokemon, IQ_SKILL_EXP_GO_GETTER) || HasIQSkill(pokemon, IQ_SKILL_EFFICIENCY_EXPERT); + bool8 hasStatusChecker = HasIQSkill(pokemon, IQ_SKILL_STATUS_CHECKER); + for (i = 0; i < faceTurnLimit; i++, facingDir++) + { + struct DungeonEntity *target; + facingDir &= DIRECTION_MASK; + target = GetMapTile_1(pokemon->posWorld.x + gAdjacentTileOffsets[facingDir].x, + pokemon->posWorld.y + gAdjacentTileOffsets[facingDir].y)->pokemon; + if (target != NULL && + GetEntityType(target) == ENTITY_POKEMON && + CanAttackInFront(pokemon, facingDir) && + CanTarget(pokemon, target, FALSE, checkPetrified) == TARGET_CAPABILITY_CAN_TARGET && + (!hasStatusChecker || target->entityData->immobilizeStatus != IMMOBILIZE_STATUS_FROZEN)) + { + potentialAttackTargetDirections[numPotentialTargets] = facingDir; + potentialAttackTargetWeights[numPotentialTargets] = WeightMove(pokemon, TARGETING_FLAG_TARGET_OTHER, target, TYPE_NONE); + if (!hasTargetingIQ) + { + *targetDir = facingDir; + return TRUE; + } + numPotentialTargets++; + } + } + if (numPotentialTargets == 0) + { + return FALSE; + } + else + { + s32 totalWeight = 0; + s32 maxWeight = 0; + s32 weightCounter; + s32 i; + for (i = 0; i < numPotentialTargets; i++) + { + if (maxWeight < potentialAttackTargetWeights[i]) + { + maxWeight = potentialAttackTargetWeights[i]; + } + } + for (i = 0; i < numPotentialTargets; i++) + { + if (maxWeight != potentialAttackTargetWeights[i]) + { + potentialAttackTargetWeights[i] = 0; + } + } + for (i = 0; i < numPotentialTargets; i++) + { + totalWeight += potentialAttackTargetWeights[i]; + } + weightCounter = DungeonRandomCapped(totalWeight); + for (i = 0; i < numPotentialTargets; i++) + { + weightCounter -= potentialAttackTargetWeights[i]; + if (weightCounter < 0) + { + break; + } + } + *targetDir = potentialAttackTargetDirections[i]; + return TRUE; + } + +} + +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_attack_1.c b/src/dungeon_ai_attack_1.c deleted file mode 100644 index 641bc8c..0000000 --- a/src/dungeon_ai_attack_1.c +++ /dev/null @@ -1,76 +0,0 @@ -#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 "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 7b85cf7..090e24a 100644 --- a/src/dungeon_ai_items.c +++ b/src/dungeon_ai_items.c @@ -7,7 +7,6 @@ #include "constants/targeting.h" #include "dungeon_action.h" #include "dungeon_ai_attack.h" -#include "dungeon_ai_attack_1.h" #include "dungeon_ai_item_weight.h" #include "dungeon_ai_items.h" #include "dungeon_ai_targeting_2.h" |