Merge branch 'main' of https://github.com/pret/pmd-sky into ground_bg

This commit is contained in:
DizzyEggg
2025-08-06 12:33:03 +02:00
9 changed files with 150 additions and 211 deletions

View File

@@ -69,9 +69,9 @@ us: ; @$(MAKE) GAME_LANGUAGE=NORTH_AMERICA
eu: ; @$(MAKE) GAME_LANGUAGE=EUROPE
jp: ; @$(MAKE) GAME_LANGUAGE=JAPAN
us-nonmatching: ; @$(MAKE) GAME_LANGUAGE=NORTH_AMERICA NONMATCHING=TRUE
eu-nonmatching: ; @$(MAKE) GAME_LANGUAGE=EUROPE NONMATCHING=TRUE
jp-nonmatching: ; @$(MAKE) GAME_LANGUAGE=JAPAN NONMATCHING=TRUE
us-nonmatching: ; @$(MAKE) GAME_LANGUAGE=NORTH_AMERICA NONMATCHING=TRUE COMPARE=0
eu-nonmatching: ; @$(MAKE) GAME_LANGUAGE=EUROPE NONMATCHING=TRUE COMPARE=0
jp-nonmatching: ; @$(MAKE) GAME_LANGUAGE=JAPAN NONMATCHING=TRUE COMPARE=0
compare: @$(MAKE) COMPARE=1

View File

@@ -4,16 +4,11 @@
.public DIRECTIONS_XY
.public DUNGEON_PTR
.public DungeonRandInt
.public GetMoveAccuracyOrAiChance
.public GetTile
.public GetTreatmentBetweenMonsters
.public HasHeldItem
.public IqSkillIsEnabled
.public IsBlinded
.public IsMonsterSleeping
.public MonsterHasNegativeStatus
.public _s32_div_f
.public ov29_023007DC
.public ov29_0230B7D4
.public ov29_0230F8D0
.public ov29_02333FD0

View File

