本文整理汇总了C++中DoSelectLowestHpFriendly函数的典型用法代码示例。如果您正苦于以下问题:C++ DoSelectLowestHpFriendly函数的具体用法?C++ DoSelectLowestHpFriendly怎么用?C++ DoSelectLowestHpFriendly使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了DoSelectLowestHpFriendly函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: UpdateAI
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_SHADOW_WORD_PAIN:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
DoCast(target, SPELL_SHADOW_WORD_PAIN);
events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 8000);
return;
case EVENT_CIRCLE_OF_DESTRUCTION:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
DoCast(target, SPELL_CIRCLE_OF_DESTRUCTION);
events.ScheduleEvent(EVENT_CIRCLE_OF_DESTRUCTION, 12000);
return;
case EVENT_COWER_IN_FEAR:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
DoCast(target, SPELL_COWER_IN_FEAR);
events.ScheduleEvent(EVENT_COWER_IN_FEAR, 10000);
return;
case EVENT_DARK_MENDING:
// find an ally with missing HP
if (Unit* target = DoSelectLowestHpFriendly(40, DUNGEON_MODE(30000, 50000)))
{
DoCast(target, SPELL_DARK_MENDING);
events.ScheduleEvent(EVENT_DARK_MENDING, 20000);
}
else
{
// no friendly unit with missing hp. re-check in just 5 sec.
events.ScheduleEvent(EVENT_DARK_MENDING, 5000);
}
return;
}
}
DoMeleeAttackIfReady();
}
示例2: UpdateAI
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (uiShieldTimer <= diff)
{
me->AddAura(RAND(SPELL_MAGIC_REFLECTION, SPELL_DAMAGE_REFLECTION), me);
// DoCast(m_creature, RAND(SPELL_MAGIC_REFLECTION, SPELL_DAMAGE_REFLECTION));
uiShieldTimer = urand(20000, 30000);
} else uiShieldTimer -= diff;
switch (me->GetEntry())
{
case NPC_FLAMEWAKER_ELITE:
if (Blastwave_Timer <= diff)
{
DoCast(SPELL_BLAST_WAVE);
Blastwave_Timer = 10000;
} else Blastwave_Timer -= diff;
if (uiFireBlastTimer <= diff)
{
DoCast(SPELL_FIRE_BLAST);
uiFireBlastTimer = 15000;
} else uiFireBlastTimer -= diff;
break;
case NPC_FLAMEWAKER_HEALER:
if (uiShadowShockTimer <= diff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, SPELL_SHADOW_SHOCK);
uiShadowShockTimer = 2000;
} else uiShadowShockTimer -= diff;
if (uiHealTimer <= diff)
{
if (Unit* pTarget = DoSelectLowestHpFriendly(200))
DoCast(pTarget, SPELL_HEAL_BRETHREN);
uiHealTimer = urand(15000, 20000);
} else uiHealTimer -= diff;
break;
}
DoMeleeAttackIfReady();
}
示例3: UpdateAI
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_ENRAGE:
DoScriptText(SAY_MOLGEIM_BERSERK, me);
DoCast(SPELL_BERSERK);
break;
case EVENT_RUNE_OF_POWER: // Improve target selection; random alive friendly
{
Unit *pTarget = DoSelectLowestHpFriendly(60);
if (!pTarget || !pTarget->isAlive())
pTarget = me;
DoCast(pTarget, SPELL_SUMMON_RUNE_OF_POWER);
events.ScheduleEvent(EVENT_RUNE_OF_POWER, 60000);
break;
}
case EVENT_SHIELD_OF_RUNES:
DoCast(me, RAID_MODE(SPELL_SHIELD_OF_RUNES, SPELL_SHIELD_OF_RUNES_H));
events.ScheduleEvent(EVENT_SHIELD_OF_RUNES, urand(27000,34000));
break;
case EVENT_RUNE_OF_DEATH:
DoScriptText(SAY_MOLGEIM_RUNE_DEATH, me);
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
DoCast(pTarget, SPELL_RUNE_OF_DEATH);
events.ScheduleEvent(EVENT_RUNE_OF_DEATH, urand(30000,40000));
break;
case EVENT_RUNE_OF_SUMMONING:
DoScriptText(SAY_MOLGEIM_SUMMON, me);
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
DoCast(pTarget, SPELL_RUNE_OF_SUMMONING);
events.ScheduleEvent(EVENT_RUNE_OF_SUMMONING, urand(20000,30000));
break;
}
}
DoMeleeAttackIfReady();
}
示例4: UpdateAI
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
if (me->HasUnitState(UNIT_STAT_CASTING))
return;
//Chain heal Timer
if (m_uiHealTimer <= uiDiff)
{
if (Unit *pAlly = DoSelectLowestHpFriendly(INTERACTION_DISTANCE*100))
DoCast(pAlly, SPELL_HEAL);
m_uiHealTimer = urand(15000, 20000);
}
else
m_uiHealTimer -= uiDiff;
//Fel Fireball Timer
if (m_uiFFireballTimer <= uiDiff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
DoCast(pTarget, SPELL_FEL_FIREBALL);
m_uiFFireballTimer = urand(10000, 15000);
}
else
m_uiFFireballTimer -= uiDiff;
//Fire Nova timer
if (m_uiFireNovaTimer <= uiDiff)
{
DoCast(me, SPELL_FIRE_NOVA);
m_uiFireNovaTimer = urand(8000, 15000);
}
else
m_uiFireNovaTimer -= uiDiff;
DoMeleeAttackIfReady();
}
示例5: UpdateAI
void UpdateAI(const uint32 uiDiff) override
{
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
// Casting Heal to Sulfuron or other Guards.
if (m_uiHealTimer < uiDiff)
{
if (Unit* pUnit = DoSelectLowestHpFriendly(60.0f, 1))
{
if (DoCastSpellIfCan(pUnit, SPELL_HEAL) == CAST_OK)
m_uiHealTimer = urand(15000, 20000);
}
}
else
m_uiHealTimer -= uiDiff;
// ShadowWord Pain Timer
if (m_uiShadowWordPainTimer < uiDiff)
{
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
{
if (DoCastSpellIfCan(pTarget, SPELL_SHADOWWORD_PAIN) == CAST_OK)
m_uiShadowWordPainTimer = urand(18000, 26000);
}
}
else
m_uiShadowWordPainTimer -= uiDiff;
// Immolate Timer
if (m_uiImmolateTimer < uiDiff)
{
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
{
if (DoCastSpellIfCan(pTarget, SPELL_IMMOLATE) == CAST_OK)
m_uiImmolateTimer = urand(15000, 25000);
}
}
else
m_uiImmolateTimer -= uiDiff;
DoMeleeAttackIfReady();
}
示例6: UpdateChampionAI
bool UpdateChampionAI(const uint32 uiDiff)
{
if (m_uiLightningTimer < uiDiff)
{
if (DoCastSpellIfCan(m_creature, SPELL_CHAIN_LIGHTNING) == CAST_OK)
m_uiLightningTimer = urand(1000, 3000);
}
else
m_uiLightningTimer -= uiDiff;
if (m_uiHealingWaveTimer < uiDiff)
{
if (Unit* pTarget = DoSelectLowestHpFriendly(40.0f))
{
if (DoCastSpellIfCan(pTarget, SPELL_HEALING_WAVE) == CAST_OK)
m_uiHealingWaveTimer = urand(8000, 13000);
}
}
else
m_uiHealingWaveTimer -= uiDiff;
if (m_uiEarthShieldTimer < uiDiff)
{
if (DoCastSpellIfCan(m_creature, SPELL_EARTH_SHIELD, CAST_AURA_NOT_PRESENT) == CAST_OK)
m_uiEarthShieldTimer = 30000;
else
m_uiEarthShieldTimer = 5000;
}
else
m_uiEarthShieldTimer -= uiDiff;
if (m_uiHexTimer < uiDiff)
{
if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_HEX_OF_MENDING) == CAST_OK)
m_uiHexTimer = urand(17000, 25000);
}
else
m_uiHexTimer -= uiDiff;
return true;
}
示例7: UpdateEscortAI
void UpdateEscortAI(const uint32 uiDiff) override
{
DialogueUpdate(uiDiff);
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
if (m_uiExorcismTimer < uiDiff)
{
if (DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_EXORCISM : SPELL_EXORCISM_H) == CAST_OK)
m_uiExorcismTimer = urand(9000, 13000);
}
else
m_uiExorcismTimer -= uiDiff;
if (m_uiHolyLightTimer < uiDiff)
{
if (Unit* pTarget = DoSelectLowestHpFriendly(40.0f))
{
if (DoCastSpellIfCan(pTarget, SPELL_HOLY_LIGHT) == CAST_OK)
m_uiHolyLightTimer = urand(18000, 25000);
}
}
else
m_uiHolyLightTimer -= uiDiff;
if (!m_bYell50Pct && m_creature->GetHealthPercent() < 50.0f)
{
DoScriptText(SAY_ARTHAS_HALF_HP, m_creature);
m_bYell50Pct = true;
}
if (!m_bYell20Pct && m_creature->GetHealthPercent() < 20.0f)
{
DoScriptText(SAY_ARTHAS_LOW_HP, m_creature);
m_bYell20Pct = true;
}
DoMeleeAttackIfReady();
}
示例8: UpdateAI
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
//Casting Heal to Sulfuron or other Guards.
if (Heal_Timer <= diff)
{
Unit* pUnit = DoSelectLowestHpFriendly(60.0f, 1);
if (!pUnit)
return;
DoCast(pUnit, SPELL_HEAL);
Heal_Timer = 15000+rand()%5000;
} else Heal_Timer -= diff;
//ShadowWordPain_Timer
if (ShadowWordPain_Timer <= diff)
{
Unit *pTarget = NULL;
pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
if (pTarget) DoCast(pTarget, SPELL_SHADOWWORDPAIN);
ShadowWordPain_Timer = 18000+rand()%8000;
} else ShadowWordPain_Timer -= diff;
//Immolate_Timer
if (Immolate_Timer <= diff)
{
Unit *pTarget = NULL;
pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
if (pTarget) DoCast(pTarget, SPELL_IMMOLATE);
Immolate_Timer = 15000+rand()%10000;
} else Immolate_Timer -= diff;
DoMeleeAttackIfReady();
}
示例9: GetAI
void PlayerbotPaladinAI::DoNonCombatActions()
{
PlayerbotAI *ai = GetAI();
Player *m_bot = GetPlayerBot();
if (!m_bot || !ai || m_bot->isDead()) { return; }
//If Casting or Eating/Drinking return
if (m_bot->HasUnitState(UNIT_STATE_CASTING)) { return; }
if (m_bot->getStandState() == UNIT_STAND_STATE_SIT) { return; }
//buff and heal raid
if (DoSupportRaid(m_bot)) { return; }
//heal pets and bots
Unit *target = DoSelectLowestHpFriendly(40, 1000);
if (target && target->isAlive() && HealTarget(target, target->GetHealth()*100 / target->GetMaxHealth())) { return; }
//mana/hp check
//Don't bother with eating, if low on hp, just let it heal themself
if (m_bot->getRace() == (uint8) RACE_UNDEAD_PLAYER && ai->GetHealthPercent() < 75 && CastSpell(R_CANNIBALIZE,m_bot)) { return; }
if (m_bot->GetHealth() < m_bot->GetMaxHealth() && CastSpell(FLASH_OF_LIGHT,m_bot)) { return; }
if (ai->GetManaPercent() < 70) { ai->Feast(); }
} //end DoNonCombatActions
示例10: GetPlayerBot
bool PlayerbotShamanAI::HealGroup (Unit *target, uint8 hp, uint8 &countNeedHeal)
{
Player *m_bot = GetPlayerBot();
if (countNeedHeal < 2) {
return false;
}
Unit *rTarget = DoSelectLowestHpFriendly(30,500);
if (!rTarget || rTarget->isDead() || rTarget->GetHealth() * 100 / rTarget->GetMaxHealth() > 80 ) {
return false;
}
if (hp < 65 && RIPTIDE && rTarget->HasAura(RIPTIDE,m_bot->GetGUID()) && CastSpell(CHAIN_HEAL, rTarget)) {
return true;
}
if (hp < 85 && CastSpell(RIPTIDE, rTarget)) {
return true;
}
if (hp < 75 && CastSpell(CHAIN_HEAL, rTarget,true,true)) {
return true;
}
return false;
}
示例11: UpdateAI
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return;
//cast bubble at 20% hp
if (m_creature->GetHealthPercent() < 20.0f)
timedCast(SPELL_BUBBLE, diff);
if (Unit *target = DoSelectLowestHpFriendly(40.0f))
if (target->GetHealthPercent() < 15.0f)
timedCast(SPELL_HAND_OF_PROTECTION, diff);
timedCast(SPELL_HOLY_SHOCK, diff);
if (Unit *target = SelectRandomFriendlyMissingBuff(SPELL_HAND_OF_FREEDOM))
timedCast(SPELL_HAND_OF_FREEDOM, diff, target);
timedCast(SPELL_HAMMER_OF_JUSTICE, diff);
if (timedQuery(SPELL_FLASH_OF_LIGHT, diff))
{
switch (urand(0,4))
{
case 0: case 1:
doCast(SPELL_FLASH_OF_LIGHT);
break;
case 2: case 3:
doCast(SPELL_HOLY_LIGHT);
break;
case 4:
doCast(SPELL_CLEANSE);
break;
}
}
boss_faction_championsAI::UpdateAI(diff);
}
示例12: UpdateAI
void UpdateAI(const uint32 uiDiff) override
{
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
if (m_uiHealTimer <= uiDiff)
{
if (Unit* pTarget = DoSelectLowestHpFriendly(50.0f))
{
if (DoCastSpellIfCan(pTarget, SPELL_SOLARIUM_GREAT_HEAL) == CAST_OK)
m_uiHealTimer = 9000;
}
}
else
m_uiHealTimer -= uiDiff;
if (m_uiHolySmiteTimer <= uiDiff)
{
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, nullptr, SELECT_FLAG_PLAYER))
{
if (DoCastSpellIfCan(pTarget, SPELL_SOLARIUM_HOLY_SMITE) == CAST_OK)
m_uiHolySmiteTimer = 4000;
}
}
else
m_uiHolySmiteTimer -= uiDiff;
if (m_uiAoESilenceTimer <= uiDiff)
{
if (DoCastSpellIfCan(m_creature, SPELL_SOLARIUM_ARCANE_TORRENT) == CAST_OK)
m_uiAoESilenceTimer = 13000;
}
else
m_uiAoESilenceTimer -= uiDiff;
DoMeleeAttackIfReady();
}
示例13: UpdateAI
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STAT_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_HEAL:
if (Unit* target = DoSelectLowestHpFriendly(60.0f, 1))
DoCast(target, SPELL_HEAL);
events.ScheduleEvent(EVENT_HEAL, urand(15000, 20000));
break;
case EVENT_SHADOW_WORD_PAIN:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_SHADOWWORDPAIN))
DoCast(target, SPELL_SHADOWWORDPAIN);
events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(18000, 26000));
break;
case EVENT_IMMOLATE:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_IMMOLATE))
DoCast(target, SPELL_IMMOLATE);
events.ScheduleEvent(EVENT_IMMOLATE, urand(15000, 25000));
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
示例14: GetAI
//.........这里部分代码省略.........
// Do support stuff
if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; }
if (ai->GetManaPercent() > 70 && DoSupportRaid(m_bot)) { return; }
break;
#pragma endregion
#pragma region BOT_ROLE_DPS_MELEE
case BOT_ROLE_DPS_MELEE:
TakePosition(pTarget);
// Do support stuff
if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; }
if (ai->GetManaPercent() > 40 && DoSupportRaid(m_bot)) { return; }
break;
#pragma endregion
#pragma region BOT_ROLE_DPS_RANGED
case BOT_ROLE_DPS_RANGED:
TakePosition(pTarget);
// Do support stuff
if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; }
if (ai->GetManaPercent() > 40 && DoSupportRaid(m_bot)) { return; }
break;
#pragma endregion
#pragma region BOT_ROLE_SUPPORT
case BOT_ROLE_SUPPORT:
TakePosition(pTarget);
// Do support stuff
if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; }
if (DoSupportRaid(m_bot)) { return; }
//heal pets and bots
Unit *target = DoSelectLowestHpFriendly(40, 1000);
if(target && target->isAlive() && HealTarget(target, target->GetHealth()*100 / target->GetMaxHealth()) ) { return; }
break;
#pragma endregion
}
#pragma region ShamanCommon
//Defensive Stuff
if (m_tank->GetGUID() != m_bot->GetGUID() && pVictim && pVictim->GetGUID() == m_bot->GetGUID() )
{
if (pDist > 5 && CastSpell(FROST_SHOCK, pTarget)) { return; }
if ((pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_BEAST || pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_HUMANOID) && CastSpell(HEX, pTarget)) { return; } // no gcd
if (CastSpell(WIND_SHEAR, pTarget)) { } // no gcd
}
if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && pTarget->IsNonMeleeSpellCasted(true) && CastSpell(R_ARCANE_TORRENT, pTarget)) { } //no gcd
if (pTarget->IsNonMeleeSpellCasted(true) && CastSpell(WIND_SHEAR, pTarget)) { } //no gcd
if (m_bot->getRace() == (uint8) RACE_TAUREN && pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; }
//Catch
if (pTarget->HasUnitMovementFlag(UNIT_FLAG_FLEEING))
{
if (CastSpell(FROST_SHOCK,pTarget)) return;
}
//Buff and restores
if ( ( (ai->GetHealthPercent() < 60 && isUnderAttack()) ||
(ai->GetManaPercent() < 30) ) && CastSpell(SHAMANISTIC_RAGE, m_bot)) { return; }
if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot)) {} // no GCD
if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot)) {} // no GCD
if (!m_bot->HasAura(HEROISM) && !m_bot->HasAura(EXHAUSTION) && !m_bot->HasAura(SATED) && CastSpell(HEROISM,m_bot)) { return; }
示例15: debug_log
//.........这里部分代码省略.........
case SUMMON_INSTANT:
pSummon = _doSummon(m_uiSpellIdx, TEMPSUMMON_MANUAL_DESPAWN,0);
if(pSummon) result = CAST_OK;
else result = CAST_FAIL_OTHER;
break;
case CAST_ON_ALLPLAYERS:
{
Map* pMap = m_creature->GetMap();
Map::PlayerList const& pPlayers = pMap->GetPlayers();
if (!pPlayers.isEmpty())
{
for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr)
{
pTarget = itr->getSource();
if (pTarget && pTarget->isAlive() && pTarget->IsWithinDistInMap(m_creature, pSpell->LocData.x))
{
if (!pSpell->m_IsBugged)
{
m_creature->CastSpell(pTarget, pSpell->m_uiSpellEntry[currentDifficulty], false);
}
else
{
_BSWDoCast(m_uiSpellIdx, pTarget);
};
result = CAST_OK;
};
}
} else result = CAST_FAIL_OTHER;
}
break;
case CAST_ON_FRENDLY:
pTarget = DoSelectLowestHpFriendly(pSpell->LocData.x,0);
result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
break;
case CAST_ON_FRENDLY_LOWHP:
pTarget = DoSelectLowestHpFriendly(pSpell->LocData.x,1);
result = _BSWCastOnTarget(pTarget, m_uiSpellIdx);
break;
case CAST_ON_RANDOM_POINT:
if (!pTarget) pTarget = m_creature;
if (pSpell->LocData.z <= 1.0f)
{
float fPosX, fPosY, fPosZ;
if (!pTarget->IsPositionValid() || !pTarget->IsInMap(m_creature))
{
if (pTarget->GetTypeId() == TYPEID_PLAYER)
error_log("BSW: CAST_ON_RANDOM_POINT FAILED: player has invalid position. SpellID is %u",pSpell->m_uiSpellEntry[currentDifficulty]);
else error_log("BSW: CAST_ON_RANDOM_POINT FAILED: creature has invalid position. SpellID is %u",pSpell->m_uiSpellEntry[currentDifficulty]);
result = CAST_FAIL_OTHER;
break;
}
pTarget->GetPosition(fPosX, fPosY, fPosZ);
pTarget->GetRandomPoint(fPosX, fPosY, fPosZ, urand((uint32)pSpell->LocData.x, (uint32)pSpell->LocData.y), fPosX, fPosY, fPosZ);
if ((int)fPosZ == 0)
{
error_log("BSW: CAST_ON_RANDOM_POINT FAILED: Positon Z is NULL. Strange bug");
result = CAST_FAIL_OTHER;
break;
}
if (SpellEntry const *spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty]))