Exemplo n.º 1
0
 /// <summary>
 /// Deals environmental damage to this Unit (cannot be resisted)
 /// </summary>
 public virtual void DealEnvironmentalDamage(EnviromentalDamageType dmgType, int amount)
 {
     DoRawDamage(new SimpleDamageAction {
         Damage = amount, Victim = this
     });
     CombatLogHandler.SendEnvironmentalDamage(this, dmgType, (uint)amount);
 }
Exemplo n.º 2
0
        /// <summary>
        /// Deals environmental damage to this Unit (cannot be resisted)
        /// </summary>
        public virtual void DealEnvironmentalDamage(EnviromentalDamageType dmgType, int amount)
        {
            //if (dmgType == EnviromentalDamageType.Fall)
            //{
            //    amount -= (int)(SafeFall * (amount / 100f));
            //}

            DoRawDamage(new SimpleDamageAction {
                Damage = amount, Victim = this
            });
            CombatLogHandler.SendEnvironmentalDamage(this, dmgType, (uint)amount);
        }
Exemplo n.º 3
0
            public override void Process(CmdTrigger <RealmServerCmdArgs> trigger)
            {
                var unkBool  = trigger.Text.NextBool();
                var flags    = trigger.Text.NextEnum(SpellLogFlags.SpellLogFlag_0x1);
                var spell    = trigger.Text.NextEnum(SpellId.ClassSkillFireballRank1);
                var damage   = trigger.Text.NextUInt(10);
                var overkill = trigger.Text.NextUInt(0);
                var schools  = trigger.Text.NextEnum(DamageSchoolMask.Fire);
                var absorbed = trigger.Text.NextUInt(0);
                var resisted = trigger.Text.NextUInt(0);
                var blocked  = trigger.Text.NextUInt(0);

                CombatLogHandler.SendMagicDamage(trigger.Args.Target, trigger.Args.User, spell, damage, overkill, schools, absorbed, resisted, blocked, unkBool, flags);
            }
Exemplo n.º 4
0
        /// <summary>
        /// Strikes the target
        /// </summary>
        public void DoStrike()
        {
            if (Damage > 0)
            {
                var level = Attacker.Level;
                var res   = Victim.GetResistance(UsedSchool) - Attacker.GetTargetResistanceMod(UsedSchool);

                if (res > 0)
                {
                    ProcHitFlags |= ProcHitFlags.Resist;

                    // This formula only applies for armor
                    if (UsedSchool == DamageSchool.Physical)
                    {
                        if (level < 60)
                        {
                            ResistPct = (res / (res + 400f + 85f * level)) * 100f;
                        }
                        else
                        {
                            ResistPct = (res / (res - 22167.5f + 467.5f * level)) * 100f;
                        }
                    }
                    else
                    {
                        // Magical damageschool
                        ResistPct = Victim.GetResistChancePct(Attacker, UsedSchool);
                    }
                }
                else
                {
                    ResistPct = 0;
                }

                if (ResistPct > 75)
                {
                    ResistPct = 75;
                }
                if (ResistPct < 0)
                {
                    ResistPct = 0;
                }

                Victim.DeathPrevention++;
                Attacker.DeathPrevention++;
                try
                {
                    // add mods and call events
                    AddDamageMods();
                    Victim.OnDefend(this);
                    Attacker.OnAttack(this);

                    Resisted = MathUtil.RoundInt(ResistPct * Damage / 100f);
                    if (Absorbed > 0)
                    {
                        HitFlags     |= HitFlags.AbsorbType1 | HitFlags.AbsorbType2;
                        ProcHitFlags |= ProcHitFlags.Absorb;
                    }
                    else
                    {
                        Absorbed = Resisted = 0;
                    }

                    if (Weapon == Attacker.OffHandWeapon)
                    {
                        HitFlags |= HitFlags.OffHand;
                    }

                    Victim.DoRawDamage(this);
                }
                finally
                {
                    Victim.DeathPrevention--;
                    Attacker.DeathPrevention--;
                }
            }

            //if ()
            //CombatHandler.SendMeleeDamage(attacker, this, schools, hitInfo, (uint)totalDamage,
            //(uint)absorbed, (uint)resisted, (uint)blocked, victimState);
            if (SpellEffect != null)
            {
                CombatLogHandler.SendMagicDamage(this);
            }
            else
            {
                CombatHandler.SendAttackerStateUpdate(this);
            }

            TriggerProcOnStrike();
        }
