summaryrefslogtreecommitdiff
path: root/src/dungeon_ai_items.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dungeon_ai_items.c')
-rw-r--r--src/dungeon_ai_items.c120
1 files changed, 87 insertions, 33 deletions
diff --git a/src/dungeon_ai_items.c b/src/dungeon_ai_items.c
index 7a348f1..48b675a 100644
--- a/src/dungeon_ai_items.c
+++ b/src/dungeon_ai_items.c
@@ -1,40 +1,53 @@
#include "global.h"
-#include "dungeon_ai_items.h"
#include "constants/direction.h"
#include "constants/dungeon_action.h"
#include "constants/iq_skill.h"
+#include "dungeon_action.h"
+#include "dungeon_ai_items.h"
#include "dungeon_capabilities.h"
#include "dungeon_capabilities_1.h"
+#include "dungeon_entity.h"
#include "dungeon_global_data.h"
+#include "dungeon_pokemon_attributes_1.h"
+#include "dungeon_util.h"
#include "item.h"
#include "team_inventory.h"
#define NUM_POTENTIAL_ROCK_TARGETS 20
#define GROUND_ITEM_TOOLBOX_INDEX 0x80
#define HELD_ITEM_TOOLBOX_INDEX 0x81
-#define ITEM_TARGET_ALLY 1 << 1
-extern void SetAction(u16*, u16);
-extern void FindStraightThrowableTargets(struct DungeonEntity*, s32 thrownAIFlag, struct ItemSlot*, bool8 ignoreRollChance);
+enum ItemTargetFlag
+{
+ ITEM_TARGET_OTHER = 1 << 0,
+ ITEM_TARGET_ALLY = 1 << 1
+};
+
+enum TargetCapability
+{
+ TARGET_CAPABILITY_CANNOT_ATTACK,
+ TARGET_CAPABILITY_CAN_TARGET,
+ TARGET_CAPABILITY_CAN_ATTACK_NOT_TARGET
+};
+
extern bool8 RollPercentChance(u32);
-extern void FindRockItemTargets(struct DungeonEntity*, struct ItemSlot*, s16*[], bool8 ignoreRollChance);
+extern void FindRockItemTargets(struct DungeonEntity*, struct ItemSlot*, s16*[], bool8);
extern s32 DungeonRandomCapped(s32);
extern s32 CalculateFacingDir(s16*, s16*);
-extern bool8 HasIQSkill(struct DungeonEntity*, u8);
extern struct MapTile* GetMapTileAtPosition(s16, s16);
-extern u32 GetEntityType(struct DungeonEntity*);
-extern struct ItemSlot* GetItemData(struct DungeonEntity*);
extern u32 EvaluateItem(struct DungeonEntity*, struct ItemSlot*, u8);
extern bool8 ToolboxEnabled(struct DungeonEntityData*);
extern void sub_8077274(struct DungeonEntity *, struct DungeonEntity *);
-extern bool8 EntityExists(struct DungeonEntity *);
+extern bool8 CanTarget(struct DungeonEntity*, struct DungeonEntity*, bool8, bool8);
+extern bool8 CanSee(struct DungeonEntity*, struct DungeonEntity*);
+extern void TargetThrownItem(struct DungeonEntity*, struct DungeonEntity*, struct ItemSlot*, u8, bool8);
extern s32 gNumPotentialTargets;
extern u32 gPotentialTargetWeights[NUM_DIRECTIONS];
extern u32 gPotentialTargetDirections[NUM_DIRECTIONS];
+extern bool8 gTargetAhead[NUM_DIRECTIONS];
extern struct TeamInventory *gTeamInventory_203B460;
-
extern struct DungeonGlobalData *gDungeonGlobalData;
void sub_807360C(struct DungeonEntity *pokemon)
@@ -49,7 +62,7 @@ void sub_807360C(struct DungeonEntity *pokemon)
{
if(entity->entityData->unk152 != 0)
{
- entity->entityData->unk152 = 0;
+ entity->entityData->unk152 = 0;
sub_8077274(entity, entity);
}
}
@@ -91,10 +104,10 @@ void DecideUseItem(struct DungeonEntity *pokemon)
if (RollPercentChance(gPotentialTargetWeights[targetIndex]))
{
SetAction(&pokemonData->action, DUNGEON_ACTION_THROW_ITEM_AI);
- pokemonData->actionUseIndex = selectedToolboxIndex;
- pokemonData->lastItemThrowPositionX = pokemon->posWorldX;
- pokemonData->lastItemThrowPositionY = pokemon->posWorldY;
- pokemonData->facingDir = gPotentialTargetDirections[targetIndex] & DIRECTION_MASK;
+ pokemonData->action.actionUseIndex = selectedToolboxIndex;
+ pokemonData->action.lastItemThrowPositionX = pokemon->posWorldX;
+ pokemonData->action.lastItemThrowPositionY = pokemon->posWorldY;
+ pokemonData->action.facingDir = gPotentialTargetDirections[targetIndex] & DIRECTION_MASK;
break;
}
}
@@ -115,10 +128,10 @@ void DecideUseItem(struct DungeonEntity *pokemon)
{
u32 chosenTargetIndex = DungeonRandomCapped(gNumPotentialTargets);
SetAction(&pokemonData->action, DUNGEON_ACTION_THROW_ITEM_AI);
- pokemonData->actionUseIndex = selectedToolboxIndex;
- pokemonData->lastItemThrowPositionX = pokemon->posWorldX;
- pokemonData->lastItemThrowPositionY = pokemon->posWorldY;
- pokemonData->facingDir = CalculateFacingDir(&pokemon->posWorldX, (s16 *) (&potentialTargetPositions[chosenTargetIndex])) & DIRECTION_MASK;
+ pokemonData->action.actionUseIndex = selectedToolboxIndex;
+ pokemonData->action.lastItemThrowPositionX = pokemon->posWorldX;
+ pokemonData->action.lastItemThrowPositionY = pokemon->posWorldY;
+ pokemonData->action.facingDir = CalculateFacingDir(&pokemon->posWorldX, (s16 *) (&potentialTargetPositions[chosenTargetIndex])) & DIRECTION_MASK;
pokemonData->itemTargetPosition = potentialTargetPositions[chosenTargetIndex];
}
}
@@ -128,9 +141,9 @@ void DecideUseItem(struct DungeonEntity *pokemon)
if (itemTypeCompare < ITEM_TYPE_HOLD_ITEM - 2)
{
SetAction(&pokemonData->action, DUNGEON_ACTION_CONSUME_ITEM_AI);
- pokemonData->actionUseIndex = selectedToolboxIndex;
- pokemonData->lastItemThrowPositionX = pokemon->posWorldX;
- pokemonData->lastItemThrowPositionY = pokemon->posWorldY;
+ pokemonData->action.actionUseIndex = selectedToolboxIndex;
+ pokemonData->action.lastItemThrowPositionX = pokemon->posWorldX;
+ pokemonData->action.lastItemThrowPositionY = pokemon->posWorldY;
}
else
{
@@ -200,9 +213,9 @@ void DecideUseItem(struct DungeonEntity *pokemon)
{
SetAction(&pokemonData->action, DUNGEON_ACTION_CONSUME_ITEM_AI);
}
- pokemonData->actionUseIndex = selectedToolboxIndex;
- pokemonData->lastItemThrowPositionX = pokemon->posWorldX;
- pokemonData->lastItemThrowPositionY = pokemon->posWorldY;
+ pokemonData->action.actionUseIndex = selectedToolboxIndex;
+ pokemonData->action.lastItemThrowPositionX = pokemon->posWorldX;
+ pokemonData->action.lastItemThrowPositionY = pokemon->posWorldY;
return;
}
}
@@ -234,10 +247,10 @@ void DecideUseItem(struct DungeonEntity *pokemon)
{
u32 chosenTargetIndex = DungeonRandomCapped(gNumPotentialTargets);
SetAction(&pokemonData->action, DUNGEON_ACTION_THROW_ITEM_AI);
- pokemonData->actionUseIndex = selectedToolboxIndex;
- pokemonData->lastItemThrowPositionX = pokemon->posWorldX;
- pokemonData->lastItemThrowPositionY = pokemon->posWorldY;
- pokemonData->facingDir = CalculateFacingDir(&pokemon->posWorldX, (s16 *) (&potentialTargetPositions[chosenTargetIndex])) & DIRECTION_MASK;
+ pokemonData->action.actionUseIndex = selectedToolboxIndex;
+ pokemonData->action.lastItemThrowPositionX = pokemon->posWorldX;
+ pokemonData->action.lastItemThrowPositionY = pokemon->posWorldY;
+ pokemonData->action.facingDir = CalculateFacingDir(&pokemon->posWorldX, (s16 *) (&potentialTargetPositions[chosenTargetIndex])) & DIRECTION_MASK;
pokemonData->itemTargetPosition = potentialTargetPositions[chosenTargetIndex];
return;
}
@@ -251,10 +264,10 @@ void DecideUseItem(struct DungeonEntity *pokemon)
if (RollPercentChance(potentialTargetWeights[targetIndex]))
{
SetAction(&pokemonData->action, DUNGEON_ACTION_THROW_ITEM_AI);
- pokemonData->actionUseIndex = selectedToolboxIndex;
- pokemonData->lastItemThrowPositionX = pokemon->posWorldX;
- pokemonData->lastItemThrowPositionY = pokemon->posWorldY;
- pokemonData->facingDir = gPotentialTargetDirections[targetIndex] & DIRECTION_MASK;
+ pokemonData->action.actionUseIndex = selectedToolboxIndex;
+ pokemonData->action.lastItemThrowPositionX = pokemon->posWorldX;
+ pokemonData->action.lastItemThrowPositionY = pokemon->posWorldY;
+ pokemonData->action.facingDir = gPotentialTargetDirections[targetIndex] & DIRECTION_MASK;
return;
}
}
@@ -265,3 +278,44 @@ void DecideUseItem(struct DungeonEntity *pokemon)
}
}
}
+
+void FindStraightThrowableTargets(struct DungeonEntity* pokemon, s32 thrownAIFlag, struct ItemSlot* item, bool8 ignoreRollChance)
+{
+ s32 i;
+ gNumPotentialTargets = 0;
+ for (i = 0; i < NUM_DIRECTIONS; i++)
+ {
+ gTargetAhead[i] = FALSE;
+ }
+ for (i = 0; i < DUNGEON_MAX_POKEMON; i++)
+ {
+ struct DungeonEntity* targetPokemon = gDungeonGlobalData->allPokemon[i];
+ if (EntityExists(targetPokemon) && pokemon != targetPokemon)
+ {
+ u8 targetingFlags;
+ if (thrownAIFlag == ITEM_AI_FLAG_TARGET_ALLY)
+ {
+ if (CanTarget(pokemon, targetPokemon, FALSE, FALSE) == TARGET_CAPABILITY_CANNOT_ATTACK)
+ {
+ targetingFlags = ITEM_TARGET_OTHER | ITEM_TARGET_ALLY;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ else if (CanTarget(pokemon, targetPokemon, FALSE, TRUE) == TARGET_CAPABILITY_CAN_TARGET)
+ {
+ targetingFlags = ITEM_TARGET_OTHER;
+ }
+ else
+ {
+ continue;
+ }
+ if (CanSee(pokemon, targetPokemon))
+ {
+ TargetThrownItem(pokemon, targetPokemon, item, targetingFlags, ignoreRollChance);
+ }
+ }
+ }
+}