mirror of
https://github.com/pret/pmd-red.git
synced 2026-04-24 06:57:18 -05:00
Decomped TargetRegularAttack()
This commit is contained in:
parent
83d097624b
commit
cc4053130f
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user