예제 #1
0
        /// <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);
        }
예제 #2
0
 /// <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));
     }
 }
예제 #3
0
        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);
        }
예제 #4
0
 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);
     }
 }
예제 #5
0
        public override void Clear()
        {
            foreach (var spell in m_byId.Values.ToArray())
            {
                OnRemove(spell);
                if (m_sendPackets)
                {
                    SpellHandler.SendSpellRemoved(OwnerChar, spell.Id);
                }
            }

            base.Clear();
        }
예제 #6
0
        /// <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
            }
        }
예제 #7
0
        /// <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!");
            }
        }
예제 #8
0
        /// <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;
        }
예제 #9
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);
         }
     }
 }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        /// <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);
        }
예제 #13
0
        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);
        }
예제 #14
0
        /// <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);
        }
예제 #15
0
        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);
        }
예제 #16
0
        /// <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;
        }
예제 #17
0
        /// <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);
            }
        }
예제 #18
0
        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);
            //    }
            //}
        }
예제 #19
0
        /// <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);
            }
        }
예제 #20
0
        /// <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();
                    }
                }
                                                           ));
            }
        }
예제 #21
0
        /// <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];
            }
        }
예제 #22
0
 /// <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!");
     }
 }
예제 #23
0
            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);
            }
예제 #24
0
        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);
            }
        }
예제 #25
0
 public void Convert(uint index, RuneType to)
 {
     this.ActiveRunes[index] = to;
     SpellHandler.SendConvertRune(this.Owner.Client, index, to);
 }
예제 #26
0
        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);
        }
예제 #27
0
 public override void AddDefaultSpells()
 {
     this.AddNew(SpellHandler.Get(SpellId.BashRank1));
     this.AddNew(SpellHandler.Get(SpellId.ArrowStrikeRank1));
 }
예제 #28
0
        /// <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);
        }
예제 #29
0
 public void Remove(SpellId spellId)
 {
     Replace(SpellHandler.Get(spellId), null);
 }
예제 #30
0
 public void Remove(SpellId spellId)
 {
     this.Replace(SpellHandler.Get(spellId), (Spell)null);
 }