non-partner good move checks

This commit is contained in:
Evan 2020-12-19 21:58:23 -07:00
parent 8a544665e4
commit 31ec3e8479
11 changed files with 3258 additions and 678 deletions

View File

@ -2301,68 +2301,6 @@ AI_CV_Encore_End:
end end
AI_CV_Encore_EncouragedMovesToEncore: AI_CV_Encore_EncouragedMovesToEncore:
.byte EFFECT_DREAM_EATER
.byte EFFECT_ATTACK_UP
.byte EFFECT_DEFENSE_UP
.byte EFFECT_SPEED_UP
.byte EFFECT_SPECIAL_ATTACK_UP
.byte EFFECT_HAZE
.byte EFFECT_ROAR
.byte EFFECT_CONVERSION
.byte EFFECT_TOXIC
.byte EFFECT_LIGHT_SCREEN
.byte EFFECT_REST
.byte EFFECT_SUPER_FANG
.byte EFFECT_SPECIAL_DEFENSE_UP_2
.byte EFFECT_CONFUSE
.byte EFFECT_POISON
.byte EFFECT_PARALYZE
.byte EFFECT_LEECH_SEED
.byte EFFECT_DO_NOTHING
.byte EFFECT_ATTACK_UP_2
.byte EFFECT_ENCORE
.byte EFFECT_CONVERSION_2
.byte EFFECT_LOCK_ON
.byte EFFECT_HEAL_BELL
.byte EFFECT_MEAN_LOOK
.byte EFFECT_NIGHTMARE
.byte EFFECT_PROTECT
.byte EFFECT_SKILL_SWAP
.byte EFFECT_FORESIGHT
.byte EFFECT_PERISH_SONG
.byte EFFECT_SANDSTORM
.byte EFFECT_ENDURE
.byte EFFECT_SWAGGER
.byte EFFECT_ATTRACT
.byte EFFECT_SAFEGUARD
.byte EFFECT_RAIN_DANCE
.byte EFFECT_SUNNY_DAY
.byte EFFECT_BELLY_DRUM
.byte EFFECT_PSYCH_UP
.byte EFFECT_FUTURE_SIGHT
.byte EFFECT_FAKE_OUT
.byte EFFECT_STOCKPILE
.byte EFFECT_SPIT_UP
.byte EFFECT_SWALLOW
.byte EFFECT_HAIL
.byte EFFECT_TORMENT
.byte EFFECT_WILL_O_WISP
.byte EFFECT_FOLLOW_ME
.byte EFFECT_CHARGE
.byte EFFECT_TRICK
.byte EFFECT_ROLE_PLAY
.byte EFFECT_INGRAIN
.byte EFFECT_RECYCLE
.byte EFFECT_KNOCK_OFF
.byte EFFECT_SKILL_SWAP
.byte EFFECT_IMPRISON
.byte EFFECT_REFRESH
.byte EFFECT_GRUDGE
.byte EFFECT_TEETER_DANCE
.byte EFFECT_MUD_SPORT
.byte EFFECT_WATER_SPORT
.byte EFFECT_DRAGON_DANCE
.byte EFFECT_CAMOUFLAGE
.byte -1 .byte -1
AI_CV_PainSplit: AI_CV_PainSplit:

View File

@ -239,20 +239,26 @@ struct AiLogicData
{ {
//attacker data //attacker data
u16 atkAbility; u16 atkAbility;
u16 atkItem;
u16 atkHoldEffect; u16 atkHoldEffect;
u8 atkParam; u8 atkParam;
u16 atkSpecies;
// target data // target data
u16 defAbility; u16 defAbility;
u16 defItem;
u16 defHoldEffect; u16 defHoldEffect;
u8 defParam; u8 defParam;
u16 defSpecies;
// attacker partner data // attacker partner data
u8 battlerAtkPartner; u8 battlerAtkPartner;
u16 partnerMove; u16 partnerMove;
u16 atkPartnerAbility; u16 atkPartnerAbility;
u16 atkPartnerHoldEffect;
bool32 targetSameSide; bool32 targetSameSide;
// target partner data // target partner data
u8 battlerDefPartner; u8 battlerDefPartner;
u16 defPartnerAbility; u16 defPartnerAbility;
u16 defPartnerHoldEffect;
}; };
struct AI_ThinkingStruct struct AI_ThinkingStruct

View File

