/// <summary> /// Gets the buff class considering potential buff command override. /// </summary> /// <param name="command">Command to apply.</param> /// <returns>Buff class</returns> public BuffClass GetBuffClass(BuffCommandInfo command) { BuffClass clazz = command.BuffClass; if (clazz != BuffClass.Standard) { return(clazz); } return(_buffInfo.BuffClass); }
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 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); }
public override void ExperimentalModeModifyBuff(BuffInfo buffInfo, Unit target) { switch (buffInfo.Entry) { // Prayer of Absolution case 8242: if (target != myPlayer) { return; } // Reduces armor by 50% and converts Strength to Willpower buffInfo.AddBuffCommand(AbilityMgr.GetBuffCommand(buffInfo.Entry, 1)); // Adds 8 RF/sec buffInfo.Interval = 1000; buffInfo.AddBuffCommand(AbilityMgr.GetBuffCommand(buffInfo.Entry, 2)); myPlayer.AbtInterface.SetCooldown(8249, _currentStance == 1 ? DPS_SWITCH_CD_MS : SWITCH_CD_MS); myPlayer.AbtInterface.SetCooldown(8243, _currentStance == 1 ? DPS_SWITCH_CD_MS : SWITCH_CD_MS); // Neutralize SE if (_currentStance == 1 && myPlayer.CbtInterface.IsInCombat) { myPlayer.ConsumeActionPoints(myPlayer.ActionPoints); ConsumeResource(250, true); } CurrentStance = 3; break; // Covenant of Tenacity case 9563: if (target != myPlayer) { return; } // Reduces armor by 50% and converts Strength to Willpower buffInfo.AddBuffCommand(AbilityMgr.GetBuffCommand(buffInfo.Entry, 1)); // Adds 8 SE/sec buffInfo.Interval = 1000; buffInfo.AddBuffCommand(AbilityMgr.GetBuffCommand(buffInfo.Entry, 2)); myPlayer.AbtInterface.SetCooldown(9559, _currentStance == 1 ? DPS_SWITCH_CD_MS : SWITCH_CD_MS); myPlayer.AbtInterface.SetCooldown(9567, _currentStance == 1 ? DPS_SWITCH_CD_MS : SWITCH_CD_MS); // Neutralize SE if (_currentStance == 1 && myPlayer.CbtInterface.IsInCombat) { myPlayer.ConsumeActionPoints(myPlayer.ActionPoints); ConsumeResource(250, true); } CurrentStance = 3; break; // Prayer of Devotion case 8249: if (target != myPlayer) { return; } // Gain Willpower when striking a target buffInfo.AddBuffCommand(AbilityMgr.GetBuffCommand(buffInfo.Entry, 1)); // Convert Willpower to Strength buffInfo.AddBuffCommand(AbilityMgr.GetBuffCommand(buffInfo.Entry, 2)); myPlayer.AbtInterface.SetCooldown(8242, _currentStance == 1 ? DPS_SWITCH_CD_MS : SWITCH_CD_MS); myPlayer.AbtInterface.SetCooldown(8243, _currentStance == 1 ? DPS_SWITCH_CD_MS : SWITCH_CD_MS); // Neutralize SE if (_currentStance == 1 && myPlayer.CbtInterface.IsInCombat) { myPlayer.ConsumeActionPoints(myPlayer.ActionPoints); ConsumeResource(250, true); } // AoE detaunt CurrentStance = 2; break; // Covenant of Vitality case 9567: if (target != myPlayer) { return; } // Gain Willpower when striking a target buffInfo.AddBuffCommand(AbilityMgr.GetBuffCommand(buffInfo.Entry, 2)); // Convert Willpower to Strength buffInfo.AddBuffCommand(AbilityMgr.GetBuffCommand(buffInfo.Entry, 3)); myPlayer.AbtInterface.SetCooldown(9559, _currentStance == 1 ? DPS_SWITCH_CD_MS : SWITCH_CD_MS); myPlayer.AbtInterface.SetCooldown(9563, _currentStance == 1 ? DPS_SWITCH_CD_MS : SWITCH_CD_MS); // Neutralize SE if (_currentStance == 1 && myPlayer.CbtInterface.IsInCombat) { myPlayer.ConsumeActionPoints(myPlayer.ActionPoints); ConsumeResource(250, true); } // AoE detaunt CurrentStance = 2; break; // Prayer of Righteousness case 8243: if (target != myPlayer) { return; } // Procs on the caster also increase speed by 20% buffInfo.AppendBuffCommand(AbilityMgr.GetBuffCommand(buffInfo.Entry, 1), 0); // Damage of Path of Wrath skills increased by 1% for every 10 RF buffInfo.AddBuffCommand(AbilityMgr.GetBuffCommand(buffInfo.Entry, 2)); // Convert Willpower to Strength buffInfo.AddBuffCommand(AbilityMgr.GetBuffCommand(buffInfo.Entry, 3)); myPlayer.AbtInterface.SetCooldown(8249, DPS_SWITCH_CD_MS); myPlayer.AbtInterface.SetCooldown(8242, DPS_SWITCH_CD_MS); // Neutralize Fury if (myPlayer.CbtInterface.IsInCombat) { myPlayer.ConsumeActionPoints(myPlayer.ActionPoints); ConsumeResource(250, true); } CurrentStance = 1; break; // Covenant of Celerity case 9559: if (target != myPlayer) { return; } //Damage of Path of Torture skills increased by 1 % for every 10 SE buffInfo.AddBuffCommand(AbilityMgr.GetBuffCommand(buffInfo.Entry, 2)); // Convert Willpower to Strength buffInfo.AddBuffCommand(AbilityMgr.GetBuffCommand(buffInfo.Entry, 3)); myPlayer.AbtInterface.SetCooldown(9563, DPS_SWITCH_CD_MS); myPlayer.AbtInterface.SetCooldown(9567, DPS_SWITCH_CD_MS); // Neutralize SE if (myPlayer.CbtInterface.IsInCombat) { myPlayer.ConsumeActionPoints(myPlayer.ActionPoints); ConsumeResource(250, true); } CurrentStance = 1; break; case 8244: // Divine Assault case 9554: // Rend Soul if (_currentStance == 2) { foreach (BuffCommandInfo command in buffInfo.CommandInfo) { for (BuffCommandInfo cmd = command; cmd != null; cmd = cmd.NextCommand) { // Is undefendable, to compensate deals half damage but heals for 75% more if (cmd.CommandName == "StealLife") { cmd.PrimaryValue = (int)(cmd.PrimaryValue * 1.75f); } else if (cmd.DamageInfo != null) { cmd.DamageInfo.Undefendable = true; cmd.DamageInfo.ResultFromRaw = true; } } } } break; case 8270: // Absence of Faith becomes 50% with DPS on if (_currentStance == 1) { buffInfo.CommandInfo[0].SecondaryValue = -50; } break; } }
public static void LoadNewAbilityInfo() { Log.Info("AbilityMgr", "Loading New Ability Info..."); IObjectDatabase db = WorldMgr.Database; #region Database List <DBAbilityInfo> dbAbilities = (List <DBAbilityInfo>)db.SelectAllObjects <DBAbilityInfo>(); List <AbilityInfo> abVolatiles = AbilityInfo.Convert(dbAbilities); Dictionary <ushort, AbilityConstants> abConstants = AbilityConstants.Convert(dbAbilities).ToDictionary(key => key.Entry); List <AbilityDamageInfo> abDmgHeals = AbilityDamageInfo.Convert(db.SelectAllObjects <DBAbilityDamageInfo>().OrderBy(dmg => dmg.ParentCommandID).ThenBy(dmg => dmg.ParentCommandSequence).ToList()); List <AbilityCommandInfo> abCommands = AbilityCommandInfo.Convert(db.SelectAllObjects <DBAbilityCommandInfo>().OrderBy(cmd => cmd.CommandID).ToList()); IList <AbilityModifierCheck> abChecks = db.SelectAllObjects <AbilityModifierCheck>().OrderBy(check => check.ID).ToList(); IList <AbilityModifierEffect> abMods = db.SelectAllObjects <AbilityModifierEffect>().OrderBy(mod => mod.Sequence).ToList(); List <BuffInfo> buffInfos = BuffInfo.Convert((List <DBBuffInfo>)db.SelectAllObjects <DBBuffInfo>()); List <BuffCommandInfo> buffCommands = BuffCommandInfo.Convert(db.SelectAllObjects <DBBuffCommandInfo>().OrderBy(buffcmd => buffcmd.CommandID).ToList()); IList <AbilityKnockbackInfo> knockbackInfos = db.SelectAllObjects <AbilityKnockbackInfo>().OrderBy(kbinfo => kbinfo.Id).ToList(); List <AbilityCommandInfo> slaveCommands = new List <AbilityCommandInfo>(); List <BuffCommandInfo> slaveBuffCommands = new List <BuffCommandInfo>(); Dictionary <ushort, int> damageTypeDictionary = new Dictionary <ushort, int>(); #endregion for (byte i = 0; i < 24; ++i) { CareerAbilities[i] = new List <AbilityInfo>(); } #region AbilityChecks foreach (AbilityModifierCheck check in abChecks) { switch (check.PreOrPost) { case 0: if (!AbilityPreCastModifiers.ContainsKey(check.Entry)) { AbilityPreCastModifiers.Add(check.Entry, new List <AbilityModifier>()); while (AbilityPreCastModifiers[check.Entry].Count < check.ID + 1) { AbilityPreCastModifiers[check.Entry].Add(new AbilityModifier(check.Entry, check.Affecting)); } AbilityPreCastModifiers[check.Entry][check.ID].AddCheck(check); } else { if (AbilityPreCastModifiers[check.Entry].Count == check.ID) { AbilityPreCastModifiers[check.Entry].Add(new AbilityModifier(check.Entry, check.Affecting)); } AbilityPreCastModifiers[check.Entry][check.ID].AddCheck(check); } break; case 1: if (!AbilityModifiers.ContainsKey(check.Entry)) { AbilityModifiers.Add(check.Entry, new List <AbilityModifier>()); while (AbilityModifiers[check.Entry].Count < check.ID + 1) { AbilityModifiers[check.Entry].Add(new AbilityModifier(check.Entry, check.Affecting)); } AbilityModifiers[check.Entry][check.ID].AddCheck(check); } else { if (AbilityModifiers[check.Entry].Count == check.ID) { AbilityModifiers[check.Entry].Add(new AbilityModifier(check.Entry, check.Affecting)); } AbilityModifiers[check.Entry][check.ID].AddCheck(check); } break; case 2: if (!BuffModifiers.ContainsKey(check.Entry)) { BuffModifiers.Add(check.Entry, new List <AbilityModifier>()); while (BuffModifiers[check.Entry].Count < check.ID + 1) { BuffModifiers[check.Entry].Add(new AbilityModifier(check.Entry, check.Affecting)); } BuffModifiers[check.Entry][check.ID].AddCheck(check); } else { if (BuffModifiers[check.Entry].Count == check.ID) { BuffModifiers[check.Entry].Add(new AbilityModifier(check.Entry, check.Affecting)); } BuffModifiers[check.Entry][check.ID].AddCheck(check); } break; case 3: if (!AbilityDelayedModifiers.ContainsKey(check.Entry)) { AbilityDelayedModifiers.Add(check.Entry, new List <AbilityModifier>()); while (AbilityDelayedModifiers[check.Entry].Count < check.ID + 1) { AbilityDelayedModifiers[check.Entry].Add(new AbilityModifier(check.Entry, check.Affecting)); } AbilityDelayedModifiers[check.Entry][check.ID].AddCheck(check); } else { if (AbilityDelayedModifiers[check.Entry].Count == check.ID) { AbilityDelayedModifiers[check.Entry].Add(new AbilityModifier(check.Entry, check.Affecting)); } AbilityDelayedModifiers[check.Entry][check.ID].AddCheck(check); } break; } } #endregion #region AbilityModifiers foreach (AbilityModifierEffect effect in abMods) { switch (effect.PreOrPost) { case 0: if (!AbilityPreCastModifiers.ContainsKey(effect.Entry)) { AbilityPreCastModifiers.Add(effect.Entry, new List <AbilityModifier>()); AbilityPreCastModifiers[effect.Entry].Add(new AbilityModifier(effect.Entry, effect.Affecting)); AbilityPreCastModifiers[effect.Entry][0].AddModifier(effect); } else { if (AbilityPreCastModifiers[effect.Entry].Count == effect.Sequence) { AbilityPreCastModifiers[effect.Entry].Add(new AbilityModifier(effect.Entry, effect.Affecting)); } AbilityPreCastModifiers[effect.Entry][effect.Sequence].AddModifier(effect); } break; case 1: if (!AbilityModifiers.ContainsKey(effect.Entry)) { AbilityModifiers.Add(effect.Entry, new List <AbilityModifier>()); AbilityModifiers[effect.Entry].Add(new AbilityModifier(effect.Entry, effect.Affecting)); AbilityModifiers[effect.Entry][0].AddModifier(effect); } else { if (AbilityModifiers[effect.Entry].Count == effect.Sequence) { AbilityModifiers[effect.Entry].Add(new AbilityModifier(effect.Entry, effect.Affecting)); } AbilityModifiers[effect.Entry][effect.Sequence].AddModifier(effect); } break; case 2: if (!BuffModifiers.ContainsKey(effect.Entry)) { BuffModifiers.Add(effect.Entry, new List <AbilityModifier>()); BuffModifiers[effect.Entry].Add(new AbilityModifier(effect.Entry, effect.Affecting)); BuffModifiers[effect.Entry][0].AddModifier(effect); } else { if (BuffModifiers[effect.Entry].Count == effect.Sequence) { BuffModifiers[effect.Entry].Add(new AbilityModifier(effect.Entry, effect.Affecting)); } BuffModifiers[effect.Entry][effect.Sequence].AddModifier(effect); } break; case 3: if (!AbilityDelayedModifiers.ContainsKey(effect.Entry)) { AbilityDelayedModifiers.Add(effect.Entry, new List <AbilityModifier>()); AbilityDelayedModifiers[effect.Entry].Add(new AbilityModifier(effect.Entry, effect.Affecting)); AbilityDelayedModifiers[effect.Entry][0].AddModifier(effect); } else { if (AbilityDelayedModifiers[effect.Entry].Count == effect.Sequence) { AbilityDelayedModifiers[effect.Entry].Add(new AbilityModifier(effect.Entry, effect.Affecting)); } AbilityDelayedModifiers[effect.Entry][effect.Sequence].AddModifier(effect); } break; } } #endregion #region CommandInfo // Ability commands foreach (AbilityCommandInfo abCommand in abCommands) { if (abCommand.CommandSequence != 0) { slaveCommands.Add(abCommand); } else { if (!AbilityCommandInfos.ContainsKey(abCommand.Entry)) { AbilityCommandInfos.Add(abCommand.Entry, new List <AbilityCommandInfo>()); } AbilityCommandInfos[abCommand.Entry].Add(abCommand); } } foreach (AbilityCommandInfo slaveCommand in slaveCommands) { if (AbilityCommandInfos.ContainsKey(slaveCommand.Entry)) { AbilityCommandInfos[slaveCommand.Entry][slaveCommand.CommandID].AddCommandToChain(slaveCommand); } else { Log.Debug("AbilityMgr", "Slave command with entry " + slaveCommand.Entry + " and depending upon master command ID " + slaveCommand.CommandID + " has no master!"); } } #endregion #region BuffCommands foreach (BuffCommandInfo buffCommand in buffCommands) { if (buffCommand.CommandSequence != 0) { slaveBuffCommands.Add(buffCommand); } else { if (!BuffCommandInfos.ContainsKey(buffCommand.Entry)) { BuffCommandInfos.Add(buffCommand.Entry, new List <BuffCommandInfo>()); } BuffCommandInfos[buffCommand.Entry].Add(buffCommand); } } foreach (BuffCommandInfo slaveBuffCommand in slaveBuffCommands) { if (BuffCommandInfos.ContainsKey(slaveBuffCommand.Entry)) { BuffCommandInfos[slaveBuffCommand.Entry][slaveBuffCommand.CommandID].AddCommandToChain(slaveBuffCommand); } else { Log.Debug("AbilityMgr", "Slave buff command with entry " + slaveBuffCommand.Entry + " and depending upon master command ID " + slaveBuffCommand.CommandID + " has no master!"); } } #endregion #region Damage/Heals // Damage and heal info gets tacked onto the command that's going to use it foreach (AbilityDamageInfo abDmgHeal in abDmgHeals) { if (abDmgHeal.DisplayEntry == 0) { abDmgHeal.DisplayEntry = abDmgHeal.Entry; } switch (abDmgHeal.Index) { case 0: if (AbilityCommandInfos.ContainsKey(abDmgHeal.Entry)) { AbilityCommandInfo desiredCommand = AbilityCommandInfos[abDmgHeal.Entry][abDmgHeal.ParentCommandID].GetSubcommand(abDmgHeal.ParentCommandSequence); if (desiredCommand != null) { desiredCommand.DamageInfo = abDmgHeal; } } if (!damageTypeDictionary.ContainsKey(abDmgHeal.Entry)) { damageTypeDictionary.Add(abDmgHeal.Entry, (int)abDmgHeal.DamageType); } break; case 1: if (BuffCommandInfos.ContainsKey(abDmgHeal.Entry)) { try { BuffCommandInfo desiredCommand = BuffCommandInfos[abDmgHeal.Entry][abDmgHeal.ParentCommandID].GetSubcommand(abDmgHeal.ParentCommandSequence); if (desiredCommand != null) { desiredCommand.DamageInfo = abDmgHeal; } } catch { Log.Error("AbilityMgr", "Failed Load: " + abDmgHeal.Entry + " " + abDmgHeal.ParentCommandID); } if (!damageTypeDictionary.ContainsKey(abDmgHeal.Entry)) { damageTypeDictionary.Add(abDmgHeal.Entry, (int)abDmgHeal.DamageType); } } break; case 2: if (!ExtraDamage.ContainsKey(abDmgHeal.Entry)) { ExtraDamage.Add(abDmgHeal.Entry, new List <List <AbilityDamageInfo> >()); } if (ExtraDamage[abDmgHeal.Entry].Count == abDmgHeal.ParentCommandID) { ExtraDamage[abDmgHeal.Entry].Add(new List <AbilityDamageInfo>()); } ExtraDamage[abDmgHeal.Entry][abDmgHeal.ParentCommandID].Add(abDmgHeal); break; default: throw new Exception("Invalid index specified for ability damage with ID " + abDmgHeal.Entry); } } #endregion #region KnockbackInfo foreach (var kbInfo in knockbackInfos) { if (!KnockbackInfos.ContainsKey(kbInfo.Entry)) { KnockbackInfos.Add(kbInfo.Entry, new List <AbilityKnockbackInfo>()); } KnockbackInfos[kbInfo.Entry].Add(kbInfo); } #endregion // Volatiles -> Constants // -> Commands -> DamageHeals foreach (AbilityInfo abVolatile in abVolatiles) { if (!NewAbilityVolatiles.ContainsKey(abVolatile.Entry)) { NewAbilityVolatiles.Add(abVolatile.Entry, abVolatile); } if (AbilityCommandInfos.ContainsKey(abVolatile.Entry)) { abVolatile.TargetType = AbilityCommandInfos[abVolatile.Entry][0].TargetType; if (AbilityCommandInfos[abVolatile.Entry][0].AoESource != 0) { abVolatile.TargetType = AbilityCommandInfos[abVolatile.Entry][0].AoESource; } } } #region ConstantInfo foreach (AbilityConstants abConstant in abConstants.Values) { if (NewAbilityVolatiles.ContainsKey(abConstant.Entry)) { NewAbilityVolatiles[abConstant.Entry].ConstantInfo = abConstant; if (damageTypeDictionary.ContainsKey(abConstant.Entry)) { if (damageTypeDictionary[abConstant.Entry] == (ushort)DamageTypes.Healing || damageTypeDictionary[abConstant.Entry] == (ushort)DamageTypes.RawHealing) { abConstant.IsHealing = true; } else { abConstant.IsDamaging = true; } } uint careerRequirement = abConstant.CareerLine; byte count = 0; while (careerRequirement > 0 && count < 24) { if ((careerRequirement & 1) > 0) { CareerAbilities[count].Add(NewAbilityVolatiles[abConstant.Entry]); } careerRequirement = careerRequirement >> 1; count++; } } } #endregion #region Damage to ConstantInfo linkage foreach (AbilityDamageInfo damageInfo in abDmgHeals) { if (abConstants.ContainsKey(damageInfo.Entry)) { damageInfo.MasteryTree = abConstants[damageInfo.Entry].MasteryTree; } } #endregion #region Buff/Command linkage foreach (BuffInfo buffInfo in buffInfos) { if (!BuffInfos.ContainsKey(buffInfo.Entry)) { BuffInfos.Add(buffInfo.Entry, buffInfo); } if (BuffCommandInfos.ContainsKey(buffInfo.Entry)) { buffInfo.CommandInfo = BuffCommandInfos[buffInfo.Entry]; } if (abConstants.ContainsKey(buffInfo.Entry)) { buffInfo.MasteryTree = abConstants[buffInfo.Entry].MasteryTree; } } #endregion Log.Success("AbilityMgr", "Finished loading " + NewAbilityVolatiles.Count + " abilities and " + BuffInfos.Count + " buffs!"); LoadCreatureAbilities(); }
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); }
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 }