@@ -1,203 +1,8 @@
.include "asm/macros.inc"
.include "overlay_29_0231A0A4.inc"
.include "overlay_29_0231A364.inc"
.text
arm_func_start IsAiTargetEligible
IsAiTargetEligible: ; 0x0231A0A4
stmdb sp!, {r4, r5, r6, r7, r8, lr}
mov r8, r0
mov r6, r2
mov r2, #0
mov r7, r1
mov r5, r3
mov r4, r2
ands r0, r8, #0xf
bne _0231A0E4
mov r0, r7
mov r1, r6
mov r3, #1
bl GetTreatmentBetweenMonsters
cmp r0, #1
moveq r4, #1
b _0231A1B8
_0231A0E4:
cmp r0, #1
bne _0231A108
mov r0, r7
mov r1, r6
mov r3, #1
bl GetTreatmentBetweenMonsters
cmp r0, #0
moveq r4, #1
b _0231A1B8
_0231A108:
cmp r0, #2
bne _0231A13C
ldr r1, [r6, #0xb4]
mov r4, #1
ldrb r0, [r1, #9]
cmp r0, #1
moveq r0, r2
ldmeqia sp!, {r4, r5, r6, r7, r8, pc}
ldrb r0, [r1, #0xbc]
cmp r0, #7
bne _0231A1B8
mov r0, r2
ldmia sp!, {r4, r5, r6, r7, r8, pc}
_0231A13C:
cmp r0, #5
bne _0231A17C
cmp r7, r6
ldr r1, [r6, #0xb4]
moveq r0, r2
ldmeqia sp!, {r4, r5, r6, r7, r8, pc}
ldrb r0, [r1, #9]
mov r4, #1
cmp r0, #1
moveq r0, r2
ldmeqia sp!, {r4, r5, r6, r7, r8, pc}
ldrb r0, [r1, #0xbc]
cmp r0, #7
bne _0231A1B8
mov r0, r2
ldmia sp!, {r4, r5, r6, r7, r8, pc}
_0231A17C:
cmp r0, #6
bne _0231A1AC
cmp r7, r6
moveq r0, r2
ldmeqia sp!, {r4, r5, r6, r7, r8, pc}
mov r0, r7
mov r1, r6
mov r3, #1
bl GetTreatmentBetweenMonsters
cmp r0, #0
moveq r4, #1
b _0231A1B8
_0231A1AC:
sub r0, r0, #3
cmp r0, #1
movls r4, #1
_0231A1B8:
cmp r4, #0
beq _0231A358
ldrb r0, [sp, #0x18]
cmp r0, #0
beq _0231A328
mov r0, r7
mov r1, r6
mov r2, r5
bl ov29_02333FD0
cmp r0, #0
moveq r0, #0
ldmeqia sp!, {r4, r5, r6, r7, r8, pc}
and r0, r8, #0xf00
cmp r0, #0x100
bne _0231A21C
mov r0, r5
mov r1, #2
bl GetMoveAccuracyOrAiChance
mov r5, r0
mov r0, #0x64
bl DungeonRandInt
cmp r0, r5
blt _0231A358
mov r0, #0
ldmia sp!, {r4, r5, r6, r7, r8, pc}
_0231A21C:
cmp r0, #0x200
bne _0231A23C
mov r0, r6
bl ov29_023007DC
cmp r0, #0
bne _0231A358
mov r0, #0
ldmia sp!, {r4, r5, r6, r7, r8, pc}
_0231A23C:
cmp r0, #0x300
bne _0231A260
mov r0, r6
mov r1, #1
bl MonsterHasNegativeStatus
cmp r0, #0
bne _0231A358
mov r0, #0
ldmia sp!, {r4, r5, r6, r7, r8, pc}
_0231A260:
cmp r0, #0x400
bne _0231A280
mov r0, r6
bl IsMonsterSleeping
cmp r0, #0
bne _0231A358
mov r0, #0
ldmia sp!, {r4, r5, r6, r7, r8, pc}
_0231A280:
cmp r0, #0x600
bne _0231A2B8
ldr r1, [r6, #0xb4]
ldrb r0, [r1, #0x5e]
cmp r0, #0xe
ldrneb r0, [r1, #0x5f]
cmpne r0, #0xe
movne r0, #0
ldmneia sp!, {r4, r5, r6, r7, r8, pc}
ldrb r0, [r1, #0xfe]
cmp r0, #0
beq _0231A358
mov r0, #0
ldmia sp!, {r4, r5, r6, r7, r8, pc}
_0231A2B8:
cmp r0, #0x500
bne _0231A358
ldrh r1, [r5, #4]
ldr r0, _0231A360 ; =0x000001B7
cmp r1, r0
addne r0, r0, #0x57
cmpne r1, r0
mov r0, r6
mov r1, #1
bne _0231A304
bl MonsterHasNegativeStatus
cmp r0, #0
bne _0231A358
mov r0, r6
bl ov29_023007DC
cmp r0, #0
bne _0231A358
mov r0, #0
ldmia sp!, {r4, r5, r6, r7, r8, pc}
_0231A304:
bl MonsterHasNegativeStatus
cmp r0, #0
bne _0231A358
mov r0, r6
bl ov29_023007DC
cmp r0, #0
bne _0231A358
mov r0, #0
ldmia sp!, {r4, r5, r6, r7, r8, pc}
_0231A328:
and r0, r8, #0xf00
cmp r0, #0x100
bne _0231A358
mov r0, r5
mov r1, #2
bl GetMoveAccuracyOrAiChance
mov r5, r0
mov r0, #0x64
bl DungeonRandInt
cmp r0, r5
movge r0, #0
ldmgeia sp!, {r4, r5, r6, r7, r8, pc}
_0231A358:
mov r0, r4
ldmia sp!, {r4, r5, r6, r7, r8, pc}
.align 2, 0
_0231A360: .word 0x000001B7
arm_func_end IsAiTargetEligible
arm_func_start WeightMoveWithIqSkills
WeightMoveWithIqSkills: ; 0x0231A364
stmdb sp!, {r3, r4, r5, r6, r7, r8, sb, lr}

View File

@@ -3,8 +3,8 @@
.text
arm_func_start ov29_02333FD0
ov29_02333FD0: ; 0x02333FD0
arm_func_start StatusCheckerCheckOnTarget
StatusCheckerCheckOnTarget: ; 0x02333FD0
#ifdef JAPAN
#define OV29_02333FD0_OFFSET -4
#else
@@ -956,7 +956,7 @@ _02334C9C:
.align 2, 0
_02334CA4: .word 0x0000010A
_02334CA8: .word 0x0000020D
arm_func_end ov29_02333FD0
arm_func_end StatusCheckerCheckOnTarget
arm_func_start ov29_02334CAC
ov29_02334CAC: ; 0x02334CAC

View File

@@ -32,5 +32,13 @@ bool8 EntityIsValid__02319F8C(struct entity *entity);
// check_all_conditions: check_all_conditions parameter to pass to IsAiTargetEligible
// return: New number of targets in the target list
s32 TryAddTargetToAiTargetList(s32 current_num_targets, s32 move_ai_range, struct entity *user, struct entity *target, struct move *move, bool8 check_all_conditions);
// Checks if a given target is eligible to be targeted by the AI with a certain move
// move_ai_range: Move's AI range field
// user: User entity pointer
// target: Target entity pointer
// move: Move pointer
// check_all_conditions True to check all the possible move_ai_condition values, false to only check for move_ai_condition::AI_CONDITION_RANDOM (if the move has a different ai condition, the result will be false).
// return: True if the target is eligible, false otherwise
bool8 IsAiTargetEligible(s32 move_ai_range, struct entity *user, struct entity *target, struct move *move, bool8 check_all_conditions);
#endif //PMDSKY_DUNGEON_AI_ATTACK_H

View File

@@ -3,6 +3,7 @@
#include "dungeon_mode.h"
// Parameters used when throwing a projectile item.
struct projectile_throw_info
{
u8 unk0;
@@ -22,6 +23,12 @@ bool8 ItemIsActive__02347B50(struct entity *entity, enum item_id item_id);
bool8 ExclusiveItemEffectIsActive__02347B80(struct entity *entity, enum exclusive_item_effect_id effect_id);
// Checks if an entity pointer points to a valid entity (not entity type 0, which represents no entity).
bool8 EntityIsValid__02347BA4(struct entity *entity);
// Throws an item in a curved arc, like a Gravelerock.
// thrower: monster entity throwing the item
// item: item being thrown
// start_pos: position to start throwing the item from
// target_pos: position to throw the item to
// projectile_throw_info: Metadata about the item being thrown
void HandleCurvedProjectileThrow(struct entity *thrower, struct item *item, struct position *start_pos, struct position *target_pos, struct projectile_throw_info *projectile_throw_info);
#endif //PMDSKY_OVERLAY_29_02347BA4_H

View File

@@ -50,8 +50,20 @@ enum move_ai_condition
AI_CONDITION_HP_25 = 0x200, // Target has HP <= 25%
AI_CONDITION_STATUS = 0x300, // Target has a negative status condition
AI_CONDITION_ASLEEP = 0x400, // Target is asleep, napping or in a nightmare
AI_CONDITION_GHOST = 0x500, // Target is ghost-type and not exposed
AI_CONDITION_HP_25_OR_STATUS = 0x600, // Target has HP <= 25% or a negative status condition
AI_CONDITION_HP_25_OR_STATUS = 0x500, // Target has HP <= 25% or a negative status condition
AI_CONDITION_GHOST = 0x600, // Target is ghost-type and not exposed
};
enum accuracy_type
{
// Accuracy used for all moves.
ACCURACY_1,
// Multiplied with the global accuracy for offensive moves (i.e., not status moves).
ACCURACY_2,
// Used by the AI to determine how often to use Spikes.
// Values exist for all other moves, though they seem to be unused.
ACCURACY_AI_CONDITION_RANDOM_CHANCE,
NUM_ACCURACY_TYPES
};
#define MOVE_RANGE_STRING_USER 19

View File

@@ -465,7 +465,7 @@ Overlay OVY_29
Object src/dungeon_ai_attack_2.o
Object asm/overlay_29_02319880.o
Object src/dungeon_ai_attack.o
Object asm/overlay_29_0231A0A4.o
Object asm/overlay_29_0231A364.o
Object src/dungeon_ai_attack_1.o
Object asm/overlay_29_0231A7A0.o
Object src/overlay_29_0231A87C.o

View File

@@ -2,7 +2,10 @@
#include "dg_random.h"
#include "dungeon_ai_attack_1.h"
#include "dungeon_ai_attack_2.h"
#include "dungeon_ai_targeting_1.h"
#include "dungeon_capabilities_4.h"
#include "dungeon_logic.h"
#include "dungeon_logic_4.h"
#include "dungeon_map_access.h"
#include "dungeon_pokemon_attributes_1.h"
#include "dungeon_statuses.h"
@@ -22,9 +25,12 @@ extern u8 AI_POTENTIAL_ATTACK_TARGET_DIRECTIONS[NUM_DIRECTIONS];
extern s32 AI_POTENTIAL_ATTACK_TARGET_WEIGHTS[NUM_DIRECTIONS];
extern struct entity *AI_POTENTIAL_ATTACK_TARGETS[NUM_DIRECTIONS];
extern bool8 IsAiTargetEligible(s32 move_ai_range, struct entity *user, struct entity *target, struct move *move, bool8 check_all_conditions);
extern enum type_id GetMoveTypeForMonster(struct entity *entity, struct move *move);
extern s32 WeightMoveWithIqSkills(struct entity *user, s32 move_ai_range, struct entity *target, enum type_id move_type);
extern bool8 StatusCheckerCheckOnTarget(struct entity *attacker, struct entity *target, struct move *move);
extern bool8 ov29_023007DC(struct entity *entity);
extern bool8 IsMonsterSleeping(struct entity *monster);
extern u8 GetMoveAccuracyOrAiChance(struct move *move, u32 which);
// https://decomp.me/scratch/jVfou
#ifdef NONMATCHING
@@ -283,3 +289,109 @@ s32 TryAddTargetToAiTargetList(s32 current_num_targets, s32 move_ai_range, struc
}
return current_num_targets;
}
bool8 IsAiTargetEligible(s32 move_ai_range, struct entity *user, struct entity *target, struct move *move, bool8 check_all_conditions)
{
bool8 has_target = FALSE;
u32 move_ai_target = move_ai_range & 0xF;
if (move_ai_target == TARGET_ENEMIES)
{
if (GetTreatmentBetweenMonsters(user, target, FALSE, TRUE) == TREATMENT_TREAT_AS_ENEMY)
has_target = TRUE;
}
else if (move_ai_target == TARGET_PARTY)
{
if (GetTreatmentBetweenMonsters(user, target, FALSE, TRUE) == TREATMENT_TREAT_AS_ALLY)
has_target = TRUE;
}
else if (move_ai_target == TARGET_ALL)
{
struct monster *target_data = target_data = GetEntInfo(target);
has_target = TRUE;
if (target_data->shopkeeper == SHOPKEEPER_MODE_SHOPKEEPER)
return FALSE;
if (target_data->monster_behavior == BEHAVIOR_RESCUE_TARGET)
return FALSE;
}
else if (move_ai_target == TARGET_ALL_EXCEPT_USER)
{
struct monster *target_data = target_data = GetEntInfo(target);
if (user == target)
return FALSE;
has_target = TRUE;
if (target_data->shopkeeper == SHOPKEEPER_MODE_SHOPKEEPER)
return FALSE;
if (target_data->monster_behavior == BEHAVIOR_RESCUE_TARGET)
return FALSE;
}
else if (move_ai_target == TARGET_TEAMMATES)
{
if (user == target)
return FALSE;
if (GetTreatmentBetweenMonsters(user, target, FALSE, TRUE) == TREATMENT_TREAT_AS_ALLY)
has_target = TRUE;
}
else if (move_ai_target - 3 <= 1) // move_ai_target == TARGET_SPECIAL
has_target = TRUE;
if (has_target)
{
if (check_all_conditions)
{
if (!StatusCheckerCheckOnTarget(user, target, move))
return FALSE;
if ((move_ai_range & 0xF00) == AI_CONDITION_RANDOM)
{
s32 use_chance = GetMoveAccuracyOrAiChance(move, ACCURACY_AI_CONDITION_RANDOM_CHANCE);
if (DungeonRandInt(100) >= use_chance)
return FALSE;
}
else if ((move_ai_range & 0xF00) == AI_CONDITION_HP_25)
{
if (!ov29_023007DC(target))
return FALSE;
}
else if ((move_ai_range & 0xF00) == AI_CONDITION_STATUS)
{
if (!MonsterHasNegativeStatus(target, TRUE))
return FALSE;
}
else if ((move_ai_range & 0xF00) == AI_CONDITION_ASLEEP)
{
if (!IsMonsterSleeping(target))
return FALSE;
}
else if ((move_ai_range & 0xF00) == AI_CONDITION_GHOST)
{
struct monster *target_data = target_data = GetEntInfo(target);
if (target_data->types[0] != TYPE_GHOST && target_data->types[1] != TYPE_GHOST)
return FALSE;
if (target_data->exposed)
return FALSE;
}
else if ((move_ai_range & 0xF00) == AI_CONDITION_HP_25_OR_STATUS)
{
if (move->id == MOVE_HEALING_WISH || move->id == MOVE_LUNAR_DANCE)
{
if (!MonsterHasNegativeStatus(target, TRUE) && !ov29_023007DC(target))
return FALSE;
}
else if (!MonsterHasNegativeStatus(target, TRUE) && !ov29_023007DC(target))
return FALSE;
}
}
else if ((move_ai_range & 0xF00) == AI_CONDITION_RANDOM)
{
s32 use_chance = GetMoveAccuracyOrAiChance(move, ACCURACY_AI_CONDITION_RANDOM_CHANCE);
if (DungeonRandInt(100) >= use_chance)
return FALSE;
}
}
return has_target;
}