@ -14,5 +14,6 @@ enum
void GetAIPartyIndexes(u32 battlerId, s32 *firstId, s32 *lastId); void GetAIPartyIndexes(u32 battlerId, s32 *firstId, s32 *lastId);
void AI_TrySwitchOrUseItem(void); void AI_TrySwitchOrUseItem(void);
u8 GetMostSuitableMonToSwitchInto(void); u8 GetMostSuitableMonToSwitchInto(void);
bool32 ShouldSwitch(void);
#endif // GUARD_BATTLE_AI_SWITCH_ITEMS_H #endif // GUARD_BATTLE_AI_SWITCH_ITEMS_H

View File

@ -1,7 +1,7 @@
#ifndef GUARD_BATTLE_AI_UTIL_H #ifndef GUARD_BATTLE_AI_UTIL_H
#define GUARD_BATTLE_AI_UTIL_H #define GUARD_BATTLE_AI_UTIL_H
// for IsBattlerFaster // for IsAiFaster
#define AI_CHECK_FASTER 0 // if_user_faster #define AI_CHECK_FASTER 0 // if_user_faster
#define AI_CHECK_SLOWER 1 // if_target_faster #define AI_CHECK_SLOWER 1 // if_target_faster
@ -20,25 +20,36 @@ void SaveBattlerData(u8 battlerId);
void SetBattlerData(u8 battlerId); void SetBattlerData(u8 battlerId);
void RestoreBattlerData(u8 battlerId); void RestoreBattlerData(u8 battlerId);
bool32 AtMaxHp(u8 battler);
u32 GetHealthPercentage(u8 battler); u32 GetHealthPercentage(u8 battler);
bool32 IsBattlerTrapped(u8 battler, bool8 switching); bool32 IsBattlerTrapped(u8 battler, bool8 switching);
bool32 IsBattlerFaster(u8 battler); bool32 IsAiFaster(u8 battler);
bool32 CanTargetFaintAi(u8 battlerDef, u8 battlerAtk); bool32 CanTargetFaintAi(u8 battlerDef, u8 battlerAtk);
bool32 CanMoveFaintBattler(u16 move, u8 battlerDef, u8 battlerAtk, u8 nHits);
bool32 CanTargetFaintAiWithMod(u8 battlerDef, u8 battlerAtk, s32 hpMod, s32 dmgMod); bool32 CanTargetFaintAiWithMod(u8 battlerDef, u8 battlerAtk, s32 hpMod, s32 dmgMod);
s32 AI_GetAbility(u32 battlerId); s32 AI_GetAbility(u32 battlerId);
u16 AI_GetHoldEffect(u32 battlerId); u16 AI_GetHoldEffect(u32 battlerId);
u32 AI_GetMoveAccuracy(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u8 atkHoldEffect, u8 defHoldEffect, u16 move); u32 AI_GetMoveAccuracy(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u8 atkHoldEffect, u8 defHoldEffect, u16 move);
bool32 DoesBattlerIgnoreAbilityChecks(u16 atkAbility, u16 move); bool32 DoesBattlerIgnoreAbilityChecks(u16 atkAbility, u16 move);
bool32 AI_WeatherHasEffect(void); bool32 AI_WeatherHasEffect(void);
bool32 CanAttackerFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index); bool32 CanAttackerFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index, u8 numHits);
bool32 AI_IsBattlerGrounded(u8 battlerId); bool32 AI_IsBattlerGrounded(u8 battlerId);
bool32 BattlerHasDamagingMove(u8 battlerId); bool32 HasDamagingMove(u8 battlerId);
bool32 BattlerHasSecondaryDamage(u8 battlerId); bool32 HasDamagingMoveOfType(u8 battlerId, u8 type);
u32 GetBattlerSecondaryDamage(u8 battlerId);
bool32 BattlerWillFaintFromWeather(u8 battler, u16 ability); bool32 BattlerWillFaintFromWeather(u8 battler, u16 ability);
bool32 BattlerWillFaintFromSecondaryDamage(u8 battler, u16 ability);
bool32 ShouldTryOHKO(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u32 accuracy, u16 move); bool32 ShouldTryOHKO(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u32 accuracy, u16 move);
bool32 ShouldUseRecoilMove(u8 battlerAtk, u8 battlerDef, u32 recoilDmg, u8 moveIndex); bool32 ShouldUseRecoilMove(u8 battlerAtk, u8 battlerDef, u32 recoilDmg, u8 moveIndex);
u16 GetBattlerSideSpeedAverage(u8 battler); u16 GetBattlerSideSpeedAverage(u8 battler);
bool32 ShouldRecover(u8 battlerAtk, u8 battlerDef, u16 move, s32 damage); bool32 ShouldAbsorb(u8 battlerAtk, u8 battlerDef, u16 move, s32 damage);
bool32 ShouldRecover(u8 battlerAtk, u8 battlerDef, u16 move, u8 healPercent);
bool32 ShouldSetScreen(u8 battlerAtk, u8 battlerDef, u16 moveEffect);
bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 moveIndex);
bool32 IsRecycleEncouragedItem(u16 item);
bool32 CanKnockOffItem(u8 battler, u16 item);
bool32 IsAbilityOfRating(u16 ability, s8 rating);
s8 GetAbilityRating(u16 ability);
// stat stage checks // stat stage checks
bool32 AnyStatIsRaised(u8 battlerId); bool32 AnyStatIsRaised(u8 battlerId);
@ -50,8 +61,15 @@ u32 CountPositiveStatStages(u8 battlerId);
u32 CountNegativeStatStages(u8 battlerId); u32 CountNegativeStatStages(u8 battlerId);
bool32 BattlerShouldRaiseAttacks(u8 battlerId, u16 ability); bool32 BattlerShouldRaiseAttacks(u8 battlerId, u16 ability);
bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex); bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex);
bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex);
bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex);
bool32 ShouldLowerSpAtk(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex);
bool32 ShouldLowerSpDef(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex);
bool32 ShouldLowerAccuracy(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex);
bool32 ShouldLowerEvasion(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex);
// move checks // move checks
bool32 IsAffectedByPowder(u8 battler, u16 ability, u16 holdEffect);
bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split); bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split);
s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef); s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef);
u8 GetMoveDamageResult(u16 move); u8 GetMoveDamageResult(u16 move);
@ -59,10 +77,12 @@ u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef);
u8 AI_GetMoveEffectiveness(u16 move); u8 AI_GetMoveEffectiveness(u16 move);
u16 *GetMovesArray(u32 battler); u16 *GetMovesArray(u32 battler);
bool32 IsConfusionMoveEffect(u16 moveEffect); bool32 IsConfusionMoveEffect(u16 moveEffect);
bool32 HasMove(u32 battlerId, u32 move);
bool32 HasMoveWithSplit(u32 battler, u32 split); bool32 HasMoveWithSplit(u32 battler, u32 split);
bool32 HasMoveWithType(u32 battler, u8 type); bool32 HasMoveWithType(u32 battler, u8 type);
bool32 HasMoveWithTypeAndSplit(u32 battler, u8 type, u8 split);
bool32 HasMoveEffect(u32 battlerId, u16 moveEffect); bool32 HasMoveEffect(u32 battlerId, u16 moveEffect);
bool32 HasMoveWithLowAccuracy(u8, u8, u8, bool32, u16, u16, u16, u16, u16); bool32 HasMoveWithLowAccuracy(u8, u8, u8, bool32, u16, u16, u16, u16);
bool32 TestMoveFlagsInMoveset(u8 battler, u32 flags); bool32 TestMoveFlagsInMoveset(u8 battler, u32 flags);
bool32 IsAromaVeilProtectedMove(u16 move); bool32 IsAromaVeilProtectedMove(u16 move);
bool32 IsNonVolatileStatusMoveEffect(u16 moveEffect); bool32 IsNonVolatileStatusMoveEffect(u16 moveEffect);
@ -73,15 +93,36 @@ bool32 IsHazardMoveEffect(u16 moveEffect);
bool32 MoveCallsOtherMove(u16 move); bool32 MoveCallsOtherMove(u16 move);
bool32 MoveRequiresRecharging(u16 move); bool32 MoveRequiresRecharging(u16 move);
bool32 IsInstructBannedMove(u16 move); bool32 IsInstructBannedMove(u16 move);
bool32 IsEncoreEncouragedEffect(u16 moveEffect);
void ProtectChecks(u8 battlerAtk, u8 battlerDef, u16 move, u16 predictedMove, s16 *score);
bool32 ShouldSetSandstorm(u8 battler, u16 ability, u16 holdEffect);
bool32 ShouldSetHail(u8 battler, u16 ability, u16 holdEffect);
bool32 ShouldSetRain(u8 battlerAtk, u16 ability, u16 holdEffect);
bool32 ShouldSetSun(u8 battlerAtk, u16 atkAbility, u16 holdEffect);
bool32 HasSleepMoveWithLowAccuracy(u8 battlerAtk, u8 battlerDef);
bool32 IsHealingMoveEffect(u16 effect);
bool32 HasHealingEffect(u32 battler);
bool32 ShouldFakeOut(u8 battlerAtk, u8 battlerDef, u16 move);
bool32 IsThawingMove(u16 move);
bool32 HasThawingMove(u8 battlerId);
// status checks // status checks
bool32 CanBeBurned(u8 battler, u16 ability);
bool32 CanBePoisoned(u8 battler, u16 ability);
bool32 IsBattlerIncapacitated(u8 battler, u16 ability);
bool32 CanSleep(u8 battler, u16 ability);
bool32 AI_CanPutToSleep(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove); bool32 AI_CanPutToSleep(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove);
bool32 ShouldPoisonSelf(u8 battler, u16 ability);
bool32 AI_CanPoison(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove); bool32 AI_CanPoison(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove);
bool32 AI_CanParalyze(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove); bool32 AI_CanParalyze(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove);
bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove); bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove);
bool32 ShouldBurnSelf(u8 battler, u16 ability);
bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove); bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove);
bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGender, u8 defGender); bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGender, u8 defGender);
bool32 AnyPartyMemberStatused(u8 battlerId, bool32 checkSoundproof); bool32 AnyPartyMemberStatused(u8 battlerId, bool32 checkSoundproof);
u32 ShouldTryToFlinch(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u16 move);
bool32 ShouldTrap(u8 battlerAtk, u8 battlerDef, u16 move);
bool32 IsWakeupTurn(u8 battler);
// partner logic // partner logic
u16 GetAllyChosenMove(void); u16 GetAllyChosenMove(void);
@ -95,10 +136,21 @@ bool32 PartnerMoveEffectIsTerrain(u8 battlerAtkPartner, u16 partnerMove);
bool32 PartnerMoveIs(u8 battlerAtkPartner, u16 partnerMove, u16 moveCheck); bool32 PartnerMoveIs(u8 battlerAtkPartner, u16 partnerMove, u16 moveCheck);
bool32 PartnerMoveIsSameAsAttacker(u8 battlerAtkPartner, u8 battlerDef, u16 move, u16 partnerMove); bool32 PartnerMoveIsSameAsAttacker(u8 battlerAtkPartner, u8 battlerDef, u16 move, u16 partnerMove);
bool32 PartnerMoveIsSameNoTarget(u8 battlerAtkPartner, u16 move, u16 partnerMove); bool32 PartnerMoveIsSameNoTarget(u8 battlerAtkPartner, u16 move, u16 partnerMove);
bool32 ShouldUseWishAromatherapy(u8 battlerAtk, u8 battlerDef, u16 move);
// party logic // party logic
s32 AI_CalcPartyMonDamage(u16 move, u8 battlerAtk, u8 battlerDef, struct Pokemon *mon); s32 AI_CalcPartyMonDamage(u16 move, u8 battlerAtk, u8 battlerDef, struct Pokemon *mon);
s32 CountUsablePartyMons(u8 battlerId); s32 CountUsablePartyMons(u8 battlerId);
bool32 IsPartyFullyHealedExceptBattler(u8 battler); bool32 IsPartyFullyHealedExceptBattler(u8 battler);
bool32 PartyHasMoveSplit(u8 battlerId, u8 split);
bool32 SideHasMoveSplit(u8 battlerId, u8 split);
// score increases
void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score);
void IncreasePoisonScore(u8 battlerAtk, u8 battlerdef, u16 move, s16 *score);
void IncreaseBurnScore(u8 battlerAtk, u8 battlerdef, u16 move, s16 *score);
void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score);
void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score);
void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score);
#endif //GUARD_BATTLE_AI_UTIL_H #endif //GUARD_BATTLE_AI_UTIL_H

