Ejemplo n.º 1
0
        public static void Cast(this Unit u, SpellCast spell)
        {
            if (u.SpellCast[spell.SpellType] != spell) //Check it is the right spell
            {
                u.SendCastResult(SpellFailedReason.SPELL_FAILED_NOT_KNOWN, spell.Spell.Id);
                return;
            }

            SpellFailedReason reason = u.CanCast(spell, false);

            if (reason != SpellFailedReason.SPELL_FAILED_NO_REASON) //Final check we can cast this
            {
                u.SendCastResult(reason, spell.Spell.Id);
                return;
            }

            int SpellTime = 0;

            if (spell.Spell.speed > 0)
            {
                float SpellDistance = 0;
                if (spell.Targets.Target != null)
                {
                    SpellDistance = u.Location.Distance(spell.Targets.Target.Location);
                }
                else if (spell.Targets.TargetLocation != null)
                {
                    SpellDistance = u.Location.Distance(spell.Targets.TargetLocation);
                }

                if (SpellDistance > 0)
                {
                    SpellTime = (int)Math.Floor(SpellDistance / spell.Spell.speed * 1000);
                }
            }

            Dictionary <WorldObject, SpellMissInfo>[] TargetsInfected = new Dictionary <WorldObject, SpellMissInfo> [3];
            TargetsInfected[0] = spell.GetTargets(0);
            TargetsInfected[1] = spell.GetTargets(1);
            TargetsInfected[2] = spell.GetTargets(2);

            if (Flag.HasFlag(spell.Spell.Attributes, (uint)SpellAttributes.SPELL_ATTR_ON_NEXT_SWING_1) || Flag.HasFlag(spell.Spell.Attributes, (uint)SpellAttributes.SPELL_ATTR_ON_NEXT_SWING_2))
            {
                //TODO combat spell
            }

            if (spell.Caster.IsTypeOf(ObjectTypes.TYPE_PLAYER))
            {
                spell.SendCooldown();
                Player p = (Player)u;

                //Reagents
                for (uint i = 0; i < 7; i++)
                {
                    if (spell.Spell.Reagent[i] > 0 && spell.Spell.ReagentCount[i] > 0)
                    {
                        p.RemoveItem(spell.Spell.Reagent[i], spell.Spell.ReagentCount[i]);
                    }
                }

                //TODO ammo

                switch ((PowerTypes)spell.Spell.powerType)
                {
                case PowerTypes.TYPE_MANA:
                    if (Flag.HasFlag(spell.Spell.Attributes, (uint)SpellAttributesEx.SPELL_ATTR_EX_DRAIN_ALL_POWER))
                    {
                        p.Mana.Current = 0;
                    }
                    else
                    {
                        p.Mana.Current -= spell.GetManaCost(p.Mana.Current);
                    }
                    break;

                case PowerTypes.TYPE_RAGE:
                    if (Flag.HasFlag(spell.Spell.Attributes, (uint)SpellAttributesEx.SPELL_ATTR_EX_DRAIN_ALL_POWER))
                    {
                        p.Rage.Current = 0;
                    }
                    else
                    {
                        p.Rage.Current = (p.Rage.Current - spell.GetManaCost(p.Rage.Current)) / 10;
                    }
                    break;

                case PowerTypes.POWER_HEALTH:
                    if (Flag.HasFlag(spell.Spell.Attributes, (uint)SpellAttributesEx.SPELL_ATTR_EX_DRAIN_ALL_POWER))
                    {
                        p.Health.Current = 1;
                    }
                    else
                    {
                        p.Health.Current -= spell.GetManaCost(p.Health.Current);
                    }
                    break;

                case PowerTypes.TYPE_FOCUS:
                    if (Flag.HasFlag(spell.Spell.Attributes, (uint)SpellAttributesEx.SPELL_ATTR_EX_DRAIN_ALL_POWER))
                    {
                        p.Focus.Current = 0;
                    }
                    else
                    {
                        p.Focus.Current -= spell.GetManaCost(p.Focus.Current);
                    }
                    break;

                case PowerTypes.TYPE_ENERGY:
                    if (Flag.HasFlag(spell.Spell.Attributes, (uint)SpellAttributesEx.SPELL_ATTR_EX_DRAIN_ALL_POWER))
                    {
                        p.Energy.Current = 0;
                    }
                    else
                    {
                        p.Energy.Current -= spell.GetManaCost(p.Energy.Current);
                    }
                    break;
                }
            }
            else if (spell.Caster.IsTypeOf(ObjectTypes.TYPE_UNIT))
            {
                switch ((PowerTypes)spell.Spell.powerType)
                {
                case PowerTypes.TYPE_MANA:
                    u.Mana.Current -= spell.GetManaCost(u.Mana.Current);
                    break;

                case PowerTypes.POWER_HEALTH:
                    u.Health.Current -= spell.GetManaCost(u.Health.Current);
                    break;
                }
            }

            u.SpellCast[spell.SpellType].State = SpellState.SPELL_STATE_FINISHED;
            Dictionary <WorldObject, SpellMissInfo> TrueTargets = TargetsInfected[0].Concat(TargetsInfected[1]).Concat(TargetsInfected[2])
                                                                  .Where(w => w.Value == SpellMissInfo.MISS_NONE).GroupBy(d => d.Key)
                                                                  .ToDictionary(d => d.Key, d => d.First().Value);

            for (int i = 0; i < 3; i++)
            {
                List <WorldObject> targets = TargetsInfected[i].Where(x => x.Value == SpellMissInfo.MISS_NONE).Select(x => x.Key).ToList();
                reason = SpellEffect.InvokeHandler((SpellEffects)spell.Spell.Effect[i], spell, targets, i, null);

                if (reason != SpellFailedReason.SPELL_FAILED_NO_REASON)
                {
                    break;
                }
            }

            if (reason == SpellFailedReason.SPELL_FAILED_NO_REASON)
            {
                spell.SendSpellGo();
                spell.SendChannelUpdate(0);
                u.SendCastResult(SpellFailedReason.SPELL_FAILED_NO_REASON, spell.Spell.Id);
            }
            else
            {
                u.SendCastResult(reason, spell.Spell.Id);
            }

            spell.State = SpellState.SPELL_STATE_FINISHED;
            GridManager.Instance.SendSurrounding(u.BuildUpdate(), u);
        }