summaryrefslogtreecommitdiff
path: root/src/dungeon_ai_attack_1.c
blob: 8a186ea9b9d020fe0e26b66e3152c26390004127 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#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 = GetMapTileAtPosition(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;
}