View File

@ -220,7 +220,8 @@
#define SIDE_STATUS_CRAFTY_SHIELD (1 << 20) #define SIDE_STATUS_CRAFTY_SHIELD (1 << 20)
#define SIDE_STATUS_MAT_BLOCK (1 << 21) #define SIDE_STATUS_MAT_BLOCK (1 << 21)
#define SIDE_HAZARDS_ANY (SIDE_STATUS_SPIKES | SIDE_STATUS_STICKY_WEB | SIDE_STATUS_TOXIC_SPIKES | SIDE_STATUS_STEALTH_ROCK) #define SIDE_STATUS_HAZARDS_ANY (SIDE_STATUS_SPIKES | SIDE_STATUS_STICKY_WEB | SIDE_STATUS_TOXIC_SPIKES | SIDE_STATUS_STEALTH_ROCK)
#define SIDE_STATUS_SCREEEN_ANY (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL)
// Field affecting statuses. // Field affecting statuses.
#define STATUS_FIELD_MAGIC_ROOM 0x1 #define STATUS_FIELD_MAGIC_ROOM 0x1

View File

@ -50,6 +50,8 @@
#define AI_FLAG_HELP_PARTNER (1 << 10) // AI can try to help partner. If not set, will tend not to target partner #define AI_FLAG_HELP_PARTNER (1 << 10) // AI can try to help partner. If not set, will tend not to target partner
#define AI_FLAG_WILL_SUICIDE (1 << 11) // AI will use explosion / self destruct / final gambit / etc #define AI_FLAG_WILL_SUICIDE (1 << 11) // AI will use explosion / self destruct / final gambit / etc
#define AI_FLAG_PREFER_STATUS_MOVES (1 << 12) // AI gets a score bonus for status moves. Should be combined with AI_FLAG_CHECK_BAD_MOVE to prevent using only status moves #define AI_FLAG_PREFER_STATUS_MOVES (1 << 12) // AI gets a score bonus for status moves. Should be combined with AI_FLAG_CHECK_BAD_MOVE to prevent using only status moves
#define AI_FLAG_STALL (1 << 13) // AI stalls battle and prefers secondary damage/trapping/etc. TODO not finished
#define AI_FLAG_SCREENER (1 << 14) // AI prefers screening effects like reflect, mist, etc. TODO unfinished
// 'other' ai logic flags // 'other' ai logic flags
#define AI_FLAG_ROAMING (1 << 29) #define AI_FLAG_ROAMING (1 << 29)

