public void AddCommandToChain(AbilityCommandInfo slaveCommand) { if (CommandSequence == 0) { if (NextCommand == null) { NextCommand = slaveCommand; slaveCommand.LastCommand = this; } else { NextCommand.AddCommandToChain(slaveCommand); } } else { if (slaveCommand.CommandSequence < CommandSequence) { LastCommand.NextCommand = slaveCommand; slaveCommand.LastCommand = LastCommand; LastCommand = slaveCommand; slaveCommand.NextCommand = this; } else if (NextCommand == null) { NextCommand = slaveCommand; slaveCommand.LastCommand = this; } else { NextCommand.AddCommandToChain(slaveCommand); } } }
/// <summary> /// Adds a command to the command sequence, linking the previous command's damage information. /// </summary> public void AddCommandToChainWithDamage(AbilityCommandInfo slaveCommand) { if (CommandSequence == 0) { if (NextCommand == null || slaveCommand.CommandSequence == CommandSequence) { NextCommand = slaveCommand; slaveCommand.LastCommand = this; if (DamageInfo != null) { slaveCommand.DamageInfo = DamageInfo.Clone(); } else { slaveCommand.DamageInfo = LastCommand.DamageInfo.Clone(); } } else { NextCommand.AddCommandToChainWithDamage(slaveCommand); } } else { if (slaveCommand.CommandSequence < CommandSequence) { LastCommand.NextCommand = slaveCommand; slaveCommand.LastCommand = LastCommand; LastCommand = slaveCommand; slaveCommand.NextCommand = this; if (slaveCommand.LastCommand.DamageInfo != null) { slaveCommand.DamageInfo = slaveCommand.LastCommand.DamageInfo.Clone(); } } else if (NextCommand == null) { NextCommand = slaveCommand; slaveCommand.LastCommand = this; if (DamageInfo != null) { slaveCommand.DamageInfo = DamageInfo.Clone(); } else { slaveCommand.DamageInfo = LastCommand.DamageInfo.Clone(); } } else { NextCommand.AddCommandToChainWithDamage(slaveCommand); } } }
public AbilityCommandInfo Clone(Unit caster) { AbilityCommandInfo cCommandInfo = (AbilityCommandInfo)MemberwiseClone(); cCommandInfo.CommandName = (string)CommandName.Clone(); cCommandInfo.LastCommand = null; cCommandInfo.NextCommand = null; if (DamageInfo != null) { cCommandInfo.DamageInfo = DamageInfo.Clone(caster); } return(cCommandInfo); }
public void DeleteCommand(byte slot, byte seq) { if (seq == 0) { CommandInfo.RemoveAt(slot); } else { AbilityCommandInfo toDelete = CommandInfo[slot].GetSubcommand(seq); if (toDelete != null) { toDelete.LastCommand.NextCommand = toDelete.NextCommand; if (toDelete.NextCommand != null) { toDelete.NextCommand.LastCommand = toDelete.LastCommand; toDelete.NextCommand = null; } toDelete.LastCommand = null; } } }
public static void GetCommandsFor(Unit caster, AbilityInfo abInfo) { if (AbilityCommandInfos.ContainsKey(abInfo.Entry)) { // Add commands to the new info if they're applicable to the player. // Has to be done here because of bloody tactics and career crap foreach (AbilityCommandInfo abCommand in AbilityCommandInfos[abInfo.Entry]) { if (!abCommand.NoAutoUse) { abInfo.CommandInfo.Add(abCommand.Clone(caster)); for (AbilityCommandInfo slaveCommand = abCommand.NextCommand; slaveCommand != null; slaveCommand = slaveCommand.NextCommand) { if (!slaveCommand.NoAutoUse) { abInfo.CommandInfo[(byte)(abInfo.CommandInfo.Count - 1)].AddCommandToChain(slaveCommand.Clone(caster)); } } } } } }
public void AppendAbilityCommandWithDamage(AbilityCommandInfo cmd, byte slot) { CommandInfo[slot].AddCommandToChainWithDamage(cmd); }
public void AppendAbilityCommand(AbilityCommandInfo cmd, byte slot) { CommandInfo[slot].AddCommandToChain(cmd); }
public void AddAbilityCommand(AbilityCommandInfo cmd) { CommandInfo.Add(cmd); }
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 override void ExperimentalModeModifyAbility(AbilityInfo abInfo) { switch (abInfo.Entry) { case 8252: // Sigmar's Radiance case 9562: // Transfer Essence if (_currentStance == 2) { foreach (AbilityCommandInfo command in abInfo.CommandInfo) { for (AbilityCommandInfo cmd = command; cmd != null; cmd = cmd.NextCommand) { // Is undefendable, to compensate deals half damage but heals for more if (cmd.CommandName == "StealLife") { cmd.DamageInfo.MinDamage = 0; cmd.DamageInfo.MaxDamage = 0; cmd.PrimaryValue = (short)(cmd.PrimaryValue * 5f); } else if (cmd.DamageInfo != null) { cmd.DamageInfo.Defensibility -= 20; cmd.DamageInfo.ResultFromRaw = true; } } } } break; case 8267: // Sigmar's Shield if (_currentStance == 2) { foreach (AbilityCommandInfo command in abInfo.CommandInfo) { for (AbilityCommandInfo cmd = command; cmd != null; cmd = cmd.NextCommand) { if (cmd.DamageInfo != null) { cmd.DamageInfo.Defensibility -= 20; } } } } break; case 8270: // Absence of Faith abInfo.Cooldown = 10; break; case 9555: // Terrifying Vision case 8245: // Repent if (_currentStance == 2) { abInfo.Cooldown = 25; } break; case 8242: // Prayer of Absolution case 9563: // Covenant of Tenacity case 8249: // Prayer of Devotion case 9567: // Covenant of Vitality if (_currentStance == 1) { abInfo.Cooldown = (ushort)(DPS_SWITCH_CD_MS / 1000); } else { abInfo.Cooldown = (ushort)(SWITCH_CD_MS / 1000); } break; case 8243: // Prayer of Righteousness case 9559: // Covenant of Celerity abInfo.Cooldown = (ushort)(DPS_SWITCH_CD_MS / 1000); break; } }