summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnonymousRandomPerson <chenghanngan.us@gmail.com>2022-03-10 22:20:44 -0500
committerAnonymousRandomPerson <chenghanngan.us@gmail.com>2022-03-10 22:33:13 -0500
commitcc4053130f1d9d0bb36c78bd39b0b07e96064f5e (patch)
treeef1292c42922bdb50518d3607070dff130260971
parent83d097624b48c58ed081ccc8f2cd9e613d290128 (diff)
Decomped TargetRegularAttack()
-rw-r--r--asm/code_807C854.s234
-rw-r--r--include/dungeon_ai_attack.h2
-rw-r--r--include/dungeon_ai_attack_1.h8
-rwxr-xr-xld_script.txt2
-rw-r--r--src/dungeon_ai_attack.c147
-rw-r--r--src/dungeon_ai_attack_1.c76
-rw-r--r--src/dungeon_ai_items.c1
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"