public override void StartBuff() { if (_buffInfo.CommandInfo != null) { for (byte i = 0; i < _buffInfo.CommandInfo.Count; ++i) { if ((_buffInfo.CommandInfo[i].InvokeOn & BuffState) > 0) { BuffEffectInvoker.InvokeCommand(this, _buffInfo.CommandInfo[i], Target); } } } BuffState = (byte)EBuffState.Running; NextTickTime = TCPManager.GetTimeStampMS() + _buffInfo.Interval; if (BuffLines.Count != 0) { SendBounceStart(); } else { BuffHasExpired = true; } }
public override void Update(long tick) { if (BuffState != (byte)EBuffState.Running) { return; } long curTime = TCPManager.GetTimeStampMS(); if (EndTime > 0 && curTime >= EndTime) { BuffEnded(false, false); } else { if (NextTickTime > 0 && curTime >= NextTickTime) { NextTickTime += _buffInfo.Interval; foreach (BuffCommandInfo command in _buffInfo.CommandInfo) { if ((command.InvokeOn & (byte)EBuffState.Running) > 0) { BuffEffectInvoker.InvokeCommand(this, command, Target); } } } if (_nextAuraPropagationTime <= tick) { _nextAuraPropagationTime = tick + _propInterval; SpreadAura(); } } }
public override void Update(long tick) { if (BuffState != (byte)EBuffState.Running) { return; } long curTime = TCPManager.GetTimeStampMS(); if (EndTime > 0 && curTime >= EndTime) { BuffEnded(false, false); } else if (NextTickTime > 0 && curTime >= NextTickTime) { NextTickTime += _buffInfo.Interval; OnUpdate?.Invoke(this, HeldObject, tick); if (_buffInfo.CommandInfo != null) { foreach (BuffCommandInfo command in _buffInfo.CommandInfo) { if ((command.InvokeOn & (byte)EBuffState.Running) > 0) { BuffEffectInvoker.InvokeCommand(this, command, Target); } } } } }
/// <summary> /// Reload abilities. /// </summary> /// <param name="plr">Player that initiated the command</param> /// <param name="values">List of command arguments (after command name)</param> /// <returns>True if command was correctly handled, false if operation was canceled</returns> public static bool ReloadAbilities(Player plr, ref List <string> values) { lock (Player._Players) { foreach (Player player in Player._Players) { player.SendClientMessage("[System] Recaching ability tables...", ChatLogFilters.CHATLOGFILTERS_CSR_TELL_RECEIVE); } } AbilityMgr.ReloadAbilities(); AbilityMgr.LoadCreatureAbilities(); AbilityModifierInvoker.LoadModifierCommands(); BuffEffectInvoker.LoadBuffCommands(); lock (Player._Players) { foreach (Player player in Player._Players) { player.SendClientMessage("[System] Ability tables successfully recached.", ChatLogFilters.CHATLOGFILTERS_CSR_TELL_RECEIVE); } } return(true); }
public void InvokeItemEvent(byte eventID, Item_Info itmInfo) { if (BuffState != (byte)EBuffState.Running) { return; } BuffCommandInfo myCommand = EventCommands.Find(evtpair => evtpair.Item1 == eventID).Item2; if (myCommand == null) { return; } BuffEffectInvoker.InvokeItemCommand(this, myCommand, itmInfo); }
public override void InvokeDamageEvent(byte eventId, AbilityDamageInfo damageInfo, Unit eventInstigator) { if (BuffState != (byte)EBuffState.Running) { return; } if (!string.IsNullOrEmpty(EventCommands[0].Item2.EventCheck) && !BuffEffectInvoker.PerformCheck(this, damageInfo, EventCommands[0].Item2, eventInstigator)) { return; } if (!CanHitTarget(eventInstigator)) { return; } BuffEffectInvoker.InvokeDamageEventCommand(this, EventCommands[0].Item2, damageInfo, Target, eventInstigator); }
protected override void BuffEnded(bool wasRemoved, bool wasManual) { if (Interlocked.CompareExchange(ref BuffEndLock, 1, 0) != 0) { return; } BuffHasExpired = true; WasManuallyRemoved = wasManual; if (wasRemoved) { BuffState = (byte)EBuffState.Removed; } else { BuffState = (byte)EBuffState.Ended; } Interlocked.Exchange(ref BuffEndLock, 0); if (_buffInfo.CommandInfo != null) { foreach (BuffCommandInfo Command in _buffInfo.CommandInfo) { if ((Command.InvokeOn & (byte)EBuffState.Ended) > 0) { BuffEffectInvoker.InvokeCommand(this, Command, Target); } } } SendBounceEnd(); if (_linkedBuff != null && !_linkedBuff.BuffHasExpired) { _linkedBuff.BuffHasExpired = true; } }
public void InvokePetEvent(byte eventID, Pet myPet) { if (BuffState != (byte)EBuffState.Running) { return; } BuffCommandInfo myCommand = EventCommands.Find(evtpair => evtpair.Item1 == eventID).Item2; if (myCommand == null) { return; } if (myCommand.ConsumesStack) { while (Interlocked.CompareExchange(ref BuffStackLock, 1, 0) != 0) { ; } if (StackLevel == 0) { Interlocked.Exchange(ref BuffStackLock, 0); return; } RemoveStack(); Interlocked.Exchange(ref BuffStackLock, 0); } if (myCommand.CommandName == "None") { return; } BuffEffectInvoker.InvokePetCommand(this, myCommand, myPet); }
protected override void BuffEnded(bool wasRemoved, bool wasManual) { if (Interlocked.CompareExchange(ref BuffEndLock, 1, 0) != 0) { return; } BuffHasExpired = true; WasManuallyRemoved = wasManual; if (wasRemoved) { BuffState = (byte)EBuffState.Removed; } else { BuffState = (byte)EBuffState.Ended; } Interlocked.Exchange(ref BuffEndLock, 0); if (_buffInfo.CommandInfo != null) { foreach (BuffCommandInfo command in _buffInfo.CommandInfo) { if ((command.InvokeOn & (byte)EBuffState.Ended) > 0) { BuffEffectInvoker.InvokeCommand(this, command, Target); } } } if (EventCommands.Count > 0) { foreach (var evtpair in EventCommands) { _buffInterface.RemoveEventSubscription(this, evtpair.Item1); } } BuffHasExpired = true; BuffState = (byte)EBuffState.Removed; Player player = (Player)Caster; if (player.HeldObject != HeldObject) { Log.Error(player.Name, "Holding multiple objects!"); } else { player.HeldObject = null; } HeldObject.HolderDied(); Caster.OSInterface.RemoveEffect(0xB); SendEnded(); }
public void InvokeResourceEvent(byte eventID, byte oldVal, ref byte change) { if (BuffState != (byte)EBuffState.Running) { return; } BuffCommandInfo myCommand = EventCommands.Find(evtpair => evtpair.Item1 == eventID).Item2; if (myCommand == null) { 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(); Interlocked.Exchange(ref BuffStackLock, 0); } if (myCommand.CommandName == "None") { return; } BuffEffectInvoker.InvokeResourceCommand(this, myCommand, oldVal, ref change); }
public virtual void InvokeCastEvent(byte eventID, AbilityInfo abInfo) { if (BuffState != (byte)EBuffState.Running) { return; } BuffCommandInfo myCommand = EventCommands.Find(evtpair => evtpair.Item1 == eventID).Item2; if (myCommand == null) { return; } if (myCommand.EventChance > 0 && StaticRandom.Instance.Next(0, 100) > myCommand.EventChance) { return; } // Lazy checking for some tactics that don't warrant creating new delegates. switch (Entry) { // Scourged Warping (requires Scourge to be the ability casted) case 3765: if (abInfo.Entry != 8548) { return; } break; // Flashfire (requires that the ability have a cast time) case 3422: if (abInfo.ConstantInfo.BaseCastTime == 0 || abInfo.ConstantInfo.ChannelID > 0 || abInfo.ConstantInfo.Origin == AbilityOrigin.AO_ITEM) { return; } break; // Shadow Prowler, Incognito (ability must break) case 8090: case 9393: if (abInfo.ConstantInfo.StealthInteraction == AbilityStealthType.Ignore) { return; } break; } if (myCommand.ConsumesStack) { while (Interlocked.CompareExchange(ref BuffStackLock, 1, 0) != 0) { ; } if (StackLevel == 0) { Interlocked.Exchange(ref BuffStackLock, 0); return; } RemoveStack(); Interlocked.Exchange(ref BuffStackLock, 0); } if (myCommand.CommandName == "None") { return; } BuffEffectInvoker.InvokeAbilityUseCommand(this, myCommand, abInfo); }
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); }
protected virtual void BuffEnded(bool wasRemoved, bool wasManual) { if (Interlocked.CompareExchange(ref BuffEndLock, 1, 0) != 0) { return; } BuffHasExpired = true; WasManuallyRemoved = wasManual; if (wasRemoved) { BuffState = (byte)EBuffState.Removed; } else { BuffState = (byte)EBuffState.Ended; } Interlocked.Exchange(ref BuffEndLock, 0); // Flag exhaustion needs to send end before performing the swap if (Entry == 14323) { SendEnded(); } if (_buffInfo.CommandInfo != null) { foreach (BuffCommandInfo command in _buffInfo.CommandInfo) { if ((command.InvokeOn & (byte)EBuffState.Ended) > 0) { BuffEffectInvoker.InvokeCommand(this, command, Target); } } } if (EventCommands.Count > 0) { foreach (var evtpair in EventCommands) { _buffInterface.RemoveEventSubscription(this, evtpair.Item1); } } if (_buffInfo.CommandInfo != null) { foreach (BuffCommandInfo command in _buffInfo.CommandInfo) { if (command.InvokeOn == 8 && command.TargetType == CommandTargetTypes.Caster) { Caster.BuffInterface.RemoveEventSubscription(this, command.EventID); } } } if (Entry != 14323) { SendEnded(); } if (_linkedBuff != null && !_linkedBuff.BuffHasExpired) { _linkedBuff.BuffHasExpired = true; } }
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 }