Decomped CanAttackInDirection

This commit is contained in:
AnonymousRandomPerson 2025-07-18 23:16:28 -04:00
parent ed733270f1
commit ec92d0dcbd
6 changed files with 51 additions and 96 deletions

View File

@ -1,4 +1,5 @@
#pragma once
.public DIRECTIONAL_BIT_MASKS__02352770
.public DIRECTIONS_XY
.public DUNGEON_PTR
.public DungeonRandInt
@ -10,5 +11,3 @@
.public IsTacticSet
.public ItemIsActive__022FF898
.public SECONDARY_TERRAIN_TYPES
.public DIRECTIONAL_BIT_MASKS__02352770
.public DIRECTIONAL_BIT_MASKS__02352778

View File

@ -1,100 +1,8 @@
.include "asm/macros.inc"
.include "overlay_29_02301234.inc"
.include "overlay_29_023012F8.inc"
.text
arm_func_start CanAttackInDirection
CanAttackInDirection: ; 0x02301234
stmdb sp!, {r4, r5, r6, lr}
mov r6, r0
ldr r2, [r6, #0xb4]
mov r5, r1
ldrsh r1, [r2, #2]
bl GetMobilityTypeCheckSlipAndFloating
mov r4, r0
ldr r1, _023012EC ; =DIRECTIONS_XY
mov ip, r5, lsl #2
cmp r4, #1
ldr r0, _023012F0 ; =DIRECTIONS_XY + 2
ldrsh r3, [r1, ip]
ldrsh lr, [r6, #4]
ldrsh r1, [r0, ip]
ldrsh r2, [r6, #6]
add r0, lr, r3
movls r4, #2
add r1, r2, r1
bl GetTile
ldrh r1, [r0]
tst r1, #0x10
movne r0, #0
ldmneia sp!, {r4, r5, r6, pc}
ldr r0, [r0, #0xc]
cmp r0, #0
ldrne r0, [r0]
cmpne r0, #1
movne r0, #0
ldmneia sp!, {r4, r5, r6, pc}
#ifdef JAPAN
bl IsCurrentTilesetBackground
cmp r0, #0
bne _02302778
ldr r0, [r6, #0xb4]
ldrb r0, [r0, #0xef]
cmp r0, #3
moveq r4, #3
beq _02302778
mov r0, r6
mov r1, #0x10
bl ItemIsActive__022FF898
cmp r0, #0
movne r4, #3
bne _02302778
mov r0, r6
mov r1, #0xc
bl IqSkillIsEnabled
cmp r0, #0
movne r4, #2
bne _02302778
mov r0, r6
mov r1, #0xd
bl IqSkillIsEnabled
cmp r0, #0
beq _02302778
tst r5, #1
movne r4, #2
moveq r4, #3
_02302778:
#else
mov r0, r6
mov r1, r4
and r2, r5, #0xff
bl GetDirectionalMobilityType
mov r4, r0
#endif
ldrsh r0, [r6, #4]
ldrsh r1, [r6, #6]
bl GetTile
add r0, r0, r4
ldr r1, _023012F4 ; =DIRECTIONAL_BIT_MASKS__02352778
and r2, r5, #7
ldrb r1, [r1, r2]
ldrb r0, [r0, #8]
tst r1, r0
#ifdef JAPAN
movne r0, #1
moveq r0, #0
and r0, r0, #0xff
#else
moveq r0, #0
movne r0, #1
#endif
ldmia sp!, {r4, r5, r6, pc}
.align 2, 0
_023012EC: .word DIRECTIONS_XY
_023012F0: .word DIRECTIONS_XY + 2
_023012F4: .word DIRECTIONAL_BIT_MASKS__02352778
arm_func_end CanAttackInDirection
arm_func_start CanAiMonsterMoveInDirection
CanAiMonsterMoveInDirection: ; 0x023012F8
stmdb sp!, {r4, r5, r6, r7, r8, lr}

View File

@ -8,5 +8,8 @@ bool8 IsMonsterCornered(struct entity *monster);
// Checks if the given monster can move in the specified direction. Includes if an allied or neutral monster is standing on an adjacent tile, as the monsters can swap places.
// Returns false if an enemy monster is standing on the target tile
bool8 CanMonsterMoveOrSwapWithAllyInDirection(struct entity *monster, s32 direction);
// Returns whether a monster can attack in a given direction.
// The check fails if the destination tile is impassable, contains a monster that isn't of type entity_type::ENTITY_MONSTER or if the monster can't directly move from the current tile into the destination tile.
bool8 CanAttackInDirection(struct entity *monster, s32 direction);
#endif //PMDSKY_DUNGEON_CAPABILITIES_4_H

View File

@ -378,7 +378,7 @@ Overlay OVY_29
Object src/dungeon_capabilities_3.o
Object asm/overlay_29_02300FCC.o
Object src/dungeon_capabilities_4.o
Object asm/overlay_29_02301234.o
Object asm/overlay_29_023012F8.o
Object src/dungeon_ai_targeting.o
Object asm/overlay_29_023016D8.o
Object src/dungeon_ai_targeting_1.o

View File

@ -68,3 +68,47 @@ bool8 CanMonsterMoveOrSwapWithAllyInDirection(struct entity *monster, s32 direct
return FALSE;
}
bool8 CanAttackInDirection(struct entity *monster, s32 direction)
{
struct monster *monster_info = GetEntInfo(monster);
enum mobility_type mobility = GetMobilityTypeCheckSlipAndFloating(monster, monster_info->id);
if (mobility <= MOBILITY_SECONDARY)
mobility = MOBILITY_HOVERING;
const struct tile *current_map_tile = GetTile(monster->pos.x + DIRECTIONS_XY[direction].x,
monster->pos.y + DIRECTIONS_XY[direction].y);
if (current_map_tile->terrain_flags & TERRAIN_TYPE_IMPASSABLE_WALL)
return FALSE;
if (current_map_tile->monster != NULL && current_map_tile->monster->type != ENTITY_MONSTER)
return FALSE;
#ifdef JAPAN
if (!IsCurrentTilesetBackground())
{
if (GetEntInfo(monster)->invisible_class_status.status == STATUS_INVISIBLE_MOBILE)
mobility = MOBILITY_INTANGIBLE;
else if (ItemIsActive__022FF898(monster, ITEM_MOBILE_SCARF))
mobility = MOBILITY_INTANGIBLE;
else if (IqSkillIsEnabled(monster, IQ_ALL_TERRAIN_HIKER))
// BUG: If a Pokémon can normally attack through walls, All-Terrain Hiker will block them from attacking through walls.
// This bug is fixed in the NA/EU versions.
mobility = MOBILITY_HOVERING;
else if (IqSkillIsEnabled(monster, IQ_ABSOLUTE_MOVER)) {
if (direction & 1)
mobility = MOBILITY_HOVERING;
else
mobility = MOBILITY_INTANGIBLE;
}
}
#else
mobility = GetDirectionalMobilityType(monster, mobility, direction);
#endif
current_map_tile = GetTile(monster->pos.x, monster->pos.y);
if (!(current_map_tile->walkable_neighbor_flags[mobility] & DIRECTIONAL_BIT_MASKS__02352778[direction & DIRECTION_MASK]))
return FALSE;
return TRUE;
}

View File

@ -35,6 +35,7 @@ bool8 StatusCheckerCheck(struct entity *attacker, struct move *move)
return FALSE;
break;
case MOVE_MIRROR_MOVE:
// This check is inconsistent for the Chatot Scarf because it includes RNG.
if (MirrorMoveIsActive(attacker))
return FALSE;
break;