View File

@ -74,5 +74,6 @@ ItemUseFunc ItemId_GetFieldFunc(u16 itemId);
u8 ItemId_GetBattleUsage(u16 itemId); u8 ItemId_GetBattleUsage(u16 itemId);
ItemUseFunc ItemId_GetBattleFunc(u16 itemId); ItemUseFunc ItemId_GetBattleFunc(u16 itemId);
u8 ItemId_GetSecondaryId(u16 itemId); u8 ItemId_GetSecondaryId(u16 itemId);
bool32 IsPinchBerryItemEffect(u16 holdEffect);
#endif // GUARD_ITEM_H #endif // GUARD_ITEM_H

File diff suppressed because it is too large Load Diff

View File

@ -417,7 +417,7 @@ static bool8 FindMonWithFlagsAndSuperEffective(u16 flags, u8 moduloPercent)
return FALSE; return FALSE;
} }
static bool8 ShouldSwitch(void) bool32 ShouldSwitch(void)
{ {
u8 battlerIn1, battlerIn2; u8 battlerIn1, battlerIn2;
s32 firstId; s32 firstId;

File diff suppressed because it is too large Load Diff

View File

@ -957,3 +957,26 @@ u8 ItemId_GetSecondaryId(u16 itemId)
{ {
return gItems[SanitizeItemId(itemId)].secondaryId; return gItems[SanitizeItemId(itemId)].secondaryId;
} }
bool32 IsPinchBerryItemEffect(u16 holdEffect)
{
switch (holdEffect)
{
case HOLD_EFFECT_ATTACK_UP:
case HOLD_EFFECT_DEFENSE_UP:
case HOLD_EFFECT_SPEED_UP:
case HOLD_EFFECT_SP_ATTACK_UP:
case HOLD_EFFECT_SP_DEFENSE_UP:
case HOLD_EFFECT_CRITICAL_UP:
case HOLD_EFFECT_RANDOM_STAT_UP:
#ifdef HOLD_EFFECT_CUSTAP_BERRY
case HOLD_EFFECT_CUSTAP_BERRY:
#endif
#ifdef HOLD_EFFECT_MICLE_BERRY
case HOLD_EFFECT_MICLE_BERRY:
#endif
return TRUE;
}
return FALSE;
}