diff options
author | Seth Barberee <seth.barberee@gmail.com> | 2021-12-28 23:00:59 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-28 23:00:59 -0600 |
commit | edf909be4da55a435bf81f96ffcbd156b2120562 (patch) | |
tree | 7bbce0d40ce8c714e793ef22f3a7c125f9ff3fbd /src | |
parent | 6512ebff67e163a5a6c0f5e19847e2a4dda19ad1 (diff) | |
parent | ea10f7b7bd6957312b9b0dfa371761c5936bc80a (diff) |
Merge pull request #91 from AnonymousRandomPerson/master
More item AI decomp
Diffstat (limited to 'src')
-rw-r--r-- | src/code_80521D0_1.c | 4 | ||||
-rw-r--r-- | src/dungeon_ai_1.c | 2 | ||||
-rw-r--r-- | src/dungeon_ai_attack.c | 77 | ||||
-rw-r--r-- | src/dungeon_ai_items.c | 77 | ||||
-rw-r--r-- | src/dungeon_movement.c | 4 | ||||
-rw-r--r-- | src/dungeon_pokemon_attributes_1.c | 17 | ||||
-rw-r--r-- | src/pokemon_3.c | 17 |
7 files changed, 174 insertions, 24 deletions
diff --git a/src/code_80521D0_1.c b/src/code_80521D0_1.c index ac9ebef..2b23a14 100644 --- a/src/code_80521D0_1.c +++ b/src/code_80521D0_1.c @@ -208,7 +208,7 @@ void sub_808BCE4(void) struct MapTile *puVar1; puVar1 = GetMapEntity(gDungeonGlobalData->unkE23C, gDungeonGlobalData->unkE23E); - puVar1->tileType &= ~(TILE_TYPE_FLOOR | TILE_TYPE_UNK_1); + puVar1->tileType &= ~(TILE_TYPE_FLOOR | TILE_TYPE_LIQUID); puVar1->tileType |= TILE_TYPE_MAP_EDGE; puVar1->tileType &= ~TILE_TYPE_STAIRS; sub_8049884(); @@ -222,7 +222,7 @@ void sub_808BD38(void) struct MapTile *puVar1; puVar1 = GetMapEntity(gDungeonGlobalData->unkE23C, gDungeonGlobalData->unkE23E); - puVar1->tileType &= ~(TILE_TYPE_FLOOR | TILE_TYPE_UNK_1); + puVar1->tileType &= ~(TILE_TYPE_FLOOR | TILE_TYPE_LIQUID); puVar1->tileType |= TILE_TYPE_FLOOR; puVar1->tileType &= ~TILE_TYPE_MAP_EDGE; puVar1->tileType |= TILE_TYPE_STAIRS; diff --git a/src/dungeon_ai_1.c b/src/dungeon_ai_1.c index 7d45909..1d177c7 100644 --- a/src/dungeon_ai_1.c +++ b/src/dungeon_ai_1.c @@ -3,8 +3,8 @@ #include "constants/status.h" #include "constants/targeting.h" +#include "dungeon_pokemon_attributes_1.h" -extern bool8 CanSeeInvisible(struct DungeonEntity*); extern bool8 gTargetingData[3][2][2][2]; u8 CanTarget(struct DungeonEntity *pokemon, struct DungeonEntity *targetPokemon, bool8 ignoreInvisible, bool8 checkPetrified) diff --git a/src/dungeon_ai_attack.c b/src/dungeon_ai_attack.c new file mode 100644 index 0000000..48ccdfe --- /dev/null +++ b/src/dungeon_ai_attack.c @@ -0,0 +1,77 @@ +#include "global.h" +#include "dungeon_ai_attack.h" + +#include "constants/iq_skill.h" +#include "dungeon_global_data.h" +#include "dungeon_map_access.h" +#include "dungeon_pokemon_attributes_1.h" + +extern struct Position gAdjacentTileOffsets[8]; + +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; +} diff --git a/src/dungeon_ai_items.c b/src/dungeon_ai_items.c index 4afc928..56e4447 100644 --- a/src/dungeon_ai_items.c +++ b/src/dungeon_ai_items.c @@ -3,9 +3,11 @@ #include "constants/direction.h" #include "constants/dungeon_action.h" #include "constants/iq_skill.h" +#include "constants/status.h" #include "constants/targeting.h" #include "dungeon_action.h" #include "dungeon_ai_1.h" +#include "dungeon_ai_attack.h" #include "dungeon_ai_items.h" #include "dungeon_capabilities.h" #include "dungeon_capabilities_1.h" @@ -24,6 +26,7 @@ #define NUM_POTENTIAL_ROCK_TARGETS 20 #define GROUND_ITEM_TOOLBOX_INDEX 0x80 #define HELD_ITEM_TOOLBOX_INDEX 0x81 +#define RANGED_ATTACK_RANGE 10 enum ItemTargetFlag { @@ -32,9 +35,8 @@ enum ItemTargetFlag }; extern s32 CalculateFacingDir(struct Position*, struct Position*); -extern u32 EvaluateItem(struct DungeonEntity*, struct ItemSlot*, u8); +extern u32 EvaluateItem(struct DungeonEntity*, struct ItemSlot*, u32); extern void sub_8077274(struct DungeonEntity *, struct DungeonEntity *); -extern void TargetThrownItem(struct DungeonEntity*, struct DungeonEntity*, struct ItemSlot*, u8, bool8); extern s32 gNumPotentialTargets; extern u32 gPotentialTargetWeights[NUM_DIRECTIONS]; @@ -284,7 +286,7 @@ void FindStraightThrowableTargets(struct DungeonEntity *pokemon, s32 thrownAIFla struct DungeonEntity* targetPokemon = gDungeonGlobalData->allPokemon[i]; if (EntityExists(targetPokemon) && pokemon != targetPokemon) { - u8 targetingFlags; + s32 targetingFlags; if (thrownAIFlag == ITEM_AI_FLAG_TARGET_ALLY) { if (CanTarget(pokemon, targetPokemon, FALSE, FALSE) == TARGET_CAPABILITY_CANNOT_ATTACK) @@ -357,3 +359,72 @@ void FindRockItemTargets(struct DungeonEntity *pokemon, struct ItemSlot *item, s } } } + +void TargetThrownItem(struct DungeonEntity *pokemon, struct DungeonEntity *targetPokemon, struct ItemSlot *item, s32 targetingFlags, bool8 ignoreRollChance) +{ + s32 posDiffX = pokemon->posWorld.x - targetPokemon->posWorld.x; + s32 posDiffY; + s32 targetDirection; + posDiffX = posDiffX < 0 ? -posDiffX : posDiffX; + posDiffY = pokemon->posWorld.y - targetPokemon->posWorld.y; + posDiffY = posDiffY < 0 ? -posDiffY : posDiffY; + if (pokemon->entityData->itemStatus == ITEM_STATUS_NONE) + { + s32 maxPosDiff = posDiffY < posDiffX ? posDiffX : posDiffY; + if (maxPosDiff > RANGED_ATTACK_RANGE) + { + return; + } + } + targetDirection = -1; + if (posDiffX == posDiffY) + { + if (pokemon->posWorld.x < targetPokemon->posWorld.x && pokemon->posWorld.y < targetPokemon->posWorld.y) + { + targetDirection = DIRECTION_SOUTHEAST; + } + else if (pokemon->posWorld.x < targetPokemon->posWorld.x && pokemon->posWorld.y > targetPokemon->posWorld.y) + { + targetDirection = DIRECTION_NORTHEAST; + } + else if (pokemon->posWorld.x > targetPokemon->posWorld.x && pokemon->posWorld.y > targetPokemon->posWorld.y) + { + targetDirection = DIRECTION_NORTHWEST; + } + else + { + targetDirection = DIRECTION_SOUTHWEST; + } + } + else + { + if (pokemon->posWorld.x == targetPokemon->posWorld.x && pokemon->posWorld.y < targetPokemon->posWorld.y) + { + targetDirection = DIRECTION_SOUTH; + } + else if (pokemon->posWorld.x < targetPokemon->posWorld.x && pokemon->posWorld.y == targetPokemon->posWorld.y) + { + targetDirection = DIRECTION_EAST; + } + else if (pokemon->posWorld.x == targetPokemon->posWorld.x && pokemon->posWorld.y > targetPokemon->posWorld.y) + { + targetDirection = DIRECTION_NORTH; + } + else if (pokemon->posWorld.x > targetPokemon->posWorld.x && pokemon->posWorld.y == targetPokemon->posWorld.y) + { + targetDirection = DIRECTION_WEST; + } + } + + if (targetDirection > -1 && !gTargetAhead[targetDirection] && IsTargetStraightAhead(pokemon, targetPokemon, targetDirection, RANGED_ATTACK_RANGE)) + { + u32 itemWeight; + u32 *targetWeight; + gTargetAhead[targetDirection] = TRUE; + gPotentialTargetDirections[gNumPotentialTargets] = targetDirection; + targetWeight = &gPotentialTargetWeights[gNumPotentialTargets]; + itemWeight = !ignoreRollChance ? EvaluateItem(targetPokemon, item, targetingFlags) : 100; + *targetWeight = itemWeight; + gNumPotentialTargets++; + } +} diff --git a/src/dungeon_movement.c b/src/dungeon_movement.c index 1601cff..bcf6163 100644 --- a/src/dungeon_movement.c +++ b/src/dungeon_movement.c @@ -51,7 +51,7 @@ u32 sub_8075818(struct DungeonEntity *entity) { tile = GetMapEntityForDungeonEntity(entity); if(HasIQSkill(entity, IQ_SKILL_SUPER_MOBILE)) - if(!(tile->tileType & (TILE_TYPE_FLOOR | TILE_TYPE_UNK_1))) + if(!(tile->tileType & (TILE_TYPE_FLOOR | TILE_TYPE_LIQUID))) return 1; subEntity = tile->mapObject; if(subEntity != NULL) @@ -95,7 +95,7 @@ flag_check: { if(!(entityData->heldItem.itemFlags & ITEM_FLAG_EXISTS)) { - if(!(tile->tileType & (TILE_TYPE_FLOOR | TILE_TYPE_UNK_1))) + if(!(tile->tileType & (TILE_TYPE_FLOOR | TILE_TYPE_LIQUID))) { if(entityData->isEnemy) break; diff --git a/src/dungeon_pokemon_attributes_1.c b/src/dungeon_pokemon_attributes_1.c index d3b8cab..a5d6acf 100644 --- a/src/dungeon_pokemon_attributes_1.c +++ b/src/dungeon_pokemon_attributes_1.c @@ -9,6 +9,7 @@ #include "constants/move_id.h" #include "constants/status.h" #include "constants/tactic.h" +#include "pokemon_3.h" extern s16 gItemMasterMinWildLevel; @@ -26,9 +27,9 @@ extern s32 GetMovePower(struct PokemonMove *move); bool8 CanSeeInvisible(struct DungeonEntity *pokemon) { struct DungeonEntityData *pokemonData = pokemon->entityData; - if(pokemonData->eyesightStatus != EYESIGHT_STATUS_EYEDROPS) + if (pokemonData->eyesightStatus != EYESIGHT_STATUS_EYEDROPS) { - if(!HasItem(pokemon, ITEM_ID_GOGGLE_SPECS)) + if (!HasItem(pokemon, ITEM_ID_GOGGLE_SPECS)) return FALSE; else return TRUE; @@ -63,7 +64,7 @@ void LoadIQSkills(struct DungeonEntity *pokemon) u8 *iVar2; s32 IQSkill; struct DungeonEntityData *pokemonData; - + pokemonData = pokemon->entityData; if (pokemonData->isEnemy) { iVar2 = pokemonData->IQSkillsEnabled; @@ -82,8 +83,8 @@ void LoadIQSkills(struct DungeonEntity *pokemon) pokemonData->IQSkillsEnabled[2] = 0; for(IQSkill = IQ_SKILL_TYPE_ADVANTAGE_MASTER; IQSkill < NUM_IQ_SKILLS; IQSkill++) { - if (HasIQForSkill(pokemonData->IQ,IQSkill) && - IsIQSkillSet(pokemonData->IQSkillsSelected, 1 << IQSkill)) + if (HasIQForSkill(pokemonData->IQ,IQSkill) && + IsIQSkillSet(pokemonData->IQSkillsSelected, 1 << IQSkill)) { SetIQSkill(pokemonData->IQSkillsEnabled,IQSkill); } @@ -95,7 +96,7 @@ bool8 CanSeeTeammate(struct DungeonEntity * pokemon) { struct DungeonEntity *teamMember; s32 memberIdx; - + if (pokemon->entityData->isEnemy) { return FALSE; } @@ -132,13 +133,13 @@ s32 CalculateMovePower(struct DungeonEntity *pokemon, struct PokemonMove *pokeMo bool8 ToolboxEnabled(struct DungeonEntityData *pokemon) { if(!IsToolboxEnabled(pokemon->entityID)) - return FALSE; + return FALSE; return TRUE; } static inline bool8 sub_8071A8C_sub(struct DungeonEntityData *pokemonData) { - if(pokemonData->joinLocation == DUNGEON_JOIN_LOCATION_CLIENT_POKEMON || + if(pokemonData->joinLocation == DUNGEON_JOIN_LOCATION_CLIENT_POKEMON || pokemonData->joinLocation == DUNGEON_RESCUE_TEAM_BASE) return TRUE; else diff --git a/src/pokemon_3.c b/src/pokemon_3.c index 743a9dd..9d28f98 100644 --- a/src/pokemon_3.c +++ b/src/pokemon_3.c @@ -1,4 +1,6 @@ #include "global.h" +#include "pokemon_3.h" + #include "pokemon.h" #include "random.h" #include "constants/iq_skill.h" @@ -45,7 +47,6 @@ extern s16 gUnknown_810AC66; // 0x8 // 2, 4, 6, 7, 8, 9, 0xA, 0xD, 0xF, 0x11 extern s32 gUnknown_810AC90[10]; -extern bool8 IsIQSkillSet(u8 *, u32); extern void SetIQSkill(u8 *, u32); extern void AddSprite(u16 *, u32, u32, u32); @@ -613,22 +614,22 @@ void SetDefaultIQSkills(u8 *param_1, bool8 enableSelfCurer) SetIQSkill(param_1, IQ_SKILL_COURSE_CHECKER); SetIQSkill(param_1, IQ_SKILL_ITEM_MASTER); - // Flag is usually enabled for Boss fights.. + // Flag is usually enabled for Boss fights. if (enableSelfCurer) { SetIQSkill(param_1, IQ_SKILL_SELF_CURER); } } -bool8 IsIQSkillSet(u8 *param_1, u32 param_2) +bool8 IsIQSkillSet(u8 *IQSkillsEnabled, u32 IQSkill) { - - if ((((param_1[0] & param_2) == 0) && - ((param_1[1] & param_2 >> 8) == 0)) && - ((param_1[2] & param_2 >> 0x10) == 0)) + if (!(IQSkillsEnabled[0] & IQSkill) && + !(IQSkillsEnabled[1] & IQSkill >> 8) && + !(IQSkillsEnabled[2] & IQSkill >> 16)) { return FALSE; } - else { + else + { return TRUE; } } |