diff --git a/asm/overlay_29_0230F02C.s b/asm/overlay_29_0230F02C.s index 0364a677..13cfe0d1 100644 --- a/asm/overlay_29_0230F02C.s +++ b/asm/overlay_29_0230F02C.s @@ -3,87 +3,6 @@ .text - arm_func_start GetPossibleAiArcItemTargets -GetPossibleAiArcItemTargets: ; 0x0230F02C - stmdb sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, lr} - ldr r4, _0230F138 ; =AI_THROWN_ITEM_ACTION_CHOICE_COUNT - mov r6, #0 - mov sl, r0 - mov fp, r1 - mov sb, r2 - mov r8, r3 - str r6, [r4] -_0230F04C: - ldr r0, _0230F13C ; =DUNGEON_PTR - ldr r0, [r0] - add r0, r0, r6, lsl #2 - add r0, r0, #0x12000 -#ifdef JAPAN - ldr r7, [r0, #0xad4] -#else - ldr r7, [r0, #0xb78] -#endif - mov r0, r7 - bl EntityIsValid__0230F008 - cmp r0, #0 - cmpne sl, r7 - beq _0230F128 - mov r0, sl - mov r1, r7 - bl CanSeeTarget - cmp r0, #0 - beq _0230F128 - mov r0, sl - mov r1, r7 - mov r2, #0 - mov r3, #1 - bl GetTreatmentBetweenMonsters - cmp r0, #1 - bne _0230F128 - ldrsh r1, [r7, #6] - ldrsh r0, [sl, #6] - sub r0, r1, r0 - bl abs - ldrsh r2, [r7, #4] - ldrsh r1, [sl, #4] - mov r5, r0 - sub r0, r2, r1 - bl abs - cmp r0, r5 - movle r0, r5 - cmp r0, #0xa - bgt _0230F128 - cmp r8, #0 - bne _0230F0FC - mov r0, r7 - mov r1, fp - mov r2, #1 - bl GetAiUseItemProbability - bl DungeonRandOutcome__022EAB20 - cmp r0, #0 - beq _0230F128 -_0230F0FC: - ldr r0, [r4] - ldrsh r1, [r7, #4] - mov r0, r0, lsl #2 - strh r1, [sb, r0] - ldr r0, [r4] - ldrsh r1, [r7, #6] - add r0, sb, r0, lsl #2 - strh r1, [r0, #2] - ldr r0, [r4] - add r0, r0, #1 - str r0, [r4] -_0230F128: - add r6, r6, #1 - cmp r6, #0x14 - blt _0230F04C - ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, pc} - .align 2, 0 -_0230F138: .word AI_THROWN_ITEM_ACTION_CHOICE_COUNT -_0230F13C: .word DUNGEON_PTR - arm_func_end GetPossibleAiArcItemTargets - arm_func_start ov29_0230F140 ov29_0230F140: ; 0x0230F140 ldr ip, _0230F148 ; =ov29_022F52BC diff --git a/include/dungeon_ai_items_1.h b/include/dungeon_ai_items_1.h index ee4b72cc..7d6b2119 100644 --- a/include/dungeon_ai_items_1.h +++ b/include/dungeon_ai_items_1.h @@ -17,5 +17,7 @@ void GetPossibleAiThrownItemDirections(struct entity *entity, s32 ally_or_enemy, struct item *item, bool8 always_add); // Checks if an entity pointer points to a valid entity (not entity type 0, which represents no entity). bool8 EntityIsValid__0230F008(struct entity *entity); +// Used to store the number of positions output by GetPossibleAiArcItemTargets and the number of directions/probabilities output by GetPossibleAiThrownItemDirections." +void GetPossibleAiArcItemTargets(struct entity *user, struct item *item, struct position positions[], bool8 always_add_position); #endif //PMDSKY_DUNGEON_AI_ITEMS_1_H diff --git a/include/util.h b/include/util.h index bbfeb0cf..ee83887f 100644 --- a/include/util.h +++ b/include/util.h @@ -40,4 +40,9 @@ static inline s32 Min(s32 a, s32 b) return a < b ? a : b; } +static inline s32 Max(s32 a, s32 b) +{ + return a > b ? a : b; +} + #endif //PMDSKY_UTIL_H diff --git a/src/dungeon_ai_attack_1.c b/src/dungeon_ai_attack_1.c index a16c9fc5..c625f512 100644 --- a/src/dungeon_ai_attack_1.c +++ b/src/dungeon_ai_attack_1.c @@ -5,11 +5,7 @@ #include "dungeon_pokemon_attributes_1.h" #include "dungeon_util.h" #include "main_0208655C.h" - -static inline s32 Max(s32 x, s32 y) -{ - return x > y ? x : y; -} +#include "util.h" bool8 IsTargetInRange(struct entity *user, struct entity *target, enum direction_id direction, s32 n_tiles) { diff --git a/src/dungeon_ai_items.c b/src/dungeon_ai_items.c index 7b811c58..c8cba671 100644 --- a/src/dungeon_ai_items.c +++ b/src/dungeon_ai_items.c @@ -22,7 +22,6 @@ u32 AI_THROWN_ITEM_DIRECTIONS[NUM_DIRECTIONS] = {0}; extern volatile s32 AI_THROWN_ITEM_ACTION_CHOICE_COUNT; extern struct bag_items *BAG_ITEMS_PTR_MIRROR; -extern void GetPossibleAiArcItemTargets(struct entity *user, struct item *item, struct position positions[], bool8 always_add_position); extern s32 GetDirectionTowardsPosition(struct position *origin, struct position *target); extern struct item *GetItemInfo(struct entity *item_entity); extern bool8 MonsterCanThrowItems(struct monster *monster); diff --git a/src/dungeon_ai_items_1.c b/src/dungeon_ai_items_1.c index a186d921..0f6cb1a6 100644 --- a/src/dungeon_ai_items_1.c +++ b/src/dungeon_ai_items_1.c @@ -1,4 +1,5 @@ #include "dungeon_ai_items_1.h" +#include "dg_random.h" #include "dungeon.h" #include "dungeon_ai_attack.h" #include "dungeon_ai_attack_1.h" @@ -10,6 +11,7 @@ #include "item.h" #include "main_0208655C.h" #include "targeting.h" +#include "util.h" // dungeon_ai_items.c and dungeon_ai_items_1.c are split up to define AI_THROWN_ITEM_ACTION_CHOICE_COUNT differently. // This needs to be marked as non-volatile here to match GetPossibleAiThrownItemDirections, @@ -107,3 +109,32 @@ bool8 EntityIsValid__0230F008(struct entity *entity) return entity->type != ENTITY_NOTHING; } + +void GetPossibleAiArcItemTargets(struct entity *user, struct item *item, struct position positions[], bool8 always_add_position) +{ + AI_THROWN_ITEM_ACTION_CHOICE_COUNT = 0; + for (s32 i = 0; i < DUNGEON_MAX_POKEMON; i++) + { + struct entity *target_pokemon = DUNGEON_PTR[0]->active_monster_ptrs[i]; + if (EntityIsValid__0230F008(target_pokemon) && user != target_pokemon && + CanSeeTarget(user, target_pokemon) && GetTreatmentBetweenMonsters(user, target_pokemon, FALSE, TRUE) == TREATMENT_TREAT_AS_ENEMY) + { + s32 distance_y = abs(target_pokemon->pos.y - user->pos.y); + s32 distance_x = abs(target_pokemon->pos.x - user->pos.x); + if (Max(distance_x, distance_y) <= 10) + { + if (!always_add_position) + { + u32 item_weight = GetAiUseItemProbability(target_pokemon, item, ITEM_TARGET_OTHER); + if (!DungeonRandOutcome__022EAB20(item_weight)) + { + continue; + } + } + positions[AI_THROWN_ITEM_ACTION_CHOICE_COUNT].x = target_pokemon->pos.x; + positions[AI_THROWN_ITEM_ACTION_CHOICE_COUNT].y = target_pokemon->pos.y; + AI_THROWN_ITEM_ACTION_CHOICE_COUNT++; + } + } + } +}