diff options
Diffstat (limited to 'src/dungeon_ai_items.c')
-rw-r--r-- | src/dungeon_ai_items.c | 120 |
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); + } + } + } +} |