public bool StartCastAtPos(Unit instigator, ushort abilityID, Point3D worldPos, ushort zoneId, byte castSequence) { if (PreventCasting) { if (_Owner is Player) { Player owner = _Owner as Player; owner?.SendClientMessage("A developer has disabled all abilities.", ChatLogFilters.CHATLOGFILTERS_USER_ERROR); } return(false); } // Allow only interruption of channeled skills of a different ID to the skill being used if (IsCasting() && (!_abilityProcessor.IsChannelling || _abilityProcessor.AbInfo.Entry == abilityID)) { return(false); } AbilityInfo abInfo = AbilityMgr.GetAbilityInfo(abilityID); if (abInfo == null || (abInfo.ConstantInfo.Origin != AbilityOrigin.AO_ITEM && !IsValidAbility(abInfo))) { return(false); } try { if (AbilityMgr.HasCommandsFor(abilityID) || abInfo.ConstantInfo.ChannelID != 0) { if (_abilityProcessor == null) { _abilityProcessor = new AbilityProcessor(_unitOwner, this); } abInfo.Instigator = instigator; if (!_abilityProcessor.HasInfo()) { _abilityProcessor.StartAbilityAtPos(abInfo, castSequence, worldPos, zoneId); } return(true); } if (_Owner is Player) { var owner = _Owner as Player; owner?.SendClientMessage(abilityID + " " + AbilityMgr.GetAbilityNameFor(abilityID) + " has no implementation.", ChatLogFilters.CHATLOGFILTERS_USER_ERROR); } return(false); } catch (Exception e) { if (_Owner is Player) { var owner = _Owner as Player; owner?.SendClientMessage(abilityID + " " + AbilityMgr.GetAbilityNameFor(abilityID) + " threw an unhandled " + e.GetType().Name + " from " + e.TargetSite + "."); } return(false); } }
public bool StartCast(Unit instigator, ushort abilityID, byte castSequence, byte cooldownGroup = 0, byte overrideAbilityLevel = 0, bool enemyVisible = true, bool friendlyVisible = true, bool moving = false) { if (PreventCasting) { if (_Owner is Player) { (_Owner as Player)?.SendClientMessage("A developer has disabled all abilities.", ChatLogFilters.CHATLOGFILTERS_USER_ERROR); } return(false); } // Allow only interruption of channeled skills of a different ID to the skill being used if (IsCasting() && (!_abilityProcessor.IsChannelling || _abilityProcessor.AbInfo.Entry == abilityID)) { return(false); } AbilityInfo abInfo = AbilityMgr.GetAbilityInfo(abilityID); if (abInfo == null || (abInfo.ConstantInfo.Origin != AbilityOrigin.AO_ITEM && !IsValidAbility(abInfo))) { return(false); } //Fix so that WE/WH cant use all their 3 openers at the same time, this is in conjunction with whats in AbilityProcessor if (_Owner is Player) { if ((_Owner as Player).StealthLevel == 0 && (abilityID == 9406 || abilityID == 9401 || abilityID == 9411 || abilityID == 8091 || abilityID == 8096 || abilityID == 8098)) { return(false); } } try { if (AbilityMgr.HasCommandsFor(abilityID) || abInfo.ConstantInfo.ChannelID != 0) { if (_abilityProcessor == null) { _abilityProcessor = new AbilityProcessor(_unitOwner, this); } abInfo.Instigator = instigator; abInfo.Level = overrideAbilityLevel; return(_abilityProcessor.StartAbility(abInfo, castSequence, cooldownGroup, enemyVisible, friendlyVisible, moving)); } if (_Owner is Player) { Player owner = _Owner as Player; owner?.SendClientMessage(abilityID + " " + AbilityMgr.GetAbilityNameFor(abilityID) + " has no implementation.", ChatLogFilters.CHATLOGFILTERS_USER_ERROR); } return(false); } catch (Exception e) { if (_Owner is Player) { (_Owner as Player)?.SendClientMessage(abilityID + " " + AbilityMgr.GetAbilityNameFor(abilityID) + " threw an unhandled " + e.GetType().Name + " from " + e.TargetSite + "."); } Log.Error("Ability System", e.ToString()); return(false); } }
public virtual void StartBuff() { if (_buffInfo.StackLine != 0) { AddBuffParameter(_buffInfo.StackLine, StackLevel); } // Invoke commands and register event subscriptions. if (_buffInfo.CommandInfo != null) { for (byte i = 0; i < _buffInfo.CommandInfo.Count; ++i) { BuffCommandInfo command = _buffInfo.CommandInfo[i]; if (command.EventID != 0) { EventCommands.Add(new Tuple <byte, BuffCommandInfo>(command.EventID, command)); _buffInterface.AddEventSubscription(this, command.EventID); //InvokeOn override - 8 == Invoke as permanent conditional effect while buff is active (for Channel) if (command.InvokeOn == 8 && command.TargetType == CommandTargetTypes.Caster) { Caster.BuffInterface.AddEventSubscription(this, command.EventID); } if (command.InvokeOn == 0 && command.BuffLine > 0) { AddBuffParameter(command.BuffLine, command.PrimaryValue); } } if ((command.InvokeOn & BuffState) > 0) { BuffEffectInvoker.InvokeCommand(this, command, Target); } } } BuffState = (byte)EBuffState.Running; #region Check for CC block or no tooltip text // If a buff is crowd control and no tooltip text was added, a CC immunity blocked it. // In this case the buff is removed here. if (BuffLines.Count != 0) { if (Duration > 0) { if (CrowdControl == 1) { DurationMs = (uint)(DurationMs * Target.StsInterface.GetStatReductionModifier(Stats.SnareDuration)); EndTime = TCPManager.GetTimeStampMS() + DurationMs; } if (CrowdControl == 16) { DurationMs = (uint)(DurationMs * Target.StsInterface.GetStatReductionModifier(Stats.KnockdownDuration)); EndTime = TCPManager.GetTimeStampMS() + DurationMs; } } SendStart(null); ChannelHandler?.NotifyBuffStarted(); } else { #if DEBUG Log.Info("Buff " + _buffInfo.Entry, "Couldn't find any buff lines."); if (CrowdControl == 0 && Caster is Player) { ((Player)Caster).SendClientMessage(Entry + " " + AbilityMgr.GetAbilityNameFor(Entry) + ": Couldn't find any buff lines."); } #endif BuffHasExpired = true; } #endregion }
public virtual void InvokeDamageEvent(byte eventId, AbilityDamageInfo damageInfo, Unit eventInstigator) { if (BuffState != (byte)EBuffState.Running) { return; } BuffCommandInfo myCommand = EventCommands.Find(evtpair => evtpair.Item1 == eventId).Item2; if (myCommand == null) { return; } if (!string.IsNullOrEmpty(myCommand.EventCheck) && !BuffEffectInvoker.PerformCheck(this, damageInfo, myCommand, eventInstigator)) { return; } if (myCommand.EventChance > 0 && StaticRandom.Instance.Next(0, 100) > myCommand.EventChance) { return; } if (myCommand.RetriggerInterval != 0) { // If two threads clash here, we're guaranteed to be setting the next time anyway // so the thread which can't get the lock should just return if (Interlocked.CompareExchange(ref BuffTimerLock, 1, 0) != 0) { return; } if (myCommand.NextTriggerTime != 0 && myCommand.NextTriggerTime > TCPManager.GetTimeStampMS()) { Interlocked.Exchange(ref BuffTimerLock, 0); return; } myCommand.NextTriggerTime = TCPManager.GetTimeStampMS() + myCommand.RetriggerInterval; Interlocked.Exchange(ref BuffTimerLock, 0); } if (myCommand.ConsumesStack) { while (Interlocked.CompareExchange(ref BuffStackLock, 1, 0) != 0) { ; } if (StackLevel == 0) { Interlocked.Exchange(ref BuffStackLock, 0); return; } RemoveStack(); if (Entry == 8090 || Entry == 9393) { ((Player)Caster).SendClientMessage((eventInstigator?.Name ?? "Something") + "'s " + AbilityMgr.GetAbilityNameFor(damageInfo.DisplayEntry) + " broke your stealth."); } Interlocked.Exchange(ref BuffStackLock, 0); } if (myCommand.CommandName == "None") { return; } BuffEffectInvoker.InvokeDamageEventCommand(this, myCommand, damageInfo, Target, eventInstigator); }
public void ReloadTactics() { List <ushort> tacList = new List <ushort>(); bool sendTacticUpdate = false; if (_myPlayer._Value.Tactic1 != 0 && !tacList.Contains(_myPlayer._Value.Tactic1)) { tacList.Add(_myPlayer._Value.Tactic1); } if (_myPlayer._Value.Tactic2 != 0 && !tacList.Contains(_myPlayer._Value.Tactic2)) { tacList.Add(_myPlayer._Value.Tactic2); } if (_myPlayer._Value.Tactic3 != 0 && !tacList.Contains(_myPlayer._Value.Tactic3)) { tacList.Add(_myPlayer._Value.Tactic3); } if (_myPlayer._Value.Tactic4 != 0 && !tacList.Contains(_myPlayer._Value.Tactic4)) { tacList.Add(_myPlayer._Value.Tactic4); } int maxAllowedTactics = _myPlayer.AdjustedLevel / 10; while (tacList.Count > maxAllowedTactics) { tacList.RemoveAt(tacList.Count - 1); sendTacticUpdate = true; } foreach (NewBuff buff in _activeBuffs) { buff.BuffHasExpired = true; if (_modifyingTactics.Contains(buff.Entry)) { _modifyingTactics.Remove(buff.Entry); List <ushort> toRemove = new List <ushort>(); if (AbilityMgr.HasPreCastModifiers(buff.Entry)) { foreach (AbilityModifier mod in AbilityMgr.GetAbilityPreCastModifiers(buff.Entry)) { if (mod.Affecting == 0) { _generalPreCastModifiers.RemoveAll(fmod => fmod.Source == buff.Entry); } else if (mod.Affecting <= 3) { _speclinePreCastModifiers[(byte)(mod.Affecting - 1)].RemoveAll(fmod => fmod.Source == buff.Entry); } else { toRemove.Add(mod.Affecting); } } foreach (ushort rem in toRemove) { _abilityPreCastModifiers[rem].RemoveAll(fmod => fmod.Source == buff.Entry); } toRemove.Clear(); } if (AbilityMgr.HasModifiers(buff.Entry)) { foreach (AbilityModifier mod in AbilityMgr.GetAbilityModifiers(buff.Entry)) { if (mod.Affecting == 0) { _generalModifiers.RemoveAll(fmod => fmod.Source == buff.Entry); } else if (mod.Affecting <= 3) { _speclineModifiers[(byte)(mod.Affecting - 1)].RemoveAll(fmod => fmod.Source == buff.Entry); } else { toRemove.Add(mod.Affecting); } } foreach (ushort rem in toRemove) { _abilityModifiers[rem].RemoveAll(fmod => fmod.Source == buff.Entry); } toRemove.Clear(); } if (AbilityMgr.HasBuffModifiers(buff.Entry)) { foreach (AbilityModifier mod in AbilityMgr.GetBuffModifiers(buff.Entry)) { if (mod.Affecting == 0) { _generalBuffModifiers.RemoveAll(fmod => fmod.Source == buff.Entry); } else if (mod.Affecting <= 3) { _speclineBuffModifiers[(byte)(mod.Affecting - 1)].RemoveAll(fmod => fmod.Source == buff.Entry); } else { toRemove.Add(mod.Affecting); } } foreach (ushort rem in toRemove) { _buffModifiers[rem].RemoveAll(fmod => fmod.Source == buff.Entry); } } } _activeTactics.Remove(buff.Entry); } _activeBuffs.Clear(); foreach (ushort id in tacList) { if (id == 0 || _activeTactics.Contains(id)) { continue; } BuffInfo b = AbilityMgr.GetBuffInfo(id); if (b == null) { _myPlayer.SendClientMessage("Nonexistent tactic: " + id + " " + AbilityMgr.GetAbilityNameFor(id)); continue; } if (!_myPlayer.AbtInterface.IsValidTactic(id)) { _myPlayer.SendClientMessage("Invalid tactic: " + id + " " + AbilityMgr.GetAbilityNameFor(id)); sendTacticUpdate = true; continue; } if (!string.IsNullOrEmpty(b.AuraPropagation)) { _myPlayer.BuffInterface.QueueBuff(new BuffQueueInfo(_myPlayer, _myPlayer.AbtInterface.GetMasteryLevelFor(AbilityMgr.GetMasteryTreeFor(b.Entry)), b, BuffEffectInvoker.CreateAura, RegisterTacticBuff)); } else { _myPlayer.BuffInterface.QueueBuff(new BuffQueueInfo(_myPlayer, _myPlayer.AbtInterface.GetMasteryLevelFor(AbilityMgr.GetMasteryTreeFor(b.Entry)), b, RegisterTacticBuff)); } _activeTactics.Add(id); } // Update the saved list for the server for (int i = 0; i < 4; ++i) { _myPlayer._Value.SetTactic((byte)(i + 1), i < _activeTactics.Count ? _activeTactics[i] : (ushort)0); } if (sendTacticUpdate) { SendTactics(); } }