/// <summary> /// Only works if you have 2 valid spell ids and oldSpellId already exists. /// </summary> public void Replace(SpellId oldSpellId, SpellId newSpellId) { Spell newSpell = SpellHandler.Get(newSpellId); Spell oldSpell; if (!this.m_byId.TryGetValue(oldSpellId, out oldSpell)) { return; } this.Replace(oldSpell, newSpell); }
/// <summary> /// Adds a set of spells to the explicite relationship set of this effect, which is used to determine whether /// a certain Spell and this effect have some kind of influence on one another (for procs, talent modifiers etc). /// Only adds the spells, will not work on the spells' trigger spells. /// </summary> /// <param name="abilities"></param> public void AddAffectingSpells(params SpellId[] spells) { if (AffectSpellSet == null) { AffectSpellSet = new HashSet <Spell>(); } foreach (var spellId in spells) { AffectSpellSet.Add(SpellHandler.Get(spellId)); } }
public Spell GetTriggerSpell() { Spell spell = SpellHandler.Get(TriggerSpellId); if (spell == null && ContentMgr.ForceDataPresence) { throw new ContentException("Spell {0} does not have a valid TriggerSpellId: {1}", (object)this, (object)TriggerSpellId); } return(spell); }
void RunSpell(Unit target, uint spellId) { if(Util.Utility.Random(0,101)>Cast.Spell.ProcChance) return; Spell spell = SpellHandler.Get(spellId); if (spell != null) { Vector3 loc = target.Position; SpellCast.Trigger(m_cast.CasterUnit, spell, ref loc, target); } }
public override void Clear() { foreach (var spell in m_byId.Values.ToArray()) { OnRemove(spell); if (m_sendPackets) { SpellHandler.SendSpellRemoved(OwnerChar, spell.Id); } } base.Clear(); }
/// <summary> /// Clears all pending spell cooldowns. /// </summary> public override void ClearCooldowns() { // send cooldown updates to client foreach (var cd in m_idCooldowns) { SpellHandler.SendClearCoolDown(OwnerChar, (SpellId)cd.SpellId); } foreach (var spell in m_byId.Values) { foreach (var cd in m_categoryCooldowns) { if (spell.Category == cd.CategoryId) { SpellHandler.SendClearCoolDown(OwnerChar, spell.SpellId); break; } } } // remove and delete all cooldowns var cds = m_idCooldowns.ToArray(); var catCds = m_categoryCooldowns.ToArray(); m_idCooldowns.Clear(); m_categoryCooldowns.Clear(); RealmServer.IOQueue.AddMessage(new Message(() => { foreach (var cooldown in cds) { if (cooldown is ActiveRecordBase) { ((ActiveRecordBase)cooldown).Delete(); } } foreach (var cooldown in catCds) { if (cooldown is ActiveRecordBase) { ((ActiveRecordBase)cooldown).Delete(); } } })); // clear rune cooldowns if (m_runes != null) { // TODO: Clear rune cooldown } }
/// <summary> /// Opens this SpellChannel. /// Will be called by SpellCast class. /// Requires an active Caster. /// </summary> internal void Open(List <SpellEffectHandler> channelHandlers, List <IAura> auras) { if (!m_channeling && m_cast != null) { m_channeling = true; m_auras = auras; var spell = m_cast.Spell; var caster = m_cast.CasterUnit; m_duration = spell.Durations.Max; m_amplitude = spell.ChannelAmplitude; if (m_amplitude < 1) { // only one tick m_amplitude = m_duration; } caster.ChannelSpell = spell.SpellId; var now = Environment.TickCount; m_ticks = 0; m_maxTicks = m_duration / m_amplitude; m_channelHandlers = channelHandlers; // get duration again, this time with modifiers m_duration = spell.GetDuration(caster.SharedReference); if (m_amplitude < 1) { // only one tick m_amplitude = m_duration; } m_until = now + m_duration; SpellHandler.SendChannelStart(m_cast, spell.SpellId, m_duration); if (m_channeling) { m_timer.Start(m_amplitude, m_amplitude); } // Send Initial Tick? // Keep in mind: Aura is not initialized at this point! } else { log.Warn(this + " was opened more than once or after disposal!"); } }
/// <summary> /// Will be called internally to close this Channel. /// Call SpellCast.Cancel to cancel channeling. /// </summary> internal void Close(bool cancelled) { if (!m_channeling) { return; } m_channeling = false; var caster = m_cast.CasterUnit; var handlers = m_channelHandlers; foreach (var handler in handlers) { handler.OnChannelClose(cancelled); } var auras = m_auras; if (auras != null) { foreach (var aura in auras) { aura.Remove(false); } auras.Clear(); SpellCast.AuraListPool.Recycle(auras); m_auras = null; } m_channelHandlers.Clear(); SpellCast.SpellEffectHandlerListPool.Recycle(m_channelHandlers); m_channelHandlers = null; m_timer.Stop(); if (cancelled) { SpellHandler.SendChannelUpdate(m_cast, 0); } var obj = caster.ChannelObject; if (obj is DynamicObject) { ((WorldObject)obj).Delete(); } caster.ChannelObject = null; caster.ChannelSpell = 0; }
private void AddCooldown() { if (!Spell.IsAutoRepeating && TriggerEffect == null) { CasterUnit.Spells.AddCooldown(Spell, CasterItem); } if (Client != null) { if (!Spell.Attributes.HasFlag(SpellAttributes.StartCooldownAfterEffectFade) && CasterItem != null) { SpellHandler.SendItemCooldown(Client, Spell.Id, CasterItem); } } }
private void RunSpell(Unit target, uint spellId) { if ((long)Utility.Random(0, 101) > (long)this.Cast.Spell.ProcChance) { return; } Spell spell = SpellHandler.Get(spellId); if (spell == null) { return; } Vector3 position = target.Position; SpellCast.Trigger((WorldObject)this.m_cast.CasterUnit, spell, ref position, (WorldObject)target); }
public void AddRequiredActivationAuras(params SpellId[] ids) { Spell[] spellArray = new Spell[ids.Length]; for (int index = 0; index < ids.Length; ++index) { SpellId id = ids[index]; Spell spell = SpellHandler.Get(id); if (spell == null) { throw new ArgumentException("Invalid spell in AddRequiredActivationAuras: " + id); } spellArray[index] = spell; } AddRequiredActivationAuras(spellArray); }
/// <summary> /// Add Spells which, when casted by others on the owner of this Aura, can cause it to trigger it's procs. /// Don't add damage spells (they will generate a Proc event anyway). /// </summary> public void AddTargetProcSpells(params SpellId[] spellIds) { var spells = new Spell[spellIds.Length]; for (var i = 0; i < spellIds.Length; i++) { var id = spellIds[i]; var spell = SpellHandler.Get(id); if (spell == null) { throw new InvalidSpellDataException("Invalid SpellId: " + id); } spells[i] = spell; } AddTargetProcSpells(spells); }
public void AddRequiredActivationAuras(params SpellId[] ids) { var spells = new Spell[ids.Length]; for (var i = 0; i < ids.Length; i++) { var spellId = ids[i]; var spell = SpellHandler.Get(spellId); if (spell == null) { throw new ArgumentException("Invalid spell in AddRequiredActivationAuras: " + spellId); } spells[i] = spell; } AddRequiredActivationAuras(spells); }
/// <summary> /// Clears the cooldown for the given spell /// </summary> public void ClearCooldown(SpellId spellId, bool alsoClearCategory = true) { var spell = SpellHandler.Get(spellId); if (spell == null) { try { throw new ArgumentException("No spell given for cooldown", "spellId"); } catch (Exception e) { LogUtil.WarnException(e); } return; } ClearCooldown(spell, alsoClearCategory); }
public SkillLearnStatus TryLearnSpell(short skillId, byte level) { var spell = SpellHandler.Get((uint)(skillId + level * 1000)); if (spell == null || level <= 0) { return(SkillLearnStatus.Fail); } if (spell.LearnLevel > OwnerChar.Level) { return(SkillLearnStatus.LowLevel); } if (spell.ClassMask != Asda2ClassMask.All && !spell.ClassMask.HasFlag(OwnerChar.Asda2ClassMask)) { return(SkillLearnStatus.BadProffession); } if (spell.ProffNum > OwnerChar.RealProffLevel) { return(SkillLearnStatus.BadProffession); } if (AvalibleSkillPoints <= 0) { return(SkillLearnStatus.NotEnoghtSpellPoints); } if (!OwnerChar.SubtractMoney((uint)spell.Cost)) { return(SkillLearnStatus.NotEnoghtMoney); } if (level > 1) { var previusLvlSpell = this.FirstOrDefault(s => s.RealId == skillId); if (previusLvlSpell == null || previusLvlSpell.Level != spell.Level - 1) { return(SkillLearnStatus.BadSpellLevel); } Replace(previusLvlSpell, spell); return(SkillLearnStatus.Ok); } AddSpell(spell, true); OwnerChar.SendMoneyUpdate(); return(SkillLearnStatus.Ok); }
/// <summary> /// Will be called internally to close this Channel. /// Call SpellCast.Cancel to cancel channeling. /// </summary> internal void Close(bool cancelled) { if (!this.m_channeling) { return; } this.m_channeling = false; Unit casterUnit = this.m_cast.CasterUnit; foreach (SpellEffectHandler channelHandler in this.m_channelHandlers) { channelHandler.OnChannelClose(cancelled); } List <IAura> auras = this.m_auras; if (auras != null) { foreach (IAura aura in auras) { aura.Remove(false); } auras.Clear(); SpellCast.AuraListPool.Recycle(auras); this.m_auras = (List <IAura>)null; } this.m_channelHandlers.Clear(); SpellCast.SpellEffectHandlerListPool.Recycle(this.m_channelHandlers); this.m_channelHandlers = (List <SpellEffectHandler>)null; this.m_timer.Stop(); if (cancelled) { SpellHandler.SendChannelUpdate(this.m_cast, 0U); } WorldObject channelObject = casterUnit.ChannelObject; if (channelObject is DynamicObject) { channelObject.Delete(); } casterUnit.ChannelObject = (WorldObject)null; casterUnit.ChannelSpell = SpellId.None; }
/// <summary>Clears the cooldown for the given spell</summary> public void ClearCooldown(SpellId spellId, bool alsoClearCategory = true) { Spell cooldownSpell = SpellHandler.Get(spellId); if (cooldownSpell == null) { try { throw new ArgumentException("No spell given for cooldown", nameof(spellId)); } catch (Exception ex) { LogUtil.WarnException(ex); } } else { this.ClearCooldown(cooldownSpell, alsoClearCategory); } }
public override void AddDefaultSpells() { // add the default Spells for the race/class /*for (var i = 0; i < OwnerChar.Archetype.Spells.Count; i++) * { * var spell = OwnerChar.Archetype.Spells[i]; * AddNew(spell); * }*/ AddNew(SpellHandler.Get(SpellId.BashRank1)); AddNew(SpellHandler.Get(SpellId.ArrowStrikeRank1)); // add all default Spells of all Skills the Char already has //foreach (var skill in OwnerChar.Skills) //{ // for (var i = 0; i < skill.SkillLine.InitialAbilities.Count; i++) // { // var ability = skill.SkillLine.InitialAbilities[i]; // AddNew(ability.Spell); // } //} }
/// <summary> /// Teaches a new spell to the unit. Also sends the spell learning animation, if applicable. /// </summary> void AddSpell(Spell spell, bool sendPacket) { // make sure the char knows the skill that this spell belongs to if (spell.Ability != null) { var skill = OwnerChar.Skills[spell.Ability.Skill.Id]; if (skill == null) { // learn new skill skill = OwnerChar.Skills.Add(spell.Ability.Skill, true); } if (skill.CurrentTierSpell == null || skill.CurrentTierSpell.SkillTier < spell.SkillTier) { // upgrade tier skill.CurrentTierSpell = spell; } } if (!m_byId.ContainsKey(spell.SpellId)) { var owner = OwnerChar; if (m_sendPackets && sendPacket) { SpellHandler.SendLearnedSpell(owner.Client, spell.Id); if (!spell.IsPassive) { SpellHandler.SendImpact(owner, 362); // ouchy: Unnamed constants } } var specIndex = GetSpecIndex(spell); var spells = GetSpellList(spell); var newRecord = new SpellRecord(spell.SpellId, owner.EntityId.Low, specIndex); newRecord.SaveLater(); spells.Add(newRecord); base.AddSpell(spell); } }
/// <summary> /// Clears the cooldown for this spell /// </summary> public override void ClearCooldown(Spell cooldownSpell, bool alsoCategory = true) { var ownerChar = OwnerChar; // send cooldown update to client SpellHandler.SendClearCoolDown(ownerChar, cooldownSpell.SpellId); if (alsoCategory && cooldownSpell.Category != 0) { foreach (var spell in m_byId.Values) { if (spell.Category == cooldownSpell.Category) { SpellHandler.SendClearCoolDown(ownerChar, spell.SpellId); } } } // remove and delete ISpellIdCooldown idCooldown = m_idCooldowns.RemoveFirst(cd => cd.SpellId == cooldownSpell.Id); ISpellCategoryCooldown catCooldown = m_categoryCooldowns.RemoveFirst(cd => cd.CategoryId == cooldownSpell.Category); // enqueue task if (idCooldown is ActiveRecordBase || catCooldown is ActiveRecordBase) { RealmServer.IOQueue.AddMessage(new Message(() => { if (idCooldown is ActiveRecordBase) { ((ActiveRecordBase)idCooldown).Delete(); } if (catCooldown is ActiveRecordBase) { ((ActiveRecordBase)catCooldown).Delete(); } } )); } }
/// <summary> /// Adds a set of spells to this Effect's AffectMask, which is used to determine whether /// a certain Spell and this effect have some kind of influence on one another (for procs, talent modifiers etc). /// Usually the mask also contains any spell that is triggered by the original spell. /// /// If you get a warning that the wrong set is affected, use AddAffectingSpells instead. /// </summary> public void AddToAffectMask(params SpellLineId[] abilities) { var newMask = new uint[SpellConstants.SpellClassMaskSize]; // build new mask from abilities if (abilities.Length != 1) { foreach (var ability in abilities) { var spell = SpellLines.GetLine(ability).FirstRank; for (int i = 0; i < SpellConstants.SpellClassMaskSize; i++) { newMask[i] |= spell.SpellClassMask[i]; } } } else { SpellLines.GetLine(abilities[0]).FirstRank.SpellClassMask.CopyTo(newMask, 0); } // verification var affectedLines = SpellHandler.GetAffectedSpellLines(Spell.ClassId, newMask); if (affectedLines.Count != abilities.Length) { LogManager.GetCurrentClassLogger().Warn("[SPELL Inconsistency for {0}] " + "Invalid affect mask affects a different set than the one intended: {1} (intended: {2}) - " + "You might want to use AddAffectingSpells instead!", Spell, affectedLines.ToString(", "), abilities.ToString(", ")); } for (int i = 0; i < SpellConstants.SpellClassMaskSize; i++) { AffectMask[i] |= newMask[i]; } }
/// <summary> /// Opens this SpellChannel. /// Will be called by SpellCast class. /// Requires an active Caster. /// </summary> internal void Open(List <SpellEffectHandler> channelHandlers, List <IAura> auras) { if (!this.m_channeling && this.m_cast != null) { this.m_channeling = true; this.m_auras = auras; Spell spell = this.m_cast.Spell; Unit casterUnit = this.m_cast.CasterUnit; this.m_duration = spell.Durations.Max; this.m_amplitude = spell.ChannelAmplitude; if (this.m_amplitude < 1) { this.m_amplitude = this.m_duration; } casterUnit.ChannelSpell = spell.SpellId; int tickCount = Environment.TickCount; this.m_ticks = 0; this.m_maxTicks = this.m_duration / this.m_amplitude; this.m_channelHandlers = channelHandlers; this.m_duration = spell.GetDuration(casterUnit.SharedReference); if (this.m_amplitude < 1) { this.m_amplitude = this.m_duration; } this.m_until = tickCount + this.m_duration; SpellHandler.SendChannelStart(this.m_cast, spell.SpellId, this.m_duration); if (!this.m_channeling) { return; } this.m_timer.Start(this.m_amplitude, this.m_amplitude); } else { SpellChannel.log.Warn(this.ToString() + " was opened more than once or after disposal!"); } }
public override void Convert(byte[] rawData) { #region Parsing int currentIndex = 0; var spell = new Spell { Id = GetUInt32(rawData, currentIndex++), SpellId = (SpellId)GetInt32(rawData, 0) }; try { spell.Category = GetUInt32(rawData, currentIndex++); // 1+ spell.DispelType = (DispelType)GetUInt32(rawData, currentIndex++); // 2+ spell.Mechanic = (SpellMechanic)GetUInt32(rawData, currentIndex++); // 3+ spell.Attributes = (SpellAttributes)GetUInt32(rawData, currentIndex++); // 4+ spell.AttributesEx = (SpellAttributesEx)GetUInt32(rawData, currentIndex++); // 5+ spell.AttributesExB = (SpellAttributesExB)GetUInt32(rawData, currentIndex++); // 6+ spell.AttributesExC = (SpellAttributesExC)GetUInt32(rawData, currentIndex++); // 7+ spell.AttributesExD = (SpellAttributesExD)GetUInt32(rawData, currentIndex++); // 8+ spell.AttributesExE = (SpellAttributesExE)GetUInt32(rawData, currentIndex++); // 9 spell.AttributesExF = (SpellAttributesExF)GetUInt32(rawData, currentIndex++); // 10 spell.RequiredShapeshiftMask = (ShapeshiftMask)GetUInt32(rawData, currentIndex++); // 11- spell.Unk_322_1 = GetUInt32(rawData, currentIndex++); // 12 spell.ExcludeShapeshiftMask = (ShapeshiftMask)GetUInt32(rawData, currentIndex++); // 13- spell.Unk_322_2 = GetUInt32(rawData, currentIndex++); // 14 spell.TargetFlags = (SpellTargetFlags)GetUInt32(rawData, currentIndex++); // 15+ spell.Unk_322_3 = GetUInt32(rawData, currentIndex++); // 16 spell.CreatureMask = (CreatureMask)GetUInt32(rawData, currentIndex++); // 17- spell.RequiredSpellFocus = (SpellFocus)GetUInt32(rawData, currentIndex++); // 18- 0 spell.FacingFlags = (SpellFacingFlags)GetUInt32(rawData, currentIndex++); // 19- spell.RequiredCasterAuraState = (AuraState)GetUInt32(rawData, currentIndex++); // 20+- spell.RequiredTargetAuraState = (AuraState)GetUInt32(rawData, currentIndex++); // 21+- spell.ExcludeCasterAuraState = (AuraState)GetUInt32(rawData, currentIndex++); // 22+- spell.ExcludeTargetAuraState = (AuraState)GetUInt32(rawData, currentIndex++); // 23+- spell.RequiredCasterAuraId = (SpellId)GetUInt32(rawData, currentIndex++); // 24+- spell.RequiredTargetAuraId = (SpellId)GetUInt32(rawData, currentIndex++); // 25+- spell.ExcludeCasterAuraId = (SpellId)GetUInt32(rawData, currentIndex++); // 26+- spell.ExcludeTargetAuraId = (SpellId)GetUInt32(rawData, currentIndex++); // 27+- int castTimeIndex = GetInt32(rawData, currentIndex++); // 28+ if (castTimeIndex > 0) { if (!mappeddbcCastTimeReader.Entries.TryGetValue(castTimeIndex, out spell.CastDelay)) { ContentMgr.OnInvalidClientData("DBC Spell \"{0}\" referred to invalid CastTime-Entry: {1}", spell.Name, castTimeIndex); } } spell.CooldownTime = Math.Max(0, GetInt32(rawData, currentIndex++) - (int)spell.CastDelay); // 29+ spell.categoryCooldownTime = GetInt32(rawData, currentIndex++); // 30+- spell.InterruptFlags = (InterruptFlags)GetUInt32(rawData, currentIndex++); // 31+- spell.AuraInterruptFlags = (AuraInterruptFlags)GetUInt32(rawData, currentIndex++); // 32+- spell.ChannelInterruptFlags = (ChannelInterruptFlags)GetUInt32(rawData, currentIndex++); // 33+- spell.ProcTriggerFlagsProp = (ProcTriggerFlags)GetUInt32(rawData, currentIndex++); // 34++- spell.ProcChance = GetUInt32(rawData, currentIndex++); // 35++- spell.ProcCharges = GetInt32(rawData, currentIndex++); // 36++- spell.MaxLevel = GetInt32(rawData, currentIndex++); // 37+ spell.BaseLevel = GetInt32(rawData, currentIndex++); // 38+ spell.Level = GetInt32(rawData, currentIndex++); // 30+ var durationIndex = GetInt32(rawData, currentIndex++); // 40+ if (durationIndex > 0) { if (!mappeddbcDurationReader.Entries.TryGetValue(durationIndex, out spell.Durations)) { ContentMgr.OnInvalidClientData("DBC Spell \"{0}\" referred to invalid Duration-Entry: {1}", spell.Name, durationIndex); } } spell.PowerType = (PowerType)GetUInt32(rawData, currentIndex++); // 41+ always mana spell.PowerCost = GetInt32(rawData, currentIndex++); // 42+ spell.PowerCostPerlevel = GetInt32(rawData, currentIndex++); // 43+ spell.PowerPerSecond = GetInt32(rawData, currentIndex++); // 44+ spell.PowerPerSecondPerLevel = GetInt32(rawData, currentIndex++); // 45- var rangeIndex = GetInt32(rawData, currentIndex++); // 46+ if (rangeIndex > 0) { if (!mappeddbcRangeReader.Entries.TryGetValue(rangeIndex, out spell.Range)) { ContentMgr.OnInvalidClientData("DBC Spell \"{0}\" referred to invalid Range-Entry: {1}", spell.Name, rangeIndex); } } spell.ProjectileSpeed = GetFloat(rawData, currentIndex++); // 47+ spell.ModalNextSpell = (SpellId)GetUInt32(rawData, currentIndex++); // 48- spell.MaxStackCount = GetInt32(rawData, currentIndex++); // 49+ 1 spell.RequiredToolIds = new uint[2]; // 50-51+- for (var i = 0; i < spell.RequiredToolIds.Length; i++) { spell.RequiredToolIds[i] = GetUInt32(rawData, currentIndex++); } List <ItemStackDescription> reagents = null; int reagentStart = currentIndex; for (int i = 0; i < 8; i++) //52-59 - spell.Reagents = ItemStackDescription.EmptyArray; { ReadReagent(rawData, reagentStart, i, out currentIndex, ref reagents); } if (reagents != null) { spell.Reagents = reagents.ToArray(); } else { spell.Reagents = ItemStackDescription.EmptyArray; } spell.RequiredItemClass = (ItemClass)GetUInt32(rawData, currentIndex++); //68+ spell.RequiredItemClass = ItemClass.None; if (spell.RequiredItemClass < 0) { spell.RequiredItemClass = ItemClass.None; } spell.RequiredItemSubClassMask = (ItemSubClassMask)GetUInt32(rawData, currentIndex++); // 69+ spell.RequiredItemSubClassMask = ItemSubClassMask.None; if (spell.RequiredItemSubClassMask < 0) { spell.RequiredItemSubClassMask = ItemSubClassMask.None; } spell.RequiredItemInventorySlotMask = (InventorySlotTypeMask)GetUInt32(rawData, currentIndex++); // 70 + spell.RequiredItemInventorySlotMask = InventorySlotTypeMask.None; if (spell.RequiredItemInventorySlotMask < 0) { spell.RequiredItemInventorySlotMask = InventorySlotTypeMask.None; } var effects = new List <SpellEffect>(3); // 71 - 127+ int effectStart = currentIndex; for (int i = 0; i < 3; i++) { var effect = ReadEffect(spell, rawData, effectStart, i, out currentIndex); if (effect != null && (effect.EffectType != SpellEffectType.None || effect.BasePoints > 0 || effect.AuraType != 0 || effect.TriggerSpellId != 0)) { effects.Add(effect); } } spell.Effects = effects.ToArray(); spell.Visual = GetUInt32(rawData, currentIndex++); // 128- spell.Visual2 = GetUInt32(rawData, currentIndex++); // 129- spell.SpellbookIconId = GetUInt32(rawData, currentIndex++); // 130- spell.BuffIconId = GetUInt32(rawData, currentIndex++); // 131- spell.Priority = GetUInt32(rawData, currentIndex++); // 132- spell.Name = GetString(rawData, ref currentIndex); // 133+ spell.RankDesc = GetString(rawData, ref currentIndex); // 124- spell.Description = GetString(rawData, ref currentIndex); // 125+ spell.BuffDescription = GetString(rawData, ref currentIndex); // 126- spell.PowerCostPercentage = GetInt32(rawData, currentIndex++); // 127+- spell.StartRecoveryTime = GetInt32(rawData, currentIndex++); // 128- spell.StartRecoveryCategory = GetInt32(rawData, currentIndex++); // 129- spell.MaxTargetLevel = GetUInt32(rawData, currentIndex++); // 130- spell.SpellClassSet = (SpellClassSet)GetUInt32(rawData, currentIndex++); // 131+ spell.SpellClassMask[0] = GetUInt32(rawData, currentIndex++); // 132- spell.SpellClassMask[1] = GetUInt32(rawData, currentIndex++); // 133- spell.SpellClassMask[2] = GetUInt32(rawData, currentIndex++); // 134- spell.MaxTargets = GetUInt32(rawData, currentIndex++); // 135+ spell.DamageType = (DamageType)GetUInt32(rawData, currentIndex++); // 136+ spell.PreventionType = (SpellPreventionType)GetUInt32(rawData, currentIndex++); // 137+ spell.StanceBarOrder = GetInt32(rawData, currentIndex++); // 138- for (int i = 0; i < spell.DamageMultipliers.Length; i++) // 139-141+ { spell.DamageMultipliers[i] = GetFloat(rawData, currentIndex++); } spell.MinFactionId = GetUInt32(rawData, currentIndex++); // 142- spell.MinReputation = GetUInt32(rawData, currentIndex++); // 143- spell.RequiredAuraVision = GetUInt32(rawData, currentIndex++); // 144- spell.RequiredToolCategories = new ToolCategory[2]; // 145-146+ for (int i = 0; i < spell.RequiredToolCategories.Length; i++) { spell.RequiredToolCategories[i] = (ToolCategory)GetUInt32(rawData, currentIndex++); } spell.AreaGroupId = GetUInt32(rawData, currentIndex++); //- spell.SchoolMask = (DamageSchoolMask)GetUInt32(rawData, currentIndex++); //+ var runeCostId = GetInt32(rawData, currentIndex++); //- if (runeCostId != 0) { mappeddbcRuneCostReader.Entries.TryGetValue(runeCostId, out spell.RuneCostEntry); } spell.MissileId = GetUInt32(rawData, currentIndex++); //- // New 3.1.0. Id from PowerDisplay.dbc spell.PowerDisplayId = GetInt32(rawData, currentIndex++); //- // 3.2.2 unk float (array?) spell.Unk_322_4_1 = GetUInt32(rawData, currentIndex++); //- spell.Unk_322_4_2 = GetUInt32(rawData, currentIndex++); //- spell.Unk_322_4_3 = GetUInt32(rawData, currentIndex++); //- // 3.2.2 spell.spellDescriptionVariablesID = GetUInt32(rawData, currentIndex++); //- } catch (Exception e) { throw new Exception(string.Format("Unable to parse Spell from DBC file. Index: " + currentIndex), e); } #endregion SpellHandler.AddSpell(spell); }
public void FinalizeDataHolder() { try { //Id SpellId = (SpellId)Id; PowerType = PowerType.Mana; Durations = new DurationEntry() { Min = Duration, Max = Duration }; Range = new SimpleRange(0, MaxRange); ProjectileSpeed = 1; RequiredToolIds = new uint[2]; Reagents = ItemStackDescription.EmptyArray; RequiredItemClass = ItemClass.None; RequiredItemSubClassMask = ItemSubClassMask.None; if (Id == 2228 || Id == 2231 || Id == 2234 || Id == 2237 || Id == 2240 || Id == 2243 || Id == 2246 || Id == 2249 || Id == 2252) { SoulGuardProffLevel = 1; } if (Id == 2229 || Id == 2232 || Id == 2235 || Id == 2238 || Id == 2241 || Id == 2244 || Id == 2247 || Id == 2250 || Id == 2253) { SoulGuardProffLevel = 2; } if (Id == 2230 || Id == 2233 || Id == 2236 || Id == 2239 || Id == 2242 || Id == 2245 || Id == 2248 || Id == 2251 || Id == 2254) { SoulGuardProffLevel = 3; } RequiredItemInventorySlotMask = InventorySlotTypeMask.None; var effects = new List <SpellEffect>(3); // 71 - 127+ #region read effects var effect = new SpellEffect(this, EffectIndex.Zero) { EffectType = Effect0_EffectType, DiceSides = 0, RealPointsPerLevel = 0, BasePoints = 0, Mechanic = Effect0_Mehanic, ImplicitTargetA = Effect0_ImplicitTargetA, ImplicitTargetB = Effect0_ImplicitTargetB, Radius = Effect0_Radius, AuraType = Effect0_AuraType, Amplitude = Effect0_Amplitude, ProcValue = Effect0_ProcValue, ChainTargets = 0, MiscValue = Effect0_MiscValue, MiscValueB = Effect0_MiscValueB, MiscValueC = Effect0_MiscValueC, TriggerSpellId = SpellId.None, PointsPerComboPoint = 0 }; effect.AffectMask[0] = 0; effect.AffectMask[1] = 0; effect.AffectMask[2] = 0; // Fix: This is a default AoE effect, thus doesn't have a fact at destination if (effect.ImplicitTargetA == ImplicitSpellTargetType.AllEnemiesAroundCaster && effect.ImplicitTargetB == ImplicitSpellTargetType.AllEnemiesInArea) { effect.ImplicitTargetB = ImplicitSpellTargetType.None; } effects.Add(effect); effect = new SpellEffect(this, EffectIndex.One) { EffectType = Effect1_EffectType, DiceSides = 0, RealPointsPerLevel = 0, BasePoints = 0, Mechanic = Effect1_Mehanic, ImplicitTargetA = Effect1_ImplicitTargetA, ImplicitTargetB = Effect1_ImplicitTargetB, Radius = Effect1_Radius, AuraType = Effect1_AuraType, Amplitude = Effect1_Amplitude, ProcValue = Effect1_ProcValue, ChainTargets = 0, MiscValue = Effect1_MiscValue, MiscValueB = Effect1_MiscValueB, MiscValueC = Effect1_MiscValueC, TriggerSpellId = SpellId.None, PointsPerComboPoint = 0 }; effect.AffectMask[0] = 0; effect.AffectMask[1] = 0; effect.AffectMask[2] = 0; // Fix: This is a default AoE effect, thus doesn't have a fact at destination if (effect.ImplicitTargetA == ImplicitSpellTargetType.AllEnemiesAroundCaster && effect.ImplicitTargetB == ImplicitSpellTargetType.AllEnemiesInArea) { effect.ImplicitTargetB = ImplicitSpellTargetType.None; } effects.Add(effect); #endregion Effects = effects.ToArray(); PowerCostPercentage = 0; // 127+- SpellClassSet = SpellClassSet.Generic; // 131+ MaxTargets = 100; // 135+ PreventionType = DamageType == DamageType.Magic ? SpellPreventionType.Magic : SpellPreventionType.Melee; //DamageMultipliers RequiredToolCategories = new ToolCategory[2]; // 145-146+ for (int i = 0; i < RequiredToolCategories.Length; i++) { RequiredToolCategories[i] = ToolCategory.None; } RuneCostEntry = new RuneCostEntry(); if (CooldownTime > 5000) { CooldownTime -= 1000; } else if (CooldownTime > 0) { CooldownTime -= 500; } if (Name.Contains("Party")) { Effect0_ImplicitTargetA = ImplicitSpellTargetType.AllParty; Effect1_ImplicitTargetA = ImplicitSpellTargetType.AllParty; } SpellHandler.AddSpell(this); } catch (Exception ex) { LogUtil.WarnException("Error when finalizing data holder of spell {0}. {1}", Name, ex); } }
public void Convert(uint index, RuneType to) { this.ActiveRunes[index] = to; SpellHandler.SendConvertRune(this.Owner.Client, index, to); }
public SkillLearnStatus TryLearnSpell(short skillId, byte level) { Spell spell = SpellHandler.Get((uint)skillId + (uint)level * 1000U); if (spell == null || level <= (byte)0) { return(SkillLearnStatus.Fail); } if ((int)spell.LearnLevel > this.OwnerChar.Level) { return(SkillLearnStatus.LowLevel); } if (spell.ClassMask != Asda2ClassMask.All && !spell.ClassMask.HasFlag((Enum)this.OwnerChar.Asda2ClassMask) || (int)spell.ProffNum > (int)this.OwnerChar.RealProffLevel) { return(SkillLearnStatus.JoblevelIsNotHighEnought); } if (this.AvalibleSkillPoints <= 0) { return(SkillLearnStatus.NotEnoghtSpellPoints); } if (!this.OwnerChar.SubtractMoney((uint)spell.Cost)) { return(SkillLearnStatus.NotEnoghtMoney); } AchievementProgressRecord progressRecord = this.OwnerChar.Achievements.GetOrCreateProgressRecord(1U); ++progressRecord.Counter; if (progressRecord.Counter == 45U) { switch (this.OwnerChar.Profession) { case Asda2Profession.Warrior: this.OwnerChar.DiscoverTitle(Asda2TitleId.ofBattle24); break; case Asda2Profession.Archer: this.OwnerChar.DiscoverTitle(Asda2TitleId.ofArchery25); break; case Asda2Profession.Mage: this.OwnerChar.DiscoverTitle(Asda2TitleId.ofMagic26); break; } } if (progressRecord.Counter > 90U) { switch (this.OwnerChar.Profession) { case Asda2Profession.Warrior: this.OwnerChar.GetTitle(Asda2TitleId.ofBattle24); break; case Asda2Profession.Archer: this.OwnerChar.GetTitle(Asda2TitleId.ofArchery25); break; case Asda2Profession.Mage: this.OwnerChar.GetTitle(Asda2TitleId.ofMagic26); break; } } progressRecord.SaveAndFlush(); if (level > (byte)1) { Spell oldSpell = this.FirstOrDefault <Spell>((Func <Spell, bool>)(s => (int)s.RealId == (int)skillId)); if (oldSpell == null || oldSpell.Level != spell.Level - 1) { return(SkillLearnStatus.BadSpellLevel); } this.Replace(oldSpell, spell); return(SkillLearnStatus.Ok); } this.AddSpell(spell, true); this.OwnerChar.SendMoneyUpdate(); return(SkillLearnStatus.Ok); }
public override void AddDefaultSpells() { this.AddNew(SpellHandler.Get(SpellId.BashRank1)); this.AddNew(SpellHandler.Get(SpellId.ArrowStrikeRank1)); }
/// <summary> /// Teaches a new spell to the unit. Also sends the spell learning animation, if applicable. /// </summary> public void AddSpell(SpellId spellId) { var spell = SpellHandler.Get(spellId); AddSpell(spell); }
public void Remove(SpellId spellId) { Replace(SpellHandler.Get(spellId), null); }
public void Remove(SpellId spellId) { this.Replace(SpellHandler.Get(spellId), (Spell)null); }