Exemplo n.º 5
0
        /// <summary>
        /// Validates targets and applies all SpellEffects
        /// </summary>
        public SpellFailedReason Impact()
        {
            if (!IsCasting)
            {
                return(SpellFailedReason.Ok);
            }

            // apply effects
            foreach (var handler in Handlers)
            {
                if (handler.Effect.IsPeriodic || handler.Effect.IsStrikeEffect)
                {
                    // weapon ability or handled by Aura or Channel
                    continue;
                }

                handler.Apply();
                if (!IsCasting)
                {
                    // the last handler cancelled the SpellCast
                    return(SpellFailedReason.DontReport);
                }
            }

            if (CasterObject is Unit && Spell.IsPhysicalAbility)
            {
                // strike at everyone
                foreach (var target in UnitTargets)
                {
                    ProcHitFlags hitFlags = CasterUnit.Strike(GetWeapon(), target, this);
                    m_hitInfoByTarget[target] = hitFlags;
                }
            }

            // open Channel and spawn DynamicObject
            DynamicObject dynObj = null;

            if (Spell.DOEffect != null)
            {
                dynObj = new DynamicObject(this, Spell.DOEffect.GetRadius(CasterReference));
            }

            if (!IsCasting)
            {
                return(SpellFailedReason.Ok);
            }

            List <MissedTarget> missedTargets = null;
            // create auras
            List <IAura> auras = null;

            if (m_auraApplicationInfos != null)
            {
                CreateAuras(ref missedTargets, ref auras, dynObj);
            }

            // check for missed targets
            if (missedTargets != null)
            {
                if (missedTargets.Count > 0)
                {
                    // TODO: Flash message ontop of missed heads when impact is delayed
                    CombatLogHandler.SendSpellMiss(this, true, missedTargets);
                    missedTargets.Clear();
                }

                CastMissListPool.Recycle(missedTargets);
            }

            // open channel
            if (Spell.IsChanneled && CasterObject != null)
            {
                Channel        = SpellChannel.SpellChannelPool.Obtain();
                Channel.m_cast = this;

                if (CasterObject is Unit)
                {
                    if (dynObj != null)
                    {
                        CasterUnit.ChannelObject = dynObj;
                    }
                    else if (SelectedTarget != null)
                    {
                        CasterUnit.ChannelObject = SelectedTarget;
                        if (SelectedTarget is NPC && Spell.IsTame)
                        {
                            ((NPC)SelectedTarget).CurrentTamer = CasterObject as Character;
                        }
                    }
                }

                var len = Handlers.Length;
                var channelEffectHandlers = SpellEffectHandlerListPool.Obtain();
                //var channelEffectHandlers = new List<SpellEffectHandler>(6);
                for (var i = 0; i < len; i++)
                {
                    var handler = Handlers[i];
                    if (handler.Effect.IsPeriodic)
                    {
                        channelEffectHandlers.Add(handler);
                    }
                }
                Channel.Open(channelEffectHandlers, auras);
            }

            // start Auras
            if (auras != null)
            {
                for (var i = 0; i < auras.Count; i++)
                {
                    var aura = auras[i];
                    aura.Start(Spell.IsChanneled ? Channel : null, false);
                }

                if (!IsChanneling)
                {
                    auras.Clear();
                    AuraListPool.Recycle(auras);
                    auras = null;
                }
            }

            // applying debuffs might cancel other Auras
            if (Spell.HasHarmfulEffects && !Spell.IsPreventionDebuff)
            {
                foreach (var target in Targets)
                {
                    if (target is Unit && Spell.IsHarmfulFor(CasterReference, target))
                    {
                        ((Unit)target).Auras.RemoveByFlag(AuraInterruptFlags.OnHostileSpellInflicted);
                    }
                }
            }

            //if (CasterChar != null)
            //{
            //    CasterChar.SendSystemMessage("SpellCast (Impact): {0} ms", sw1.ElapsedTicks / 10000d);
            //}

            return(SpellFailedReason.Ok);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Does spell-damage to this Unit
        /// </summary>
        public void DealSpellDamage(Unit attacker, SpellEffect effect, int dmg, bool addDamageBonuses = true, bool mayCrit = true, bool forceCrit = false)
        {
            EnsureContext();
            if (!IsAlive)
            {
                return;
            }
            if (attacker != null && !attacker.IsInContext)
            {
                attacker = null;
            }
            if (attacker is NPC)
            {
                dmg = (int)(dmg * NPCMgr.DefaultNPCDamageFactor + 0.999999f);
            }

            DamageSchool school;

            if (effect != null)
            {
                school = GetLeastResistantSchool(effect.Spell);
                if (effect.Spell.DamageIncreasedByAP)
                {
                    int ap;
                    if (effect.Spell.IsRangedAbility)
                    {
                        ap = TotalRangedAP;
                    }
                    else
                    {
                        ap = TotalMeleeAP;
                    }

                    dmg += (ap + 7) / 14;                     // round
                }
            }
            else
            {
                school = DamageSchool.Physical;
            }

            if (IsEvading || IsImmune(school) || IsInvulnerable || !IsAlive)
            {
                // cannot deal damage to this guy
                return;
            }

            var action = GetUnusedAction();

            // reset values
            action.Attacker    = attacker;
            action.HitFlags    = 0;
            action.VictimState = 0;
            action.Weapon      = null;

            if (effect != null)
            {
                // Some kind of spell is involved
                action.UsedSchool = school;
                action.Schools    = effect.Spell.SchoolMask;
                action.IsDot      = effect.IsPeriodic;
            }
            else
            {
                // pure white melee damage
                action.UsedSchool = DamageSchool.Physical;
                action.Schools    = DamageSchoolMask.Physical;
                action.IsDot      = false;
            }

            action.Damage      = dmg;
            action.ResistPct   = GetResistChancePct(this, action.UsedSchool);
            action.Absorbed    = 0;
            action.SpellEffect = effect;

            action.Victim = this;
            if (attacker != null)
            {
                attacker.DeathPrevention++;
            }

            DeathPrevention++;
            try
            {
                if (attacker != null)
                {
                    // the damage is caused by someone else (i.e. not environmental damage etc)

                    // critical hits
                    if (forceCrit || action.CalcCritChance() > Utility.Random(0, 10000))
                    {
                        action.IsCritical = true;
                        action.SetCriticalDamage();
                    }
                    else
                    {
                        action.IsCritical = false;
                    }

                    // add mods and call events
                    if (addDamageBonuses)
                    {
                        action.AddDamageMods();
                    }

                    OnDefend(action);
                    attacker.OnAttack(action);
                }

                action.Resisted = (int)Math.Round(action.Damage * action.ResistPct / 100);
                action.Blocked  = 0;                // TODO: Deflect

                DoRawDamage(action);

                CombatLogHandler.SendMagicDamage(action);
            }
            finally
            {
                DeathPrevention--;
                if (attacker != null)
                {
                    attacker.DeathPrevention--;
                }
                action.OnFinished();
            }
            //Your average resistance can still be anywhere betweeen 0% and 75%. If your average resistance is maxed out, then there's a really good chance of having 75% of the spell's damage be resisted.
            //There's also a fairly good chance of having 100% of the spell's damage be resisted, a slightly lower chance of 50% of its damage being resisted, a small chances of only 25%, or even 0% of the damage being resisted.
            //It's a weighted average. Visualize it as a bell curve around your average resistance.
        }