private static void UseItem(WoWItem item, SimpleStringDelegate log = null) { if (!CanUseItem(item)) { return; } if (log == null) { log = s => string.Format("/use {0}", item.Name); } Logger.Write(LogColor.Hilite, log(item)); item.Use(); }
private void InitList(ItemsList targetList, string selectedEffect, SimpleStringDelegate command) { targetList.Clear(); IGeometryManager geometryManager = ServiceRegistration.Get <IGeometryManager>(); string standardEffectFile = geometryManager.StandardEffectFile; foreach (KeyValuePair <string, string> nameToEffect in geometryManager.AvailableEffects) { string file = nameToEffect.Key; string effectFile = selectedEffect ?? standardEffectFile; string effectName = nameToEffect.Value; ListItem item = new ListItem(Consts.KEY_NAME, effectName) { Command = new MethodDelegateCommand(() => command(effectName, file)), Selected = file == effectFile, }; targetList.Add(item); } targetList.FireChange(); }
public SeqDbg(double secs, SimpleStringDelegate msg) : base(1, TimeSpan.FromSeconds(secs), RunStatus.Success, new Action(r => { if (SingularSettings.Debug) Logger.WriteDebug(msg(r)); return(RunStatus.Success); })) { }
/// <summary> /// Creates a behavior to cast a spell by name resolved during tree execution (rather than creation), with special requirements, /// on the current target. Returns RunStatus.Success if successful, RunStatus.Failure otherwise. /// </summary> /// <remarks> /// Created 11/25/2012. /// </remarks> /// <param name = "name">The name.</param> /// <param name = "requirements">The requirements.</param> /// <returns>.</returns> public static Composite Cast(SimpleStringDelegate name, SimpleBooleanDelegate requirements) { return Cast(name, onUnit => StyxWoW.Me.CurrentTarget, requirements); }
/// <summary> /// Creates a behavior to cast a spell by name resolved during tree execution (rather than creation) on the current target. /// Returns RunStatus.Success if successful, RunStatus.Failure otherwise. /// </summary> /// <remarks> /// Created 11/25/2012. /// </remarks> /// <param name = "name">The name.</param> /// <returns>.</returns> public static Composite Cast(SimpleStringDelegate name) { return Cast(name, onUnit => StyxWoW.Me.CurrentTarget); }
// always create passing the existing context so it is preserved for delegate usage internal CogContext(object ctx, SpellFindDelegate ssd, SimpleLocationRetriever locrtrv, SimpleStringDelegate descrtrv) { if (ssd(ctx, out sfr)) { spell = sfr.Override ?? sfr.Original; name = spell.Name; context = ctx; loc = WoWPoint.Empty; targetDesc = ""; if (locrtrv != null) { loc = locrtrv(ctx); if (descrtrv != null) { targetDesc = descrtrv(ctx) + " "; } } } }
/// <summary> /// Creates a behavior to cast a spell by name, with special requirements, on a specific unit. Will make sure any spell with /// a non-zero cast time (everything not instant) will stay here until passing the latency boundary (point where .IsCasting == false while cast is in progress.) /// Returns RunStatus.Success if successful, RunStatus.Failure otherwise. Note: will return as soon as spell cast is in progress, unless cancel delegate provided /// </summary> /// <remarks> /// Created 5/2/2011. /// </remarks> /// <param name = "name">The name.</param> /// <param name="checkMovement"></param> /// <param name = "onUnit">The on unit.</param> /// <param name = "requirements">The requirements.</param> /// <param name="cancel">The cancel cast in progress delegate</param> /// <param name="allow">allow next spell to queue before this one completes</param> /// <returns>.</returns> /* public static Composite Cast(SimpleStringDelegate name, SimpleBooleanDelegate checkMovement, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements, SimpleBooleanDelegate cancel = null, LagTolerance allow = LagTolerance.Yes, bool skipWowCheck = false) { return Cast(name, checkMovement, onUnit, requirements, cancel, allow, skipWowCheck, null); } */ /// <summary> /// Creates a behavior to cast a spell by name, with special requirements, on a specific unit. Will make sure any spell with /// a non-zero cast time (everything not instant) will stay here until passing the latency boundary (point where .IsCasting == false while cast is in progress.) /// Returns RunStatus.Success if successful, RunStatus.Failure otherwise. Note: will return as soon as spell cast is in progress, unless cancel delegate provided /// </summary> /// <remarks> /// Created 5/2/2011. /// </remarks> /// <param name = "name">The name.</param> /// <param name="checkMovement"></param> /// <param name = "onUnit">The on unit.</param> /// <param name = "requirements">The requirements.</param> /// <param name="cancel">The cancel cast in progress delegate</param> /// <param name="allow">allow next spell to queue before this one completes</param> /// <param name="allow">check if spell can be cast</param> /// <returns>.</returns> public static Composite Cast(SimpleStringDelegate name, SimpleBooleanDelegate checkMovement, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements, SimpleBooleanDelegate cancel = null, LagTolerance allow = LagTolerance.Yes, bool skipWowCheck = false, CanCastDelegate canCast = null, HasGcd gcd = HasGcd.Yes) { SpellFindDelegate ssd = (object ctx, out SpellFindResults sfr) => { if (name != null) { string spellName = name(ctx); if (spellName != null) { return SpellManager.FindSpell(spellName, out sfr); } else { AddUndefinedSpell(spellName); } } sfr = EmptySFR; return false; }; return Cast(ssd, checkMovement, onUnit, requirements, cancel, allow, skipWowCheck, canCast, gcd); }
public static Composite BuffSelfAndWait(SimpleStringDelegate name, SimpleBooleanDelegate requirements = null, int expirSecs = 0, CanRunDecoratorDelegate until = null, bool measure = false, HasGcd gcd = HasGcd.Yes) { if (requirements == null) requirements = req => true; if (until == null) until = u => StyxWoW.Me.HasAura(name(u)); return new Sequence( BuffSelf(name, requirements, expirSecs, gcd), new PrioritySelector( new DynaWait( time => TimeSpan.FromMilliseconds(Me.Combat ? 500 : 1000), until, new ActionAlwaysSucceed(), measure ), new Action(r => { Logger.WriteDiagnostic("BuffSelfAndWait: buff of [{0}] failed", name(r)); return RunStatus.Failure; }) ) ); }
/// <summary> /// Creates a behavior to cast a spell by name, with special requirements, on a specific unit. Will make sure any spell with /// a non-zero cast time (everything not instant) will stay here until passing the latency boundary (point where .IsCasting == false while cast is in progress.) /// Returns RunStatus.Success if successful, RunStatus.Failure otherwise. Note: will return as soon as spell cast is in progress, unless cancel delegate provided /// </summary> /// <remarks> /// Created 5/2/2011. /// </remarks> /// <param name = "name">The name.</param> /// <param name="checkMovement"></param> /// <param name = "onUnit">The on unit.</param> /// <param name = "requirements">The requirements.</param> /// <param name="cancel">The cancel cast in progress delegate</param> /// <param name="allow">allow next spell to queue before this one completes</param> /// <returns>.</returns> public static Composite Cast(SimpleStringDelegate name, SimpleBooleanDelegate checkMovement, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements, SimpleBooleanDelegate cancel = null, LagTolerance allow = LagTolerance.Yes, bool skipWowCheck = false) { return new Decorator( ret => name != null && checkMovement != null && onUnit != null && requirements != null && name(ret) != null, new Throttle( new PrioritySelector( new Sequence( // save flag indicating if currently in a GCD or IsCasting before queueing our cast new Action(ret => { _castSpell = null; _castOnUnit = onUnit(ret); if (_castOnUnit == null) return RunStatus.Failure; // health/dist change quickly, so grab these now where // .. we check requirements so the log message we output // .. later reflects what they were when we were testing // .. as opposed to what they may have changed to // .. (since spell lookup, move while casting check, and cancast take time) double health = _castOnUnit.HealthPercent; double dist = _castOnUnit.Distance; if (!requirements(ret)) return RunStatus.Failure; // find spell SpellFindResults sfr; if (!SpellManager.FindSpell(name(ret), out sfr)) return RunStatus.Failure; _castSpell = sfr.Override ?? sfr.Original; if (checkMovement(ret) && Me.IsMoving && !AllowMovingWhileCasting(_castSpell)) { if (SingularSettings.Instance.EnableDebugLoggingGCD) Logger.WriteDebug("skipping Spell.Cast({0},[{1}]) because we are moving", _castOnUnit.SafeName(), _castSpell.Name); return RunStatus.Failure; } // check we can cast it on target without checking for movement // if (!Spell.CanCastHack(_spell, _castOnUnit, true, false, allow == LagTolerance.Yes)) if (!CanCastHack(name(ret), _castOnUnit, skipWowCheck)) { if (SingularSettings.Instance.EnableDebugLoggingGCD) Logger.WriteDebug("skipping Spell.Cast({0},[{1}]) because CanCastHack failed", _castOnUnit.SafeName(), _castSpell.Name); return RunStatus.Failure; } // save status of queueing spell (lag tolerance - the prior spell still completing) _IsSpellBeingQueued = allow == LagTolerance.Yes && (Spell.GcdActive || StyxWoW.Me.IsCasting || StyxWoW.Me.IsChanneling); LogCast(_castSpell.Name, _castOnUnit, health, dist); if (!SpellManager.Cast(_castSpell, _castOnUnit)) { Logger.WriteDebug(Color.LightPink, "cast of {0} on {1} failed!", _castSpell.Name, _castOnUnit.SafeName()); return RunStatus.Failure; } SingularRoutine.UpdateDiagnosticCastingState(); return RunStatus.Success; }), #if OLD_WAY_OF_ENSURING // when accountForLag = true, wait for in progress spell (if any) to complete new WaitContinue( TimeSpan.FromMilliseconds(500), ret => SingularRoutine.UpdateDiagnosticCastingState(false) || !_IsSpellBeingQueued || !(Spell.GcdActive || StyxWoW.Me.IsCasting || StyxWoW.Me.IsChanneling), new ActionAlwaysSucceed() ), // new Action(r => Logger.WriteDebug("Spell.Cast(\"{0}\"): waited for queued spell {1}", name(r), _IsSpellBeingQueued )), // failsafe: max time we should be waiting with the prior and latter WaitContinue is latency x 2 // .. if system is borked, could be 1 second but shouldnt notice. // .. instant spells should be very quick since only prior wait applies // now for non-instant spell, wait for .IsCasting to be true new WaitContinue( TimeSpan.FromMilliseconds(300), ret => { SingularRoutine.UpdateDiagnosticCastingState(); SpellFindResults sfr; if (SpellManager.FindSpell(name(ret), out sfr)) { WoWSpell spell = sfr.Override ?? sfr.Original; if (spell.CastTime == 0 && !IsFunnel(spell)) { return true; } } return StyxWoW.Me.IsCasting || StyxWoW.Me.IsChanneling; }, new ActionAlwaysSucceed() ), /// new Action(r => Logger.WriteDebug("Spell.Cast(\"{0}\"): assume we are casting (actual={1}, gcd={2})", name(r), StyxWoW.Me.IsCasting || StyxWoW.Me.IsChanneling, Spell.GlobalCooldown )), #else // for instant spell, wait for GCD to start // for non-instant spell, wait for .IsCasting / .IsChanneling to start new WaitContinue( TimeSpan.FromMilliseconds(350), ret => { if ((_castSpell.CastTime == 0 && Spell.GcdTimeLeft.TotalMilliseconds > 750) || Me.CurrentCastTimeLeft.TotalMilliseconds > 750 || Me.CurrentChannelTimeLeft.TotalMilliseconds > 750) return true; return false; }, new ActionAlwaysSucceed() ), #endif // now check for one of the possible done casting states new PrioritySelector( // for instant or no cancel method given, we are done new Decorator( ret => cancel == null || _castSpell.CastTime == 0, new Action(r => { // Logger.WriteDebug("Spell.Cast(\"{0}\"): no cancel delegate", _castSpell.Name); return RunStatus.Success; }) ), // while casting/channeling call the cancel method to see if we should abort new Wait(12, ret => { SingularRoutine.UpdateDiagnosticCastingState(); // Interrupted or finished casting. if (!Spell.IsCastingOrChannelling(allow)) { Logger.WriteDebug("Spell.Cast(\"{0}\"): cast has ended", _castSpell.Name); return true; } // check cancel delegate if we are finished if (cancel(ret)) { SpellManager.StopCasting(); Logger.Write(System.Drawing.Color.Orange, "/cancel {0} on {1} @ {2:F1}%", _castSpell.Name, _castOnUnit.SafeName(), _castOnUnit.HealthPercent); return true; } // continue casting/channeling at this point return false; }, new ActionAlwaysSucceed() ), // if we are here, we timed out after 12 seconds (very odd) new Action(r => { Logger.WriteDebug("Spell.Cast(\"{0}\"): timed out waiting", _castSpell.Name); return RunStatus.Success; }) ), // made it this far the we are RunStatus.Success, so reset wowunit reference and return new Action(ret => { _castOnUnit = null; _castSpell = null; return RunStatus.Success; }) ), // cast Sequence failed, so only thing left is to reset cached references and report failure new Action(ret => { _castOnUnit = null; _castSpell = null; return RunStatus.Failure; }) ) ) ); }
public static Composite Buff(SimpleStringDelegate name, bool myBuff, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements, int expirSecs, params string[] buffNames) { return new Decorator( ret => { if (onUnit == null || name == null || requirements == null) return false; _buffUnit = onUnit(ret); if (_buffUnit == null) return false; _buffName = name(ret); if (_buffName == null) return false; if (DoubleCastPreventionDict.Contains(_buffUnit, _buffName)) return false; bool hasExpired; if (!buffNames.Any()) { hasExpired = _buffUnit.HasAuraExpired(_buffName, expirSecs, myBuff); if (hasExpired && SingularSettings.Debug) Logger.WriteDebug("Spell.Buff(r=>'{0}'): hasspell={1}, auraleft={2:F1} secs", _buffName, SpellManager.HasSpell(_buffName).ToYN(), _buffUnit.GetAuraTimeLeft(_buffName, true).TotalSeconds); return hasExpired; } hasExpired = SpellManager.HasSpell(_buffName) && buffNames.All(b => _buffUnit.HasKnownAuraExpired(b, expirSecs, myBuff)); if (hasExpired && SingularSettings.Debug) Logger.WriteDebug("Spell.Buff(r=>'{0}'): hasspell={1}, all auras less than {2:F1} secs", _buffName, SpellManager.HasSpell(_buffName).ToYN(), expirSecs ); return hasExpired; }, new Sequence( // new Action(ctx => _lastBuffCast = name), Cast(name, chkMov => true, onUnit, requirements, cancel => false /* causes cast to complete */ ), new Action(ret => UpdateDoubleCastDict(name(ret), onUnit(ret))) ) ); }
public static Composite Buff(SimpleStringDelegate name, bool myBuff, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements, params string[] buffNames) { return new Decorator( ret => { if (onUnit == null || name == null || requirements == null) return false; _buffUnit = onUnit(ret); if (_buffUnit == null) return false; _buffName = name(ret); if (_buffName == null) return false; if (DoubleCastPreventionDict.Contains(_buffUnit, _buffName)) return false; if (!buffNames.Any()) return !(myBuff ? _buffUnit.HasMyAura(_buffName) : _buffUnit.HasAura(_buffName)); bool buffFound; try { if (myBuff) buffFound = buffNames.Any(b => _buffUnit.HasMyAura(b)); else buffFound = buffNames.Any(b => _buffUnit.HasAura(b)); } catch { // mark as found buff, so we return false buffFound = true; } return !buffFound; }, new Sequence( // new Action(ctx => _lastBuffCast = name), Cast( sp => _buffName, chkMov => true, on => _buffUnit, requirements, cancel => false /* causes cast to complete */ ), new Action(ret => UpdateDoubleCastDict(_buffName, _buffUnit)) ) ); }
public PriDiag(double secs, SimpleStringDelegate msg) : base(1, TimeSpan.FromSeconds(secs), RunStatus.Failure, new Action(r => { Logger.WriteDiagnostic(msg(r)); return(RunStatus.Failure); })) { }
public PriDbg(double secs, Color clr, SimpleStringDelegate msg) : base(1, TimeSpan.FromSeconds(secs), RunStatus.Failure, new Action(r => { if (SingularSettings.Debug) Logger.WriteDebug(clr, msg(r)); return(RunStatus.Failure); })) { }
public PriLog(double secs, Color clr, SimpleStringDelegate msg) : base(1, TimeSpan.FromSeconds(secs), RunStatus.Failure, new Action(r => { Logger.Write(clr, msg(r)); return(RunStatus.Failure); })) { }
public static Composite BuffSelf(SimpleStringDelegate name, SimpleBooleanDelegate requirements) { return Buff(name, false, on => Me, requirements); }
public static Composite BuffSelf(SimpleStringDelegate name, SimpleBooleanDelegate requirements, int expirSecs, HasGcd gcd = HasGcd.Yes) { return Buff(name, expirSecs, on => Me, require: requirements, gcd:gcd); }
/// <summary> /// Creates a behavior to cast a spell by name, on the ground at the specified location. Returns RunStatus.Success if successful, RunStatus.Failure otherwise. /// </summary> /// <remarks> /// Created 5/2/2011. /// </remarks> /// <param name = "spell">The spell.</param> /// <param name = "onLocation">The on location.</param> /// <param name = "requirements">The requirements.</param> /// <param name="waitForSpell">Waits for spell to become active on cursor if true. </param> /// <returns>.</returns> public static Composite CastOnGround(string spell, LocationRetriever onLocation, SimpleBooleanDelegate requirements, bool waitForSpell = true, SimpleStringDelegate targetDesc = null) { return new Decorator( ret => requirements(ret) && onLocation != null && Spell.CanCastHack(spell, null, skipWowCheck:true) && LocationInRange(spell, onLocation(ret)) && GameWorld.IsInLineOfSpellSight(StyxWoW.Me.GetTraceLinePos(), onLocation(ret)), new Sequence( new Action(ret => Logger.Write("Casting {0} {1}at location {2} at {3:F1} yds", spell, targetDesc == null ? "" : "on " + targetDesc(ret) + " ", onLocation(ret), onLocation(ret).Distance(StyxWoW.Me.Location))), new Action(ret => { return SpellManager.Cast(spell) ? RunStatus.Success : RunStatus.Failure; } ), new DecoratorContinue( ctx => waitForSpell, new PrioritySelector( new WaitContinue(1, ret => GetPendingCursorSpell != null && GetPendingCursorSpell.Name == spell, new ActionAlwaysSucceed() ), new Action(r => { Logger.WriteDebug("error: spell {0} not seen as pending on cursor after 1 second", spell); return RunStatus.Failure; }) ) ), new Action(ret => SpellManager.ClickRemoteLocation(onLocation(ret))), // check for we are done status new PrioritySelector( // done if cursor doesn't have spell anymore new Decorator( ret => !waitForSpell, new Action(r => Lua.DoString("SpellStopTargeting()")) //just in case ), new Wait(TimeSpan.FromMilliseconds(750), ret => Spell.GetPendingCursorSpell == null || Me.IsCasting || Me.IsChanneling, new ActionAlwaysSucceed() ), // otherwise cancel new Action(ret => { Logger.WriteDebug("/cancel {0} - click {1} failed -OR- Pending Cursor Spell API broken -- distance={2:F1} yds, loss={3}, face={4}", spell, onLocation(ret), StyxWoW.Me.Location.Distance(onLocation(ret)), GameWorld.IsInLineOfSpellSight(StyxWoW.Me.GetTraceLinePos(), onLocation(ret)), StyxWoW.Me.IsSafelyFacing(onLocation(ret)) ); // Pending Spell Cursor API is broken... seems like we can't really check at this point, so assume it failed and worked... uggghhh Lua.DoString("SpellStopTargeting()"); return RunStatus.Failure; }) ) ) ); }
public static Composite BuffSelfAndWaitPassive(SimpleStringDelegate name, SimpleBooleanDelegate requirements = null, int expirSecs = 0, CanRunDecoratorDelegate until = null, HasGcd gcd = HasGcd.Yes) { if (requirements == null) requirements = req => true; if (until == null) until = u => StyxWoW.Me.HasAura(u as string); return new PrioritySelector( ctx => { string spellName = name(ctx); SpellFindResults sfr; if (SpellManager.FindSpell(spellName, out sfr)) { spellName = (sfr.Override ?? sfr.Original).Name; } return spellName; }, new Decorator( req => SpellManager.HasSpell( req as string) && !Me.HasAura(req as string) && !DoubleCastContains(Me, req as string), new Sequence( Spell.Cast( sp => sp as string, mov => true, on => Me, requirements, cancel => false, LagTolerance.Yes, false, null, gcd: gcd), new PrioritySelector( new DynaWait( time => TimeSpan.FromMilliseconds(Me.Combat ? 500 : 1000), until, new Action( r => UpdateDoubleCast( r as string, Me, 3000 )) ), new Action(r => { Logger.WriteDiagnostic("BuffSelfAndWaitPassive: buff of [{0}] failed", name(r)); return RunStatus.Failure; }) ) ) ) ); }
public TMsg(SimpleStringDelegate str) : base(ret => ShowTraceMessages, new Action(r => { Logger.WriteDebug(str(r)); return(RunStatus.Failure); })) { }
/// <summary> /// Creates a behavior to cast a spell by name, on the ground at the specified location. Returns RunStatus.Success if successful, RunStatus.Failure otherwise. /// </summary> /// <remarks> /// Created 5/2/2011. /// </remarks> /// <param name = "spell">The spell.</param> /// <param name = "onLocation">The on location.</param> /// <param name = "requirements">The requirements.</param> /// <param name="waitForSpell">Waits for spell to become active on cursor if true. </param> /// <returns>.</returns> public static Composite CastOnGround(string spellName, SimpleLocationRetriever onLocRtrv, SimpleBooleanDelegate requirements, bool waitForSpell = true, SimpleStringDelegate tgtDescRtrv = null) { if (spellName == null || onLocRtrv == null || requirements == null) return new ActionAlwaysFail(); SpellFindDelegate ssd = (object ctx, out SpellFindResults sfr) => { if (!SpellManager.FindSpell(spellName, out sfr)) { AddUndefinedSpell(spellName); return false; } return true; }; return new Decorator( req => requirements(req), new PrioritySelector( ctx => new CogContext( ctx, ssd, onLocRtrv, tgtDescRtrv), ContextCastOnGround(null, waitForSpell) ) ); }
private void InitList(ItemsList targetList, string selectedEffect, SimpleStringDelegate command) { targetList.Clear(); IGeometryManager geometryManager = ServiceRegistration.Get<IGeometryManager>(); string standardEffectFile = geometryManager.StandardEffectFile; foreach (KeyValuePair<string, string> nameToEffect in geometryManager.AvailableEffects) { string file = nameToEffect.Key; string effectFile = selectedEffect ?? standardEffectFile; string effectName = nameToEffect.Value; ListItem item = new ListItem(Consts.KEY_NAME, effectName) { Command = new MethodDelegateCommand(() => command(effectName, file)), Selected = file == effectFile, }; targetList.Add(item); } targetList.FireChange(); }
internal CogContext(CastContext cc, SimpleStringDelegate descrtrv) { if (cc.unit != null) { loc = cc.unit.Location; spell = cc.spell; context = cc.context; name = cc.name; sfr = cc.sfr; spell = cc.spell; if (descrtrv != null) { targetDesc = descrtrv(context) + " "; } } }
public static Composite Buff(SimpleStringDelegate name, bool myBuff, UnitSelectionDelegate onUnit, SimpleBooleanDelegate require, params string[] buffNames) { System.Diagnostics.Debug.Assert(name != null); System.Diagnostics.Debug.Assert(onUnit != null); System.Diagnostics.Debug.Assert(require != null); return new Decorator( ret => { _buffUnit = onUnit(ret); if (_buffUnit == null) return false; _buffName = name(ret); if (_buffName == null) return false; SpellFindResults sfr; if (!SpellManager.FindSpell(_buffName, out sfr)) return false; if (sfr.Override != null) _buffName = sfr.Override.Name; if (DoubleCastContains(_buffUnit, _buffName)) return false; if (!buffNames.Any()) return !(myBuff ? _buffUnit.HasMyAura(_buffName) : _buffUnit.HasAura(_buffName)); bool buffFound; try { if (myBuff) buffFound = buffNames.Any(b => _buffUnit.HasMyAura(b)); else buffFound = buffNames.Any(b => _buffUnit.HasAura(b)); } catch { // mark as found buff, so we return false buffFound = true; } return !buffFound; }, new Sequence( // new Action(ctx => _lastBuffCast = name), Cast(sp => _buffName, chkMov => true, on => _buffUnit, require, cancel => false /* causes cast to complete */ ), new Action(ret => UpdateDoubleCast(_buffName, _buffUnit)) ) ); }
/// <summary> /// Creates a behavior to cast a spell by name resolved during tree execution (rather than creation) on a specific unit. /// Returns RunStatus.Success if successful, RunStatus.Failure otherwise. /// </summary> /// <remarks> /// Created 11/25/2012. /// </remarks> /// <param name = "name">The name.</param> /// <param name = "onUnit">The on unit.</param> /// <returns>.</returns> public static Composite Cast(SimpleStringDelegate name, UnitSelectionDelegate onUnit) { return Cast(name, onUnit, req => true); }
public static Composite Buff(SimpleStringDelegate name, int expirSecs, UnitSelectionDelegate onUnit = null, SimpleBooleanDelegate require = null, bool myBuff = true, HasGcd gcd = HasGcd.Yes, params string[] buffNames) { return Buff(name, TimeSpan.FromSeconds(expirSecs), onUnit, require, myBuff, gcd, buffNames); }
/// <summary> /// Creates a behavior to cast a spell by name resolved during tree execution (rather than creation), with special requirements, /// on a specific unit. Returns RunStatus.Success if successful, RunStatus.Failure otherwise. /// </summary> /// <remarks> /// Created 11/25/2012. /// </remarks> /// <param name = "name">The name.</param> /// <param name = "onUnit">The on unit.</param> /// <param name = "requirements">The requirements.</param> /// <returns>.</returns> public static Composite Cast(SimpleStringDelegate name, UnitSelectionDelegate onUnit, SimpleBooleanDelegate requirements) { return Cast(name, ret => true, onUnit, requirements); }
public static Composite Buff(SimpleStringDelegate name, TimeSpan expires, UnitSelectionDelegate onUnit = null, SimpleBooleanDelegate require = null, bool myBuff = true, HasGcd gcd = HasGcd.Yes, params string[] buffNames) { if (onUnit == null) onUnit = u => Me.CurrentTarget; if (require == null) require = req => true; return new Decorator( ret => { if (onUnit == null || name == null || require == null) return false; _buffUnit = onUnit(ret); if (_buffUnit == null) return false; _buffName = name(ret); if (_buffName == null) return false; SpellFindResults sfr; if (!SpellManager.FindSpell(_buffName, out sfr)) { AddUndefinedSpell(_buffName); return false; } WoWSpell spell = sfr.Override ?? sfr.Original; _buffName = spell.Name; if (DoubleCastContains(_buffUnit, _buffName)) return false; if (!spell.CanCast && (sfr.Override == null || !sfr.Original.CanCast)) { if (SingularSettings.DebugSpellCasting) Logger.WriteFile("BuffCanCast[{0}]: spell specific CanCast failed (#{1})", spell.Name, spell.Id); return false; } bool hasExpired; if (!buffNames.Any()) { hasExpired = _buffUnit.HasAuraExpired(_buffName, expires, myBuff); if (SingularSettings.DebugSpellCasting) { if (hasExpired ) Logger.WriteDebug("Buff=expired: '{0}')={1}: hasspell={2}, auraleft={3:F1} secs", _buffName, hasExpired, SpellManager.HasSpell(_buffName).ToYN(), _buffUnit.GetAuraTimeLeft(_buffName, true).TotalSeconds); else Logger.WriteDebug("Buff=present: '{0}')={1}: hasspell={2}, auraleft={3:F1} secs", _buffName, hasExpired, SpellManager.HasSpell(_buffName).ToYN(), _buffUnit.GetAuraTimeLeft(_buffName, true).TotalSeconds); } return hasExpired; } hasExpired = SpellManager.HasSpell(_buffName) && buffNames.All(b => _buffUnit.HasKnownAuraExpired(b, expires, myBuff)); if (hasExpired && SingularSettings.DebugSpellCasting) Logger.WriteDebug("Spell.Buff(r=>'{0}')={1}: hasspell={2}, all auras less than {3:F1} secs", _buffName, hasExpired, SpellManager.HasSpell(_buffName).ToYN(), expires.TotalSeconds); return hasExpired; }, new Sequence( // new Action(ctx => _lastBuffCast = name), Cast(sp => _buffName, chkMov => true, onUnit, require, cancel => false /* causes cast to complete */, gcd: gcd ), new Action(ret => UpdateDoubleCast( _buffName, _buffUnit)) ) ); }
public TMsg(SimpleStringDelegate str) : base(ret => ShowTraceMessages, new Action(r => { Logger.WriteDebug(str(r)); return RunStatus.Failure; })) { }
public SeqLog(double secs, SimpleStringDelegate msg) : base(1, TimeSpan.FromSeconds(secs), RunStatus.Success, new Action(r => { Logger.Write(msg(r)); return(RunStatus.Success); })) { }