private static void HandlePartyMemberDisable(object sender, LuaEventArgs args) { // Since we hooked this in ctor, make sure we are the selected CC if (RoutineManager.Current.Name != SingularRoutine.Instance.Name) { return; } WoWPartyMember pm = Unit.GroupMemberInfos.FirstOrDefault(g => g.ToPlayer() != null && string.Equals(g.ToPlayer().Name, args.Args[0].ToString(), StringComparison.InvariantCulture)); string name = "(null)"; string status = "(unknown)"; if (pm == null) { Logger.WriteDiagnostic("Group Member: {0} disabled but could not be found", args.Args[0].ToString()); } else { WoWUnit o = ObjectManager.GetObjectByGuid <WoWUnit>(pm.Guid); name = o.Name; if (!o.IsAlive) { status = "Died!"; } else if (!pm.IsOnline) { status = "went Offline"; } Logger.WriteDiagnostic("Group Member {0}: {1} {2}", pm.RaidRank, name, status); } }
public static WoWPartyMember.GroupRole GetGroupRoleAssigned(WoWPartyMember pm) { WoWPartyMember.GroupRole role = WoWPartyMember.GroupRole.None; if (pm != null) { role = (WoWPartyMember.GroupRole)((int)pm.Role & ROLEMASK); } return(role); }
public static WoWPartyMember.GroupRole GetGroupRoleAssigned(WoWPartyMember pm) { WoWPartyMember.GroupRole role = WoWPartyMember.GroupRole.None; if (pm != null && IsInGroup) { const int ROLEMASK = (int)WoWPartyMember.GroupRole.None | (int)WoWPartyMember.GroupRole.Tank | (int)WoWPartyMember.GroupRole.Healer | (int)WoWPartyMember.GroupRole.Damage; role = (WoWPartyMember.GroupRole)((int)pm.Role & ROLEMASK); } return(role); }
public static WoWPartyMember.GroupRole GetGroupRoleAssigned(WoWPlayer p) { WoWPartyMember.GroupRole role = WoWPartyMember.GroupRole.None; if (p != null && IsInGroup) { // GroupMemberInfos.FirstOrDefault(t => t.Guid == p.Guid); WoWPartyMember pm = new WoWPartyMember(p.Guid, true); if (pm != null) { role = GetGroupRoleAssigned(pm); } } return(role); }
public static string Safe_UnitName(WoWPartyMember pm) { if (pm == null) { return("(null)"); } WoWPlayer p = pm.ToPlayer(); if (p != null) { return(Safe_UnitName(p)); } return(GetGroupRoleAssigned(pm).ToString() + " (max health:" + pm.HealthMax + ")"); }
public static WoWPartyMember.GroupRole GetGroupRoleAssigned(WoWPlayer p) { WoWPartyMember.GroupRole role = WoWPartyMember.GroupRole.None; if (p != null && IsInGroup) { if (p.IsMe) { role = (WoWPartyMember.GroupRole)((int)Me.Role & ROLEMASK); } else { WoWPartyMember pm = GroupMemberInfos.FirstOrDefault(t => t.Guid == p.Guid); if (pm != null) { role = GetGroupRoleAssigned(pm); } } } return(role); }
public static string Role(this WoWPlayer p) { string fnname = "FTWExtensionMethods.Role"; MyTimer.Start(fnname); IEnumerable <WoWPartyMember> wpms = StyxWoW.Me.GroupInfo.RaidMembers.Union(StyxWoW.Me.GroupInfo.PartyMembers).Distinct(); WoWPartyMember wpm = (from member in wpms let x = member.ToPlayer() where x != null && p.Guid == x.Guid select member).FirstOrDefault(); MyTimer.Stop(fnname); if (wpm == null) { return(""); } else { return(wpm.Role.ToString()); } }
public static WoWPartyMember.GroupRole GetGroupRoleAssigned(WoWPlayer p) { WoWPartyMember.GroupRole role = WoWPartyMember.GroupRole.None; if (p != null && IsInGroup) { // GroupMemberInfos.FirstOrDefault(t => t.Guid == p.Guid); WoWPartyMember pm = new WoWPartyMember( p.Guid, true ); if (pm != null) role = GetGroupRoleAssigned(pm); } return role; }
public static WoWPartyMember.GroupRole GetGroupRoleAssigned(WoWPartyMember pm) { WoWPartyMember.GroupRole role = WoWPartyMember.GroupRole.None; if (pm != null && IsInGroup ) { const int ROLEMASK = (int)WoWPartyMember.GroupRole.None | (int)WoWPartyMember.GroupRole.Tank | (int)WoWPartyMember.GroupRole.Healer | (int)WoWPartyMember.GroupRole.Damage; role = (WoWPartyMember.GroupRole)((int)pm.Role & ROLEMASK ); } return role; }
private static void HandleCombatLog(object sender, LuaEventArgs args) { // Since we hooked this in ctor, make sure we are the selected CC if (RoutineManager.Current.Name != SingularRoutine.Instance.Name) { return; } // convert args to usable form var e = new CombatLogEventArgs(args.EventName, args.FireTimeStamp, args.Args); bool itWasDamage = false; if (TrackDamage || SingularRoutine.CurrentWoWContext == WoWContext.Normal) { if (e.DestGuid == StyxWoW.Me.Guid && e.SourceGuid != StyxWoW.Me.Guid) { long damageAmount = 0; switch (e.EventName) { case "SWING_DAMAGE": itWasDamage = true; damageAmount = (long)e.Args[11]; Logger.WriteDebug("HandleCombatLog(Damage): {0} = {1}", e.EventName, damageAmount); break; case "SPELL_DAMAGE": case "SPELL_PERIODIC_DAMAGE": case "RANGE_DAMAGE": itWasDamage = true; damageAmount = (long)e.Args[14]; break; } if (TrackDamage) { if (itWasDamage) { Logger.WriteDebug("HandleCombatLog(Damage): {0} = {1}", e.EventName, damageAmount); } else { LogUndesirableEvent("On Character", e); } if (damageAmount > 0) { DamageHistory.Enqueue(new Damage(DateTime.UtcNow, damageAmount)); } } if (itWasDamage && SingularRoutine.CurrentWoWContext == WoWContext.Normal) { WoWUnit enemy = e.SourceUnit; if (Unit.ValidUnit(enemy) && enemy.IsPlayer) { Logger.WriteDiagnostic("GankDetect: received {0} src={1} dst={2}", args.EventName, e.SourceGuid, e.DestGuid); // if (guidLastEnemy != enemy.Guid || (TimeLastAttackedByEnemyPlayer - DateTime.UtcNow).TotalSeconds > 30) { guidLastEnemy = enemy.Guid; string extra = ""; if (e.Args.GetUpperBound(0) >= 12) { extra = string.Format(" using {0}", e.SpellName); } AttackedWithSpellSchool = WoWSpellSchool.None; if (e.Args.GetUpperBound(0) >= 12) { AttackedWithSpellSchool = e.SpellSchool; } Logger.WriteDiagnostic("GankDetect: attacked by Level {0} {1}{2}", enemy.Level, enemy.SafeName(), extra); if (SingularSettings.Instance.TargetWorldPvpRegardless && (BotPoi.Current == null || BotPoi.Current.Guid != enemy.Guid)) { Logger.Write(LogColor.Hilite, "GankDetect: setting {0} as BotPoi Kill Target", enemy.SafeName()); BotPoi.Current = new BotPoi(enemy, PoiType.Kill); } } AttackingEnemyPlayer = enemy; TimeLastAttackedByEnemyPlayer = DateTime.UtcNow; } } } } // Logger.WriteDebug("[CombatLog] " + e.Event + " - " + e.SourceName + " - " + e.SpellName); switch (e.Event) { default: LogUndesirableEvent("From Character", e); break; // spell_cast_failed only passes filter in Singular debug mode case "SPELL_CAST_FAILED": Logger.WriteDiagnostic("[CombatLog] {0} {1}#{2} failure: '{3}'", e.Event, e.Spell.Name, e.SpellId, e.Args[14]); if (e.Args[14].ToString() == LocalizedLineOfSightFailure) { WoWGuid guid = WoWGuid.Empty; try { LastLineOfSightTarget = e.DestUnit; guid = LastLineOfSightTarget == null ? WoWGuid.Empty : LastLineOfSightTarget.Guid; } catch { } if (!guid.IsValid) { Logger.WriteFile("[CombatLog] no valid destunit so using CurrentTarget"); LastLineOfSightTarget = StyxWoW.Me.CurrentTarget; guid = StyxWoW.Me.CurrentTargetGuid; } LastLineOfSightFailure = DateTime.UtcNow; Logger.WriteFile("[CombatLog] cast failed due to los reported at {0} on target {1:X}", LastLineOfSightFailure.ToString("HH:mm:ss.fff"), e.DestGuid); } else if (e.Args[14].ToString() == LocalizedUnitNotInfrontFailure) { WoWGuid guid = e.DestGuid; LastUnitNotInfrontFailure = DateTime.UtcNow; if (guid.IsValid && guid != WoWGuid.Empty) { LastUnitNotInfrontGuid = guid; Logger.WriteFile("[CombatLog] not facing SpellTarget [{0}] at {1}", LastUnitNotInfrontGuid, LastUnitNotInfrontFailure.ToString("HH:mm:ss.fff")); } else { LastUnitNotInfrontGuid = Spell.LastSpellTarget; Logger.WriteFile("[CombatLog] not facing LastTarget [{0}] at {1}", LastUnitNotInfrontGuid, LastUnitNotInfrontFailure.ToString("HH:mm:ss.fff"), guid); } } else if (!MovementManager.IsMovementDisabled && StyxWoW.Me.Class == WoWClass.Warrior && e.Args[14].ToString() == LocalizedNoPathAvailableFailure) { LastNoPathFailure = DateTime.UtcNow; LastNoPathGuid = StyxWoW.Me.CurrentTargetGuid; if (!StyxWoW.Me.GotTarget()) { Logger.WriteFile("[CombatLog] cast failed - no path available to current target"); } else { Logger.WriteFile("[CombatLog] cast failed - no path available to {0}, heightOffGround={1}, pos={2}", StyxWoW.Me.CurrentTarget.SafeName(), StyxWoW.Me.CurrentTarget.HeightOffTheGround(), StyxWoW.Me.CurrentTarget.Location ); } } else if (!SingularRoutine.IsManualMovementBotActive && (StyxWoW.Me.Class == WoWClass.Druid || StyxWoW.Me.Class == WoWClass.Shaman)) { if (LocalizedShapeshiftMessages.ContainsKey(e.Args[14].ToString())) { string symbolicName = LocalizedShapeshiftMessages[e.Args[14].ToString()]; SuppressShapeshiftUntil = DateTime.UtcNow.Add(TimeSpan.FromSeconds(30)); Logger.Write(LogColor.Cancel, "/cancel{0} - due to Shapeshift Error '{1}' on cast, suppress form for {2:F1} seconds", StyxWoW.Me.Shapeshift.ToString().CamelToSpaced(), symbolicName, (SuppressShapeshiftUntil - DateTime.UtcNow).TotalSeconds); Lua.DoString("CancelShapeshiftForm()"); } } else if (StyxWoW.Me.Class == WoWClass.Rogue && SingularSettings.Instance.Rogue().UsePickPocket) { if (e.Args[14].ToString() == LocalizedNoPocketsToPickFailure) { HandleRogueNoPocketsError(); } } break; case "SPELL_AURA_APPLIED": case "SPELL_CAST_SUCCESS": if (e.SourceGuid != StyxWoW.Me.Guid) { return; } // Update the last spell we cast. So certain classes can 'switch' their logic around. Spell.LastSpellCast = e.SpellName; Logger.WriteDebug("Storing {0} as last spell cast.", Spell.LastSpellCast); // following commented block should not be needed since rewrite of Pet summon // //// Force a wait for all summoned minions. This prevents double-casting it. //if (StyxWoW.Me.Class == WoWClass.Warlock && e.SpellName.StartsWith("Summon ")) //{ // StyxWoW.SleepForLagDuration(); //} break; case "SWING_MISSED": if (e.Args[11].ToString() == "EVADE") { HandleEvadeBuggedMob(args, e); } else if (e.Args[11].ToString() == "IMMUNE") { WoWUnit unit = e.DestUnit; if (unit != null && !unit.IsPlayer) { Logger.WriteDebug("{0} is immune to Physical spell school", unit.Name); SpellImmunityManager.Add(unit.Entry, WoWSpellSchool.Physical, e.Spell); } } break; case "SPELL_MISSED": case "RANGE_MISSED": // Why log misses? Because users of classes with DoTs testing on training dummies // .. that they don't have enough +Hit for will get DoT spam. This allows easy // .. diagnosis of false reports of rotation issues where a user simply isn't geared // .. this happens more at the beginning of an expansion especially if (SingularSettings.Debug) { Logger.WriteDebug( "[CombatLog] {0} {1}#{2} {3}", e.Event, e.Spell.Name, e.SpellId, e.Args[14] ); } if (e.Args[14].ToString() == "EVADE") { HandleEvadeBuggedMob(args, e); } else if (e.Args[14].ToString() == "IMMUNE") { WoWUnit unit = e.DestUnit; if (unit != null && !unit.IsPlayer) { Logger.WriteDebug("{0} is immune to {1} spell school", unit.Name, e.SpellSchool); SpellImmunityManager.Add(unit.Entry, e.SpellSchool, e.Spell); } if (StyxWoW.Me.Class == WoWClass.Rogue && e.SpellId == 6770) { WoWUnit unitImmune = unit; if (unitImmune == null) { unitImmune = ObjectManager.GetObjectByGuid <WoWUnit>(Singular.ClassSpecific.Rogue.Common.lastSapTarget); } Singular.ClassSpecific.Rogue.Common.AddEntryToSapImmuneList(unitImmune); } } break; case "UNIT_DIED": if (StyxWoW.Me.CurrentTarget != null && e.DestGuid == StyxWoW.Me.CurrentTarget.Guid) { Spell.LastSpellCast = ""; } try { WoWUnit corpse = e.SourceUnit; WoWPartyMember pm = Unit.GroupMemberInfos.First(m => m.Guid == corpse.Guid); Logger.WriteDiagnostic("Combat Log: UNIT_DIED - Role={0} {1}", pm.Role & (~WoWPartyMember.GroupRole.Leader), corpse.SafeName()); } catch { } break; } }
private static Composite CreateFollowBehavior() { return(new PrioritySelector( new Decorator(ret => !LazyRaiderSettings.Instance.FollowTank, new ActionAlwaysSucceed()), new Decorator(ret => !IsInGroup, new ActionAlwaysSucceed()), new Decorator(ret => RaFHelper.Leader == null, new ActionAlwaysSucceed()), new Decorator(ret => Me.CurrentHealth <= 1, // if dead or ghost new ActionAlwaysSucceed()), new Decorator(ret => RaFHelper.Leader.CurrentHealth <= 1, // if dead or ghost new ActionAlwaysSucceed()), new Decorator(ret => NeedToMount(), new Action(delegate { WaitForMount(); })), new Decorator(ret => NeedToDismount(), new Action(delegate { WaitForDismount(); })), new Decorator(ret => !RaFHelper.Leader.InLineOfSightOCD || RaFHelper.Leader.Distance > LazyRaiderSettings.Instance.FollowDistance, new Action(delegate { botMovement = true; WoWPoint pt = RaFHelper.Leader.Location; WoWPartyMember tankInfo = GroupMemberInfos.FirstOrDefault(t => t.Guid == RaFHelper.Leader.Guid); if (tankInfo != null && Me.Location.Distance(tankInfo.Location3D) > 100) { pt = tankInfo.Location3D; } Navigator.MoveTo(RaFHelper.Leader.Location); return RunStatus.Success; })), new Decorator(ret => Me.IsMoving && botMovement, new Action(delegate { botMovement = false; while (IsGameStable() && Me.IsMoving) { WoWMovement.MoveStop(); if (Me.IsMoving) { System.Threading.Thread.Sleep(25); } } return RunStatus.Success; })) )); }
public static WoWPartyMember.GroupRole GetGroupRoleAssigned(WoWPartyMember pm) { WoWPartyMember.GroupRole role = WoWPartyMember.GroupRole.None; if (pm != null) { role = (WoWPartyMember.GroupRole)((int)pm.Role & ROLEMASK); } return role; }
public static string Safe_UnitName(WoWPartyMember pm) { if (pm == null) return "(null)"; WoWPlayer p = pm.ToPlayer(); if (p != null) return Safe_UnitName(p); return GetGroupRoleAssigned(pm).ToString() + " (max health:" + pm.HealthMax + ")"; }
private static bool SyncTankWithRaFLeader() { try { // check if Tank we saved is now in range if (Tank.Current != null && Tank.Current.ToPlayer() != null) { Dlog("SyncTankWithRaFLeader: Tank now in range, so setting RaFHelper"); Tank.SetAsLeader(); return(false); } // otherwise, tank out of range pointer for WoWPlayer so clear if (RaFHelper.Leader != null) { Dlog("SyncTankWithRaFLeader: Tank doesn't match RaFHelper so clearing"); RaFHelper.ClearLeader(); } // user wants to control choosing new when we lost tank if (!LazyRaiderSettings.Instance.AutoTankSelect) { if (haveFoundTankAtGroupForming) { return(false); } } // have Tank, so keep it until user changes if (Tank.Current != null && Tank.Current.IsOnline) { return(false); } WoWPartyMember tank = (from pm in GroupMemberInfos where GetGroupRoleAssigned(pm) == WoWPartyMember.GroupRole.Tank && pm.Guid != Me.Guid && pm.IsOnline && pm.ToPlayer() != null orderby pm.Location3D.Distance(Me.Location) ascending select pm).FirstOrDefault(); if (tank != null) { haveFoundTankAtGroupForming = true; Tank.Current = tank; Log("Tank set to {0} based upon role", LazyRaider.Safe_UnitName(Tank.Current)); TreeRoot.StatusText = String.Format("[lr] tank is {0}", Safe_UnitName(tank)); return(true); } #if DONT_SET_BY_MAX_HEALTH_FOR_NOW tank = (from pm in GroupMemberInfos where pm.Guid != Me.Guid && pm.IsOnline && pm.ToPlayer() != null orderby pm.HealthMax descending select pm).FirstOrDefault(); if (tank != null) { Log("Tank set to {0} based upon Max Health", tank.ToPlayer().Class); Tank.Current = tank; TreeRoot.StatusText = String.Format("[lr] tank is {0}", Safe_UnitName(tank)); return(true); } #endif return(false); } catch { return(true); } }