mirror of
https://github.com/pret/pmd-red.git
synced 2026-08-27 03:07:22 -05:00
Fix some AI functions
This commit is contained in:
@@ -61,4 +61,29 @@ enum TargetingFlag
|
||||
TARGETING_FLAG_EXPOSE = 0x600,
|
||||
};
|
||||
|
||||
enum MoveTarget
|
||||
{
|
||||
TARGET_ENEMIES = 0,
|
||||
TARGET_PARTY = 1, // including the user
|
||||
TARGET_ALL = 2, // including the user
|
||||
TARGET_USER = 3,
|
||||
TARGET_ENEMIES_AFTER_CHARGING = 4, // in some sense the user while charging, then enemies
|
||||
TARGET_ALL_EXCEPT_USER = 5,
|
||||
TARGET_TEAMMATES = 6, // excluding the user
|
||||
TARGET_SPECIAL = 15, // for weird moves
|
||||
};
|
||||
|
||||
enum MoveAiCondition
|
||||
{
|
||||
AI_CONDITION_NONE = 0,
|
||||
// The AI will consider a target elegible wirh a chance equal to the
|
||||
// move's "ai_condition_random_chance" value
|
||||
AI_CONDITION_RANDOM = 0x100,
|
||||
AI_CONDITION_HP_25 = 0x200, // Target has HP <= 25%
|
||||
AI_CONDITION_STATUS = 0x300, // Target has a negative status condition
|
||||
AI_CONDITION_ASLEEP = 0x400, // Target is asleep, napping or in a nightmare
|
||||
AI_CONDITION_HP_25_OR_STATUS = 0x500, // Target has HP <= 25% or a negative status condition
|
||||
AI_CONDITION_GHOST = 0x600, // Target is ghost-type and not exposed
|
||||
};
|
||||
|
||||
#endif // GUARD_CONSTANTS_MOVE_H
|
||||
|
||||
@@ -19,9 +19,9 @@ s32 sub_8070828(Entity *pokemon, bool8 displayMessage);
|
||||
void SetMessageArgument_2(u8 *buffer, EntityInfo *param_2, s32 colorNum);
|
||||
void sub_8070968(u8 *buffer, EntityInfo *entityInfo, s32 colorNum);
|
||||
void CopyEntityNameForDungeonExitSummary(u8 *buffer, EntityInfo *entityInfo);
|
||||
bool8 HasNegativeStatus(Entity *pokemon);
|
||||
bool8 IsSleeping(Entity *pokemon);
|
||||
bool8 HasLowHealth(Entity *pokemon);
|
||||
bool8 MonsterHasNegativeStatus(Entity *pokemon);
|
||||
bool8 IsMonsterSleeping(Entity *pokemon);
|
||||
bool8 MonsterHasQuarterHp(Entity *pokemon);
|
||||
bool8 CheckVariousStatuses2(Entity *pokemon, bool8 checkBlinker);
|
||||
bool8 sub_8070BC0(Entity* entity);
|
||||
bool8 CheckVariousConditions(Entity *pokemon);
|
||||
@@ -47,7 +47,7 @@ bool8 AbilityIsActive(Entity *pokemon, u8 ability);
|
||||
bool8 MonsterIsType(Entity *pokemon, u8 type);
|
||||
bool8 CanSeeInvisibleMonsters(Entity *pokemon);
|
||||
bool8 IsTacticSet(Entity *pokemon, u8 tactic);
|
||||
bool8 IQSkillIsEnabled(Entity *pokemon, u8 IQSkill);
|
||||
bool8 IqSkillIsEnabled(Entity *pokemon, u8 IQSkill);
|
||||
void LoadIQSkills(Entity *pokemon);
|
||||
bool8 CanSeeTeammate(Entity * pokemon);
|
||||
u8 GetMoveTypeForMonster(Entity *pokemon, Move *pokeMove);
|
||||
|
||||
@@ -48,7 +48,7 @@ bool8 FailsWhileMuzzled(u16 moveID);
|
||||
const u8 *GetHMTMMoves(s16 species);
|
||||
const u8 *GetLevelUpMoves(s16 species);
|
||||
s32 GetLinkedSequence(s32 index, Move *moves, u16 *sequenceMoveIDs);
|
||||
s32 GetMoveAccuracyOrAIChance(Move *move, u32 accuracyType);
|
||||
s32 GetMoveAccuracyOrAiChance(Move *move, u32 accuracyType);
|
||||
u8 GetMoveAIWeight(Move *move);
|
||||
s32 GetMoveBasePower(Move *move);
|
||||
u32 GetMoveBasePP(Move *move);
|
||||
|
||||
@@ -49,7 +49,7 @@ extern s32 sub_800EBC8(struct UnkStruct_8040094 *a0);
|
||||
extern bool8 sub_800E7D0(struct UnkStruct_8040094 *a0);
|
||||
extern bool8 EffectiveMoveHasSineWobble(s32 moveId);
|
||||
extern bool8 MoveMatchesBideClassStatus(Entity *pokemon, Move *move);
|
||||
extern bool8 IsSleeping(Entity *pokemon);
|
||||
extern bool8 IsMonsterSleeping(Entity *pokemon);
|
||||
|
||||
extern const s32 gUnknown_8106A8C[];
|
||||
|
||||
@@ -441,7 +441,7 @@ static bool32 MoveHasSpecialEffect(Entity *entity, Move *move)
|
||||
}
|
||||
}
|
||||
else if (move->id == MOVE_SNORE || move->id == MOVE_SLEEP_TALK) {
|
||||
if (!IsSleeping(entity))
|
||||
if (!IsMonsterSleeping(entity))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
@@ -155,7 +155,7 @@ bool8 ExecuteEntityDungeonAction(Entity *entity)
|
||||
pos.y = entity->pos.y;
|
||||
sub_80694C0(entity,pos1.x,pos1.y,0);
|
||||
sub_8074FB0(entity,(info->action).direction,&pos);
|
||||
if (((IQSkillIsEnabled(entity, IQ_SUPER_MOBILE)) && (info->invisibleClassStatus.status != STATUS_MOBILE)) &&
|
||||
if (((IqSkillIsEnabled(entity, IQ_SUPER_MOBILE)) && (info->invisibleClassStatus.status != STATUS_MOBILE)) &&
|
||||
(!HasHeldItem(entity,ITEM_MOBILE_SCARF))) {
|
||||
sub_804AE08(&entity->pos);
|
||||
}
|
||||
@@ -342,7 +342,7 @@ static void HandleSleepTalk(void)
|
||||
if(CannotAttack(entity, TRUE)){
|
||||
info->unk164 |= 0xFF;
|
||||
}
|
||||
else if(!IsSleeping(entity)){
|
||||
else if(!IsMonsterSleeping(entity)){
|
||||
info->unk164 |= 0xFF;
|
||||
}
|
||||
else if(info->muzzled.muzzled == TRUE){
|
||||
@@ -418,7 +418,7 @@ static void HandleSnore(void)
|
||||
info->unk165 |= 0xff;
|
||||
info->unk164 |= 0xff;
|
||||
}
|
||||
else if (!IsSleeping(pokemon)) {
|
||||
else if (!IsMonsterSleeping(pokemon)) {
|
||||
info->unk165 |= 0xff;
|
||||
info->unk164 |= 0xff;
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ void RunMonsterAI(Entity *pokemon, u32 unused)
|
||||
AIDecideUseItem(pokemon);
|
||||
if (pokemonInfo->action.action == ACTION_NOTHING)
|
||||
{
|
||||
if (!IQSkillIsEnabled(pokemon, IQ_DEDICATED_TRAVELER))
|
||||
if (!IqSkillIsEnabled(pokemon, IQ_DEDICATED_TRAVELER))
|
||||
{
|
||||
ChooseAIMove(pokemon);
|
||||
if (pokemonInfo->action.action != ACTION_NOTHING)
|
||||
|
||||
@@ -127,8 +127,8 @@ void ChooseAIMove(Entity *pokemon)
|
||||
}
|
||||
return;
|
||||
}
|
||||
hasWeakTypePicker = IQSkillIsEnabled(pokemon, IQ_WEAK_TYPE_PICKER);
|
||||
hasPPChecker = IQSkillIsEnabled(pokemon, IQ_PP_CHECKER) != FALSE;
|
||||
hasWeakTypePicker = IqSkillIsEnabled(pokemon, IQ_WEAK_TYPE_PICKER);
|
||||
hasPPChecker = IqSkillIsEnabled(pokemon, IQ_PP_CHECKER) != FALSE;
|
||||
total = 0;
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
@@ -220,7 +220,7 @@ void ChooseAIMove(Entity *pokemon)
|
||||
}
|
||||
}
|
||||
aiPossibleMove[REGULAR_ATTACK_INDEX].weight = 0;
|
||||
if (!IQSkillIsEnabled(pokemon, IQ_EXCLUSIVE_MOVE_USER) && pokemonInfo->bideClassStatus.status != chargeStatus)
|
||||
if (!IqSkillIsEnabled(pokemon, IQ_EXCLUSIVE_MOVE_USER) && pokemonInfo->bideClassStatus.status != chargeStatus)
|
||||
{
|
||||
aiPossibleMove[REGULAR_ATTACK_INDEX].canBeUsed = TRUE;
|
||||
if (pokemonInfo->bideClassStatus.status == chargeStatus)
|
||||
@@ -274,7 +274,7 @@ void ChooseAIMove(Entity *pokemon)
|
||||
}
|
||||
randomWeight = DungeonRandInt(total);
|
||||
weightCounter = 0;
|
||||
if (!IQSkillIsEnabled(pokemon, IQ_EXCLUSIVE_MOVE_USER))
|
||||
if (!IqSkillIsEnabled(pokemon, IQ_EXCLUSIVE_MOVE_USER))
|
||||
{
|
||||
canTargetRegularAttack = TargetRegularAttack(pokemon, ®ularAttackTargetDir, TRUE);
|
||||
}
|
||||
@@ -353,7 +353,7 @@ s32 AIConsiderMove(struct AIPossibleMove *aiPossibleMove, Entity *pokemon, Move
|
||||
gCanAttackInDirection[i] = FALSE;
|
||||
}
|
||||
targetingFlags = GetMoveTargetAndRangeForPokemon(pokemon, move, TRUE);
|
||||
hasStatusChecker = IQSkillIsEnabled(pokemon, IQ_STATUS_CHECKER);
|
||||
hasStatusChecker = IqSkillIsEnabled(pokemon, IQ_STATUS_CHECKER);
|
||||
aiPossibleMove->canBeUsed = FALSE;
|
||||
if ((pokemonInfo->cringeClassStatus.status == STATUS_TAUNTED && !MoveIgnoresTaunted(move)) ||
|
||||
(hasStatusChecker && !CanUseOnSelfWithStatusChecker(pokemon, move)))
|
||||
@@ -605,127 +605,113 @@ static s32 TryAddTargetToAITargetList(s32 numPotentialTargets, s32 targetingFlag
|
||||
return numPotentialTargets;
|
||||
}
|
||||
|
||||
static bool8 IsAITargetEligible(s32 targetingFlags, Entity *user, Entity *target, Move *move, bool32 hasStatusChecker)
|
||||
static bool8 IsAITargetEligible(s32 moveAiRange_, Entity *user, Entity *target, Move *move, bool32 checkAllConditions_)
|
||||
{
|
||||
EntityInfo *targetData;
|
||||
s32 targetingFlags2 = (s16) targetingFlags;
|
||||
bool8 hasStatusChecker2 = hasStatusChecker;
|
||||
s32 moveAiRange = (s16) moveAiRange_;
|
||||
bool8 checkAllConditions = checkAllConditions_;
|
||||
bool8 hasTarget = FALSE;
|
||||
u32 categoryTargetingFlags = targetingFlags2 & 0xF;
|
||||
u32 *categoryTargetingFlags2 = &categoryTargetingFlags; // Fixes a regswap.
|
||||
if (*categoryTargetingFlags2 == TARGETING_FLAG_TARGET_OTHER)
|
||||
u32 moveAiTarget = moveAiRange & 0xF;
|
||||
// Needed to fix a regswap.
|
||||
u32 *matchMe = &moveAiTarget;
|
||||
if (*matchMe == TARGET_ENEMIES)
|
||||
{
|
||||
if (GetTreatmentBetweenMonsters(user, target, FALSE, TRUE) == TREATMENT_TREAT_AS_ENEMY)
|
||||
{
|
||||
hasTarget = TRUE;
|
||||
}
|
||||
}
|
||||
else if (categoryTargetingFlags == TARGETING_FLAG_HEAL_TEAM)
|
||||
else if (moveAiTarget == TARGET_PARTY)
|
||||
{
|
||||
goto checkCanTarget;
|
||||
}
|
||||
else if (categoryTargetingFlags == TARGETING_FLAG_LONG_RANGE)
|
||||
{
|
||||
targetData = GetEntInfo(target);
|
||||
goto checkThirdParty;
|
||||
}
|
||||
else if (categoryTargetingFlags == TARGETING_FLAG_ATTACK_ALL)
|
||||
{
|
||||
targetData = GetEntInfo(target);
|
||||
if (user == target)
|
||||
{
|
||||
goto returnFalse;
|
||||
}
|
||||
checkThirdParty:
|
||||
hasTarget = TRUE;
|
||||
if (targetData->shopkeeper == SHOPKEEPER_MODE_SHOPKEEPER ||
|
||||
targetData->monsterBehavior == BEHAVIOR_DIGLETT ||
|
||||
targetData->monsterBehavior == BEHAVIOR_RESCUE_TARGET)
|
||||
{
|
||||
returnFalse:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (categoryTargetingFlags == TARGETING_FLAG_BOOST_TEAM)
|
||||
{
|
||||
if (user == target)
|
||||
{
|
||||
goto returnFalse;
|
||||
}
|
||||
checkCanTarget:
|
||||
if (GetTreatmentBetweenMonsters(user, target, FALSE, TRUE) == TREATMENT_TREAT_AS_ALLY)
|
||||
{
|
||||
hasTarget = TRUE;
|
||||
}
|
||||
else if (moveAiTarget == TARGET_ALL)
|
||||
{
|
||||
EntityInfo *targetData = targetData = GetEntInfo(target);
|
||||
hasTarget = TRUE;
|
||||
if (targetData->shopkeeper == SHOPKEEPER_MODE_SHOPKEEPER)
|
||||
return FALSE;
|
||||
if (targetData->monsterBehavior == BEHAVIOR_DIGLETT)
|
||||
return FALSE;
|
||||
if (targetData->monsterBehavior == BEHAVIOR_RESCUE_TARGET)
|
||||
return FALSE;
|
||||
}
|
||||
else if (moveAiTarget == TARGET_ALL_EXCEPT_USER)
|
||||
{
|
||||
EntityInfo *targetData = targetData = GetEntInfo(target);
|
||||
if (user == target)
|
||||
return FALSE;
|
||||
|
||||
hasTarget = TRUE;
|
||||
if (targetData->shopkeeper == SHOPKEEPER_MODE_SHOPKEEPER)
|
||||
return FALSE;
|
||||
if (targetData->monsterBehavior == BEHAVIOR_DIGLETT)
|
||||
return FALSE;
|
||||
if (targetData->monsterBehavior == BEHAVIOR_RESCUE_TARGET)
|
||||
return FALSE;
|
||||
}
|
||||
else if (moveAiTarget == TARGET_TEAMMATES)
|
||||
{
|
||||
if (user == target)
|
||||
return FALSE;
|
||||
|
||||
if (GetTreatmentBetweenMonsters(user, target, FALSE, TRUE) == TREATMENT_TREAT_AS_ALLY)
|
||||
hasTarget = TRUE;
|
||||
}
|
||||
else {
|
||||
// s16 memes
|
||||
u16 asU16 = moveAiTarget;
|
||||
if (asU16 == TARGET_USER || asU16 == TARGET_ENEMIES_AFTER_CHARGING) {
|
||||
hasTarget = TRUE;
|
||||
}
|
||||
}
|
||||
else if ((u16) (categoryTargetingFlags - 3) <= 1) // categoryTargetingFlags == TARGETING_FLAG_ITEM
|
||||
{
|
||||
hasTarget = TRUE;
|
||||
}
|
||||
|
||||
if (hasTarget)
|
||||
{
|
||||
if (hasStatusChecker2)
|
||||
if (checkAllConditions)
|
||||
{
|
||||
if (!CanUseOnTargetWithStatusChecker(user, target, move))
|
||||
return FALSE;
|
||||
|
||||
if ((moveAiRange & 0xF00) == AI_CONDITION_RANDOM)
|
||||
{
|
||||
goto returnFalse;
|
||||
s32 use_chance = GetMoveAccuracyOrAiChance(move, ACCURACY_AI_CONDITION_RANDOM_CHANCE);
|
||||
if (DungeonRandInt(100) >= use_chance)
|
||||
return FALSE;
|
||||
}
|
||||
if ((targetingFlags2 & 0xF00) == TARGETING_FLAG_SET_TRAP)
|
||||
else if ((moveAiRange & 0xF00) == AI_CONDITION_HP_25)
|
||||
{
|
||||
goto rollMoveUseChance;
|
||||
if (!MonsterHasQuarterHp(target))
|
||||
return FALSE;
|
||||
}
|
||||
else if ((targetingFlags2 & 0xF00) == TARGETING_FLAG_HEAL_HP)
|
||||
else if ((moveAiRange & 0xF00) == AI_CONDITION_STATUS)
|
||||
{
|
||||
if (!HasLowHealth(target))
|
||||
{
|
||||
if (*categoryTargetingFlags2);
|
||||
goto returnFalse;
|
||||
}
|
||||
if (!MonsterHasNegativeStatus(target))
|
||||
return FALSE;
|
||||
}
|
||||
else if ((targetingFlags2 & 0xF00) == TARGETING_FLAG_HEAL_STATUS)
|
||||
else if ((moveAiRange & 0xF00) == AI_CONDITION_ASLEEP)
|
||||
{
|
||||
if (!HasNegativeStatus(target))
|
||||
{
|
||||
if (*categoryTargetingFlags2); // Flips the conditional.
|
||||
goto returnFalse;
|
||||
}
|
||||
if (!IsMonsterSleeping(target))
|
||||
return FALSE;
|
||||
}
|
||||
else if ((targetingFlags2 & 0xF00) == TARGETING_FLAG_DREAM_EATER)
|
||||
else if ((moveAiRange & 0xF00) == AI_CONDITION_GHOST)
|
||||
{
|
||||
if (!IsSleeping(target))
|
||||
{
|
||||
if (*categoryTargetingFlags2); // Flips the conditional.
|
||||
goto returnFalse;
|
||||
}
|
||||
EntityInfo *targetData = targetData = GetEntInfo(target);
|
||||
if (targetData->types[0] != TYPE_GHOST && targetData->types[1] != TYPE_GHOST)
|
||||
return FALSE;
|
||||
|
||||
if (targetData->exposed)
|
||||
return FALSE;
|
||||
}
|
||||
else if ((targetingFlags2 & 0xF00) == TARGETING_FLAG_EXPOSE)
|
||||
else if ((moveAiRange & 0xF00) == AI_CONDITION_HP_25_OR_STATUS)
|
||||
{
|
||||
targetData = GetEntInfo(target);
|
||||
if ((targetData->types[0] != TYPE_GHOST && targetData->types[1] != TYPE_GHOST) || targetData->exposed)
|
||||
{
|
||||
if (*categoryTargetingFlags2); // Flips the conditional.
|
||||
goto returnFalse;
|
||||
}
|
||||
}
|
||||
else if ((targetingFlags2 & 0xF00) == TARGETING_FLAG_HEAL_ALL)
|
||||
{
|
||||
if (!HasNegativeStatus(target) && !HasLowHealth(target))
|
||||
{
|
||||
if (*categoryTargetingFlags2); // Flips the conditional.
|
||||
goto returnFalse;
|
||||
}
|
||||
if (!MonsterHasNegativeStatus(target) && !MonsterHasQuarterHp(target))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if ((targetingFlags2 & 0xF00) == TARGETING_FLAG_SET_TRAP)
|
||||
else if ((moveAiRange & 0xF00) == AI_CONDITION_RANDOM)
|
||||
{
|
||||
s32 useChance;
|
||||
rollMoveUseChance:
|
||||
useChance = GetMoveAccuracyOrAIChance(move, ACCURACY_AI_CONDITION_RANDOM_CHANCE);
|
||||
if (DungeonRandInt(100) >= useChance)
|
||||
{
|
||||
goto returnFalse;
|
||||
}
|
||||
s32 use_chance = GetMoveAccuracyOrAiChance(move, ACCURACY_AI_CONDITION_RANDOM_CHANCE);
|
||||
if (DungeonRandInt(100) >= use_chance)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return hasTarget;
|
||||
@@ -743,22 +729,22 @@ static s32 WeightMove(Entity *user, s32 targetingFlags, Entity *target, u32 move
|
||||
if ((targetingFlags2 & 0xF) != TARGETING_FLAG_TARGET_OTHER)
|
||||
return 1;
|
||||
|
||||
if (IQSkillIsEnabled(user, IQ_EXP_GO_GETTER))
|
||||
if (IqSkillIsEnabled(user, IQ_EXP_GO_GETTER))
|
||||
{
|
||||
// BUG: expYieldRankings has lower values as the Pokémon's experience yield increases.
|
||||
// This causes Exp. Go-Getter to prioritize Pokémon worth less experience
|
||||
// instead of Pokémon worth more experience.
|
||||
weight = gDungeon->expYieldRankings[targetData->id];
|
||||
}
|
||||
else if (IQSkillIsEnabled(user, IQ_EFFICIENCY_EXPERT))
|
||||
else if (IqSkillIsEnabled(user, IQ_EFFICIENCY_EXPERT))
|
||||
{
|
||||
weight = -12 - targetData->HP;
|
||||
weight = 500 - targetData->HP;
|
||||
if (weight == 0)
|
||||
{
|
||||
weight = 1;
|
||||
}
|
||||
}
|
||||
else if (IQSkillIsEnabled(user, IQ_WEAK_TYPE_PICKER))
|
||||
else if (IqSkillIsEnabled(user, IQ_WEAK_TYPE_PICKER))
|
||||
{
|
||||
weight = WeightWeakTypePicker(user, target, moveType2) + 1;
|
||||
}
|
||||
@@ -774,8 +760,8 @@ static bool8 TargetRegularAttack(Entity *pokemon, u32 *targetDir, bool8 checkPet
|
||||
s32 i;
|
||||
s32 potentialAttackTargetDirections[NUM_DIRECTIONS];
|
||||
s32 potentialAttackTargetWeights[NUM_DIRECTIONS];
|
||||
bool8 hasTargetingIQ = IQSkillIsEnabled(pokemon, IQ_EXP_GO_GETTER) || IQSkillIsEnabled(pokemon, IQ_EFFICIENCY_EXPERT);
|
||||
bool8 hasStatusChecker = IQSkillIsEnabled(pokemon, IQ_STATUS_CHECKER);
|
||||
bool8 hasTargetingIQ = IqSkillIsEnabled(pokemon, IQ_EXP_GO_GETTER) || IqSkillIsEnabled(pokemon, IQ_EFFICIENCY_EXPERT);
|
||||
bool8 hasStatusChecker = IqSkillIsEnabled(pokemon, IQ_STATUS_CHECKER);
|
||||
for (i = 0; i < faceTurnLimit; i++, direction++)
|
||||
{
|
||||
Entity *target;
|
||||
@@ -841,69 +827,48 @@ static bool8 TargetRegularAttack(Entity *pokemon, u32 *targetDir, bool8 checkPet
|
||||
|
||||
}
|
||||
|
||||
bool8 IsTargetInRange(Entity *pokemon, Entity *targetPokemon, s32 direction, s32 maxRange)
|
||||
bool8 IsTargetInRange(Entity *user, Entity *target, s32 direction, s32 nTiles)
|
||||
{
|
||||
s32 distanceX = pokemon->pos.x - targetPokemon->pos.x;
|
||||
s32 effectiveMaxRange;
|
||||
if (distanceX < 0)
|
||||
{
|
||||
distanceX = -distanceX;
|
||||
}
|
||||
effectiveMaxRange = pokemon->pos.y - targetPokemon->pos.y;
|
||||
if (effectiveMaxRange < 0)
|
||||
{
|
||||
effectiveMaxRange = -effectiveMaxRange;
|
||||
}
|
||||
if (effectiveMaxRange < distanceX)
|
||||
{
|
||||
effectiveMaxRange = distanceX;
|
||||
}
|
||||
if (effectiveMaxRange > maxRange)
|
||||
{
|
||||
effectiveMaxRange = maxRange;
|
||||
}
|
||||
if (!IQSkillIsEnabled(pokemon, IQ_COURSE_CHECKER))
|
||||
{
|
||||
// BUG: effectiveMaxRange is already capped at maxRange, so this condition always evaluates to TRUE.
|
||||
s32 effectiveMaxRange = max(abs(user->pos.x - target->pos.x), abs(user->pos.y - target->pos.y));
|
||||
|
||||
if (effectiveMaxRange > nTiles)
|
||||
effectiveMaxRange = nTiles;
|
||||
|
||||
if (!IqSkillIsEnabled(user, IQ_COURSE_CHECKER)) {
|
||||
// BUG: effectiveMaxRange is already capped at nTiles, 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)
|
||||
{
|
||||
if (effectiveMaxRange <= nTiles)
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
s32 currentPosX = pokemon->pos.x;
|
||||
s32 currentPosY = pokemon->pos.y;
|
||||
else {
|
||||
s32 i;
|
||||
s32 currentPosX = user->pos.x;
|
||||
s32 currentPosY = user->pos.y;
|
||||
s32 adjacentTileOffsetX = gAdjacentTileOffsets[direction].x;
|
||||
s32 adjacentTileOffsetY = gAdjacentTileOffsets[direction].y;
|
||||
s32 i;
|
||||
for (i = 0; i <= effectiveMaxRange; i++)
|
||||
{
|
||||
const Tile *mapTile;
|
||||
|
||||
currentPosX += adjacentTileOffsetX;
|
||||
currentPosY += adjacentTileOffsetY;
|
||||
if (currentPosX <= 0 || currentPosY <= 0 ||
|
||||
if (currentPosX < 1 || currentPosY < 1 ||
|
||||
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 = GetTile(currentPosX, currentPosY);
|
||||
if (!(mapTile->terrainFlags & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (mapTile->monster == targetPokemon)
|
||||
{
|
||||
if (GetTerrainType(mapTile) == TERRAIN_TYPE_WALL)
|
||||
return FALSE;
|
||||
|
||||
if (mapTile->monster == target)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (mapTile->monster != NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
@@ -941,7 +906,7 @@ void HandleUseOrbAction(Entity *pokemon)
|
||||
bool8 r4;
|
||||
Item *item;
|
||||
Item IVar5;
|
||||
EntityInfo *entityInfo; // r7
|
||||
EntityInfo *entityInfo;
|
||||
ActionContainer act;
|
||||
Move move;
|
||||
struct AIPossibleMove sp28;
|
||||
|
||||
@@ -100,7 +100,7 @@ u32 GetAIUseItemProbability(Entity *targetPokemon, Item *item, u32 itemTargetFla
|
||||
}
|
||||
break;
|
||||
case ITEM_HEAL_SEED:
|
||||
if (HasNegativeStatus(targetPokemon))
|
||||
if (MonsterHasNegativeStatus(targetPokemon))
|
||||
{
|
||||
itemWeight = 80;
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ void AIDecideUseItem(Entity *pokemon)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_ITEM_MASTER))
|
||||
else if (IqSkillIsEnabled(pokemon, IQ_ITEM_MASTER))
|
||||
{
|
||||
for (toolboxIndex = 1; toolboxIndex < INVENTORY_SIZE + 2; toolboxIndex++)
|
||||
{
|
||||
|
||||
@@ -601,7 +601,7 @@ static bool8 HandleDealingDamageInternal(Entity *attacker, Entity *target, struc
|
||||
|
||||
}
|
||||
|
||||
if (IQSkillIsEnabled(target, IQ_ITEM_MASTER)) {
|
||||
if (IqSkillIsEnabled(target, IQ_ITEM_MASTER)) {
|
||||
s32 i; // r3
|
||||
Item *reviverSeed = NULL; // r4
|
||||
if (ItemExists(&targetData->heldItem) && !ItemSticky(&targetData->heldItem) && ItemId(&targetData->heldItem) == ITEM_REVIVER_SEED)
|
||||
@@ -1026,7 +1026,7 @@ static void ApplyAtkDefStatBoosts(Entity *attacker, Entity *target, u8 moveType,
|
||||
|
||||
if (AbilityIsActive(attacker, ABILITY_GUTS)) {
|
||||
EntityInfo *entInfo = GetEntInfo(attacker);
|
||||
bool8 gutsBoost = HasNegativeStatus(attacker);
|
||||
bool8 gutsBoost = MonsterHasNegativeStatus(attacker);
|
||||
bool8 visFlags_attacker_1 = SetVisualFlags(entInfo,1,gutsBoost);
|
||||
|
||||
if (gutsBoost) {
|
||||
@@ -1081,7 +1081,7 @@ static void ApplyAtkDefStatBoosts(Entity *attacker, Entity *target, u8 moveType,
|
||||
|
||||
if ((AbilityIsActive(target, ABILITY_MARVEL_SCALE)) && (splitIndex == 0)) {
|
||||
EntityInfo *targetInfo = GetEntInfo(target);
|
||||
bool8 hasNegStatus_target = HasNegativeStatus(target);
|
||||
bool8 hasNegStatus_target = MonsterHasNegativeStatus(target);
|
||||
bool8 visFlags_target = SetVisualFlags(targetInfo, 8, hasNegStatus_target);
|
||||
|
||||
if (hasNegStatus_target) {
|
||||
@@ -1330,7 +1330,7 @@ void CalcDamage(Entity *attacker, Entity *target, u8 moveType, s32 movePower, s3
|
||||
critOdds += gCritOddsScopeLensPatsyBand;
|
||||
gDungeon->unk134.unk165 = 1;
|
||||
}
|
||||
if (r5 && IQSkillIsEnabled(attacker, IQ_TYPE_ADVANTAGE_MASTER)) {
|
||||
if (r5 && IqSkillIsEnabled(attacker, IQ_TYPE_ADVANTAGE_MASTER)) {
|
||||
critOdds = gCritOddsIqAdvantageMaster;
|
||||
gDungeon->unk134.unk169 = 1;
|
||||
}
|
||||
|
||||
@@ -351,7 +351,7 @@ static void TryInteractWithTile(Entity *entity)
|
||||
return;
|
||||
|
||||
tile = GetTileAtEntitySafe(entity);
|
||||
if (IQSkillIsEnabled(entity, IQ_SUPER_MOBILE)
|
||||
if (IqSkillIsEnabled(entity, IQ_SUPER_MOBILE)
|
||||
&& info->invisibleClassStatus.status != STATUS_MOBILE
|
||||
&& !(HasHeldItem(entity, ITEM_MOBILE_SCARF)))
|
||||
{
|
||||
@@ -366,7 +366,7 @@ static void TryInteractWithTile(Entity *entity)
|
||||
Trap *trapData = GetTrapInfo(tileEntity);
|
||||
bool8 trigger = FALSE;
|
||||
bool8 onlyMakeVisible = FALSE;
|
||||
if (IQSkillIsEnabled(entity, IQ_TRAP_SEER) && !tileEntity->isVisible) {
|
||||
if (IqSkillIsEnabled(entity, IQ_TRAP_SEER) && !tileEntity->isVisible) {
|
||||
tileEntity->isVisible = TRUE;
|
||||
UpdateTrapsVisibility();
|
||||
onlyMakeVisible = TRUE;
|
||||
@@ -410,7 +410,7 @@ bool8 CheckEntityTileForInteraction(Entity *entity)
|
||||
return FALSE;
|
||||
|
||||
tile = GetTileAtEntitySafe(entity);
|
||||
if (IQSkillIsEnabled(entity, IQ_SUPER_MOBILE) && GetTerrainType(tile) == TERRAIN_TYPE_WALL)
|
||||
if (IqSkillIsEnabled(entity, IQ_SUPER_MOBILE) && GetTerrainType(tile) == TERRAIN_TYPE_WALL)
|
||||
return TRUE;
|
||||
subEntity = tile->object;
|
||||
if (subEntity == NULL)
|
||||
|
||||
@@ -100,7 +100,7 @@ void sub_80479B8(char param_1, char param_2, u8 param_3, Entity *pokemon, Entity
|
||||
}
|
||||
else {
|
||||
if (GetItemCategory(item->id) != CATEGORY_BERRIES_SEEDS_VITAMINS) {
|
||||
flag = IQSkillIsEnabled(target, IQ_ITEM_CATCHER);
|
||||
flag = IqSkillIsEnabled(target, IQ_ITEM_CATCHER);
|
||||
}
|
||||
}
|
||||
if (CheckVariousConditions(target)) {
|
||||
@@ -503,7 +503,7 @@ static void HungerSeedItemAction(Entity *pokemon, Entity * target)
|
||||
{
|
||||
entityInfo = GetEntInfo(target);
|
||||
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], target, 0);
|
||||
if (IQSkillIsEnabled(target, IQ_SELF_CURER))
|
||||
if (IqSkillIsEnabled(target, IQ_SELF_CURER))
|
||||
TryDisplayDungeonLoggableMessage3(pokemon, target, gPtrSelfHealPreventedHungerMessage);
|
||||
else
|
||||
{
|
||||
|
||||
@@ -105,10 +105,10 @@ u8 sub_80703A0(Entity *pokemon, DungeonPos *pos)
|
||||
if ((IsCurrentFixedRoomBossFight()) || ((entityInfo->invisibleClassStatus.status != STATUS_MOBILE && (!HasHeldItem(pokemon, ITEM_MOBILE_SCARF))))) {
|
||||
crossableTerrain = GetCrossableTerrain(entityInfo->id);
|
||||
tileFlags = tile->terrainFlags & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY);
|
||||
if (IQSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER)) {
|
||||
if (IqSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER)) {
|
||||
crossableTerrain = CROSSABLE_TERRAIN_CREVICE;
|
||||
}
|
||||
if (IQSkillIsEnabled(pokemon, IQ_SUPER_MOBILE)) {
|
||||
if (IqSkillIsEnabled(pokemon, IQ_SUPER_MOBILE)) {
|
||||
crossableTerrain = CROSSABLE_TERRAIN_WALL;
|
||||
}
|
||||
switch(crossableTerrain)
|
||||
@@ -171,10 +171,10 @@ bool8 sub_807049C(Entity *pokemon, DungeonPos *pos)
|
||||
if (IsCurrentFixedRoomBossFight() || (entityInfo->invisibleClassStatus.status != STATUS_MOBILE && !HasHeldItem(pokemon, ITEM_MOBILE_SCARF))) {
|
||||
crossableTerrain = GetCrossableTerrain(entityInfo->id);
|
||||
tileFlags = tile->terrainFlags & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY);
|
||||
if (IQSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER)) {
|
||||
if (IqSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER)) {
|
||||
crossableTerrain = CROSSABLE_TERRAIN_CREVICE;
|
||||
}
|
||||
if (IQSkillIsEnabled(pokemon, IQ_SUPER_MOBILE)) {
|
||||
if (IqSkillIsEnabled(pokemon, IQ_SUPER_MOBILE)) {
|
||||
crossableTerrain = CROSSABLE_TERRAIN_WALL;
|
||||
}
|
||||
switch(crossableTerrain)
|
||||
@@ -255,10 +255,10 @@ bool8 sub_80705F0(Entity *pokemon, DungeonPos *pos)
|
||||
if (IsCurrentFixedRoomBossFight() || (entityInfo->invisibleClassStatus.status != STATUS_MOBILE && !HasHeldItem(pokemon, ITEM_MOBILE_SCARF))) {
|
||||
crossableTerrain = GetCrossableTerrain(entityInfo->id);
|
||||
tileFlags = tile->terrainFlags & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY);
|
||||
if (IQSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER)) {
|
||||
if (IqSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER)) {
|
||||
crossableTerrain = CROSSABLE_TERRAIN_CREVICE;
|
||||
}
|
||||
if (IQSkillIsEnabled(pokemon, IQ_SUPER_MOBILE)) {
|
||||
if (IqSkillIsEnabled(pokemon, IQ_SUPER_MOBILE)) {
|
||||
crossableTerrain = CROSSABLE_TERRAIN_WALL;
|
||||
}
|
||||
|
||||
@@ -296,10 +296,10 @@ bool8 sub_80706A4(Entity *pokemon, DungeonPos *pos)
|
||||
if (IsCurrentFixedRoomBossFight() || (entityInfo->invisibleClassStatus.status != STATUS_MOBILE && !HasHeldItem(pokemon, ITEM_MOBILE_SCARF))) {
|
||||
crossableTerrain = GetCrossableTerrain(entityInfo->id);
|
||||
tileFlags = tile->terrainFlags & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY);
|
||||
if (IQSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER)) {
|
||||
if (IqSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER)) {
|
||||
crossableTerrain = CROSSABLE_TERRAIN_CREVICE;
|
||||
}
|
||||
if (IQSkillIsEnabled(pokemon, IQ_SUPER_MOBILE)) {
|
||||
if (IqSkillIsEnabled(pokemon, IQ_SUPER_MOBILE)) {
|
||||
crossableTerrain = CROSSABLE_TERRAIN_WALL;
|
||||
}
|
||||
switch(crossableTerrain)
|
||||
@@ -468,7 +468,7 @@ void CopyEntityNameForDungeonExitSummary(u8 *buffer, EntityInfo *entityInfo)
|
||||
}
|
||||
}
|
||||
|
||||
bool8 HasNegativeStatus(Entity *pokemon)
|
||||
bool8 MonsterHasNegativeStatus(Entity *pokemon)
|
||||
{
|
||||
EntityInfo *pokemonInfo = GetEntInfo(pokemon);
|
||||
s32 i;
|
||||
@@ -508,7 +508,7 @@ bool8 HasNegativeStatus(Entity *pokemon)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool8 IsSleeping(Entity *pokemon)
|
||||
bool8 IsMonsterSleeping(Entity *pokemon)
|
||||
{
|
||||
if (GetEntInfo(pokemon)->sleepClassStatus.status != STATUS_SLEEP &&
|
||||
GetEntInfo(pokemon)->sleepClassStatus.status != STATUS_NAPPING &&
|
||||
@@ -519,7 +519,7 @@ bool8 IsSleeping(Entity *pokemon)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool8 HasLowHealth(Entity *pokemon)
|
||||
bool8 MonsterHasQuarterHp(Entity *pokemon)
|
||||
{
|
||||
EntityInfo *pokemonInfo = GetEntInfo(pokemon);
|
||||
if (pokemonInfo->HP <= pokemonInfo->maxHPStat / 4)
|
||||
@@ -695,9 +695,9 @@ bool8 CanMoveInDirection(Entity *pokemon, u32 direction)
|
||||
{
|
||||
if (GetEntInfo(pokemon)->invisibleClassStatus.status == STATUS_MOBILE || HasHeldItem(pokemon, ITEM_MOBILE_SCARF))
|
||||
crossableTerrain = CROSSABLE_TERRAIN_WALL;
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER))
|
||||
else if (IqSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER))
|
||||
crossableTerrain = CROSSABLE_TERRAIN_CREVICE;
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_SUPER_MOBILE)) {
|
||||
else if (IqSkillIsEnabled(pokemon, IQ_SUPER_MOBILE)) {
|
||||
if (direction & 1)
|
||||
// Super Mobile can't break walls diagonally.
|
||||
crossableTerrain = CROSSABLE_TERRAIN_CREVICE;
|
||||
@@ -730,13 +730,13 @@ bool8 sub_8070F3C(Entity * pokemon, DungeonPos *pos, s32 direction)
|
||||
{
|
||||
terrain = CROSSABLE_TERRAIN_WALL;
|
||||
}
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER))
|
||||
else if (IqSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER))
|
||||
{
|
||||
// BUG: If the Pokémon is a Ghost type that can normally attack through walls,
|
||||
// All-Terrain Hiker/Super Mobile may make the AI think it can't attack through walls.
|
||||
terrain = CROSSABLE_TERRAIN_CREVICE;
|
||||
}
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_SUPER_MOBILE))
|
||||
else if (IqSkillIsEnabled(pokemon, IQ_SUPER_MOBILE))
|
||||
{
|
||||
if ((direction & 1) != 0)
|
||||
{
|
||||
@@ -793,13 +793,13 @@ bool8 sub_8070F80(Entity * pokemon, s32 direction)
|
||||
{
|
||||
terrain = CROSSABLE_TERRAIN_WALL;
|
||||
}
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER))
|
||||
else if (IqSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER))
|
||||
{
|
||||
// BUG: If the Pokémon is a Ghost type that can normally attack through walls,
|
||||
// All-Terrain Hiker/Super Mobile may make the AI think it can't attack through walls.
|
||||
terrain = CROSSABLE_TERRAIN_CREVICE;
|
||||
}
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_SUPER_MOBILE))
|
||||
else if (IqSkillIsEnabled(pokemon, IQ_SUPER_MOBILE))
|
||||
{
|
||||
if ((direction & 1) != 0)
|
||||
{
|
||||
@@ -839,13 +839,13 @@ UNUSED static bool8 sub_8071058(Entity * pokemon, s32 direction)
|
||||
{
|
||||
terrain = CROSSABLE_TERRAIN_WALL;
|
||||
}
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER))
|
||||
else if (IqSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER))
|
||||
{
|
||||
// BUG: If the Pokémon is a Ghost type that can normally attack through walls,
|
||||
// All-Terrain Hiker/Super Mobile may make the AI think it can't attack through walls.
|
||||
terrain = CROSSABLE_TERRAIN_CREVICE;
|
||||
}
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_SUPER_MOBILE))
|
||||
else if (IqSkillIsEnabled(pokemon, IQ_SUPER_MOBILE))
|
||||
{
|
||||
if ((direction & 1) != 0)
|
||||
{
|
||||
@@ -886,13 +886,13 @@ bool8 CanAttackInDirection(Entity *pokemon, s32 direction)
|
||||
{
|
||||
crossableTerrain = CROSSABLE_TERRAIN_WALL;
|
||||
}
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER))
|
||||
else if (IqSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER))
|
||||
{
|
||||
// BUG: If the Pokémon is a Ghost type that can normally attack through walls,
|
||||
// All-Terrain Hiker/Super Mobile may make the AI think it can't attack through walls.
|
||||
crossableTerrain = CROSSABLE_TERRAIN_CREVICE;
|
||||
}
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_SUPER_MOBILE))
|
||||
else if (IqSkillIsEnabled(pokemon, IQ_SUPER_MOBILE))
|
||||
{
|
||||
if ((direction & 1) != 0)
|
||||
{
|
||||
@@ -927,12 +927,12 @@ bool8 CanAIMonsterMoveInDirection(Entity *pokemon, s32 direction, bool8 *pokemon
|
||||
}
|
||||
if (frontTile->terrainFlags & TERRAIN_TYPE_IN_MONSTER_HOUSE &&
|
||||
!gDungeon->unk644.monsterHouseTriggered &&
|
||||
IQSkillIsEnabled(pokemon, IQ_HOUSE_AVOIDER))
|
||||
IqSkillIsEnabled(pokemon, IQ_HOUSE_AVOIDER))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (frontTile->object != NULL &&
|
||||
IQSkillIsEnabled(pokemon, IQ_TRAP_AVOIDER) &&
|
||||
IqSkillIsEnabled(pokemon, IQ_TRAP_AVOIDER) &&
|
||||
GetEntityType(frontTile->object) == ENTITY_TRAP &&
|
||||
(frontTile->object->isVisible || GetEntInfo(pokemon)->blinkerClassStatus.status == STATUS_EYEDROPS))
|
||||
{
|
||||
@@ -940,7 +940,7 @@ bool8 CanAIMonsterMoveInDirection(Entity *pokemon, s32 direction, bool8 *pokemon
|
||||
}
|
||||
if ((frontTile->terrainFlags & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_SECONDARY &&
|
||||
gDungeonWaterType[gDungeon->tileset] == DUNGEON_WATER_TYPE_LAVA &&
|
||||
IQSkillIsEnabled(pokemon, IQ_LAVA_EVADER))
|
||||
IqSkillIsEnabled(pokemon, IQ_LAVA_EVADER))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -951,13 +951,13 @@ bool8 CanAIMonsterMoveInDirection(Entity *pokemon, s32 direction, bool8 *pokemon
|
||||
{
|
||||
crossableTerrain = CROSSABLE_TERRAIN_WALL;
|
||||
}
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER))
|
||||
else if (IqSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER))
|
||||
{
|
||||
// BUG: If the Pokémon is a Ghost type that can normally move through walls,
|
||||
// All-Terrain Hiker/Super Mobile may make the AI think it can't move through walls.
|
||||
crossableTerrain = CROSSABLE_TERRAIN_CREVICE;
|
||||
}
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_SUPER_MOBILE))
|
||||
else if (IqSkillIsEnabled(pokemon, IQ_SUPER_MOBILE))
|
||||
{
|
||||
if ((direction & 1) != 0)
|
||||
{
|
||||
@@ -993,11 +993,11 @@ bool8 IsAtJunction(Entity *pokemon)
|
||||
{
|
||||
crossableTerrain = CROSSABLE_TERRAIN_WALL;
|
||||
}
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER))
|
||||
else if (IqSkillIsEnabled(pokemon, IQ_ALL_TERRAIN_HIKER))
|
||||
{
|
||||
crossableTerrain = CROSSABLE_TERRAIN_CREVICE;
|
||||
}
|
||||
else if (IQSkillIsEnabled(pokemon, IQ_SUPER_MOBILE))
|
||||
else if (IqSkillIsEnabled(pokemon, IQ_SUPER_MOBILE))
|
||||
{
|
||||
crossableTerrain = CROSSABLE_TERRAIN_WALL;
|
||||
}
|
||||
@@ -1021,7 +1021,7 @@ bool8 IsAtJunction(Entity *pokemon)
|
||||
char walkableNeighborFlags;
|
||||
if (gDungeonWaterType[gDungeon->tileset] == DUNGEON_WATER_TYPE_LAVA
|
||||
&& crossableTerrain == CROSSABLE_TERRAIN_LIQUID
|
||||
&& IQSkillIsEnabled(pokemon, IQ_LAVA_EVADER))
|
||||
&& IqSkillIsEnabled(pokemon, IQ_LAVA_EVADER))
|
||||
{
|
||||
crossableTerrain = CROSSABLE_TERRAIN_REGULAR;
|
||||
}
|
||||
@@ -1320,7 +1320,7 @@ bool8 IsTacticSet(Entity *pokemon, u8 tactic)
|
||||
return pokemonInfo->tactic == tactic;
|
||||
}
|
||||
|
||||
bool8 IQSkillIsEnabled(Entity *pokemon, u8 IQSkill)
|
||||
bool8 IqSkillIsEnabled(Entity *pokemon, u8 IQSkill)
|
||||
{
|
||||
return IsIQSkillSet(&GetEntInfo(pokemon)->IQSkillFlags, 1 << IQSkill);
|
||||
}
|
||||
|
||||
@@ -936,7 +936,7 @@ void CheckLeaderTile(void)
|
||||
return;
|
||||
|
||||
tile = GetTileAtEntitySafe(leader);
|
||||
if (IQSkillIsEnabled(leader, IQ_SUPER_MOBILE) && GetEntInfo(leader)->invisibleClassStatus.status != STATUS_MOBILE && !HasHeldItem(leader, ITEM_MOBILE_SCARF))
|
||||
if (IqSkillIsEnabled(leader, IQ_SUPER_MOBILE) && GetEntInfo(leader)->invisibleClassStatus.status != STATUS_MOBILE && !HasHeldItem(leader, ITEM_MOBILE_SCARF))
|
||||
sub_804AE84(&leader->pos);
|
||||
if (tile->terrainFlags & TERRAIN_TYPE_STAIRS)
|
||||
gDungeon->unk1 = 1;
|
||||
@@ -950,7 +950,7 @@ void CheckLeaderTile(void)
|
||||
Trap *trap = GetTrapInfo(tileObject);
|
||||
bool32 r8 = FALSE;
|
||||
bool32 r7 = FALSE;
|
||||
if (IQSkillIsEnabled(leader, IQ_TRAP_SEER) && !tileObject->isVisible) {
|
||||
if (IqSkillIsEnabled(leader, IQ_TRAP_SEER) && !tileObject->isVisible) {
|
||||
tileObject->isVisible = TRUE;
|
||||
UpdateTrapsVisibility();
|
||||
r7 = TRUE;
|
||||
|
||||
@@ -1714,7 +1714,7 @@ void EndAbilityImmuneStatus(Entity *attacker, Entity *target)
|
||||
}
|
||||
|
||||
if ((AbilityIsActive(target, ABILITY_INSOMNIA) || AbilityIsActive(target, ABILITY_VITAL_SPIRIT))
|
||||
&& (IsSleeping(target) || targetInfo->sleepClassStatus.status == STATUS_YAWNING))
|
||||
&& (IsMonsterSleeping(target) || targetInfo->sleepClassStatus.status == STATUS_YAWNING))
|
||||
{
|
||||
EndSleepClassStatus(attacker, target, FALSE, TRUE);
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ bool32 sub_8055A00(Entity *attacker, s32 firstMoveId, s32 var_34, s32 itemId, s3
|
||||
break;
|
||||
|
||||
if (currMove->id == MOVE_SNORE || currMove->id == MOVE_SLEEP_TALK) {
|
||||
if (!IsSleeping(attacker)) {
|
||||
if (!IsMonsterSleeping(attacker)) {
|
||||
if (CannotAttack(attacker, TRUE))
|
||||
break;
|
||||
}
|
||||
@@ -406,7 +406,7 @@ bool8 TryUseChosenMove(struct Entity *attacker, u32 r6, s32 itemId, u32 var_30,
|
||||
|
||||
entInfo = GetEntInfo(attacker);
|
||||
if (var_30 != 0 || move->id == MOVE_SNORE || move->id == MOVE_SLEEP_TALK) {
|
||||
if (!IsSleeping(attacker) && CannotAttack(attacker, TRUE))
|
||||
if (!IsMonsterSleeping(attacker) && CannotAttack(attacker, TRUE))
|
||||
break;
|
||||
}
|
||||
else {
|
||||
@@ -743,14 +743,14 @@ bool8 AccuracyCalc(Entity *attacker, Entity *target, Move *move, s32 accuracyTyp
|
||||
{
|
||||
s32 statStageAccuracy, statStageEvasion;
|
||||
s24_8 statStageMul;
|
||||
s32 accuracy = GetMoveAccuracyOrAIChance(move, accuracyType);
|
||||
s32 accuracy = GetMoveAccuracyOrAiChance(move, accuracyType);
|
||||
s32 rand = DungeonRandInt(100);
|
||||
EntityInfo *attackerInfo = GetEntInfo(attacker);
|
||||
EntityInfo *targetInfo = GetEntInfo(target);
|
||||
|
||||
if (selfAlwaysHits && attacker == target)
|
||||
return TRUE;
|
||||
if (move->id == MOVE_REGULAR_ATTACK && IQSkillIsEnabled(attacker, IQ_SURE_HIT_ATTACKER))
|
||||
if (move->id == MOVE_REGULAR_ATTACK && IqSkillIsEnabled(attacker, IQ_SURE_HIT_ATTACKER))
|
||||
return TRUE;
|
||||
if (attackerInfo->sureShotClassStatus.status == STATUS_SURE_SHOT)
|
||||
return TRUE;
|
||||
@@ -762,7 +762,7 @@ bool8 AccuracyCalc(Entity *attacker, Entity *target, Move *move, s32 accuracyTyp
|
||||
if (HasHeldItem(target, ITEM_DETECT_BAND)) {
|
||||
accuracy -= gDetectBandAccuracyDebuffValue;
|
||||
}
|
||||
if (IQSkillIsEnabled(target, IQ_QUICK_DODGER)) {
|
||||
if (IqSkillIsEnabled(target, IQ_QUICK_DODGER)) {
|
||||
accuracy -= gIqQuickDodgerAccuracyDebuffValue;
|
||||
}
|
||||
|
||||
@@ -829,7 +829,7 @@ void SetTargetsForMove(Entity **targetsArray, Entity *attacker, Move *move)
|
||||
|| GetEntInfo(attacker)->cringeClassStatus.status == STATUS_COWERING);
|
||||
bool8 canHitSelf = (GetEntInfo(attacker)->cringeClassStatus.status == STATUS_CONFUSED || GetEntInfo(attacker)->cringeClassStatus.status == STATUS_COWERING);
|
||||
|
||||
if (IQSkillIsEnabled(attacker, IQ_NONTRAITOR)) {
|
||||
if (IqSkillIsEnabled(attacker, IQ_NONTRAITOR)) {
|
||||
canHitSelf = FALSE;
|
||||
canHitPartner = FALSE;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ s32 CalculateStatusTurns(Entity *target, const s16 *turnRange, bool8 factorCurer
|
||||
|
||||
numTurns = DungeonRandRange(turnRange[0],turnRange[1]);
|
||||
if (EntityIsValid(target) && (GetEntityType(target) == ENTITY_MONSTER) && (factorCurerSkills)) {
|
||||
if (IQSkillIsEnabled(target, IQ_SELF_CURER) && (numTurns != 0x7f)) {
|
||||
if (IqSkillIsEnabled(target, IQ_SELF_CURER) && (numTurns != 0x7f)) {
|
||||
numTurns /= 2;
|
||||
}
|
||||
if (AbilityIsActive(target, ABILITY_NATURAL_CURE) && (numTurns != 0x7f) && (4 < numTurns)) {
|
||||
|
||||
@@ -87,7 +87,7 @@ void ApplyEndOfTurnEffects(Entity *entity)
|
||||
arrIndex = 0;
|
||||
if (HasHeldItem(entity, ITEM_STAMINA_BAND))
|
||||
arrIndex--;
|
||||
if (IQSkillIsEnabled(entity, IQ_ENERGY_SAVER))
|
||||
if (IqSkillIsEnabled(entity, IQ_ENERGY_SAVER))
|
||||
arrIndex--;
|
||||
if (HasHeldItem(entity, ITEM_DIET_RIBBON))
|
||||
arrIndex++;
|
||||
@@ -180,7 +180,7 @@ void ApplyEndOfTurnEffects(Entity *entity)
|
||||
|
||||
// Abilities check
|
||||
rand = DungeonRandInt(100);
|
||||
if (AbilityIsActive(entity, ABILITY_SHED_SKIN) && rand < gShedSkinActivateChance && HasNegativeStatus(entity)) {
|
||||
if (AbilityIsActive(entity, ABILITY_SHED_SKIN) && rand < gShedSkinActivateChance && MonsterHasNegativeStatus(entity)) {
|
||||
DisplayActions(NULL);
|
||||
if (!EntityIsValid(entity) || IsFloorOver())
|
||||
return;
|
||||
|
||||
@@ -259,7 +259,7 @@ bool8 CanUseOnSelfWithStatusChecker(Entity *pokemon, Move *move)
|
||||
}
|
||||
break;
|
||||
case MOVE_REST:
|
||||
if (!HasLowHealth(pokemon) && !HasNegativeStatus(pokemon))
|
||||
if (!MonsterHasQuarterHp(pokemon) && !MonsterHasNegativeStatus(pokemon))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -467,7 +467,7 @@ bool8 CanUseOnTargetWithStatusChecker(Entity *user, Entity *target, Move *move)
|
||||
case MOVE_SING:
|
||||
case MOVE_SLEEP_POWDER:
|
||||
case MOVE_SPORE:
|
||||
if (IsSleeping(target))
|
||||
if (IsMonsterSleeping(target))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -477,7 +477,7 @@ bool8 CanUseOnTargetWithStatusChecker(Entity *user, Entity *target, Move *move)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (IsSleeping(target))
|
||||
if (IsMonsterSleeping(target))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ bool8 SnoreMoveAction(Entity *pokemon, Entity *target, Move * move, s32 itemId)
|
||||
bool8 flag;
|
||||
|
||||
flag = FALSE;
|
||||
if (IsSleeping(pokemon)) {
|
||||
if (IsMonsterSleeping(pokemon)) {
|
||||
if (HandleDamagingMove(pokemon,target,move,IntToF248(1),itemId) != 0) {
|
||||
flag = TRUE;
|
||||
if (sub_805727C(pokemon,target,gSnoreSecondaryChance)) {
|
||||
|
||||
@@ -221,7 +221,7 @@ bool8 DreamEaterMoveAction(Entity * pokemon, Entity * target, Move *move, s32 it
|
||||
|
||||
flag = FALSE;
|
||||
hasLiquidOoze = AbilityIsActive(target, ABILITY_LIQUID_OOZE);
|
||||
if (IsSleeping(target)) {
|
||||
if (IsMonsterSleeping(target)) {
|
||||
iVar3 = HandleDamagingMove(pokemon,target,move,IntToF248(1),itemId);
|
||||
if (iVar3 != 0) {
|
||||
flag = TRUE;
|
||||
|
||||
@@ -103,7 +103,7 @@ bool8 CannotSleep(Entity * pokemon, Entity * target, u8 param_3, bool8 displayMe
|
||||
(SafeguardIsActive(pokemon,target,displayMessage))))) {
|
||||
return TRUE;
|
||||
}
|
||||
else if (IQSkillIsEnabled(target, IQ_NONSLEEPER)) {
|
||||
else if (IqSkillIsEnabled(target, IQ_NONSLEEPER)) {
|
||||
if (displayMessage) {
|
||||
TryDisplayDungeonLoggableMessage3(pokemon,target,gUnknown_80FCD54);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ void sub_8079F20(Entity * pokemon, Entity * target, u8 param_3, u8 param_4)
|
||||
moveUnsealed = FALSE;
|
||||
if (EntityIsValid(target)) {
|
||||
entityInfo = GetEntInfo(target);
|
||||
if (HasNegativeStatus(target)) {
|
||||
if (MonsterHasNegativeStatus(target)) {
|
||||
bVar8 = TRUE;
|
||||
EndSleepClassStatus(pokemon,target,0,0);
|
||||
if (!EntityIsValid(target)) {
|
||||
|
||||
@@ -190,7 +190,7 @@ s32 GetMoveBasePower(Move *move)
|
||||
return sMovesData[move->id].basePower;
|
||||
}
|
||||
|
||||
s32 GetMoveAccuracyOrAIChance(Move *move, u32 accuracyType)
|
||||
s32 GetMoveAccuracyOrAiChance(Move *move, u32 accuracyType)
|
||||
{
|
||||
return sMovesData[move->id].accuracy[accuracyType];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user