public static bool AbilityAvailable(this EliteAPI api, string ability) { // IF YOU HAVE INPAIRMENT/AMNESIA THEN BLOCK JOB ABILITY CASTING if (api.HasStatus(StatusEffect.No_Job_Abilities) || api.HasStatus(StatusEffect.Amnesia)) { return(false); } var apiAbility = api.Resources.GetAbility(ability, 0); //int recast = api.Recast.GetAbilityRecast(apiAbility); return(api.Player.HasAbility(apiAbility.ID) && api.GetAbilityRecast(ability) == 0); }
public static bool SpellAvailable(this EliteAPI api, string spell) { // IF YOU HAVE OMERTA THEN BLOCK MAGIC CASTING if (api.HasStatus(StatusEffect.No_Magic_Casting)) { return(false); } var apiSpell = api.Resources.GetSpell(spell, 0); var mainLevelReq = apiSpell.LevelRequired[api.Player.MainJob]; var subLevelReq = apiSpell.LevelRequired[api.Player.SubJob]; // First check for definite no. // If our main either can't learn it, or isn't high enough, and similar for our sub. if ((mainLevelReq == -1 || mainLevelReq > api.Player.MainJobLevel) && (subLevelReq == -1 || subLevelReq > api.Player.SubJobLevel)) { return(false); } // Then check for special case where we need job points if (mainLevelReq > 99) { var jobPointsTuple = Data.JobPointSpells[spell]; if (api.Player.MainJob != (byte)jobPointsTuple.Item1 || api.Player.GetJobPoints(api.Player.MainJob).SpentJobPoints < jobPointsTuple.Item2) { return(false); } } // If we get here, we qualify for the spell. So make sure we own it, and that it's off cooldown. return(api.Player.HasSpell(apiSpell.ID) && (api.Recast.GetSpellRecast(apiSpell.Index) == 0)); }
public static int ShadowsRemaining(this EliteAPI api) { if (api.HasStatus(StatusEffect.Utsusemi_4_Shadows_Left)) { return(4); } else if (api.HasStatus(StatusEffect.Utsusemi_3_Shadows_Left)) { return(3); } else if (api.HasStatus(StatusEffect.Utsusemi_2_Shadows_Left)) { return(2); } else if (api.HasStatus(StatusEffect.Utsusemi_1_Shadow_Left)) { return(1); } return(0); }
public static bool HasStatus(this EliteAPI api, StatusEffect effect) { return(api.HasStatus((short)effect)); }
public static int CurrentSCHCharges(this EliteAPI api) { if (api != null) { int MainJob = api.Player.MainJob; int SubJob = api.Player.SubJob; if (MainJob == (int)Job.SCH || SubJob == (int)Job.SCH) { if (api.HasStatus(StatusEffect.Light_Arts) || api.HasStatus(StatusEffect.Addendum_White)) { // Stragem charge recast = ability ID 231? int currentRecastTimer = api.Recast.GetAbilityRecast(231); int SpentPoints = api.Player.GetJobPoints((int)Job.SCH).SpentJobPoints; int MainLevel = api.Player.MainJobLevel; int SubLevel = api.Player.SubJobLevel; int baseTimer = 240; int baseCharges = 1; // Generate the correct timer between charges depending on level / Job Points if (MainJob == (int)Job.SCH) { if (SpentPoints >= 550) { baseTimer = 33; baseCharges = 5; } else if (MainLevel >= 90) { baseTimer = 48; baseCharges = 5; } else if (MainLevel >= 70 && MainLevel < 90) { baseTimer = 60; baseCharges = 4; } else if (MainLevel >= 50 && MainLevel < 70) { baseTimer = 80; baseCharges = 3; } else if (MainLevel >= 30 && MainLevel < 50) { baseTimer = 120; baseCharges = 2; } else if (MainLevel >= 10 && MainLevel < 30) { baseTimer = 240; baseCharges = 1; } } else if (SubJob == (int)Job.SCH) { if (SubLevel >= 30 && SubLevel < 50) { baseTimer = 120; baseCharges = 2; } } // Now knowing what the time between charges is lets calculate how many // charges are available if (currentRecastTimer == 0) { return(baseCharges); } else { int t = currentRecastTimer / 60; int stratsUsed = t / baseTimer; int currentCharges = (int)Math.Ceiling((decimal)baseCharges - stratsUsed); return((baseTimer == 120) ? currentCharges-- : currentCharges); } } } } return(-1); }
public EngineAction Run(GeoConfig Config) { _config = Config; EngineAction actionResult = new EngineAction { Target = Target.Me }; if (Config.EntrustEnabled && !PL.HasStatus((StatusEffect)584) && CheckEngagedStatus() == true && PL.AbilityAvailable(Ability.Entrust)) { actionResult.JobAbility = Ability.Entrust; return(actionResult); } else if (Config.DematerializeEnabled && CheckEngagedStatus() == true && PL.Player.Pet.HealthPercent >= 90 && PL.AbilityAvailable(Ability.Dematerialize)) { actionResult.JobAbility = Ability.Dematerialize; return(actionResult); } else if (Config.EclipticAttritionEnabled && CheckEngagedStatus() == true && PL.Player.Pet.HealthPercent >= 90 && PL.AbilityAvailable(Ability.EclipticAttrition) && !PL.HasStatus(516) && EclipticStillUp != true) { actionResult.JobAbility = Ability.EclipticAttrition; return(actionResult); } else if (Config.LifeCycleEnabled && CheckEngagedStatus() == true && PL.Player.Pet.HealthPercent <= 30 && PL.Player.Pet.HealthPercent >= 5 && PL.Player.HPP >= 90 && PL.AbilityAvailable(Ability.LifeCycle)) { actionResult.JobAbility = Ability.LifeCycle; return(actionResult); } // TODO: Fix up this logic, I think something was lost in the refactoring. // Need to see if there's a situation where both of these JA's would be activated for the cast. // For now the old logic seems to be use RA on it's own, or check for FC + Cast. if (Config.RadialArcanaEnabled && (PL.Player.MP <= Config.RadialArcanaMP) && PL.AbilityAvailable(Ability.RadialArcana) && !PL.Player.Buffs.Contains((short)StatusEffect.Weakness)) { // Check if a pet is already active if (PL.Player.Pet.HealthPercent >= 1 && PL.Player.Pet.Distance <= 9) { actionResult.JobAbility = Ability.RadialArcana; return(actionResult); } else if (PL.Player.Pet.HealthPercent >= 1 && PL.Player.Pet.Distance >= 9 && PL.AbilityAvailable(Ability.FullCircle)) { actionResult.JobAbility = Ability.FullCircle; } actionResult.Spell = ReturnGeoSpell(Config.RadialArcanaSpell, 2); } else if (Config.FullCircleEnabled) { // When out of range Distance is 59 Yalms regardless, Must be within 15 yalms to gain // the effect //Check if "pet" is active and out of range of the monitored player if (PL.Player.Pet.HealthPercent >= 1) { if (Config.FullCircleGeoTarget == true && Config.LuopanSpellTarget != "") { ushort PetsIndex = PL.Player.PetIndex; XiEntity PetsEntity = PL.Entity.GetEntity(PetsIndex); int FullCircle_CharID = 0; for (int x = 0; x < 2048; x++) { XiEntity entity = PL.Entity.GetEntity(x); if (entity.Name != null && entity.Name.ToLower().Equals(Config.LuopanSpellTarget.ToLower())) { FullCircle_CharID = Convert.ToInt32(entity.TargetID); break; } } if (FullCircle_CharID != 0) { XiEntity FullCircleEntity = PL.Entity.GetEntity(FullCircle_CharID); float fX = PetsEntity.X - FullCircleEntity.X; float fY = PetsEntity.Y - FullCircleEntity.Y; float fZ = PetsEntity.Z - FullCircleEntity.Z; float generatedDistance = (float)Math.Sqrt((fX * fX) + (fY * fY) + (fZ * fZ)); if (generatedDistance >= 10) { FullCircleTimer.Enabled = true; } } } else if (Config.FullCircleGeoTarget == false && Monitored.Player.Status == 1) { ushort PetsIndex = PL.Player.PetIndex; XiEntity PetsEntity = Monitored.Entity.GetEntity(PetsIndex); if (PetsEntity.Distance >= 10) { FullCircleTimer.Enabled = true; } } } } // ENTRUSTED INDI SPELL CASTING, WILL BE CAST SO LONG AS ENTRUST IS ACTIVE else if (Config.GeoSpellsEnabled && PL.HasStatus((StatusEffect)584) && PL.Player.Status != 33) { string SpellCheckedResult = ReturnGeoSpell(Config.EntrustSpell, 1); if (SpellCheckedResult == "SpellError_Cancel") { Config.GeoSpellsEnabled = false; actionResult.Error = "An error has occurred with Entrusted INDI spell casting, please report what spell was active at the time."; } else if (SpellCheckedResult == "SpellRecast" || SpellCheckedResult == "SpellUnknown") { } else { actionResult.Target = string.IsNullOrEmpty(Config.EntrustSpellTarget) ? Monitored.Player.Name : Config.EntrustSpellTarget; actionResult.Spell = SpellCheckedResult; } } // CAST NON ENTRUSTED INDI SPELL else if (Config.GeoSpellsEnabled && !PL.HasStatus(612) && PL.Player.Status != 33 && (CheckEngagedStatus() == true || !Config.IndiWhenEngaged)) { string SpellCheckedResult = ReturnGeoSpell(Config.IndiSpell, 1); if (SpellCheckedResult == "SpellError_Cancel") { Config.GeoSpellsEnabled = false; actionResult.Error = "An error has occurred with INDI spell casting, please report what spell was active at the time."; } else if (SpellCheckedResult == "SpellRecast" || SpellCheckedResult == "SpellUnknown") { } else { actionResult.Spell = SpellCheckedResult; } } // GEO SPELL CASTING else if (Config.LuopanSpellsEnabled && (PL.Player.Pet.HealthPercent < 1) && (CheckEngagedStatus() == true)) { // Use BLAZE OF GLORY if ENABLED if (Config.BlazeOfGloryEnabled && PL.AbilityAvailable(Ability.BlazeOfGlory) && CheckEngagedStatus() == true && GEO_EnemyCheck() == true) { actionResult.JobAbility = Ability.BlazeOfGlory; return(actionResult); } // Grab GEO spell name string SpellCheckedResult = ReturnGeoSpell(Config.GeoSpell, 2); if (SpellCheckedResult == "SpellError_Cancel") { Config.GeoSpellsEnabled = false; actionResult.Error = "An error has occurred with GEO spell casting, please report what spell was active at the time."; } else if (SpellCheckedResult == "SpellRecast" || SpellCheckedResult == "SpellUnknown") { // Do nothing and continue on with the program } else { if (PL.Resources.GetSpell(SpellCheckedResult, 0).ValidTargets == 5) { // PLAYER CHARACTER TARGET actionResult.Target = string.IsNullOrEmpty(Config.LuopanSpellTarget) ? Monitored.Player.Name : Config.LuopanSpellTarget; if (PL.HasStatus(516)) // IF ECLIPTIC IS UP THEN ACTIVATE THE BOOL { EclipticStillUp = true; } actionResult.Spell = SpellCheckedResult; } else { // ENEMY BASED TARGET NEED TO ASSURE PLAYER IS ENGAGED if (CheckEngagedStatus() == true) { int GrabbedTargetID = GrabGEOTargetID(); if (GrabbedTargetID != 0) { PL.Target.SetTarget(GrabbedTargetID); if (PL.HasStatus(516)) // IF ECLIPTIC IS UP THEN ACTIVATE THE BOOL { EclipticStillUp = true; } actionResult.Target = "<t>"; actionResult.Spell = SpellCheckedResult; } } } } } return(actionResult); }